aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
commitc6da2cfeb05178a11c6d062a06f8078150ee492f (patch)
treef3b4021d252c52d6463a9b3c1bb7245e399b009c /arch
parentc6d7c4dbff353eac7919342ae6b3299a378160a6 (diff)
downloadkernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2
samsung update 1
Diffstat (limited to 'arch')
-rw-r--r--arch/.gitignore2
-rw-r--r--arch/alpha/kernel/.gitignore1
-rw-r--r--arch/arm/Kconfig86
-rw-r--r--arch/arm/Kconfig.debug5
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/boot/.gitignore5
-rw-r--r--arch/arm/boot/Makefile4
-rw-r--r--arch/arm/boot/compressed/.gitignore7
-rw-r--r--arch/arm/boot/compressed/Makefile5
-rw-r--r--arch/arm/boot/compressed/head.S43
-rw-r--r--arch/arm/common/Kconfig50
-rw-r--r--arch/arm/common/Makefile2
-rw-r--r--arch/arm/common/fiq_debugger.c1196
-rw-r--r--arch/arm/common/fiq_debugger_ringbuf.h94
-rw-r--r--arch/arm/common/fiq_glue.S111
-rw-r--r--arch/arm/common/fiq_glue_setup.c100
-rw-r--r--arch/arm/common/gic.c68
-rw-r--r--arch/arm/common/pl330.c120
-rw-r--r--arch/arm/configs/exynos4_defconfig72
-rw-r--r--arch/arm/configs/m0_00_defconfig3206
-rw-r--r--arch/arm/configs/mxs_defconfig129
-rw-r--r--arch/arm/configs/omap1_defconfig286
-rw-r--r--arch/arm/configs/omap2plus_defconfig236
-rw-r--r--arch/arm/configs/pcontrol_g20_defconfig175
-rw-r--r--arch/arm/configs/s5p64x0_defconfig68
-rw-r--r--arch/arm/configs/spear3xx_defconfig53
-rw-r--r--arch/arm/configs/spear6xx_defconfig49
-rw-r--r--arch/arm/configs/tegra_defconfig146
-rw-r--r--arch/arm/configs/vexpress_defconfig140
-rw-r--r--arch/arm/include/asm/assembler.h9
-rw-r--r--arch/arm/include/asm/bitops.h4
-rw-r--r--arch/arm/include/asm/cacheflush.h42
-rw-r--r--arch/arm/include/asm/device.h3
-rw-r--r--arch/arm/include/asm/fiq_debugger.h64
-rw-r--r--arch/arm/include/asm/fiq_glue.h30
-rw-r--r--arch/arm/include/asm/hardirq.h2
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h3
-rw-r--r--arch/arm/include/asm/hardware/coresight.h26
-rw-r--r--arch/arm/include/asm/hardware/gic.h5
-rw-r--r--arch/arm/include/asm/hardware/pl330.h1
-rw-r--r--arch/arm/include/asm/hwcap.h36
-rw-r--r--arch/arm/include/asm/irq.h3
-rw-r--r--arch/arm/include/asm/mach/mmc.h28
-rw-r--r--arch/arm/include/asm/memory.h1
-rw-r--r--arch/arm/include/asm/outercache.h8
-rw-r--r--arch/arm/include/asm/perf_event.h2
-rw-r--r--arch/arm/include/asm/sections.h8
-rw-r--r--arch/arm/include/asm/setup.h2
-rw-r--r--arch/arm/include/asm/smp.h2
-rw-r--r--arch/arm/include/asm/tlb.h10
-rw-r--r--arch/arm/kernel/.gitignore1
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/entry-armv.S2
-rw-r--r--arch/arm/kernel/etm.c473
-rw-r--r--arch/arm/kernel/hibernate.c470
-rw-r--r--arch/arm/kernel/hibernate_asm.S139
-rw-r--r--arch/arm/kernel/leds.c27
-rw-r--r--arch/arm/kernel/perf_event.c6
-rw-r--r--arch/arm/kernel/perf_event_v7.c344
-rw-r--r--arch/arm/kernel/process.c120
-rw-r--r--arch/arm/kernel/setup.c4
-rw-r--r--arch/arm/kernel/smp.c132
-rw-r--r--arch/arm/kernel/smp_scu.c16
-rw-r--r--arch/arm/kernel/stacktrace.c15
-rw-r--r--arch/arm/kernel/traps.c4
-rw-r--r--arch/arm/lib/copy_from_user.S9
-rw-r--r--arch/arm/lib/copy_template.S46
-rw-r--r--arch/arm/lib/copy_to_user.S9
-rw-r--r--arch/arm/lib/memcpy.S9
-rw-r--r--arch/arm/mach-exynos/Kconfig1706
-rw-r--r--arch/arm/mach-exynos/Kconfig.local136
-rw-r--r--arch/arm/mach-exynos/Makefile224
-rw-r--r--arch/arm/mach-exynos/Makefile.boot (renamed from arch/arm/mach-exynos4/Makefile.boot)0
-rw-r--r--arch/arm/mach-exynos/asv-4210.c457
-rw-r--r--arch/arm/mach-exynos/asv-4x12.c190
-rw-r--r--arch/arm/mach-exynos/asv-5250.c200
-rw-r--r--arch/arm/mach-exynos/asv.c105
-rw-r--r--arch/arm/mach-exynos/bcm47511.c253
-rw-r--r--arch/arm/mach-exynos/board-bluetooth-bcm43241.c383
-rw-r--r--arch/arm/mach-exynos/board-bluetooth-bcm4330.c360
-rw-r--r--arch/arm/mach-exynos/board-bluetooth-bcm4334.c380
-rw-r--r--arch/arm/mach-exynos/board-bluetooth-csr8811.c334
-rw-r--r--arch/arm/mach-exynos/board-c1-modems.c1302
-rw-r--r--arch/arm/mach-exynos/board-c1ctc-modems.c1712
-rw-r--r--arch/arm/mach-exynos/board-c1lgt-modems.c1937
-rw-r--r--arch/arm/mach-exynos/board-c1vzw-modems.c1930
-rw-r--r--arch/arm/mach-exynos/board-gaia-modems.c1369
-rw-r--r--arch/arm/mach-exynos/board-gps-bcm475x.c69
-rw-r--r--arch/arm/mach-exynos/board-gps-gsd4t.c90
-rw-r--r--arch/arm/mach-exynos/board-jenga-modems.c429
-rw-r--r--arch/arm/mach-exynos/board-m0-modems.c498
-rw-r--r--arch/arm/mach-exynos/board-m0-td-modems.c292
-rw-r--r--arch/arm/mach-exynos/board-m0ctc-modems.c1877
-rw-r--r--arch/arm/mach-exynos/board-midas-modems.c250
-rwxr-xr-xarch/arm/mach-exynos/board-midas-wlan.c326
-rw-r--r--arch/arm/mach-exynos/board-mobile.h39
-rw-r--r--arch/arm/mach-exynos/board-p10-wlan.c333
-rw-r--r--arch/arm/mach-exynos/board-p4notepq-modems.c535
-rw-r--r--arch/arm/mach-exynos/board-s2plus-modems.c479
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-audio.c177
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-display.c695
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-input.c117
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-mmc.c271
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-power.c808
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-spi.c176
-rw-r--r--arch/arm/mach-exynos/board-smdk5250-usb.c201
-rw-r--r--arch/arm/mach-exynos/board-smdk5250.h26
-rw-r--r--arch/arm/mach-exynos/board-u1-lgt-modems.c1461
-rw-r--r--arch/arm/mach-exynos/board-u1-modems.c512
-rw-r--r--arch/arm/mach-exynos/bts.c545
-rw-r--r--arch/arm/mach-exynos/busfreq.c974
-rw-r--r--arch/arm/mach-exynos/busfreq_opp_4210.c298
-rw-r--r--arch/arm/mach-exynos/busfreq_opp_4x12.c939
-rw-r--r--arch/arm/mach-exynos/busfreq_opp_5250.c892
-rw-r--r--arch/arm/mach-exynos/busfreq_opp_exynos4.c677
-rw-r--r--arch/arm/mach-exynos/busfreq_opp_exynos5.c498
-rw-r--r--arch/arm/mach-exynos/clock-domain.c105
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.c2480
-rw-r--r--arch/arm/mach-exynos/clock-exynos4210.c426
-rw-r--r--arch/arm/mach-exynos/clock-exynos4212.c1151
-rw-r--r--arch/arm/mach-exynos/clock-exynos5.c2921
-rw-r--r--arch/arm/mach-exynos/cpu-exynos4.c466
-rw-r--r--arch/arm/mach-exynos/cpu-exynos5.c381
-rw-r--r--arch/arm/mach-exynos/cpufreq-4210.c453
-rw-r--r--arch/arm/mach-exynos/cpufreq-4x12.c736
-rw-r--r--arch/arm/mach-exynos/cpufreq-5250.c526
-rw-r--r--arch/arm/mach-exynos/cpufreq.c830
-rw-r--r--arch/arm/mach-exynos/cpuidle-exynos4.c1024
-rw-r--r--arch/arm/mach-exynos/cpuidle-exynos5.c674
-rw-r--r--arch/arm/mach-exynos/dev-ahci-exynos5.c486
-rw-r--r--arch/arm/mach-exynos/dev-ahci.c (renamed from arch/arm/mach-exynos4/dev-ahci.c)2
-rw-r--r--arch/arm/mach-exynos/dev-audio.c438
-rw-r--r--arch/arm/mach-exynos/dev-c2c.c85
-rw-r--r--arch/arm/mach-exynos/dev-dwmci.c239
-rw-r--r--arch/arm/mach-exynos/dev-fimc-is.c136
-rw-r--r--arch/arm/mach-exynos/dev-fimc-lite.c85
-rw-r--r--arch/arm/mach-exynos/dev-gsc.c123
-rw-r--r--arch/arm/mach-exynos/dev-ion.c46
-rw-r--r--arch/arm/mach-exynos/dev-pd-exynos4.c255
-rw-r--r--arch/arm/mach-exynos/dev-pd-exynos5.c120
-rw-r--r--arch/arm/mach-exynos/dev-pd.c167
-rw-r--r--arch/arm/mach-exynos/dev-spi.c308
-rw-r--r--arch/arm/mach-exynos/dev-sysmmu-exynos4.c130
-rw-r--r--arch/arm/mach-exynos/dev-sysmmu.c301
-rw-r--r--arch/arm/mach-exynos/dev.c188
-rw-r--r--arch/arm/mach-exynos/dma.c404
-rw-r--r--arch/arm/mach-exynos/dvfs-hotplug.c180
-rw-r--r--arch/arm/mach-exynos/dynamic-dvfs-nr_running-hotplug.c322
-rw-r--r--arch/arm/mach-exynos/dynamic-nr_running-hotplug.c199
-rw-r--r--arch/arm/mach-exynos/exynos4-smc.c52
-rw-r--r--arch/arm/mach-exynos/gc1-gpio.c528
-rw-r--r--arch/arm/mach-exynos/gc1-power.c791
-rw-r--r--arch/arm/mach-exynos/headsmp.S (renamed from arch/arm/mach-exynos4/headsmp.S)4
-rw-r--r--arch/arm/mach-exynos/hotplug.c (renamed from arch/arm/mach-exynos4/hotplug.c)52
-rw-r--r--arch/arm/mach-exynos/idle-exynos4.S241
-rw-r--r--arch/arm/mach-exynos/idle-exynos5.S210
-rw-r--r--arch/arm/mach-exynos/include/mach/asv.h124
-rw-r--r--arch/arm/mach-exynos/include/mach/bcm47511.h27
-rw-r--r--arch/arm/mach-exynos/include/mach/board-bluetooth-bcm.h30
-rw-r--r--arch/arm/mach-exynos/include/mach/board-bluetooth-csr.h30
-rw-r--r--arch/arm/mach-exynos/include/mach/board-gps.h29
-rw-r--r--arch/arm/mach-exynos/include/mach/board_rev.h26
-rw-r--r--arch/arm/mach-exynos/include/mach/busfreq.h120
-rw-r--r--arch/arm/mach-exynos/include/mach/busfreq_exynos4.h103
-rw-r--r--arch/arm/mach-exynos/include/mach/busfreq_exynos5.h93
-rw-r--r--arch/arm/mach-exynos/include/mach/c2c.h68
-rw-r--r--arch/arm/mach-exynos/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-exynos/include/mach/clock-domain.h33
-rw-r--r--arch/arm/mach-exynos/include/mach/cpufreq.h152
-rw-r--r--arch/arm/mach-exynos/include/mach/debug-macro.S (renamed from arch/arm/mach-exynos4/include/mach/debug-macro.S)2
-rw-r--r--arch/arm/mach-exynos/include/mach/dev-sysmmu.h87
-rw-r--r--arch/arm/mach-exynos/include/mach/dev.h43
-rw-r--r--arch/arm/mach-exynos/include/mach/diag_bridge.h55
-rw-r--r--arch/arm/mach-exynos/include/mach/dma.h (renamed from arch/arm/mach-exynos4/include/mach/dma.h)0
-rw-r--r--arch/arm/mach-exynos/include/mach/dsim.h259
-rw-r--r--arch/arm/mach-exynos/include/mach/dwmci.h20
-rw-r--r--arch/arm/mach-exynos/include/mach/entry-macro.S (renamed from arch/arm/mach-exynos4/include/mach/entry-macro.S)58
-rw-r--r--arch/arm/mach-exynos/include/mach/exynos-clock.h80
-rw-r--r--arch/arm/mach-exynos/include/mach/exynos-ion.h20
-rw-r--r--arch/arm/mach-exynos/include/mach/gc1-power.h37
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-exynos4.h241
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-exynos5.h201
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-midas.h52
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-naples.h23
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-p10.h28
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-p2.h242
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-p4.h233
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-p8.h233
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-q1.h296
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-c1.h293
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-c1ctc.h287
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-c1vzw.h316
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-gc1.h321
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-jenga.h265
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-m0.h322
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-m0ctc.h296
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-m0grandectc.h227
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-m3.h291
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-naples.h295
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-p10-lte.h376
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-p10-wifi.h376
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-p10.h311
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-p4note.h346
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-p4notepq.h336
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-s2plus.h715
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev00-t0.h322
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev01-midas.h215
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo-wifi.h387
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo.h387
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev02-midas.h244
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-rev03-c1kor.h346
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-u1.h337
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio-u1camera.h296
-rw-r--r--arch/arm/mach-exynos/include/mach/gpio.h43
-rw-r--r--arch/arm/mach-exynos/include/mach/gpufreq.h38
-rw-r--r--arch/arm/mach-exynos/include/mach/hardware.h (renamed from arch/arm/mach-exynos4/include/mach/hardware.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/iic-hdmiphy.h16
-rw-r--r--arch/arm/mach-exynos/include/mach/io.h (renamed from arch/arm/mach-exynos4/include/mach/io.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs-exynos4.h248
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs-exynos5.h274
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h40
-rw-r--r--arch/arm/mach-exynos/include/mach/map-exynos4.h319
-rw-r--r--arch/arm/mach-exynos/include/mach/map-exynos5.h295
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h34
-rw-r--r--arch/arm/mach-exynos/include/mach/mdm2.h23
-rw-r--r--arch/arm/mach-exynos/include/mach/media.h36
-rw-r--r--arch/arm/mach-exynos/include/mach/memory.h (renamed from arch/arm/mach-exynos4/include/mach/memory.h)10
-rw-r--r--arch/arm/mach-exynos/include/mach/midas-lcd.h34
-rw-r--r--arch/arm/mach-exynos/include/mach/midas-power.h35
-rw-r--r--arch/arm/mach-exynos/include/mach/midas-sound.h32
-rw-r--r--arch/arm/mach-exynos/include/mach/midas-thermistor.h59
-rw-r--r--arch/arm/mach-exynos/include/mach/midas-tsp.h35
-rw-r--r--arch/arm/mach-exynos/include/mach/mipi_ddi.h63
-rw-r--r--arch/arm/mach-exynos/include/mach/naples-tsp.h20
-rw-r--r--arch/arm/mach-exynos/include/mach/p10-battery.h16
-rw-r--r--arch/arm/mach-exynos/include/mach/p10-input.h17
-rw-r--r--arch/arm/mach-exynos/include/mach/p4-input.h21
-rw-r--r--arch/arm/mach-exynos/include/mach/p4note-jack.h25
-rw-r--r--arch/arm/mach-exynos/include/mach/pm-core.h (renamed from arch/arm/mach-exynos4/include/mach/pm-core.h)34
-rw-r--r--arch/arm/mach-exynos/include/mach/pmu.h117
-rw-r--r--arch/arm/mach-exynos/include/mach/ppmu.h122
-rw-r--r--arch/arm/mach-exynos/include/mach/pwm-clock.h (renamed from arch/arm/mach-exynos4/include/mach/pwm-clock.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-audss.h46
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-c2c.h73
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-cec.h93
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-clock.h699
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-fimg2d3x.h162
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-gpio.h53
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-hdmi.h1787
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-iem.h27
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-irq.h (renamed from arch/arm/mach-exynos4/include/mach/regs-irq.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-mct.h (renamed from arch/arm/mach-exynos4/include/mach/regs-mct.h)7
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-mem.h (renamed from arch/arm/mach-exynos4/include/mach/regs-mem.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-mfc.h197
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-mixer.h216
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu-4210.h32
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu-4212.h134
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu-5210.h34
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu-5250.h36
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu.h207
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu5.h568
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-sdo.h449
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-sysmmu.h (renamed from arch/arm/mach-exynos4/include/mach/regs-sysmmu.h)7
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-tmu.h164
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-tsi.h163
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-usb-host.h60
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-usb-phy-4210.h42
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-usb-phy-4212.h49
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-usb-phy.h118
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-vp.h293
-rw-r--r--arch/arm/mach-exynos/include/mach/restart.h29
-rw-r--r--arch/arm/mach-exynos/include/mach/sec_debug.h196
-rw-r--r--arch/arm/mach-exynos/include/mach/sec_modem.h18
-rw-r--r--arch/arm/mach-exynos/include/mach/sec_thermistor.h45
-rw-r--r--arch/arm/mach-exynos/include/mach/secmem.h70
-rw-r--r--arch/arm/mach-exynos/include/mach/smc.h50
-rw-r--r--arch/arm/mach-exynos/include/mach/spi-clocks.h17
-rw-r--r--arch/arm/mach-exynos/include/mach/subsystem_notif.h80
-rw-r--r--arch/arm/mach-exynos/include/mach/subsystem_restart.h72
-rw-r--r--arch/arm/mach-exynos/include/mach/sysmmu.h68
-rw-r--r--arch/arm/mach-exynos/include/mach/system.h (renamed from arch/arm/mach-exynos4/include/mach/system.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/tdmb_pdata.h31
-rw-r--r--arch/arm/mach-exynos/include/mach/timex.h (renamed from arch/arm/mach-exynos4/include/mach/timex.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/uncompress.h (renamed from arch/arm/mach-exynos4/include/mach/uncompress.h)2
-rw-r--r--arch/arm/mach-exynos/include/mach/usb_bridge.h156
-rw-r--r--arch/arm/mach-exynos/include/mach/usb_switch.h28
-rw-r--r--arch/arm/mach-exynos/include/mach/usbdiag.h58
-rw-r--r--arch/arm/mach-exynos/include/mach/videonode-exynos4.h21
-rw-r--r--arch/arm/mach-exynos/include/mach/videonode-exynos5.h32
-rw-r--r--arch/arm/mach-exynos/include/mach/videonode.h24
-rw-r--r--arch/arm/mach-exynos/include/mach/vmalloc.h (renamed from arch/arm/mach-exynos4/include/mach/vmalloc.h)4
-rw-r--r--arch/arm/mach-exynos/init.c (renamed from arch/arm/mach-exynos4/init.c)10
-rw-r--r--arch/arm/mach-exynos/irq-combiner.c (renamed from arch/arm/mach-exynos4/irq-combiner.c)40
-rw-r--r--arch/arm/mach-exynos/irq-eint.c (renamed from arch/arm/mach-exynos4/irq-eint.c)114
-rw-r--r--arch/arm/mach-exynos/irq-sgi.c76
-rw-r--r--arch/arm/mach-exynos/mach-armlex4210.c (renamed from arch/arm/mach-exynos4/mach-armlex4210.c)3
-rw-r--r--arch/arm/mach-exynos/mach-midas.c2802
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c (renamed from arch/arm/mach-exynos4/mach-nuri.c)2
-rw-r--r--arch/arm/mach-exynos/mach-p10.c3091
-rw-r--r--arch/arm/mach-exynos/mach-p4notepq.c2561
-rw-r--r--arch/arm/mach-exynos/mach-px.c7558
-rw-r--r--arch/arm/mach-exynos/mach-smdk4x12.c4388
-rw-r--r--arch/arm/mach-exynos/mach-smdk5210.c1174
-rw-r--r--arch/arm/mach-exynos/mach-smdk5250.c1316
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c2680
-rw-r--r--arch/arm/mach-exynos/mach-u1.c7497
-rw-r--r--arch/arm/mach-exynos/mach-u1cam.c6993
-rw-r--r--arch/arm/mach-exynos/mach-universal_c210.c (renamed from arch/arm/mach-exynos4/mach-universal_c210.c)3
-rw-r--r--arch/arm/mach-exynos/mct.c (renamed from arch/arm/mach-exynos4/mct.c)230
-rw-r--r--arch/arm/mach-exynos/mdm2.c253
-rw-r--r--arch/arm/mach-exynos/mdm_common.c567
-rw-r--r--arch/arm/mach-exynos/mdm_device.c64
-rw-r--r--arch/arm/mach-exynos/mdm_private.h56
-rw-r--r--arch/arm/mach-exynos/midas-camera.c3450
-rw-r--r--arch/arm/mach-exynos/midas-extcon.c90
-rw-r--r--arch/arm/mach-exynos/midas-gpio.c2873
-rw-r--r--arch/arm/mach-exynos/midas-gps.c50
-rw-r--r--arch/arm/mach-exynos/midas-lcd.c810
-rw-r--r--arch/arm/mach-exynos/midas-leds.c54
-rw-r--r--arch/arm/mach-exynos/midas-mhl.c192
-rw-r--r--arch/arm/mach-exynos/midas-nfc.c78
-rw-r--r--arch/arm/mach-exynos/midas-power.c1125
-rw-r--r--arch/arm/mach-exynos/midas-sensor.c428
-rw-r--r--arch/arm/mach-exynos/midas-sound.c365
-rw-r--r--arch/arm/mach-exynos/midas-thermistor.c600
-rw-r--r--arch/arm/mach-exynos/midas-tsp.c1095
-rw-r--r--arch/arm/mach-exynos/midas.h35
-rw-r--r--arch/arm/mach-exynos/naples-camera.c860
-rw-r--r--arch/arm/mach-exynos/naples-gpio.c1424
-rw-r--r--arch/arm/mach-exynos/naples-power.c1118
-rw-r--r--arch/arm/mach-exynos/naples-tsp.c317
-rw-r--r--arch/arm/mach-exynos/p10-battery.c511
-rw-r--r--arch/arm/mach-exynos/p10-gpio.c580
-rw-r--r--arch/arm/mach-exynos/p10-input.c347
-rw-r--r--arch/arm/mach-exynos/p10-mhl.c130
-rw-r--r--arch/arm/mach-exynos/p10-switch.c239
-rw-r--r--arch/arm/mach-exynos/p10-wlan.h13
-rw-r--r--arch/arm/mach-exynos/p2-gpio.c574
-rw-r--r--arch/arm/mach-exynos/p4-gpio.c488
-rw-r--r--arch/arm/mach-exynos/p4-input.c378
-rw-r--r--arch/arm/mach-exynos/p4note-gpio.c587
-rw-r--r--arch/arm/mach-exynos/p4note-jack.c126
-rw-r--r--arch/arm/mach-exynos/p4note-power.c1112
-rw-r--r--arch/arm/mach-exynos/p8-gpio.c515
-rw-r--r--arch/arm/mach-exynos/platsmp.c (renamed from arch/arm/mach-exynos4/platsmp.c)148
-rw-r--r--arch/arm/mach-exynos/pm-exynos4.c613
-rw-r--r--arch/arm/mach-exynos/pm-exynos5.c466
-rw-r--r--arch/arm/mach-exynos/pm-hotplug.c225
-rw-r--r--arch/arm/mach-exynos/pmu-exynos4.c447
-rw-r--r--arch/arm/mach-exynos/pmu-exynos5.c298
-rw-r--r--arch/arm/mach-exynos/ppc.c74
-rw-r--r--arch/arm/mach-exynos/ppmu.c194
-rw-r--r--arch/arm/mach-exynos/px-switch.c435
-rw-r--r--arch/arm/mach-exynos/px.h24
-rw-r--r--arch/arm/mach-exynos/px_thermistor.h204
-rw-r--r--arch/arm/mach-exynos/q1-gpio.c441
-rw-r--r--arch/arm/mach-exynos/reserve_mem-exynos4.c156
-rw-r--r--arch/arm/mach-exynos/s2p-panel.c1047
-rw-r--r--arch/arm/mach-exynos/s2plus-panel.c1672
-rw-r--r--arch/arm/mach-exynos/s2plus-panel.h215
-rw-r--r--arch/arm/mach-exynos/sec-common.c18
-rw-r--r--arch/arm/mach-exynos/sec-reboot.c133
-rw-r--r--arch/arm/mach-exynos/sec-switch.c513
-rw-r--r--arch/arm/mach-exynos/sec-switch_max8997.c496
-rw-r--r--arch/arm/mach-exynos/sec_debug.c1241
-rw-r--r--arch/arm/mach-exynos/sec_gaf.c224
-rw-r--r--arch/arm/mach-exynos/sec_getlog.c126
-rw-r--r--arch/arm/mach-exynos/sec_log.c171
-rw-r--r--arch/arm/mach-exynos/sec_thermistor.c285
-rw-r--r--arch/arm/mach-exynos/sec_watchdog.c205
-rw-r--r--arch/arm/mach-exynos/secmem-allocdev.c331
-rw-r--r--arch/arm/mach-exynos/setup-c2c.c151
-rw-r--r--arch/arm/mach-exynos/setup-csis.c159
-rw-r--r--arch/arm/mach-exynos/setup-dp.c32
-rw-r--r--arch/arm/mach-exynos/setup-dsim.c120
-rw-r--r--arch/arm/mach-exynos/setup-fb-s5p.c970
-rw-r--r--arch/arm/mach-exynos/setup-fimc-is.c1111
-rw-r--r--arch/arm/mach-exynos/setup-fimc.c (renamed from arch/arm/mach-exynos4/setup-fimc.c)8
-rw-r--r--arch/arm/mach-exynos/setup-fimc0.c107
-rw-r--r--arch/arm/mach-exynos/setup-fimc1.c (renamed from arch/arm/mach-exynos4/setup-i2c4.c)18
-rw-r--r--arch/arm/mach-exynos/setup-fimc2.c (renamed from arch/arm/mach-exynos4/setup-i2c5.c)18
-rw-r--r--arch/arm/mach-exynos/setup-fimc3.c21
-rw-r--r--arch/arm/mach-exynos/setup-fimd.c73
-rw-r--r--arch/arm/mach-exynos/setup-fimd0.c119
-rw-r--r--arch/arm/mach-exynos/setup-gsc.c95
-rw-r--r--arch/arm/mach-exynos/setup-hdmi.c27
-rw-r--r--arch/arm/mach-exynos/setup-i2c0.c (renamed from arch/arm/mach-exynos4/setup-i2c0.c)11
-rw-r--r--arch/arm/mach-exynos/setup-i2c1.c (renamed from arch/arm/mach-exynos4/setup-i2c1.c)11
-rw-r--r--arch/arm/mach-exynos/setup-i2c2.c (renamed from arch/arm/mach-exynos4/setup-i2c2.c)11
-rw-r--r--arch/arm/mach-exynos/setup-i2c3.c (renamed from arch/arm/mach-exynos4/setup-i2c3.c)11
-rw-r--r--arch/arm/mach-exynos/setup-i2c4.c31
-rw-r--r--arch/arm/mach-exynos/setup-i2c5.c31
-rw-r--r--arch/arm/mach-exynos/setup-i2c6.c (renamed from arch/arm/mach-exynos4/setup-i2c6.c)11
-rw-r--r--arch/arm/mach-exynos/setup-i2c7.c (renamed from arch/arm/mach-exynos4/setup-i2c7.c)11
-rw-r--r--arch/arm/mach-exynos/setup-jpeg.c133
-rw-r--r--arch/arm/mach-exynos/setup-keypad.c (renamed from arch/arm/mach-exynos4/setup-keypad.c)13
-rw-r--r--arch/arm/mach-exynos/setup-mfc.c54
-rw-r--r--arch/arm/mach-exynos/setup-mipidsim.c93
-rw-r--r--arch/arm/mach-exynos/setup-mshci-gpio.c220
-rw-r--r--arch/arm/mach-exynos/setup-mshci.c37
-rw-r--r--arch/arm/mach-exynos/setup-sdhci-gpio.c336
-rw-r--r--arch/arm/mach-exynos/setup-sdhci.c (renamed from arch/arm/mach-exynos4/setup-sdhci.c)2
-rw-r--r--arch/arm/mach-exynos/setup-tvout.c118
-rw-r--r--arch/arm/mach-exynos/setup-usb-phy.c1407
-rw-r--r--arch/arm/mach-exynos/sleep-exynos4.S (renamed from arch/arm/mach-exynos4/sleep.S)52
-rw-r--r--arch/arm/mach-exynos/sleep-exynos5.S137
-rw-r--r--arch/arm/mach-exynos/stand-hotplug.c414
-rw-r--r--arch/arm/mach-exynos/subsystem_notif.c222
-rw-r--r--arch/arm/mach-exynos/subsystem_restart.c680
-rw-r--r--arch/arm/mach-exynos/sysreg.c78
-rw-r--r--arch/arm/mach-exynos/tmu.c1432
-rw-r--r--arch/arm/mach-exynos/tmu_exynos.c423
-rw-r--r--arch/arm/mach-exynos/u1-gpio.c678
-rw-r--r--arch/arm/mach-exynos/u1-otg.c218
-rw-r--r--arch/arm/mach-exynos/u1-panel.c1665
-rw-r--r--arch/arm/mach-exynos/u1-panel.h146
-rw-r--r--arch/arm/mach-exynos/u1-panel_a2.c1668
-rw-r--r--arch/arm/mach-exynos/u1-panel_m2.c1660
-rw-r--r--arch/arm/mach-exynos/u1-wlan.c329
-rw-r--r--arch/arm/mach-exynos/u1.h25
-rw-r--r--arch/arm/mach-exynos/u1_regulator_consumer.c147
-rw-r--r--arch/arm/mach-exynos/u1camera-gpio.c439
-rw-r--r--arch/arm/mach-exynos/wakeup_assist.c110
-rw-r--r--arch/arm/mach-exynos4/Kconfig209
-rw-r--r--arch/arm/mach-exynos4/Makefile59
-rw-r--r--arch/arm/mach-exynos4/clock.c1216
-rw-r--r--arch/arm/mach-exynos4/cpu.c226
-rw-r--r--arch/arm/mach-exynos4/cpufreq.c569
-rw-r--r--arch/arm/mach-exynos4/cpuidle.c86
-rw-r--r--arch/arm/mach-exynos4/dev-audio.c367
-rw-r--r--arch/arm/mach-exynos4/dev-pd.c139
-rw-r--r--arch/arm/mach-exynos4/dev-sysmmu.c232
-rw-r--r--arch/arm/mach-exynos4/dma.c172
-rw-r--r--arch/arm/mach-exynos4/include/mach/gpio.h156
-rw-r--r--arch/arm/mach-exynos4/include/mach/irqs.h160
-rw-r--r--arch/arm/mach-exynos4/include/mach/map.h166
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-clock.h180
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-gpio.h42
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-pmu.h165
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-usb-phy.h64
-rw-r--r--arch/arm/mach-exynos4/include/mach/sysmmu.h46
-rw-r--r--arch/arm/mach-exynos4/localtimer.c26
-rw-r--r--arch/arm/mach-exynos4/mach-smdkc210.c223
-rw-r--r--arch/arm/mach-exynos4/mach-smdkv310.c244
-rw-r--r--arch/arm/mach-exynos4/pm.c429
-rw-r--r--arch/arm/mach-exynos4/setup-sdhci-gpio.c152
-rw-r--r--arch/arm/mach-exynos4/setup-usb-phy.c136
-rw-r--r--arch/arm/mach-exynos4/time.c301
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/pm-core.h3
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig1
-rw-r--r--arch/arm/mach-s3c64xx/cpu.c22
-rw-r--r--arch/arm/mach-s3c64xx/dev-onenand1.c10
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h5
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h19
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-fb.h21
-rw-r--r--arch/arm/mach-s3c64xx/irq.c12
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c2
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c43
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c1
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig2
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c54
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c54
-rw-r--r--arch/arm/mach-s5pc100/Kconfig1
-rw-r--r--arch/arm/mach-s5pc100/clock.c37
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-fb.h105
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c57
-rw-r--r--arch/arm/mach-s5pc100/setup-fb-24bpp.c1
-rw-r--r--arch/arm/mach-s5pv210/Kconfig22
-rw-r--r--arch/arm/mach-s5pv210/Makefile4
-rw-r--r--arch/arm/mach-s5pv210/Makefile.boot3
-rw-r--r--arch/arm/mach-s5pv210/clock.c148
-rw-r--r--arch/arm/mach-s5pv210/cpu.c14
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-s5pv210/cpufreq.c218
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c7
-rw-r--r--arch/arm/mach-s5pv210/dev-cpufreq.c28
-rw-r--r--arch/arm/mach-s5pv210/dma.c74
-rw-r--r--arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h31
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h14
-rw-r--r--arch/arm/mach-s5pv210/include/mach/media.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/memory.h4
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pm-core.h3
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-audss.h44
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h31
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-fb.h21
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c2
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c2
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c589
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c393
-rw-r--r--arch/arm/mach-s5pv210/reserve_mem-s5pv210.c113
-rw-r--r--arch/arm/mach-s5pv210/setup-fb-24bpp.c1
-rw-r--r--arch/arm/mach-s5pv210/setup-keypad.c3
-rw-r--r--arch/arm/mm/Kconfig10
-rw-r--r--arch/arm/mm/Makefile11
-rw-r--r--arch/arm/mm/cache-fa.S15
-rw-r--r--arch/arm/mm/cache-l2x0.c67
-rw-r--r--arch/arm/mm/cache-v3.S15
-rw-r--r--arch/arm/mm/cache-v4.S15
-rw-r--r--arch/arm/mm/cache-v4wb.S15
-rw-r--r--arch/arm/mm/cache-v4wt.S15
-rw-r--r--arch/arm/mm/cache-v6.S32
-rw-r--r--arch/arm/mm/cache-v7.S15
-rw-r--r--arch/arm/mm/cache_perf.c348
-rw-r--r--arch/arm/mm/ioremap.c3
-rw-r--r--arch/arm/mm/proc-arm1020.S45
-rw-r--r--arch/arm/mm/proc-arm1020e.S52
-rw-r--r--arch/arm/mm/proc-arm1022.S52
-rw-r--r--arch/arm/mm/proc-arm1026.S53
-rw-r--r--arch/arm/mm/proc-arm6_7.S166
-rw-r--r--arch/arm/mm/proc-arm720.S85
-rw-r--r--arch/arm/mm/proc-arm740.S42
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S216
-rw-r--r--arch/arm/mm/proc-arm920.S53
-rw-r--r--arch/arm/mm/proc-arm922.S53
-rw-r--r--arch/arm/mm/proc-arm925.S88
-rw-r--r--arch/arm/mm/proc-arm926.S51
-rw-r--r--arch/arm/mm/proc-arm940.S51
-rw-r--r--arch/arm/mm/proc-arm946.S53
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S78
-rw-r--r--arch/arm/mm/proc-fa526.S38
-rw-r--r--arch/arm/mm/proc-feroceon.S202
-rw-r--r--arch/arm/mm/proc-macros.S63
-rw-r--r--arch/arm/mm/proc-mohawk.S61
-rw-r--r--arch/arm/mm/proc-sa110.S39
-rw-r--r--arch/arm/mm/proc-sa1100.S84
-rw-r--r--arch/arm/mm/proc-v6.S39
-rw-r--r--arch/arm/mm/proc-v7.S226
-rw-r--r--arch/arm/mm/proc-xsc3.S90
-rw-r--r--arch/arm/mm/proc-xscale.S507
-rw-r--r--arch/arm/mm/tlb-fa.S8
-rw-r--r--arch/arm/mm/tlb-v3.S8
-rw-r--r--arch/arm/mm/tlb-v4.S8
-rw-r--r--arch/arm/mm/tlb-v4wb.S8
-rw-r--r--arch/arm/mm/tlb-v4wbi.S8
-rw-r--r--arch/arm/mm/tlb-v6.S8
-rw-r--r--arch/arm/mm/tlb-v7.S9
-rw-r--r--arch/arm/mvp/Kconfig24
-rw-r--r--arch/arm/mvp/Makefile3
-rw-r--r--arch/arm/mvp/commkm/COPYING341
-rw-r--r--arch/arm/mvp/commkm/Kbuild9
-rw-r--r--arch/arm/mvp/commkm/Makefile1
-rw-r--r--arch/arm/mvp/commkm/check_kconfig.c91
-rw-r--r--arch/arm/mvp/commkm/comm.c1457
-rw-r--r--arch/arm/mvp/commkm/comm.h171
-rw-r--r--arch/arm/mvp/commkm/comm_ev.h51
-rw-r--r--arch/arm/mvp/commkm/comm_ev_kernel.c136
-rw-r--r--arch/arm/mvp/commkm/comm_os.h150
-rw-r--r--arch/arm/mvp/commkm/comm_os_linux.c371
-rw-r--r--arch/arm/mvp/commkm/comm_os_linux.h699
-rw-r--r--arch/arm/mvp/commkm/comm_os_mod_linux.c105
-rw-r--r--arch/arm/mvp/commkm/comm_os_mod_ver.h38
-rw-r--r--arch/arm/mvp/commkm/comm_svc.c421
-rw-r--r--arch/arm/mvp/commkm/comm_svc.h71
-rw-r--r--arch/arm/mvp/commkm/comm_transp.h90
-rw-r--r--arch/arm/mvp/commkm/comm_transp_impl.h165
-rw-r--r--arch/arm/mvp/commkm/comm_transp_mvp.c944
-rw-r--r--arch/arm/mvp/commkm/fatalerror.h126
-rw-r--r--arch/arm/mvp/commkm/include_check.h18
-rw-r--r--arch/arm/mvp/commkm/mksck.h153
-rw-r--r--arch/arm/mvp/commkm/mksck_sockaddr.h50
-rw-r--r--arch/arm/mvp/commkm/mvp.h48
-rw-r--r--arch/arm/mvp/commkm/mvp_assert.h125
-rw-r--r--arch/arm/mvp/commkm/mvp_compiler.h56
-rw-r--r--arch/arm/mvp/commkm/mvp_compiler_gcc.h87
-rw-r--r--arch/arm/mvp/commkm/mvp_types.h94
-rw-r--r--arch/arm/mvp/commkm/mvpkm_comm_ev.h53
-rw-r--r--arch/arm/mvp/commkm/nottested.h54
-rw-r--r--arch/arm/mvp/commkm/platdefx.h67
-rw-r--r--arch/arm/mvp/commkm/qp.h332
-rw-r--r--arch/arm/mvp/commkm/utils.h172
-rw-r--r--arch/arm/mvp/commkm/vmid.h44
-rw-r--r--arch/arm/mvp/mvpkm/COPYING341
-rw-r--r--arch/arm/mvp/mvpkm/Kbuild24
-rw-r--r--arch/arm/mvp/mvpkm/Makefile1
-rw-r--r--arch/arm/mvp/mvpkm/actions.h57
-rw-r--r--arch/arm/mvp/mvpkm/arm_as_macros.h91
-rw-r--r--arch/arm/mvp/mvpkm/arm_defs.h54
-rw-r--r--arch/arm/mvp/mvpkm/arm_gcc_inline.h206
-rw-r--r--arch/arm/mvp/mvpkm/arm_inline.h179
-rw-r--r--arch/arm/mvp/mvpkm/arm_types.h42
-rw-r--r--arch/arm/mvp/mvpkm/atomic.h88
-rw-r--r--arch/arm/mvp/mvpkm/atomic_arm.h329
-rw-r--r--arch/arm/mvp/mvpkm/check_kconfig.c91
-rw-r--r--arch/arm/mvp/mvpkm/comm_os.h150
-rw-r--r--arch/arm/mvp/mvpkm/comm_os_linux.h699
-rw-r--r--arch/arm/mvp/mvpkm/comm_transp.h90
-rw-r--r--arch/arm/mvp/mvpkm/comm_transp_impl.h165
-rw-r--r--arch/arm/mvp/mvpkm/coproc_defs.h351
-rw-r--r--arch/arm/mvp/mvpkm/cpufreq_kernel.c308
-rw-r--r--arch/arm/mvp/mvpkm/cpufreq_kernel.h47
-rw-r--r--arch/arm/mvp/mvpkm/exc_defs.h67
-rw-r--r--arch/arm/mvp/mvpkm/exc_types.h53
-rw-r--r--arch/arm/mvp/mvpkm/exitstatus.h67
-rw-r--r--arch/arm/mvp/mvpkm/fatalerror.h126
-rw-r--r--arch/arm/mvp/mvpkm/include_check.h18
-rw-r--r--arch/arm/mvp/mvpkm/instr_defs.h426
-rw-r--r--arch/arm/mvp/mvpkm/lowmemkiller_variant.sh83
-rw-r--r--arch/arm/mvp/mvpkm/lpae_defs.h92
-rw-r--r--arch/arm/mvp/mvpkm/lpae_types.h124
-rw-r--r--arch/arm/mvp/mvpkm/mksck.h153
-rw-r--r--arch/arm/mvp/mvpkm/mksck_kernel.c2589
-rw-r--r--arch/arm/mvp/mvpkm/mksck_kernel.h68
-rw-r--r--arch/arm/mvp/mvpkm/mksck_shared.c343
-rw-r--r--arch/arm/mvp/mvpkm/mksck_shared.h189
-rw-r--r--arch/arm/mvp/mvpkm/mksck_sockaddr.h50
-rw-r--r--arch/arm/mvp/mvpkm/mmu_defs.h218
-rw-r--r--arch/arm/mvp/mvpkm/mmu_types.h226
-rw-r--r--arch/arm/mvp/mvpkm/montimer_kernel.c102
-rw-r--r--arch/arm/mvp/mvpkm/montimer_kernel.h47
-rw-r--r--arch/arm/mvp/mvpkm/monva_common.h106
-rw-r--r--arch/arm/mvp/mvpkm/mutex.h107
-rw-r--r--arch/arm/mvp/mvpkm/mutex_kernel.c480
-rw-r--r--arch/arm/mvp/mvpkm/mutex_kernel.h41
-rw-r--r--arch/arm/mvp/mvpkm/mvp.h48
-rw-r--r--arch/arm/mvp/mvpkm/mvp_assert.h125
-rw-r--r--arch/arm/mvp/mvpkm/mvp_balloon.h217
-rw-r--r--arch/arm/mvp/mvpkm/mvp_compiler.h56
-rw-r--r--arch/arm/mvp/mvpkm/mvp_compiler_gcc.h87
-rw-r--r--arch/arm/mvp/mvpkm/mvp_math.h133
-rw-r--r--arch/arm/mvp/mvpkm/mvp_timer.h72
-rw-r--r--arch/arm/mvp/mvpkm/mvp_types.h94
-rw-r--r--arch/arm/mvp/mvpkm/mvp_version.h116
-rw-r--r--arch/arm/mvp/mvpkm/mvpkm_comm_ev.c60
-rw-r--r--arch/arm/mvp/mvpkm/mvpkm_comm_ev.h53
-rw-r--r--arch/arm/mvp/mvpkm/mvpkm_kernel.h83
-rw-r--r--arch/arm/mvp/mvpkm/mvpkm_main.c2690
-rw-r--r--arch/arm/mvp/mvpkm/mvpkm_private.h97
-rw-r--r--arch/arm/mvp/mvpkm/mvpkm_types.h49
-rw-r--r--arch/arm/mvp/mvpkm/nottested.h54
-rw-r--r--arch/arm/mvp/mvpkm/platdefx.h67
-rw-r--r--arch/arm/mvp/mvpkm/psr_defs.h117
-rw-r--r--arch/arm/mvp/mvpkm/qp.h332
-rw-r--r--arch/arm/mvp/mvpkm/qp_common.c337
-rw-r--r--arch/arm/mvp/mvpkm/qp_host_kernel.c574
-rw-r--r--arch/arm/mvp/mvpkm/qp_host_kernel.h44
-rw-r--r--arch/arm/mvp/mvpkm/tsc.h49
-rw-r--r--arch/arm/mvp/mvpkm/utils.h172
-rw-r--r--arch/arm/mvp/mvpkm/ve_defs.h72
-rw-r--r--arch/arm/mvp/mvpkm/vfp_switch.S216
-rw-r--r--arch/arm/mvp/mvpkm/vmid.h44
-rw-r--r--arch/arm/mvp/mvpkm/worldswitch.h381
-rw-r--r--arch/arm/mvp/mvpkm/wscalls.h165
-rw-r--r--arch/arm/mvp/pvtcpkm/COPYING341
-rw-r--r--arch/arm/mvp/pvtcpkm/Kbuild9
-rw-r--r--arch/arm/mvp/pvtcpkm/Makefile1
-rw-r--r--arch/arm/mvp/pvtcpkm/check_kconfig.c91
-rw-r--r--arch/arm/mvp/pvtcpkm/comm.h171
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_os.h150
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_os_linux.c371
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_os_linux.h699
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_os_mod_linux.c105
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_os_mod_ver.h38
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_svc.h71
-rw-r--r--arch/arm/mvp/pvtcpkm/comm_transp.h90
-rw-r--r--arch/arm/mvp/pvtcpkm/include_check.h18
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp.c587
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp.h458
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off.c81
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off.h219
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off_io_linux.c831
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off_linux.c2858
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h226
-rw-r--r--arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S70
-rw-r--r--arch/arm/oprofile/common.c2
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c9
-rw-r--r--arch/arm/plat-s3c24xx/devs.c38
-rw-r--r--arch/arm/plat-s5p/Kconfig193
-rw-r--r--arch/arm/plat-s5p/Makefile32
-rw-r--r--arch/arm/plat-s5p/bts.c393
-rw-r--r--arch/arm/plat-s5p/clock.c42
-rw-r--r--arch/arm/plat-s5p/cpu.c72
-rw-r--r--arch/arm/plat-s5p/dev-ace.c45
-rw-r--r--arch/arm/plat-s5p/dev-csis-s5p.c113
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c15
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c15
-rw-r--r--arch/arm/plat-s5p/dev-dp.c52
-rw-r--r--arch/arm/plat-s5p/dev-dsim.c110
-rw-r--r--arch/arm/plat-s5p/dev-dsim02.c47
-rw-r--r--arch/arm/plat-s5p/dev-dsim12.c52
-rw-r--r--arch/arm/plat-s5p/dev-ehci.c58
-rw-r--r--arch/arm/plat-s5p/dev-fimc-s5p.c225
-rw-r--r--arch/arm/plat-s5p/dev-fimc0.c3
-rw-r--r--arch/arm/plat-s5p/dev-fimc1.c3
-rw-r--r--arch/arm/plat-s5p/dev-fimc2.c3
-rw-r--r--arch/arm/plat-s5p/dev-fimc3.c3
-rw-r--r--arch/arm/plat-s5p/dev-fimd-s5p.c104
-rw-r--r--arch/arm/plat-s5p/dev-fimd0.c67
-rw-r--r--arch/arm/plat-s5p/dev-fimd1.c71
-rw-r--r--arch/arm/plat-s5p/dev-fimg2d.c75
-rw-r--r--arch/arm/plat-s5p/dev-i2c-hdmiphy.c59
-rw-r--r--arch/arm/plat-s5p/dev-jpeg.c35
-rw-r--r--arch/arm/plat-s5p/dev-mfc.c38
-rw-r--r--arch/arm/plat-s5p/dev-mipidsim.c53
-rw-r--r--arch/arm/plat-s5p/dev-pmu.c41
-rw-r--r--arch/arm/plat-s5p/dev-rotator.c42
-rw-r--r--arch/arm/plat-s5p/dev-tmu.c118
-rw-r--r--arch/arm/plat-s5p/dev-tsi.c47
-rw-r--r--arch/arm/plat-s5p/dev-tv.c185
-rw-r--r--arch/arm/plat-s5p/dev-tvout.c151
-rw-r--r--arch/arm/plat-s5p/dev-usb-switch.c65
-rw-r--r--arch/arm/plat-s5p/dev-usbgadget.c253
-rw-r--r--arch/arm/plat-s5p/include/plat/ace-core.h26
-rw-r--r--arch/arm/plat-s5p/include/plat/bts.h92
-rw-r--r--arch/arm/plat-s5p/include/plat/csis.h45
-rw-r--r--arch/arm/plat-s5p/include/plat/dp.h20
-rw-r--r--arch/arm/plat-s5p/include/plat/dsim.h330
-rw-r--r--arch/arm/plat-s5p/include/plat/ehci.h20
-rw-r--r--arch/arm/plat-s5p/include/plat/exynos4.h20
-rw-r--r--arch/arm/plat-s5p/include/plat/exynos5.h36
-rw-r--r--arch/arm/plat-s5p/include/plat/fb-s5p.h97
-rw-r--r--arch/arm/plat-s5p/include/plat/fimc.h153
-rw-r--r--arch/arm/plat-s5p/include/plat/fimg2d.h26
-rw-r--r--arch/arm/plat-s5p/include/plat/hdmi.h36
-rw-r--r--arch/arm/plat-s5p/include/plat/irqs.h4
-rw-r--r--arch/arm/plat-s5p/include/plat/jpeg.h17
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h28
-rw-r--r--arch/arm/plat-s5p/include/plat/media.h40
-rw-r--r--arch/arm/plat-s5p/include/plat/mipi_csis.h2
-rw-r--r--arch/arm/plat-s5p/include/plat/mipi_dsi.h51
-rw-r--r--arch/arm/plat-s5p/include/plat/mipi_dsim2.h392
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h56
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-csis.h124
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-dsim.h237
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-dsim2.h155
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-fb-s5p.h415
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-fimc.h510
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-ipc.h143
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-mipidsim.h149
-rw-r--r--arch/arm/plat-s5p/include/plat/regs_jpeg.h144
-rw-r--r--arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h217
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h8
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-iovmm.h55
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-mfc.h29
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-otghost.h68
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-sysmmu.h120
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-tmu.h108
-rw-r--r--arch/arm/plat-s5p/include/plat/sysmmu.h95
-rw-r--r--arch/arm/plat-s5p/include/plat/system-reset.h18
-rw-r--r--arch/arm/plat-s5p/include/plat/tvout.h49
-rw-r--r--arch/arm/plat-s5p/include/plat/usb-phy.h13
-rw-r--r--arch/arm/plat-s5p/include/plat/usb-switch.h30
-rw-r--r--arch/arm/plat-s5p/include/plat/usbgadget.h29
-rw-r--r--arch/arm/plat-s5p/irq-eint.c22
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c97
-rw-r--r--arch/arm/plat-s5p/reserve_mem.c307
-rw-r--r--arch/arm/plat-s5p/reset.c33
-rw-r--r--arch/arm/plat-s5p/s5p-sysmmu.c582
-rw-r--r--arch/arm/plat-s5p/s5p_iommu.c459
-rw-r--r--arch/arm/plat-s5p/s5p_iovmm.c365
-rw-r--r--arch/arm/plat-s5p/sysmmu.c312
-rw-r--r--arch/arm/plat-samsung/Kconfig89
-rw-r--r--arch/arm/plat-samsung/Makefile10
-rw-r--r--arch/arm/plat-samsung/adc.c271
-rw-r--r--arch/arm/plat-samsung/clock.c131
-rw-r--r--arch/arm/plat-samsung/cpu.c58
-rw-r--r--arch/arm/plat-samsung/dev-adc.c4
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c14
-rw-r--r--arch/arm/plat-samsung/dev-backlight.c149
-rw-r--r--arch/arm/plat-samsung/dev-fb.c14
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c3
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c1
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c8
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c7
-rw-r--r--arch/arm/plat-samsung/dev-hwmon.c14
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c16
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c24
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c24
-rw-r--r--arch/arm/plat-samsung/dev-mshc.c101
-rw-r--r--arch/arm/plat-samsung/dev-nand.c9
-rw-r--r--arch/arm/plat-samsung/dev-pwm.c93
-rw-r--r--arch/arm/plat-samsung/dev-ts.c16
-rw-r--r--arch/arm/plat-samsung/dev-ts1.c60
-rw-r--r--arch/arm/plat-samsung/dev-usb.c9
-rw-r--r--arch/arm/plat-samsung/dev-usb3-exynos-drd.c103
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c2
-rw-r--r--arch/arm/plat-samsung/dma_m2m_test.c323
-rw-r--r--arch/arm/plat-samsung/gpio-config.c96
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/backlight.h26
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h12
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h145
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h120
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h18
-rw-r--r--arch/arm/plat-samsung/include/plat/fb-core.h21
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h63
-rw-r--r--arch/arm/plat-samsung/include/plat/fimd_lite_ext.h99
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h81
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h9
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/iovmm.h76
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h14
-rw-r--r--arch/arm/plat-samsung/include/plat/mshci.h161
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h37
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h17
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-adc.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb-v4.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb.h117
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-otg.h260
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h75
-rw-r--r--arch/arm/plat-samsung/include/plat/rtc-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h22
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/sysmmu.h107
-rw-r--r--arch/arm/plat-samsung/include/plat/ts.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/tv-core.h37
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h11
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h12
-rw-r--r--arch/arm/plat-samsung/irq-uart.c11
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c5
-rw-r--r--arch/arm/plat-samsung/pd.c42
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c33
-rw-r--r--arch/arm/plat-samsung/pm.c69
-rw-r--r--arch/arm/plat-samsung/pwm.c103
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c109
-rw-r--r--arch/arm/tools/mach-types6
-rw-r--r--arch/arm/vfp/entry.S3
-rw-r--r--arch/arm/vfp/vfphw.S20
-rw-r--r--arch/arm/vfp/vfpmodule.c46
-rw-r--r--arch/avr32/boot/images/.gitignore4
-rw-r--r--arch/avr32/kernel/.gitignore1
-rw-r--r--arch/blackfin/boot/.gitignore2
-rw-r--r--arch/blackfin/kernel/.gitignore1
-rw-r--r--arch/cris/boot/.gitignore2
-rw-r--r--arch/ia64/kernel/.gitignore2
-rw-r--r--arch/m32r/kernel/.gitignore1
-rw-r--r--arch/m68k/kernel/.gitignore1
-rw-r--r--arch/mips/boot/.gitignore6
-rw-r--r--arch/mips/kernel/.gitignore1
-rw-r--r--arch/mn10300/boot/.gitignore1
-rw-r--r--arch/parisc/kernel/.gitignore1
-rw-r--r--arch/powerpc/boot/.gitignore47
-rw-r--r--arch/powerpc/kernel/.gitignore1
-rw-r--r--arch/powerpc/kernel/vdso32/.gitignore2
-rw-r--r--arch/powerpc/kernel/vdso64/.gitignore2
-rw-r--r--arch/powerpc/platforms/cell/spufs/.gitignore2
-rw-r--r--arch/sh/boot/.gitignore3
-rw-r--r--arch/sh/boot/compressed/.gitignore1
-rw-r--r--arch/sh/kernel/.gitignore1
-rw-r--r--arch/sh/kernel/vsyscall/.gitignore1
-rw-r--r--arch/sparc/boot/.gitignore8
-rw-r--r--arch/sparc/kernel/.gitignore1
-rw-r--r--arch/um/.gitignore3
-rw-r--r--arch/unicore32/.gitignore21
-rw-r--r--arch/x86/.gitignore3
-rw-r--r--arch/x86/boot/.gitignore10
-rw-r--r--arch/x86/boot/compressed/.gitignore6
-rw-r--r--arch/x86/boot/tools/.gitignore1
-rw-r--r--arch/x86/include/asm/idle.h7
-rw-r--r--arch/x86/kernel/.gitignore3
-rw-r--r--arch/x86/kernel/acpi/realmode/.gitignore3
-rw-r--r--arch/x86/kernel/cpu/.gitignore1
-rw-r--r--arch/x86/kernel/process_64.c18
-rw-r--r--arch/x86/lib/.gitignore1
-rw-r--r--arch/x86/vdso/.gitignore6
-rw-r--r--arch/x86/vdso/vdso32/.gitignore1
870 files changed, 205611 insertions, 11435 deletions
diff --git a/arch/.gitignore b/arch/.gitignore
deleted file mode 100644
index 7414689..0000000
--- a/arch/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-i386
-x86_64
diff --git a/arch/alpha/kernel/.gitignore b/arch/alpha/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/alpha/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2456bad..1e3390d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -110,7 +110,6 @@ config STACKTRACE_SUPPORT
config HAVE_LATENCYTOP_SUPPORT
bool
- depends on !SMP
default y
config LOCKDEP_SUPPORT
@@ -213,6 +212,9 @@ config ARM_PATCH_PHYS_VIRT_16BIT
to allow physical memory down to a theoretical minimum of 64K
boundaries.
+config ARCH_HIBERNATION_POSSIBLE
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -761,19 +763,22 @@ config ARCH_S5PV210
help
Samsung S5PV210/S5PC110 series based systems
-config ARCH_EXYNOS4
- bool "Samsung EXYNOS4"
+config ARCH_EXYNOS
+ bool "Samsung EXYNOS"
select CPU_V7
- select ARCH_SPARSEMEM_ENABLE
+ select ARCH_FLATMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
+ select CLKDEV_LOOKUP
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
help
- Samsung EXYNOS4 series based systems
+ Samsung EXYNOS series based systems
config ARCH_SHARK
bool "Shark"
@@ -987,7 +992,7 @@ source "arch/arm/mach-s5pc100/Kconfig"
source "arch/arm/mach-s5pv210/Kconfig"
-source "arch/arm/mach-exynos4/Kconfig"
+source "arch/arm/mach-exynos/Kconfig"
source "arch/arm/mach-shmobile/Kconfig"
@@ -1033,6 +1038,11 @@ config ARM_TIMER_SP804
source arch/arm/mm/Kconfig
+config ARM_PLD_SIZE
+ int
+ default 64 if ARCH_EXYNOS5
+ default 32
+
config IWMMXT
bool "Enable iWMMXt support"
depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
@@ -1163,6 +1173,16 @@ config ARM_ERRATA_720789
tables. The workaround changes the TLB flushing routines to invalidate
entries regardless of the ASID.
+config ARM_ERRATA_720791
+ bool "ARM errata: Dynamic high-level clock gating corrupts the Jazelle instruction stream"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 720791 Cortex-A9
+ (r1p0..r1p2) erratum. The Jazelle instruction stream may be
+ corrupted when dynamic high-level clock gating is enabled.
+ This workaround disables gating the Core clock when the Instruction
+ side is waiting for a Page Table Walk answer or linefill completion.
+
config PL310_ERRATA_727915
bool "Background Clean & Invalidate by Way operation can cause data corruption"
depends on CACHE_L2X0
@@ -1179,7 +1199,7 @@ config ARM_ERRATA_743622
depends on CPU_V7
help
This option enables the workaround for the 743622 Cortex-A9
- (r2p0..r2p2) erratum. Under very rare conditions, a faulty
+ (r2p*) erratum. Under very rare conditions, a faulty
optimisation in the Cortex-A9 Store Buffer may lead to data
corruption. This workaround sets a specific bit in the diagnostic
register of the Cortex-A9 which disables the Store Buffer
@@ -1234,6 +1254,29 @@ config ARM_ERRATA_754327
This workaround defines cpu_relax() as smp_mb(), preventing correctly
written polling loops from denying visibility of updates to memory.
+config ARM_ERRATA_761320
+ bool "ARM errata: no direct eviction"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 761320 Cortex-A9 erratum.
+
+config ARM_ERRATA_761171
+ bool "ARM errata: disable store streaming of mode 3"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 761171 Cortex-A15 erratum.
+
+config ARM_ERRATA_762974
+ bool "ARM errata: disable l2 prefetch"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 762964 Cortex-A15 erratum.
+
+config ARM_ERRATA_763722
+ bool "ARM errata: disable store streaming of mode 2 and mode 3"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 763722 Cortex-A15 erratum.
endmenu
source "arch/arm/common/Kconfig"
@@ -1336,7 +1379,7 @@ config SMP
depends on GENERIC_CLOCKEVENTS
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
- ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
+ ARCH_EXYNOS || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
@@ -1423,7 +1466,7 @@ config LOCAL_TIMERS
bool "Use local timer interrupts"
depends on SMP
default y
- select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
+ select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS_MCT)
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
@@ -1435,7 +1478,8 @@ source kernel/Kconfig.preempt
config HZ
int
default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
- ARCH_S5PV210 || ARCH_EXYNOS4
+ ARCH_S5PV210 || (ARCH_EXYNOS && !MACH_FPGA5410)
+ default 20 if MACH_FPGA5410
default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
default AT91_TIMER_HZ if ARCH_AT91
default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
@@ -1534,6 +1578,16 @@ config ARCH_SELECT_MEMORY_MODEL
config HAVE_ARCH_PFN_VALID
def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
+config ARCH_SKIP_SECONDARY_CALIBRATE
+ bool "Skip secondary CPU calibration"
+ depends on SMP
+ help
+ On some architectures, secondary cores shares clock with primiary
+ core and hence scale together. Hence secondary core lpj calibration
+ is not necessary and can be skipped to save considerable time.
+
+ If unsure, say n.
+
config HIGHMEM
bool "High Memory Support"
depends on MMU
@@ -1569,6 +1623,7 @@ config FORCE_MAX_ZONEORDER
int "Maximum zone order" if ARCH_SHMOBILE
range 11 64 if ARCH_SHMOBILE
default "9" if SA1111
+ default "12" if ARCH_EXYNOS
default "11"
help
The kernel memory allocator divides physically contiguous memory
@@ -1697,6 +1752,17 @@ config DEPRECATED_PARAM_STRUCT
This was deprecated in 2001 and announced to live on for 5 years.
Some old boot loaders still use this way.
+config ARM_FLUSH_CONSOLE_ON_RESTART
+ bool "Force flush the console on restart"
+ help
+ If the console is locked while the system is rebooted, the messages
+ in the temporary logbuffer would not have propogated to all the
+ console drivers. This option forces the console lock to be
+ released if it failed to be acquired, which will cause all the
+ pending messages to be flushed.
+
+source "arch/arm/mvp/Kconfig"
+
endmenu
menu "Boot options"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 81cbe40..25846f8 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -129,4 +129,9 @@ config DEBUG_S3C_UART
The uncompressor code port configuration is now handled
by CONFIG_S3C_LOWLEVEL_UART_PORT.
+config CACHE_PERF
+ tristate "cache performance test"
+ help
+ Measure the performance of cache maintenance operation.
+
endmenu
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index f5b2b39..825ad6d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -178,7 +178,7 @@ machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0
machine-$(CONFIG_ARCH_S5PC100) := s5pc100
machine-$(CONFIG_ARCH_S5PV210) := s5pv210
-machine-$(CONFIG_ARCH_EXYNOS4) := exynos4
+machine-$(CONFIG_ARCH_EXYNOS) := exynos
machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
@@ -249,6 +249,7 @@ endif
core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
core-$(CONFIG_VFP) += arch/arm/vfp/
+core-$(CONFIG_VMWARE_MVP) += arch/arm/mvp/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
deleted file mode 100644
index ce1c5ff..0000000
--- a/arch/arm/boot/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-Image
-zImage
-xipImage
-bootpImage
-uImage
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 9128fdd..9ec1a8d 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -12,6 +12,7 @@
#
MKIMAGE := $(srctree)/scripts/mkuboot.sh
+MKFIPS := $(srctree)/scripts/mk_fipsbinary.sh
ifneq ($(MACHINE),)
include $(srctree)/$(MACHINE)/Makefile.boot
@@ -55,6 +56,9 @@ $(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
+ifeq ($(CONFIG_CRYPTO_FIPS),y)
+ $(MKFIPS) $(obj)/zImage
+endif
@echo ' Kernel: $@ is ready'
endif
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
deleted file mode 100644
index c602896..0000000
--- a/arch/arm/boot/compressed/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-font.c
-lib1funcs.S
-piggy.gzip
-piggy.lzo
-piggy.lzma
-vmlinux
-vmlinux.lds
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 23aad07..54c9428 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -16,6 +16,11 @@ endif
endif
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
+# change@wtl.rsengott
+# FIPS_KERNEL_RAM_BASE is start of kernel text in RAM
+ifeq ($(CONFIG_CRYPTO_FIPS),y)
+AFLAGS_head.o += -DFIPS_KERNEL_RAM_BASE=0x40008000
+endif
HEAD = head.o
OBJS += misc.o decompress.o
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 940b201..3a959994 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -186,7 +186,7 @@ restart: adr r0, LC0
* We might be running at a different address. We need
* to fix up various pointers.
*/
- sub r0, r0, r1 @ calculate the delta offset
+ sub r0, r0, r1 @ calculate the delta offset
add r6, r6, r0 @ _edata
add r10, r10, r0 @ inflated kernel size location
@@ -292,7 +292,13 @@ wont_overwrite:
* sp = stack pointer
*/
teq r0, #0
+#ifndef CONFIG_CRYPTO_FIPS
beq not_relocated
+#else
+ movw r5, #:lower16:zimage_ram_base_addr
+ movt r5, #:upper16:zimage_ram_base_addr
+ beq not_relocated_copy
+#endif
add r11, r11, r0
add r12, r12, r0
@@ -305,6 +311,11 @@ wont_overwrite:
add r2, r2, r0
add r3, r3, r0
+#ifdef CONFIG_CRYPTO_FIPS
+ movw r5, #:lower16:zimage_ram_base_addr
+ movt r5, #:upper16:zimage_ram_base_addr
+ bl copy_compressed
+#endif
/*
* Relocate all entries in the GOT table.
*/
@@ -367,6 +378,10 @@ LC0: .word LC0 @ r1
.word .L_user_stack_end @ sp
.size LC0, . - LC0
+#ifdef CONFIG_CRYPTO_FIPS
+ .equ zimage_ram_base_addr, FIPS_KERNEL_RAM_BASE
+#endif
+
#ifdef CONFIG_ARCH_RPC
.globl params
params: ldr r0, =0x10000100 @ params_phys for RPC
@@ -375,6 +390,29 @@ params: ldr r0, =0x10000100 @ params_phys for RPC
.align
#endif
+
+#ifdef CONFIG_CRYPTO_FIPS
+not_relocated_copy:
+ bl copy_compressed
+ b not_relocated
+
+copy_compressed:
+ mov r1, r5
+ add r9, r4, #CONFIG_CRYPTO_FIPS_INTEG_OFFSET
+
+1:
+ ldmia r1!, {r5}
+ stmia r9!, {r5}
+ cmp r1, r2
+ blo 1b
+
+ .rept 8
+ ldmia r1!, {r5}
+ stmia r9!, {r5}
+ .endr
+ mov pc, lr
+#endif
+
/*
* Turn on the cache. We need to setup some page tables so that we
* can have both the I and D caches on.
@@ -656,6 +694,8 @@ proc_types:
@ b __arm6_mmu_cache_off
@ b __armv3_mmu_cache_flush
+#if !defined(CONFIG_CPU_V7)
+ /* This collides with some V7 IDs, preventing correct detection */
.word 0x00000000 @ old ARM ID
.word 0x0000f000
mov pc, lr
@@ -664,6 +704,7 @@ proc_types:
THUMB( nop )
mov pc, lr
THUMB( nop )
+#endif
.word 0x41007000 @ ARM7/710
.word 0xfff8fe00
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 4b71766..6382566 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -39,3 +39,53 @@ config SHARP_PARAM
config SHARP_SCOOP
bool
+
+config FIQ_GLUE
+ bool
+ select FIQ
+
+config FIQ_DEBUGGER
+ bool "FIQ Mode Serial Debugger"
+ select FIQ
+ select FIQ_GLUE
+ default n
+ help
+ The FIQ serial debugger can accept commands even when the
+ kernel is unresponsive due to being stuck with interrupts
+ disabled.
+
+
+config FIQ_DEBUGGER_NO_SLEEP
+ bool "Keep serial debugger active"
+ depends on FIQ_DEBUGGER
+ default n
+ help
+ Enables the serial debugger at boot. Passing
+ fiq_debugger.no_sleep on the kernel commandline will
+ override this config option.
+
+config FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
+ bool "Don't disable wakeup IRQ when debugger is active"
+ depends on FIQ_DEBUGGER
+ default n
+ help
+ Don't disable the wakeup irq when enabling the uart clock. This will
+ cause extra interrupts, but it makes the serial debugger usable with
+ on some MSM radio builds that ignore the uart clock request in power
+ collapse.
+
+config FIQ_DEBUGGER_CONSOLE
+ bool "Console on FIQ Serial Debugger port"
+ depends on FIQ_DEBUGGER
+ default n
+ help
+ Enables a console so that printk messages are displayed on
+ the debugger serial port as the occur.
+
+config FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE
+ bool "Put the FIQ debugger into console mode by default"
+ depends on FIQ_DEBUGGER_CONSOLE
+ default n
+ help
+ If enabled, this puts the fiq debugger into console mode by default.
+ Otherwise, the fiq debugger will start out in debug mode.
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 6ea9b6f..3ab5d76 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -17,3 +17,5 @@ obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
+obj-$(CONFIG_FIQ_GLUE) += fiq_glue.o fiq_glue_setup.o
+obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger.o
diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
new file mode 100644
index 0000000..3ed18ae
--- /dev/null
+++ b/arch/arm/common/fiq_debugger.c
@@ -0,0 +1,1196 @@
+/*
+ * arch/arm/common/fiq_debugger.c
+ *
+ * Serial Debugger Interface accessed through an FIQ interrupt.
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdarg.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/console.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/kernel_stat.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/wakelock.h>
+
+#include <asm/fiq_debugger.h>
+#include <asm/fiq_glue.h>
+#include <asm/stacktrace.h>
+
+#include <mach/system.h>
+
+#include <linux/uaccess.h>
+
+#include "fiq_debugger_ringbuf.h"
+
+#define DEBUG_MAX 64
+#define MAX_UNHANDLED_FIQ_COUNT 1000000
+
+#define THREAD_INFO(sp) ((struct thread_info *) \
+ ((unsigned long)(sp) & ~(THREAD_SIZE - 1)))
+
+struct fiq_debugger_state {
+ struct fiq_glue_handler handler;
+
+ int fiq;
+ int uart_irq;
+ int signal_irq;
+ int wakeup_irq;
+ bool wakeup_irq_no_set_wake;
+ struct clk *clk;
+ struct fiq_debugger_pdata *pdata;
+ struct platform_device *pdev;
+
+ char debug_cmd[DEBUG_MAX];
+ int debug_busy;
+ int debug_abort;
+
+ char debug_buf[DEBUG_MAX];
+ int debug_count;
+
+ bool no_sleep;
+ bool debug_enable;
+ bool ignore_next_wakeup_irq;
+ struct timer_list sleep_timer;
+ spinlock_t sleep_timer_lock;
+ bool uart_enabled;
+ struct wake_lock debugger_wake_lock;
+ bool console_enable;
+ int current_cpu;
+ atomic_t unhandled_fiq_count;
+ bool in_fiq;
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+ struct console console;
+ struct tty_driver *tty_driver;
+ struct tty_struct *tty;
+ int tty_open_count;
+ struct fiq_debugger_ringbuf *tty_rbuf;
+ bool syslog_dumping;
+#endif
+
+ unsigned int last_irqs[NR_IRQS];
+ unsigned int last_local_timer_irqs[NR_CPUS];
+};
+
+#ifdef CONFIG_FIQ_DEBUGGER_NO_SLEEP
+static bool initial_no_sleep = true;
+#else
+static bool initial_no_sleep;
+#endif
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE
+static bool initial_debug_enable = true;
+static bool initial_console_enable = true;
+#else
+static bool initial_debug_enable;
+static bool initial_console_enable;
+#endif
+
+module_param_named(no_sleep, initial_no_sleep, bool, 0644);
+module_param_named(debug_enable, initial_debug_enable, bool, 0644);
+module_param_named(console_enable, initial_console_enable, bool, 0644);
+
+#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
+static inline void enable_wakeup_irq(struct fiq_debugger_state *state) {}
+static inline void disable_wakeup_irq(struct fiq_debugger_state *state) {}
+#else
+static inline void enable_wakeup_irq(struct fiq_debugger_state *state)
+{
+ if (state->wakeup_irq < 0)
+ return;
+ enable_irq(state->wakeup_irq);
+ if (!state->wakeup_irq_no_set_wake)
+ enable_irq_wake(state->wakeup_irq);
+}
+static inline void disable_wakeup_irq(struct fiq_debugger_state *state)
+{
+ if (state->wakeup_irq < 0)
+ return;
+ disable_irq_nosync(state->wakeup_irq);
+ if (!state->wakeup_irq_no_set_wake)
+ disable_irq_wake(state->wakeup_irq);
+}
+#endif
+
+static bool inline debug_have_fiq(struct fiq_debugger_state *state)
+{
+ return (state->fiq >= 0);
+}
+
+static void debug_force_irq(struct fiq_debugger_state *state)
+{
+ unsigned int irq = state->signal_irq;
+
+ if (WARN_ON(!debug_have_fiq(state)))
+ return;
+ if (state->pdata->force_irq) {
+ state->pdata->force_irq(state->pdev, irq);
+ } else {
+ struct irq_chip *chip = irq_get_chip(irq);
+ if (chip && chip->irq_retrigger)
+ chip->irq_retrigger(irq_get_irq_data(irq));
+ }
+}
+
+static void debug_uart_enable(struct fiq_debugger_state *state)
+{
+ if (state->clk)
+ clk_enable(state->clk);
+ if (state->pdata->uart_enable)
+ state->pdata->uart_enable(state->pdev);
+}
+
+static void debug_uart_disable(struct fiq_debugger_state *state)
+{
+ if (state->pdata->uart_disable)
+ state->pdata->uart_disable(state->pdev);
+ if (state->clk)
+ clk_disable(state->clk);
+}
+
+static void debug_uart_flush(struct fiq_debugger_state *state)
+{
+ if (state->pdata->uart_flush)
+ state->pdata->uart_flush(state->pdev);
+}
+
+static void debug_puts(struct fiq_debugger_state *state, char *s)
+{
+ unsigned c;
+ while ((c = *s++)) {
+ if (c == '\n')
+ state->pdata->uart_putc(state->pdev, '\r');
+ state->pdata->uart_putc(state->pdev, c);
+ }
+}
+
+static void debug_prompt(struct fiq_debugger_state *state)
+{
+ debug_puts(state, "debug> ");
+}
+
+int log_buf_copy(char *dest, int idx, int len);
+static void dump_kernel_log(struct fiq_debugger_state *state)
+{
+ char buf[1024];
+ int idx = 0;
+ int ret;
+ int saved_oip;
+
+ /* setting oops_in_progress prevents log_buf_copy()
+ * from trying to take a spinlock which will make it
+ * very unhappy in some cases...
+ */
+ saved_oip = oops_in_progress;
+ oops_in_progress = 1;
+ for (;;) {
+ ret = log_buf_copy(buf, idx, 1023);
+ if (ret <= 0)
+ break;
+ buf[ret] = 0;
+ debug_puts(state, buf);
+ idx += ret;
+ }
+ oops_in_progress = saved_oip;
+}
+
+static char *mode_name(unsigned cpsr)
+{
+ switch (cpsr & MODE_MASK) {
+ case USR_MODE: return "USR";
+ case FIQ_MODE: return "FIQ";
+ case IRQ_MODE: return "IRQ";
+ case SVC_MODE: return "SVC";
+ case ABT_MODE: return "ABT";
+ case UND_MODE: return "UND";
+ case SYSTEM_MODE: return "SYS";
+ default: return "???";
+ }
+}
+
+static int debug_printf(void *cookie, const char *fmt, ...)
+{
+ struct fiq_debugger_state *state = cookie;
+ char buf[256];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ debug_puts(state, buf);
+ return state->debug_abort;
+}
+
+/* Safe outside fiq context */
+static int debug_printf_nfiq(void *cookie, const char *fmt, ...)
+{
+ struct fiq_debugger_state *state = cookie;
+ char buf[256];
+ va_list ap;
+ unsigned long irq_flags;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, 128, fmt, ap);
+ va_end(ap);
+
+ local_irq_save(irq_flags);
+ debug_puts(state, buf);
+ debug_uart_flush(state);
+ local_irq_restore(irq_flags);
+ return state->debug_abort;
+}
+
+static void dump_regs(struct fiq_debugger_state *state, unsigned *regs)
+{
+ debug_printf(state, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
+ regs[0], regs[1], regs[2], regs[3]);
+ debug_printf(state, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
+ regs[4], regs[5], regs[6], regs[7]);
+ debug_printf(state, " r8 %08x r9 %08x r10 %08x r11 %08x mode %s\n",
+ regs[8], regs[9], regs[10], regs[11],
+ mode_name(regs[16]));
+ if ((regs[16] & MODE_MASK) == USR_MODE)
+ debug_printf(state, " ip %08x sp %08x lr %08x pc %08x "
+ "cpsr %08x\n", regs[12], regs[13], regs[14],
+ regs[15], regs[16]);
+ else
+ debug_printf(state, " ip %08x sp %08x lr %08x pc %08x "
+ "cpsr %08x spsr %08x\n", regs[12], regs[13],
+ regs[14], regs[15], regs[16], regs[17]);
+}
+
+struct mode_regs {
+ unsigned long sp_svc;
+ unsigned long lr_svc;
+ unsigned long spsr_svc;
+
+ unsigned long sp_abt;
+ unsigned long lr_abt;
+ unsigned long spsr_abt;
+
+ unsigned long sp_und;
+ unsigned long lr_und;
+ unsigned long spsr_und;
+
+ unsigned long sp_irq;
+ unsigned long lr_irq;
+ unsigned long spsr_irq;
+
+ unsigned long r8_fiq;
+ unsigned long r9_fiq;
+ unsigned long r10_fiq;
+ unsigned long r11_fiq;
+ unsigned long r12_fiq;
+ unsigned long sp_fiq;
+ unsigned long lr_fiq;
+ unsigned long spsr_fiq;
+};
+
+void __naked get_mode_regs(struct mode_regs *regs)
+{
+ asm volatile (
+ "mrs r1, cpsr\n"
+ "msr cpsr_c, #0xd3 @(SVC_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xd7 @(ABT_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xdb @(UND_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xd2 @(IRQ_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r13 - r14}\n"
+ "mrs r2, spsr\n"
+ "msr cpsr_c, #0xd1 @(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)\n"
+ "stmia r0!, {r2, r8 - r14}\n"
+ "mrs r2, spsr\n"
+ "stmia r0!, {r2}\n"
+ "msr cpsr_c, r1\n"
+ "bx lr\n");
+}
+
+
+static void dump_allregs(struct fiq_debugger_state *state, unsigned *regs)
+{
+ struct mode_regs mode_regs;
+ dump_regs(state, regs);
+ get_mode_regs(&mode_regs);
+ debug_printf(state, " svc: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_svc, mode_regs.lr_svc, mode_regs.spsr_svc);
+ debug_printf(state, " abt: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_abt, mode_regs.lr_abt, mode_regs.spsr_abt);
+ debug_printf(state, " und: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_und, mode_regs.lr_und, mode_regs.spsr_und);
+ debug_printf(state, " irq: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_irq, mode_regs.lr_irq, mode_regs.spsr_irq);
+ debug_printf(state, " fiq: r8 %08x r9 %08x r10 %08x r11 %08x "
+ "r12 %08x\n",
+ mode_regs.r8_fiq, mode_regs.r9_fiq, mode_regs.r10_fiq,
+ mode_regs.r11_fiq, mode_regs.r12_fiq);
+ debug_printf(state, " fiq: sp %08x lr %08x spsr %08x\n",
+ mode_regs.sp_fiq, mode_regs.lr_fiq, mode_regs.spsr_fiq);
+}
+
+static void dump_irqs(struct fiq_debugger_state *state)
+{
+ int n;
+ unsigned int cpu;
+
+ debug_printf(state, "irqnr total since-last status name\n");
+ for (n = 0; n < NR_IRQS; n++) {
+ struct irqaction *act = irq_desc[n].action;
+ if (!act && !kstat_irqs(n))
+ continue;
+ debug_printf(state, "%5d: %10u %11u %8x %s\n", n,
+ kstat_irqs(n),
+ kstat_irqs(n) - state->last_irqs[n],
+ irq_desc[n].status_use_accessors,
+ (act && act->name) ? act->name : "???");
+ state->last_irqs[n] = kstat_irqs(n);
+ }
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+
+ debug_printf(state, "LOC %d: %10u %11u\n", cpu,
+ __IRQ_STAT(cpu, local_timer_irqs),
+ __IRQ_STAT(cpu, local_timer_irqs) -
+ state->last_local_timer_irqs[cpu]);
+ state->last_local_timer_irqs[cpu] =
+ __IRQ_STAT(cpu, local_timer_irqs);
+ }
+}
+
+struct stacktrace_state {
+ struct fiq_debugger_state *state;
+ unsigned int depth;
+};
+
+static int report_trace(struct stackframe *frame, void *d)
+{
+ struct stacktrace_state *sts = d;
+
+ if (sts->depth) {
+ debug_printf(sts->state,
+ " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n",
+ frame->pc, frame->pc, frame->lr, frame->lr,
+ frame->sp, frame->fp);
+ sts->depth--;
+ return 0;
+ }
+ debug_printf(sts->state, " ...\n");
+
+ return sts->depth == 0;
+}
+
+struct frame_tail {
+ struct frame_tail *fp;
+ unsigned long sp;
+ unsigned long lr;
+} __attribute__((packed));
+
+static struct frame_tail *user_backtrace(struct fiq_debugger_state *state,
+ struct frame_tail *tail)
+{
+ struct frame_tail buftail[2];
+
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail))) {
+ debug_printf(state, " invalid frame pointer %p\n", tail);
+ return NULL;
+ }
+ if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) {
+ debug_printf(state,
+ " failed to copy frame pointer %p\n", tail);
+ return NULL;
+ }
+
+ debug_printf(state, " %p\n", buftail[0].lr);
+
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (tail >= buftail[0].fp)
+ return NULL;
+
+ return buftail[0].fp-1;
+}
+
+void dump_stacktrace(struct fiq_debugger_state *state,
+ struct pt_regs * const regs, unsigned int depth, void *ssp)
+{
+ struct frame_tail *tail;
+ struct thread_info *real_thread_info = THREAD_INFO(ssp);
+ struct stacktrace_state sts;
+
+ sts.depth = depth;
+ sts.state = state;
+ *current_thread_info() = *real_thread_info;
+
+ if (!current)
+ debug_printf(state, "current NULL\n");
+ else
+ debug_printf(state, "pid: %d comm: %s\n",
+ current->pid, current->comm);
+ dump_regs(state, (unsigned *)regs);
+
+ if (!user_mode(regs)) {
+ struct stackframe frame;
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+ debug_printf(state,
+ " pc: %p (%pF), lr %p (%pF), sp %p, fp %p\n",
+ regs->ARM_pc, regs->ARM_pc, regs->ARM_lr, regs->ARM_lr,
+ regs->ARM_sp, regs->ARM_fp);
+ walk_stackframe(&frame, report_trace, &sts);
+ return;
+ }
+
+ tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+ while (depth-- && tail && !((unsigned long) tail & 3))
+ tail = user_backtrace(state, tail);
+}
+
+static void do_ps(struct fiq_debugger_state *state)
+{
+ struct task_struct *g;
+ struct task_struct *p;
+ unsigned task_state;
+ static const char stat_nam[] = "RSDTtZX";
+
+ debug_printf(state, "pid ppid prio task pc\n");
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ task_state = p->state ? __ffs(p->state) + 1 : 0;
+ debug_printf(state,
+ "%5d %5d %4d ", p->pid, p->parent->pid, p->prio);
+ debug_printf(state, "%-13.13s %c", p->comm,
+ task_state >= sizeof(stat_nam) ? '?' : stat_nam[task_state]);
+ if (task_state == TASK_RUNNING)
+ debug_printf(state, " running\n");
+ else
+ debug_printf(state, " %08lx\n", thread_saved_pc(p));
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+}
+
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+static void begin_syslog_dump(struct fiq_debugger_state *state)
+{
+ state->syslog_dumping = true;
+}
+
+static void end_syslog_dump(struct fiq_debugger_state *state)
+{
+ state->syslog_dumping = false;
+}
+#else
+extern int do_syslog(int type, char __user *bug, int count);
+static void begin_syslog_dump(struct fiq_debugger_state *state)
+{
+ do_syslog(5 /* clear */, NULL, 0);
+}
+
+static void end_syslog_dump(struct fiq_debugger_state *state)
+{
+ char buf[128];
+ int ret;
+ int idx = 0;
+
+ while (1) {
+ ret = log_buf_copy(buf, idx, sizeof(buf) - 1);
+ if (ret <= 0)
+ break;
+ buf[ret] = 0;
+ debug_printf(state, "%s", buf);
+ idx += ret;
+ }
+}
+#endif
+
+static void do_sysrq(struct fiq_debugger_state *state, char rq)
+{
+ begin_syslog_dump(state);
+ handle_sysrq(rq);
+ end_syslog_dump(state);
+}
+
+/* This function CANNOT be called in FIQ context */
+static void debug_irq_exec(struct fiq_debugger_state *state, char *cmd)
+{
+ if (!strcmp(cmd, "ps"))
+ do_ps(state);
+ if (!strcmp(cmd, "sysrq"))
+ do_sysrq(state, 'h');
+ if (!strncmp(cmd, "sysrq ", 6))
+ do_sysrq(state, cmd[6]);
+}
+
+static void debug_help(struct fiq_debugger_state *state)
+{
+ debug_printf(state, "FIQ Debugger commands:\n"
+ " pc PC status\n"
+ " regs Register dump\n"
+ " allregs Extended Register dump\n"
+ " bt Stack trace\n"
+ " reboot Reboot\n"
+ " irqs Interupt status\n"
+ " kmsg Kernel log\n"
+ " version Kernel version\n");
+ debug_printf(state, " sleep Allow sleep while in FIQ\n"
+ " nosleep Disable sleep while in FIQ\n"
+ " console Switch terminal to console\n"
+ " cpu Current CPU\n"
+ " cpu <number> Switch to CPU<number>\n");
+ debug_printf(state, " ps Process list\n"
+ " sysrq sysrq options\n"
+ " sysrq <param> Execute sysrq with <param>\n");
+}
+
+static void take_affinity(void *info)
+{
+ struct fiq_debugger_state *state = info;
+ struct cpumask cpumask;
+
+ cpumask_clear(&cpumask);
+ cpumask_set_cpu(get_cpu(), &cpumask);
+
+ irq_set_affinity(state->uart_irq, &cpumask);
+}
+
+static void switch_cpu(struct fiq_debugger_state *state, int cpu)
+{
+ if (!debug_have_fiq(state))
+ smp_call_function_single(cpu, take_affinity, state, false);
+ state->current_cpu = cpu;
+}
+
+static bool debug_fiq_exec(struct fiq_debugger_state *state,
+ const char *cmd, unsigned *regs, void *svc_sp)
+{
+ bool signal_helper = false;
+
+ if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) {
+ debug_help(state);
+ } else if (!strcmp(cmd, "pc")) {
+ debug_printf(state, " pc %08x cpsr %08x mode %s\n",
+ regs[15], regs[16], mode_name(regs[16]));
+ } else if (!strcmp(cmd, "regs")) {
+ dump_regs(state, regs);
+ } else if (!strcmp(cmd, "allregs")) {
+ dump_allregs(state, regs);
+ } else if (!strcmp(cmd, "bt")) {
+ dump_stacktrace(state, (struct pt_regs *)regs, 100, svc_sp);
+ } else if (!strcmp(cmd, "reboot")) {
+ arch_reset(0, 0);
+ } else if (!strcmp(cmd, "irqs")) {
+ dump_irqs(state);
+ } else if (!strcmp(cmd, "kmsg")) {
+ dump_kernel_log(state);
+ } else if (!strcmp(cmd, "version")) {
+ debug_printf(state, "%s\n", linux_banner);
+ } else if (!strcmp(cmd, "sleep")) {
+ state->no_sleep = false;
+ debug_printf(state, "enabling sleep\n");
+ } else if (!strcmp(cmd, "nosleep")) {
+ state->no_sleep = true;
+ debug_printf(state, "disabling sleep\n");
+ } else if (!strcmp(cmd, "console")) {
+ state->console_enable = true;
+ debug_printf(state, "console mode\n");
+ } else if (!strcmp(cmd, "cpu")) {
+ debug_printf(state, "cpu %d\n", state->current_cpu);
+ } else if (!strncmp(cmd, "cpu ", 4)) {
+ unsigned long cpu = 0;
+ if (strict_strtoul(cmd + 4, 10, &cpu) == 0)
+ switch_cpu(state, cpu);
+ else
+ debug_printf(state, "invalid cpu\n");
+ debug_printf(state, "cpu %d\n", state->current_cpu);
+ } else {
+ if (state->debug_busy) {
+ debug_printf(state,
+ "command processor busy. trying to abort.\n");
+ state->debug_abort = -1;
+ } else {
+ strcpy(state->debug_cmd, cmd);
+ state->debug_busy = 1;
+ }
+
+ return true;
+ }
+ if (!state->console_enable)
+ debug_prompt(state);
+
+ return signal_helper;
+}
+
+static void sleep_timer_expired(unsigned long data)
+{
+ struct fiq_debugger_state *state = (struct fiq_debugger_state *)data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->sleep_timer_lock, flags);
+ if (state->uart_enabled && !state->no_sleep) {
+ if (state->debug_enable && !state->console_enable) {
+ state->debug_enable = false;
+ debug_printf_nfiq(state, "suspending fiq debugger\n");
+ }
+ state->ignore_next_wakeup_irq = true;
+ debug_uart_disable(state);
+ state->uart_enabled = false;
+ enable_wakeup_irq(state);
+ }
+ wake_unlock(&state->debugger_wake_lock);
+ spin_unlock_irqrestore(&state->sleep_timer_lock, flags);
+}
+
+static void handle_wakeup(struct fiq_debugger_state *state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->sleep_timer_lock, flags);
+ if (state->wakeup_irq >= 0 && state->ignore_next_wakeup_irq) {
+ state->ignore_next_wakeup_irq = false;
+ } else if (!state->uart_enabled) {
+ wake_lock(&state->debugger_wake_lock);
+ debug_uart_enable(state);
+ state->uart_enabled = true;
+ disable_wakeup_irq(state);
+ mod_timer(&state->sleep_timer, jiffies + HZ / 2);
+ }
+ spin_unlock_irqrestore(&state->sleep_timer_lock, flags);
+}
+
+static irqreturn_t wakeup_irq_handler(int irq, void *dev)
+{
+ struct fiq_debugger_state *state = dev;
+
+ if (!state->no_sleep)
+ debug_puts(state, "WAKEUP\n");
+ handle_wakeup(state);
+
+ return IRQ_HANDLED;
+}
+
+
+static void debug_handle_irq_context(struct fiq_debugger_state *state)
+{
+ if (!state->no_sleep) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&state->sleep_timer_lock, flags);
+ wake_lock(&state->debugger_wake_lock);
+ mod_timer(&state->sleep_timer, jiffies + HZ * 5);
+ spin_unlock_irqrestore(&state->sleep_timer_lock, flags);
+ }
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+ if (state->tty) {
+ int i;
+ int count = fiq_debugger_ringbuf_level(state->tty_rbuf);
+ for (i = 0; i < count; i++) {
+ int c = fiq_debugger_ringbuf_peek(state->tty_rbuf, 0);
+ tty_insert_flip_char(state->tty, c, TTY_NORMAL);
+ if (!fiq_debugger_ringbuf_consume(state->tty_rbuf, 1))
+ pr_warn("fiq tty failed to consume byte\n");
+ }
+ tty_flip_buffer_push(state->tty);
+ }
+#endif
+ if (state->debug_busy) {
+ debug_irq_exec(state, state->debug_cmd);
+ debug_prompt(state);
+ state->debug_busy = 0;
+ }
+}
+
+static int debug_getc(struct fiq_debugger_state *state)
+{
+ return state->pdata->uart_getc(state->pdev);
+}
+
+static bool debug_handle_uart_interrupt(struct fiq_debugger_state *state,
+ int this_cpu, void *regs, void *svc_sp)
+{
+ int c;
+ static int last_c;
+ int count = 0;
+ bool signal_helper = false;
+
+ if (this_cpu != state->current_cpu) {
+ if (state->in_fiq)
+ return false;
+
+ if (atomic_inc_return(&state->unhandled_fiq_count) !=
+ MAX_UNHANDLED_FIQ_COUNT)
+ return false;
+
+ debug_printf(state, "fiq_debugger: cpu %d not responding, "
+ "reverting to cpu %d\n", state->current_cpu,
+ this_cpu);
+
+ atomic_set(&state->unhandled_fiq_count, 0);
+ switch_cpu(state, this_cpu);
+ return false;
+ }
+
+ state->in_fiq = true;
+
+ while ((c = debug_getc(state)) != FIQ_DEBUGGER_NO_CHAR) {
+ count++;
+ if (!state->debug_enable) {
+ if ((c == 13) || (c == 10)) {
+ state->debug_enable = true;
+ state->debug_count = 0;
+ debug_prompt(state);
+ }
+ } else if (c == FIQ_DEBUGGER_BREAK) {
+ state->console_enable = false;
+ debug_puts(state, "fiq debugger mode\n");
+ state->debug_count = 0;
+ debug_prompt(state);
+#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
+ } else if (state->console_enable && state->tty_rbuf) {
+ fiq_debugger_ringbuf_push(state->tty_rbuf, c);
+ signal_helper = true;
+#endif
+ } else if ((c >= ' ') && (c < 127)) {
+ if (state->debug_count < (DEBUG_MAX - 1)) {
+ state->debug_buf[state->debug_count++] = c;
+ state->pdata->uart_putc(state->pdev, c);
+ }
+ } else if ((c == 8) || (c == 127)) {
+ if (state->debug_count > 0) {
+ state->debug_count--;
+ state->pdata->uart_putc(state->pdev, 8);
+ state->pdata->uart_putc(state->pdev, ' ');
+ state->pdata->uart_putc(state->pdev, 8);
+ }
+ } else if ((c == 13) || (c == 10)) {
+ if (c == '\r' || (c == '\n' && last_c != '\r')) {
+ state->pdata->uart_putc(state->pdev, '\r');
+ state->pdata->uart_putc(state->pdev, '\n');
+ }
+ if (state->debug_count) {
+ state->debug_buf[state->debug_count] = 0;
+ state->debug_count = 0;
+ signal_helper |=
+ debug_fiq_exec(state, state->debug_buf,
+ regs, svc_sp);
+ } else {
+ debug_prompt(state);
+ }
+ }
+ last_c = c;
+ }
+ debug_uart_flush(state);
+ if (state->pdata->fiq_ack)
+ state->pdata->fiq_ack(state->pdev, state->fiq);
+
+ /* poke sleep timer if necessary */
+ if (state->debug_enable && !state->no_sleep)
+ signal_helper = true;
+
+ atomic_set(&state->unhandled_fiq_count, 0);
+ state->in_fiq = false;
+
+ return signal_helper;
+}
+
+static void debug_fiq(struct fiq_glue_handler *h, void *regs, void *svc_sp)
+{
+ struct fiq_debugger_state *state =
+ container_of(h, struct fiq_debugger_state, handler);
+ unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu;
+ bool need_irq;
+
+ need_irq = debug_handle_uart_interrupt(state, this_cpu, regs, svc_sp);
+ if (need_irq)
+ debug_force_irq(state);
+}
+
+/*
+ * When not using FIQs, we only use this single interrupt as an entry point.
+ * This just effectively takes over the UART interrupt and does all the work
+ * in this context.
+ */
+static irqreturn_t debug_uart_irq(int irq, void *dev)
+{
+ struct fiq_debugger_state *state = dev;
+ bool not_done;
+
+ handle_wakeup(state);
+
+ /* handle the debugger irq in regular context */
+ not_done = debug_handle_uart_interrupt(state, smp_processor_id(),
+ get_irq_regs(),
+ current_thread_info());
+ if (not_done)
+ debug_handle_irq_context(state);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * If FIQs are used, not everything can happen in fiq context.
+ * FIQ handler does what it can and then signals this interrupt to finish the
+ * job in irq context.
+ */
+static irqreturn_t debug_signal_irq(int irq, void *dev)
+{
+ struct fiq_debugger_state *state = dev;
+
+ if (state->pdata->force_irq_ack)
+ state->pdata->force_irq_ack(state->pdev, state->signal_irq);
+
+ debug_handle_irq_context(state);
+
+ return IRQ_HANDLED;
+}
+
+static void debug_resume(struct fiq_glue_handler *h)
+{
+ struct fiq_debugger_state *state =
+ container_of(h, struct fiq_debugger_state, handler);
+ if (state->pdata->uart_resume)
+ state->pdata->uart_resume(state->pdev);
+}
+
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+struct tty_driver *debug_console_device(struct console *co, int *index)
+{
+ struct fiq_debugger_state *state;
+ state = container_of(co, struct fiq_debugger_state, console);
+ *index = 0;
+ return state->tty_driver;
+}
+
+static void debug_console_write(struct console *co,
+ const char *s, unsigned int count)
+{
+ struct fiq_debugger_state *state;
+
+ state = container_of(co, struct fiq_debugger_state, console);
+
+ if (!state->console_enable && !state->syslog_dumping)
+ return;
+
+ debug_uart_enable(state);
+ while (count--) {
+ if (*s == '\n')
+ state->pdata->uart_putc(state->pdev, '\r');
+ state->pdata->uart_putc(state->pdev, *s++);
+ }
+ debug_uart_flush(state);
+ debug_uart_disable(state);
+}
+
+static struct console fiq_debugger_console = {
+ .name = "ttyFIQ",
+ .device = debug_console_device,
+ .write = debug_console_write,
+ .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_ENABLED,
+};
+
+int fiq_tty_open(struct tty_struct *tty, struct file *filp)
+{
+ struct fiq_debugger_state *state = tty->driver->driver_state;
+ if (state->tty_open_count++)
+ return 0;
+
+ tty->driver_data = state;
+ state->tty = tty;
+ return 0;
+}
+
+void fiq_tty_close(struct tty_struct *tty, struct file *filp)
+{
+ struct fiq_debugger_state *state = tty->driver_data;
+ if (--state->tty_open_count)
+ return;
+ state->tty = NULL;
+}
+
+int fiq_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+ int i;
+ struct fiq_debugger_state *state = tty->driver_data;
+
+ if (!state->console_enable)
+ return count;
+
+ debug_uart_enable(state);
+ for (i = 0; i < count; i++)
+ state->pdata->uart_putc(state->pdev, *buf++);
+ debug_uart_disable(state);
+
+ return count;
+}
+
+int fiq_tty_write_room(struct tty_struct *tty)
+{
+ return 1024;
+}
+
+static const struct tty_operations fiq_tty_driver_ops = {
+ .write = fiq_tty_write,
+ .write_room = fiq_tty_write_room,
+ .open = fiq_tty_open,
+ .close = fiq_tty_close,
+};
+
+static int fiq_debugger_tty_init(struct fiq_debugger_state *state)
+{
+ int ret = -EINVAL;
+
+ state->tty_driver = alloc_tty_driver(1);
+ if (!state->tty_driver) {
+ pr_err("Failed to allocate fiq debugger tty\n");
+ return -ENOMEM;
+ }
+
+ state->tty_driver->owner = THIS_MODULE;
+ state->tty_driver->driver_name = "fiq-debugger";
+ state->tty_driver->name = "ttyFIQ";
+ state->tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ state->tty_driver->subtype = SERIAL_TYPE_NORMAL;
+ state->tty_driver->init_termios = tty_std_termios;
+ state->tty_driver->init_termios.c_cflag =
+ B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+ state->tty_driver->init_termios.c_ispeed =
+ state->tty_driver->init_termios.c_ospeed = 115200;
+ state->tty_driver->flags = TTY_DRIVER_REAL_RAW;
+ tty_set_operations(state->tty_driver, &fiq_tty_driver_ops);
+ state->tty_driver->driver_state = state;
+
+ ret = tty_register_driver(state->tty_driver);
+ if (ret) {
+ pr_err("Failed to register fiq tty: %d\n", ret);
+ goto err;
+ }
+
+ state->tty_rbuf = fiq_debugger_ringbuf_alloc(1024);
+ if (!state->tty_rbuf) {
+ pr_err("Failed to allocate fiq debugger ringbuf\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ pr_info("Registered FIQ tty driver %p\n", state->tty_driver);
+ return 0;
+
+err:
+ fiq_debugger_ringbuf_free(state->tty_rbuf);
+ state->tty_rbuf = NULL;
+ put_tty_driver(state->tty_driver);
+ return ret;
+}
+#endif
+
+static int fiq_debugger_dev_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fiq_debugger_state *state = platform_get_drvdata(pdev);
+
+ if (state->pdata->uart_dev_suspend)
+ return state->pdata->uart_dev_suspend(pdev);
+ return 0;
+}
+
+static int fiq_debugger_dev_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fiq_debugger_state *state = platform_get_drvdata(pdev);
+
+ if (state->pdata->uart_dev_resume)
+ return state->pdata->uart_dev_resume(pdev);
+ return 0;
+}
+
+static int fiq_debugger_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct fiq_debugger_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct fiq_debugger_state *state;
+ int fiq;
+ int uart_irq;
+
+ if (!pdata->uart_getc || !pdata->uart_putc)
+ return -EINVAL;
+ if ((pdata->uart_enable && !pdata->uart_disable) ||
+ (!pdata->uart_enable && pdata->uart_disable))
+ return -EINVAL;
+
+ fiq = platform_get_irq_byname(pdev, "fiq");
+ uart_irq = platform_get_irq_byname(pdev, "uart_irq");
+
+ /* uart_irq mode and fiq mode are mutually exclusive, but one of them
+ * is required */
+ if ((uart_irq < 0 && fiq < 0) || (uart_irq >= 0 && fiq >= 0))
+ return -EINVAL;
+ if (fiq >= 0 && !pdata->fiq_enable)
+ return -EINVAL;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ setup_timer(&state->sleep_timer, sleep_timer_expired,
+ (unsigned long)state);
+ state->pdata = pdata;
+ state->pdev = pdev;
+ state->no_sleep = initial_no_sleep;
+ state->debug_enable = initial_debug_enable;
+ state->console_enable = initial_console_enable;
+
+ state->fiq = fiq;
+ state->uart_irq = uart_irq;
+ state->signal_irq = platform_get_irq_byname(pdev, "signal");
+ state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup");
+
+ platform_set_drvdata(pdev, state);
+
+ spin_lock_init(&state->sleep_timer_lock);
+
+ if (state->wakeup_irq < 0 && debug_have_fiq(state))
+ state->no_sleep = true;
+ state->ignore_next_wakeup_irq = !state->no_sleep;
+
+ wake_lock_init(&state->debugger_wake_lock,
+ WAKE_LOCK_SUSPEND, "serial-debug");
+
+ state->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(state->clk))
+ state->clk = NULL;
+
+ /* do not call pdata->uart_enable here since uart_init may still
+ * need to do some initialization before uart_enable can work.
+ * So, only try to manage the clock during init.
+ */
+ if (state->clk)
+ clk_enable(state->clk);
+
+ if (pdata->uart_init) {
+ ret = pdata->uart_init(pdev);
+ if (ret)
+ goto err_uart_init;
+ }
+
+ debug_printf_nfiq(state, "<hit enter %sto activate fiq debugger>\n",
+ state->no_sleep ? "" : "twice ");
+
+ if (debug_have_fiq(state)) {
+ state->handler.fiq = debug_fiq;
+ state->handler.resume = debug_resume;
+ ret = fiq_glue_register_handler(&state->handler);
+ if (ret) {
+ pr_err("%s: could not install fiq handler\n", __func__);
+ goto err_register_fiq;
+ }
+
+ pdata->fiq_enable(pdev, state->fiq, 1);
+ } else {
+ ret = request_irq(state->uart_irq, debug_uart_irq,
+ IRQF_NO_SUSPEND, "debug", state);
+ if (ret) {
+ pr_err("%s: could not install irq handler\n", __func__);
+ goto err_register_irq;
+ }
+
+ /* for irq-only mode, we want this irq to wake us up, if it
+ * can.
+ */
+ enable_irq_wake(state->uart_irq);
+ }
+
+ if (state->clk)
+ clk_disable(state->clk);
+
+ if (state->signal_irq >= 0) {
+ ret = request_irq(state->signal_irq, debug_signal_irq,
+ IRQF_TRIGGER_RISING, "debug-signal", state);
+ if (ret)
+ pr_err("serial_debugger: could not install signal_irq");
+ }
+
+ if (state->wakeup_irq >= 0) {
+ ret = request_irq(state->wakeup_irq, wakeup_irq_handler,
+ IRQF_TRIGGER_FALLING | IRQF_DISABLED,
+ "debug-wakeup", state);
+ if (ret) {
+ pr_err("serial_debugger: "
+ "could not install wakeup irq\n");
+ state->wakeup_irq = -1;
+ } else {
+ ret = enable_irq_wake(state->wakeup_irq);
+ if (ret) {
+ pr_err("serial_debugger: "
+ "could not enable wakeup\n");
+ state->wakeup_irq_no_set_wake = true;
+ }
+ }
+ }
+ if (state->no_sleep)
+ handle_wakeup(state);
+
+#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
+ state->console = fiq_debugger_console;
+ register_console(&state->console);
+ fiq_debugger_tty_init(state);
+#endif
+ return 0;
+
+err_register_irq:
+err_register_fiq:
+ if (pdata->uart_free)
+ pdata->uart_free(pdev);
+err_uart_init:
+ if (state->clk)
+ clk_disable(state->clk);
+ if (state->clk)
+ clk_put(state->clk);
+ wake_lock_destroy(&state->debugger_wake_lock);
+ platform_set_drvdata(pdev, NULL);
+ kfree(state);
+ return ret;
+}
+
+static const struct dev_pm_ops fiq_debugger_dev_pm_ops = {
+ .suspend = fiq_debugger_dev_suspend,
+ .resume = fiq_debugger_dev_resume,
+};
+
+static struct platform_driver fiq_debugger_driver = {
+ .probe = fiq_debugger_probe,
+ .driver = {
+ .name = "fiq_debugger",
+ .pm = &fiq_debugger_dev_pm_ops,
+ },
+};
+
+static int __init fiq_debugger_init(void)
+{
+ return platform_driver_register(&fiq_debugger_driver);
+}
+
+postcore_initcall(fiq_debugger_init);
diff --git a/arch/arm/common/fiq_debugger_ringbuf.h b/arch/arm/common/fiq_debugger_ringbuf.h
new file mode 100644
index 0000000..2649b55
--- /dev/null
+++ b/arch/arm/common/fiq_debugger_ringbuf.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/common/fiq_debugger_ringbuf.c
+ *
+ * simple lockless ringbuffer
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+struct fiq_debugger_ringbuf {
+ int len;
+ int head;
+ int tail;
+ u8 buf[];
+};
+
+
+static inline struct fiq_debugger_ringbuf *fiq_debugger_ringbuf_alloc(int len)
+{
+ struct fiq_debugger_ringbuf *rbuf;
+
+ rbuf = kzalloc(sizeof(*rbuf) + len, GFP_KERNEL);
+ if (rbuf == NULL)
+ return NULL;
+
+ rbuf->len = len;
+ rbuf->head = 0;
+ rbuf->tail = 0;
+ smp_mb();
+
+ return rbuf;
+}
+
+static inline void fiq_debugger_ringbuf_free(struct fiq_debugger_ringbuf *rbuf)
+{
+ kfree(rbuf);
+}
+
+static inline int fiq_debugger_ringbuf_level(struct fiq_debugger_ringbuf *rbuf)
+{
+ int level = rbuf->head - rbuf->tail;
+
+ if (level < 0)
+ level = rbuf->len + level;
+
+ return level;
+}
+
+static inline int fiq_debugger_ringbuf_room(struct fiq_debugger_ringbuf *rbuf)
+{
+ return rbuf->len - fiq_debugger_ringbuf_level(rbuf) - 1;
+}
+
+static inline u8
+fiq_debugger_ringbuf_peek(struct fiq_debugger_ringbuf *rbuf, int i)
+{
+ return rbuf->buf[(rbuf->tail + i) % rbuf->len];
+}
+
+static inline int
+fiq_debugger_ringbuf_consume(struct fiq_debugger_ringbuf *rbuf, int count)
+{
+ count = min(count, fiq_debugger_ringbuf_level(rbuf));
+
+ rbuf->tail = (rbuf->tail + count) % rbuf->len;
+ smp_mb();
+
+ return count;
+}
+
+static inline int
+fiq_debugger_ringbuf_push(struct fiq_debugger_ringbuf *rbuf, u8 datum)
+{
+ if (fiq_debugger_ringbuf_room(rbuf) == 0)
+ return 0;
+
+ rbuf->buf[rbuf->head] = datum;
+ smp_mb();
+ rbuf->head = (rbuf->head + 1) % rbuf->len;
+ smp_mb();
+
+ return 1;
+}
diff --git a/arch/arm/common/fiq_glue.S b/arch/arm/common/fiq_glue.S
new file mode 100644
index 0000000..9e3455a
--- /dev/null
+++ b/arch/arm/common/fiq_glue.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+ .global fiq_glue_end
+
+ /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */
+
+ENTRY(fiq_glue)
+ /* store pc, cpsr from previous mode */
+ mrs r12, spsr
+ sub r11, lr, #4
+ subs r10, #1
+ bne nested_fiq
+
+ stmfd sp!, {r11-r12, lr}
+
+ /* store r8-r14 from previous mode */
+ sub sp, sp, #(7 * 4)
+ stmia sp, {r8-r14}^
+ nop
+
+ /* store r0-r7 from previous mode */
+ stmfd sp!, {r0-r7}
+
+ /* setup func(data,regs) arguments */
+ mov r0, r9
+ mov r1, sp
+ mov r3, r8
+
+ mov r7, sp
+
+ /* Get sp and lr from non-user modes */
+ and r4, r12, #MODE_MASK
+ cmp r4, #USR_MODE
+ beq fiq_from_usr_mode
+
+ mov r7, sp
+ orr r4, r4, #(PSR_I_BIT | PSR_F_BIT)
+ msr cpsr_c, r4
+ str sp, [r7, #(4 * 13)]
+ str lr, [r7, #(4 * 14)]
+ mrs r5, spsr
+ str r5, [r7, #(4 * 17)]
+
+ cmp r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
+ /* use fiq stack if we reenter this mode */
+ subne sp, r7, #(4 * 3)
+
+fiq_from_usr_mode:
+ msr cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
+ mov r2, sp
+ sub sp, r7, #12
+ stmfd sp!, {r2, ip, lr}
+ /* call func(data,regs) */
+ blx r3
+ ldmfd sp, {r2, ip, lr}
+ mov sp, r2
+
+ /* restore/discard saved state */
+ cmp r4, #USR_MODE
+ beq fiq_from_usr_mode_exit
+
+ msr cpsr_c, r4
+ ldr sp, [r7, #(4 * 13)]
+ ldr lr, [r7, #(4 * 14)]
+ msr spsr_cxsf, r5
+
+fiq_from_usr_mode_exit:
+ msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
+
+ ldmfd sp!, {r0-r7}
+ add sp, sp, #(7 * 4)
+ ldmfd sp!, {r11-r12, lr}
+exit_fiq:
+ msr spsr_cxsf, r12
+ add r10, #1
+ movs pc, r11
+
+nested_fiq:
+ orr r12, r12, #(PSR_F_BIT)
+ b exit_fiq
+
+fiq_glue_end:
+
+ENTRY(fiq_glue_setup) /* func, data, sp */
+ mrs r3, cpsr
+ msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
+ movs r8, r0
+ mov r9, r1
+ mov sp, r2
+ moveq r10, #0
+ movne r10, #1
+ msr cpsr_c, r3
+ bx lr
+
diff --git a/arch/arm/common/fiq_glue_setup.c b/arch/arm/common/fiq_glue_setup.c
new file mode 100644
index 0000000..4044c7d
--- /dev/null
+++ b/arch/arm/common/fiq_glue_setup.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+#include <asm/fiq.h>
+#include <asm/fiq_glue.h>
+
+extern unsigned char fiq_glue, fiq_glue_end;
+extern void fiq_glue_setup(void *func, void *data, void *sp);
+
+static struct fiq_handler fiq_debbuger_fiq_handler = {
+ .name = "fiq_glue",
+};
+DEFINE_PER_CPU(void *, fiq_stack);
+static struct fiq_glue_handler *current_handler;
+static DEFINE_MUTEX(fiq_glue_lock);
+
+static void fiq_glue_setup_helper(void *info)
+{
+ struct fiq_glue_handler *handler = info;
+ fiq_glue_setup(handler->fiq, handler,
+ __get_cpu_var(fiq_stack) + THREAD_START_SP);
+}
+
+int fiq_glue_register_handler(struct fiq_glue_handler *handler)
+{
+ int ret;
+ int cpu;
+
+ if (!handler || !handler->fiq)
+ return -EINVAL;
+
+ mutex_lock(&fiq_glue_lock);
+ if (fiq_stack) {
+ ret = -EBUSY;
+ goto err_busy;
+ }
+
+ for_each_possible_cpu(cpu) {
+ void *stack;
+ stack = (void *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
+ if (WARN_ON(!stack)) {
+ ret = -ENOMEM;
+ goto err_alloc_fiq_stack;
+ }
+ per_cpu(fiq_stack, cpu) = stack;
+ }
+
+ ret = claim_fiq(&fiq_debbuger_fiq_handler);
+ if (WARN_ON(ret))
+ goto err_claim_fiq;
+
+ current_handler = handler;
+ on_each_cpu(fiq_glue_setup_helper, handler, true);
+ set_fiq_handler(&fiq_glue, &fiq_glue_end - &fiq_glue);
+
+ mutex_unlock(&fiq_glue_lock);
+ return 0;
+
+err_claim_fiq:
+err_alloc_fiq_stack:
+ for_each_possible_cpu(cpu) {
+ __free_pages(per_cpu(fiq_stack, cpu), THREAD_SIZE_ORDER);
+ per_cpu(fiq_stack, cpu) = NULL;
+ }
+err_busy:
+ mutex_unlock(&fiq_glue_lock);
+ return ret;
+}
+
+/**
+ * fiq_glue_resume - Restore fiqs after suspend or low power idle states
+ *
+ * This must be called before calling local_fiq_enable after returning from a
+ * power state where the fiq mode registers were lost. If a driver provided
+ * a resume hook when it registered the handler it will be called.
+ */
+
+void fiq_glue_resume(void)
+{
+ if (!current_handler)
+ return;
+ fiq_glue_setup(current_handler->fiq, current_handler,
+ __get_cpu_var(fiq_stack) + THREAD_START_SP);
+ if (current_handler->resume)
+ current_handler->resume(current_handler);
+}
+
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 4ddd0a6..7d3e611 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -33,17 +33,25 @@
#include <asm/mach/irq.h>
#include <asm/hardware/gic.h>
+struct gic_chip_data {
+ unsigned int irq_offset;
+ void __percpu __iomem **dist_base;
+ void __percpu __iomem **cpu_base;
+#ifdef CONFIG_CPU_PM
+ u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+ u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+ u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+ u32 __percpu *saved_ppi_enable;
+ u32 __percpu *saved_ppi_conf;
+#endif
+ unsigned int gic_irqs;
+};
+
static DEFINE_SPINLOCK(irq_controller_lock);
/* Address of GIC 0 CPU interface */
void __iomem *gic_cpu_base_addr __read_mostly;
-struct gic_chip_data {
- unsigned int irq_offset;
- void __iomem *dist_base;
- void __iomem *cpu_base;
-};
-
/*
* Supported arch specific GIC irq extension.
* Default make them NULL.
@@ -63,16 +71,26 @@ struct irq_chip gic_arch_extn = {
static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
+static inline void __iomem *gic_data_dist_base(struct gic_chip_data *data)
+{
+ return *__this_cpu_ptr(data->dist_base);
+}
+
static inline void __iomem *gic_dist_base(struct irq_data *d)
{
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
- return gic_data->dist_base;
+ return gic_data_dist_base(gic_data);
+}
+
+static inline void __iomem *gic_data_cpu_base(struct gic_chip_data *data)
+{
+ return *__this_cpu_ptr(data->cpu_base);
}
static inline void __iomem *gic_cpu_base(struct irq_data *d)
{
struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
- return gic_data->cpu_base;
+ return gic_data_cpu_base(gic_data);
}
static inline unsigned int gic_irq(struct irq_data *d)
@@ -223,7 +241,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
chained_irq_enter(chip, desc);
spin_lock(&irq_controller_lock);
- status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
+ status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK);
spin_unlock(&irq_controller_lock);
gic_irq = (status & 0x3ff);
@@ -266,7 +284,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
unsigned int irq_start)
{
unsigned int gic_irqs, irq_limit, i;
- void __iomem *base = gic->dist_base;
+ void __iomem *base = gic_data_dist_base(gic);
u32 cpumask = 1 << smp_processor_id();
cpumask |= cpumask << 8;
@@ -329,8 +347,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
{
- void __iomem *dist_base = gic->dist_base;
- void __iomem *base = gic->cpu_base;
+ void __iomem *dist_base = gic_data_dist_base(gic);
+ void __iomem *base = gic_data_cpu_base(gic);
int i;
/*
@@ -354,12 +372,24 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __iomem *dist_base, void __iomem *cpu_base)
{
struct gic_chip_data *gic;
+ int cpu;
BUG_ON(gic_nr >= MAX_GIC_NR);
gic = &gic_data[gic_nr];
- gic->dist_base = dist_base;
- gic->cpu_base = cpu_base;
+ gic->dist_base = alloc_percpu(void __iomem *);
+ gic->cpu_base = alloc_percpu(void __iomem *);
+ if (WARN_ON(!gic->dist_base || !gic->cpu_base)) {
+ free_percpu(gic->dist_base);
+ free_percpu(gic->cpu_base);
+ return;
+ }
+
+ for_each_possible_cpu(cpu) {
+ *per_cpu_ptr(gic->dist_base, cpu) = dist_base;
+ *per_cpu_ptr(gic->cpu_base, cpu) = cpu_base;
+ }
+
gic->irq_offset = (irq_start - 1) & ~31;
if (gic_nr == 0)
@@ -369,10 +399,16 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
gic_cpu_init(gic);
}
-void __cpuinit gic_secondary_init(unsigned int gic_nr)
+void __cpuinit gic_secondary_init_base(unsigned int gic_nr,
+ void __iomem *dist_base,
+ void __iomem *cpu_base)
{
BUG_ON(gic_nr >= MAX_GIC_NR);
+ if (dist_base)
+ *__this_cpu_ptr(gic_data[gic_nr].dist_base) = dist_base;
+ if (cpu_base)
+ *__this_cpu_ptr(gic_data[gic_nr].cpu_base) = cpu_base;
gic_cpu_init(&gic_data[gic_nr]);
}
@@ -398,6 +434,6 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
dsb();
/* this always happens on GIC0 */
- writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
+ writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
}
#endif
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index 97912fa..6ff29e5 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -1116,6 +1116,54 @@ static inline int _loop(unsigned dry_run, u8 buf[],
return off;
}
+/* Returns bytes consumed and updates bursts */
+static inline int _loop_infiniteloop(unsigned dry_run, u8 buf[],
+ unsigned long bursts, const struct _xfer_spec *pxs, int ev)
+{
+ int cyc, off;
+ unsigned lcnt0, lcnt1, ljmp0, ljmp1, ljmpfe;
+ struct _arg_LPEND lpend;
+
+ off = 0;
+ ljmpfe = off;
+ lcnt0 = pxs->r->infiniteloop;
+ lcnt1 = 256;
+ cyc = bursts/256;
+
+ /* forever loop */
+ off += _emit_MOV(dry_run, &buf[off], SAR, pxs->x->src_addr);
+ off += _emit_MOV(dry_run, &buf[off], DAR, pxs->x->dst_addr);
+
+ /* loop0 */
+ off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
+ ljmp0 = off;
+
+ /* loop1 */
+ off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
+ ljmp1 = off;
+ off += _bursts(dry_run, &buf[off], pxs, cyc);
+ lpend.cond = ALWAYS;
+ lpend.forever = false;
+ lpend.loop = 1;
+ lpend.bjump = off - ljmp1;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+ off += _emit_SEV(dry_run, &buf[off], ev);
+
+ lpend.cond = ALWAYS;
+ lpend.forever = false;
+ lpend.loop = 0;
+ lpend.bjump = off - ljmp0;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+
+ lpend.cond = ALWAYS;
+ lpend.forever = true;
+ lpend.loop = 1;
+ lpend.bjump = off - ljmpfe;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+
+ return off;
+}
+
static inline int _setup_loops(unsigned dry_run, u8 buf[],
const struct _xfer_spec *pxs)
{
@@ -1150,6 +1198,20 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
return off;
}
+static inline int _setup_xfer_infiniteloop(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int ev)
+{
+ struct pl330_xfer *x = pxs->x;
+ u32 ccr = pxs->ccr;
+ unsigned long bursts = BYTE_TO_BURST(x->bytes, ccr);
+ int off = 0;
+
+ /* Setup Loop(s) */
+ off += _loop_infiniteloop(dry_run, &buf[off], bursts, pxs, ev);
+
+ return off;
+}
+
/*
* A req is a sequence of one or more xfer units.
* Returns the number of bytes taken to setup the MC for the req.
@@ -1168,22 +1230,33 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
x = pxs->r->x;
- do {
+
+ if (!pxs->r->infiniteloop) {
+ do {
+ /* Error if xfer length is not aligned at burst size */
+ if (x->bytes % (BRST_SIZE(pxs->ccr)
+ * BRST_LEN(pxs->ccr)))
+ return -EINVAL;
+
+ pxs->x = x;
+ off += _setup_xfer(dry_run, &buf[off], pxs);
+
+ x = x->next;
+ } while (x);
+
+ /* DMASEV peripheral/event */
+ off += _emit_SEV(dry_run, &buf[off], thrd->ev);
+ /* DMAEND */
+ off += _emit_END(dry_run, &buf[off]);
+ } else {
/* Error if xfer length is not aligned at burst size */
if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
return -EINVAL;
pxs->x = x;
- off += _setup_xfer(dry_run, &buf[off], pxs);
-
- x = x->next;
- } while (x);
-
- /* DMASEV peripheral/event */
- off += _emit_SEV(dry_run, &buf[off], thrd->ev);
- /* DMAEND */
- off += _emit_END(dry_run, &buf[off]);
-
+ off += _setup_xfer_infiniteloop
+ (dry_run, &buf[off], pxs, thrd->ev);
+ }
return off;
}
@@ -1281,17 +1354,17 @@ int pl330_submit_req(void *ch_id, struct pl330_req *r)
goto xfer_exit;
}
- /* Prefer Secure Channel */
- if (!_manager_ns(thrd))
- r->cfg->nonsecure = 0;
- else
- r->cfg->nonsecure = 1;
-
/* Use last settings, if not provided */
- if (r->cfg)
+ if (r->cfg) {
+ /* Prefer Secure Channel */
+ if (!_manager_ns(thrd))
+ r->cfg->nonsecure = 0;
+ else
+ r->cfg->nonsecure = 1;
ccr = _prepare_ccr(r->cfg);
- else
+ } else {
ccr = readl(regs + CC(thrd->id));
+ }
/* If this req doesn't have valid xfer settings */
if (!_is_valid(ccr)) {
@@ -1468,10 +1541,13 @@ int pl330_update(const struct pl330_info *pi)
active -= 1;
rqdone = &thrd->req[active];
- MARK_FREE(rqdone);
- /* Get going again ASAP */
- _start(thrd);
+ if (!rqdone->r->infiniteloop) {
+ MARK_FREE(rqdone);
+
+ /* Get going again ASAP */
+ _start(thrd);
+ }
/* For now, just make a list of callbacks to be done */
list_add_tail(&rqdone->rqd, &pl330->req_done);
diff --git a/arch/arm/configs/exynos4_defconfig b/arch/arm/configs/exynos4_defconfig
deleted file mode 100644
index da53ff3..0000000
--- a/arch/arm/configs/exynos4_defconfig
+++ /dev/null
@@ -1,72 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_EXYNOS4=y
-CONFIG_S3C_LOWLEVEL_UART_PORT=1
-CONFIG_MACH_SMDKC210=y
-CONFIG_MACH_SMDKV310=y
-CONFIG_MACH_ARMLEX4210=y
-CONFIG_MACH_UNIVERSAL_C210=y
-CONFIG_MACH_NURI=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_HOTPLUG_CPU=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
-CONFIG_VFP=y
-CONFIG_NEON=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_SAMSUNG=y
-CONFIG_SERIAL_SAMSUNG_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-# CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_S3C_UART=1
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/m0_00_defconfig b/arch/arm/configs/m0_00_defconfig
new file mode 100644
index 0000000..f8eaf59
--- /dev/null
+++ b/arch/arm/configs/m0_00_defconfig
@@ -0,0 +1,3206 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.15 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE="/usr/local/arm/arm-eabi-4.4.3/bin/arm-eabi-"
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HAVE_SPARSE_IRQ=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_CHIP=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+# CONFIG_CGROUP_MEM_RES_CTLR is not set
+# CONFIG_CGROUP_PERF is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+# CONFIG_BLK_CGROUP is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_CHECK_WARNING_STRICTLY=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=1
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_ASHMEM=y
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+CONFIG_ARCH_EXYNOS=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_TCC_926 is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_PLAT_SAMSUNG=y
+
+#
+# Base Address for SFR mapping
+#
+CONFIG_S3C_ADDR_BASE=0xFC000000
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_WATCHDOG is not set
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=2
+CONFIG_SAMSUNG_CLKSRC=y
+CONFIG_SAMSUNG_IRQ_VIC_TIMER=y
+CONFIG_SAMSUNG_IRQ_UART=y
+CONFIG_SAMSUNG_GPIOLIB_4BIT=y
+CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_CFG_S3C64XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_S5P_GPIO_DRVSTR=y
+CONFIG_SAMSUNG_GPIO_EXTRA=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+CONFIG_S3C_ADC=y
+CONFIG_S3C_DEV_ADC=y
+# CONFIG_S3C_DEV_ADC1 is not set
+CONFIG_S3C_DEV_HSMMC2=y
+CONFIG_S3C_DEV_HSMMC3=y
+CONFIG_EXYNOS4_DEV_MSHC=y
+CONFIG_S3C_DEV_I2C1=y
+CONFIG_S3C_DEV_I2C3=y
+CONFIG_S3C_DEV_I2C4=y
+CONFIG_S3C_DEV_I2C5=y
+CONFIG_S3C_DEV_I2C6=y
+CONFIG_S3C_DEV_I2C7=y
+CONFIG_S3C_DEV_WDT=y
+CONFIG_S3C_DEV_RTC=y
+CONFIG_SAMSUNG_DEV_ADC=y
+CONFIG_S3C64XX_DEV_SPI=y
+CONFIG_SAMSUNG_DEV_PWM=y
+CONFIG_SAMSUNG_DEV_BACKLIGHT=y
+CONFIG_S3C24XX_PWM=y
+CONFIG_S3C_PL330_DMA=y
+# CONFIG_DMA_M2M_TEST is not set
+
+#
+# Power management
+#
+# CONFIG_SAMSUNG_PM_DEBUG is not set
+# CONFIG_SAMSUNG_PM_CHECK is not set
+
+#
+# Power Domain
+#
+CONFIG_SAMSUNG_PD=y
+CONFIG_PLAT_S5P=y
+CONFIG_S5P_GPIO_INT=y
+CONFIG_S5P_SYSTEM_MMU=y
+CONFIG_S5P_SYSTEM_MMU_REFCOUNT=y
+# CONFIG_S5P_SYSTEM_MMU_DEBUG is not set
+CONFIG_IOVMM=y
+CONFIG_IOMMU_EXYNOS4_API=y
+CONFIG_S3C_DEV_FIMC=y
+CONFIG_S5P_DEV_MFC=y
+CONFIG_S5P_DEV_TVOUT=y
+CONFIG_S5P_DEV_FIMG2D=y
+CONFIG_S5P_DEV_CSIS=y
+CONFIG_S5P_DEV_JPEG=y
+CONFIG_S5P_DEV_USB_EHCI=y
+CONFIG_S5P_DEV_FIMD_S5P=y
+CONFIG_S5P_DEV_USBGADGET=y
+CONFIG_S5P_MEM_CMA=y
+CONFIG_S5P_DEV_MIPI_DSI=y
+# CONFIG_S5P_BTS is not set
+# CONFIG_S3C_DEV_TSI is not set
+CONFIG_ARCH_EXYNOS4=y
+# CONFIG_ARCH_EXYNOS5 is not set
+CONFIG_CPU_EXYNOS4212=y
+CONFIG_CPU_EXYNOS4412=y
+# CONFIG_S5PV310_HI_ARMCLK_THAN_1_2GHZ is not set
+CONFIG_EXYNOS_CONTENT_PATH_PROTECTION=y
+CONFIG_EXYNOS4_PM=y
+CONFIG_EXYNOS4_CPUIDLE=y
+CONFIG_EXYNOS4_LOWPWR_IDLE=y
+CONFIG_EXYNOS_MCT=y
+CONFIG_EXYNOS_DEV_PD=y
+CONFIG_EXYNOS4_DEV_FIMC_LITE=y
+CONFIG_EXYNOS4_DEV_FIMC_IS=y
+CONFIG_EXYNOS4_SETUP_I2C1=y
+CONFIG_EXYNOS4_SETUP_I2C3=y
+CONFIG_EXYNOS4_SETUP_I2C4=y
+CONFIG_EXYNOS4_SETUP_I2C5=y
+CONFIG_EXYNOS4_SETUP_I2C6=y
+CONFIG_EXYNOS4_SETUP_I2C7=y
+CONFIG_EXYNOS4_SETUP_MFC=y
+CONFIG_EXYNOS4_SETUP_SDHCI=y
+CONFIG_EXYNOS4_SETUP_SDHCI_GPIO=y
+CONFIG_EXYNOS4_SETUP_MSHCI=y
+CONFIG_EXYNOS4_SETUP_MSHCI_GPIO=y
+CONFIG_EXYNOS4_SETUP_FIMC0=y
+CONFIG_EXYNOS4_SETUP_FIMC1=y
+CONFIG_EXYNOS4_SETUP_FIMC2=y
+CONFIG_EXYNOS4_SETUP_FIMC3=y
+CONFIG_EXYNOS4_SETUP_FIMC_IS=y
+CONFIG_EXYNOS4_SETUP_USB_PHY=y
+CONFIG_EXYNOS4_SETUP_CSIS=y
+CONFIG_EXYNOS4_SETUP_FB_S5P=y
+CONFIG_EXYNOS4_SETUP_TVOUT=y
+CONFIG_EXYNOS4_SETUP_THERMAL=y
+# CONFIG_EXYNOS_SETUP_THERMAL is not set
+CONFIG_EXYNOS4_SETUP_MIPI_DSI=y
+CONFIG_EXYNOS4_SETUP_JPEG=y
+CONFIG_EXYNOS4_ENABLE_CLOCK_DOWN=y
+CONFIG_EXYNOS4_CPUFREQ=y
+# CONFIG_EXYNOS4X12_1500MHZ_SUPPORT is not set
+CONFIG_EXYNOS4X12_1400MHZ_SUPPORT=y
+# CONFIG_EXYNOS4X12_1200MHZ_SUPPORT is not set
+# CONFIG_EXYNOS4212_1000MHZ_SUPPORT is not set
+CONFIG_MIDAS_COMMON=y
+
+#
+# Support dynamic CPU Hotplug
+#
+# CONFIG_EXYNOS_PM_HOTPLUG is not set
+
+#
+# Busfreq Model
+#
+# CONFIG_BUSFREQ is not set
+CONFIG_BUSFREQ_OPP=y
+# CONFIG_DEVFREQ_BUS is not set
+CONFIG_BUSFREQ_QOS_NONE=y
+# CONFIG_BUSFREQ_QOS_1024X600 is not set
+# CONFIG_BUSFREQ_QOS_1280X720 is not set
+# CONFIG_BUSFREQ_QOS_1280X800 is not set
+# CONFIG_BUSFREQ_DEBUG is not set
+# CONFIG_BUSFREQ_L2_160M is not set
+CONFIG_SEC_THERMISTOR=y
+# CONFIG_EXYNOS_SYSREG_PM is not set
+CONFIG_ANDROID_WIP=y
+
+#
+# EXYNOS4 Machines
+#
+# CONFIG_MACH_SMDKC210 is not set
+# CONFIG_MACH_SMDKV310 is not set
+# CONFIG_MACH_ARMLEX4210 is not set
+# CONFIG_MACH_UNIVERSAL_C210 is not set
+# CONFIG_MACH_NURI is not set
+# CONFIG_MACH_U1 is not set
+# CONFIG_MACH_PX is not set
+# CONFIG_PANEL_S2PLUS is not set
+CONFIG_TARGET_LOCALE_EUR=y
+# CONFIG_TARGET_LOCALE_LTN is not set
+# CONFIG_TARGET_LOCALE_KOR is not set
+# CONFIG_TARGET_LOCALE_NAATT_TEMP is not set
+# CONFIG_TARGET_LOCALE_P2EUR_TEMP is not set
+# CONFIG_TARGET_LOCALE_P2TMO_TEMP is not set
+# CONFIG_TARGET_LOCALE_EUR_U1_NFC is not set
+# CONFIG_TARGET_LOCALE_NTT is not set
+# CONFIG_TARGET_LOCALE_CHN is not set
+# CONFIG_TARGET_LOCALE_USA is not set
+# CONFIG_MACH_SMDK4X12 is not set
+CONFIG_MACH_MIDAS=y
+# CONFIG_MACH_MIDAS_01_BD is not set
+# CONFIG_MACH_MIDAS_02_BD is not set
+CONFIG_MACH_M0=y
+# CONFIG_MACH_M3 is not set
+# CONFIG_MACH_C1 is not set
+# CONFIG_MACH_C1VZW is not set
+# CONFIG_MACH_C1CTC is not set
+# CONFIG_MACH_JENGA is not set
+# CONFIG_MACH_S2PLUS is not set
+# CONFIG_MACH_P4NOTE is not set
+# CONFIG_MACH_GC1 is not set
+CONFIG_MIDAS_COMMON_BD=y
+# CONFIG_P4NOTE_00_BD is not set
+# CONFIG_GC1_00_BD is not set
+# CONFIG_SLP is not set
+# CONFIG_GPS_BCM47511 is not set
+# CONFIG_GPIO_NAPLES_00_BD is not set
+# CONFIG_EXYNOS4_DEV_TMU is not set
+# CONFIG_WRITEBACK_ENABLED is not set
+# CONFIG_EXYNOS5_DEV_BTS is not set
+
+#
+# MMC/SD slot setup
+#
+
+#
+# SELECT SYNOPSYS CONTROLLER INTERFACE DRIVER
+#
+CONFIG_EXYNOS4_MSHC_MPLL_40MHZ=y
+# CONFIG_EXYNOS4_MSHC_VPLL_46MHZ is not set
+# CONFIG_EXYNOS4_MSHC_EPLL_45MHZ is not set
+
+#
+# Use 8-bit bus width
+#
+CONFIG_EXYNOS4_MSHC_8BIT=y
+# CONFIG_EXYNOS4_SDHCI_CH2_8BIT is not set
+
+#
+# Use DDR
+#
+CONFIG_EXYNOS4_MSHC_DDR=y
+
+#
+# Miscellaneous drivers
+#
+# CONFIG_WAKEUP_ASSIST is not set
+# CONFIG_S3C64XX_DEV_SPI0 is not set
+
+#
+# Debugging Feature
+#
+CONFIG_SEC_DEBUG=y
+CONFIG_SEC_DEBUG_SCHED_LOG=y
+CONFIG_SEC_DEBUG_SCHED_LOG_NONCACHED=y
+# CONFIG_SEC_DEBUG_SEMAPHORE_LOG is not set
+CONFIG_SEC_DEBUG_USER=y
+# CONFIG_SEC_DEBUG_PM_TEMP is not set
+# CONFIG_SEC_DEBUG_IRQ_EXIT_LOG is not set
+# CONFIG_SEC_DEBUG_AUXILIARY_LOG is not set
+# CONFIG_SEC_DEBUG_FUPLOAD_DUMP_MORE is not set
+# CONFIG_SEC_DEBUG_LIST_CORRUPTION is not set
+# CONFIG_SEC_DEBUG_SYSRQ_B is not set
+CONFIG_SEC_WATCHDOG_RESET=y
+CONFIG_SEC_WATCHDOG_PET_TIME=0
+CONFIG_SEC_LOG=y
+CONFIG_SEC_LOG_NONCACHED=y
+CONFIG_SEC_LOG_LAST_KMSG=y
+
+#
+# Samsung Modem Feature
+#
+# CONFIG_LTE_VIA_SWITCH is not set
+# CONFIG_SEC_MODEM_M0_C2C is not set
+CONFIG_SEC_MODEM_M0=y
+# CONFIG_SEC_MODEM_M0_CTC is not set
+# CONFIG_SEC_MODEM_M1 is not set
+# CONFIG_SEC_MODEM_C1 is not set
+# CONFIG_SEC_MODEM_C1_VZW is not set
+# CONFIG_SEC_MODEM_C1_LGT is not set
+# CONFIG_SEC_MODEM_C1_CTC is not set
+# CONFIG_SEC_MODEM_M2 is not set
+# CONFIG_SEC_MODEM_U1 is not set
+# CONFIG_SEC_MODEM_JENGA is not set
+# CONFIG_SEC_MODEM_S2PLUS is not set
+# CONFIG_SEC_MODEM_U1_LGT is not set
+# CONFIG_SEC_MODEM_GAIA is not set
+# CONFIG_BT_CSR8811 is not set
+# CONFIG_BT_BCM4330 is not set
+CONFIG_BT_BCM4334=y
+# CONFIG_BT_BCM43241 is not set
+CONFIG_BT_MGMT=y
+
+#
+# Qualcomm Modem Feature
+#
+# CONFIG_QC_MODEM is not set
+# CONFIG_MSM_SUBSYSTEM_RESTART is not set
+# CONFIG_QC_MODEM_MDM9X15 is not set
+# CONFIG_SAMSUNG_PRODUCT_SHIP is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_TRUSTZONE=y
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_CACHE_L2X0=y
+CONFIG_CACHE_PL310=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARM_PLD_SIZE=32
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_742230 is not set
+# CONFIG_ARM_ERRATA_742231 is not set
+# CONFIG_PL310_ERRATA_588369 is not set
+# CONFIG_ARM_ERRATA_720789 is not set
+# CONFIG_ARM_ERRATA_720791 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_751472=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+# CONFIG_ARM_ERRATA_754327 is not set
+CONFIG_ARM_ERRATA_761320=y
+# CONFIG_ARM_ERRATA_761171 is not set
+# CONFIG_ARM_ERRATA_762974 is not set
+# CONFIG_ARM_ERRATA_763722 is not set
+CONFIG_ARM_GIC=y
+CONFIG_PL330=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+CONFIG_ARM_ERRATA_764369=y
+# CONFIG_PL310_ERRATA_769419 is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_SMP_ON_UP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=200
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_ARCH_SKIP_SECONDARY_CALIBRATE=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CLEANCACHE is not set
+CONFIG_CMA=y
+# CONFIG_CMA_DEVELOPEMENT is not set
+CONFIG_CMA_BEST_FIT=y
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y
+CONFIG_VMWARE_MVP=y
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttySAC2,115200"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ADAPTIVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PEGASUSQ=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE is not set
+# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_FREQ_GOV_ADAPTIVE is not set
+CONFIG_CPU_FREQ_GOV_PEGASUSQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+CONFIG_WAKELOCK=y
+CONFIG_WAKELOCK_STAT=y
+CONFIG_USER_WAKELOCK=y
+CONFIG_EARLYSUSPEND=y
+# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set
+# CONFIG_CONSOLE_EARLYSUSPEND is not set
+CONFIG_FB_EARLYSUSPEND=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_HAS_OPP=y
+CONFIG_PM_OPP=y
+CONFIG_PM_RUNTIME_CLK=y
+# CONFIG_SUSPEND_TIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+CONFIG_INET_ESP=y
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+# CONFIG_IPV6_ROUTE_INFO is not set
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MROUTE is not set
+CONFIG_ANDROID_PARANOID_NETWORK=y
+CONFIG_NET_ACTIVITY_STATS=y
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=y
+CONFIG_NETFILTER_NETLINK_QUEUE=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_GRE=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_BROADCAST=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+# CONFIG_NF_CONNTRACK_SNMP is not set
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=y
+CONFIG_NETFILTER_XT_CONNMARK=y
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_HL=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+# CONFIG_IP_SET is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=y
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_NF_NAT_PROTO_DCCP=y
+CONFIG_NF_NAT_PROTO_GRE=y
+CONFIG_NF_NAT_PROTO_UDPLITE=y
+CONFIG_NF_NAT_PROTO_SCTP=y
+CONFIG_NF_NAT_FTP=y
+CONFIG_NF_NAT_IRC=y
+CONFIG_NF_NAT_TFTP=y
+CONFIG_NF_NAT_AMANDA=y
+CONFIG_NF_NAT_PPTP=y
+CONFIG_NF_NAT_H323=y
+CONFIG_NF_NAT_SIP=y
+CONFIG_IP_NF_MANGLE=y
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+# CONFIG_IP6_NF_QUEUE is not set
+CONFIG_IP6_NF_IPTABLES=y
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_EUI64 is not set
+# CONFIG_IP6_NF_MATCH_FRAG is not set
+# CONFIG_IP6_NF_MATCH_OPTS is not set
+# CONFIG_IP6_NF_MATCH_HL is not set
+# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
+# CONFIG_IP6_NF_MATCH_RT is not set
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_PHONET=y
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+CONFIG_NET_SCH_HTB=y
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFB is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_DRR is not set
+# CONFIG_NET_SCH_MQPRIO is not set
+# CONFIG_NET_SCH_CHOKE is not set
+# CONFIG_NET_SCH_QFQ is not set
+CONFIG_NET_SCH_INGRESS=y
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+CONFIG_NET_CLS_U32=y
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_CLS_CGROUP is not set
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+# CONFIG_NET_EMATCH_CMP is not set
+# CONFIG_NET_EMATCH_NBYTE is not set
+CONFIG_NET_EMATCH_U32=y
+# CONFIG_NET_EMATCH_META is not set
+# CONFIG_NET_EMATCH_TEXT is not set
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=y
+# CONFIG_GACT_PROB is not set
+CONFIG_NET_ACT_MIRRED=y
+# CONFIG_NET_ACT_IPT is not set
+# CONFIG_NET_ACT_NAT is not set
+# CONFIG_NET_ACT_PEDIT is not set
+# CONFIG_NET_ACT_SIMP is not set
+# CONFIG_NET_ACT_SKBEDIT is not set
+# CONFIG_NET_ACT_CSUM is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+# CONFIG_DNS_RESOLVER is not set
+# CONFIG_BATMAN_ADV is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+# CONFIG_BT_HCIUART_BCSP is not set
+# CONFIG_BT_HCIUART_ATH3K is not set
+# CONFIG_BT_HCIUART_LL is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_CFG80211_ALLOW_RECONNECT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_PM=y
+# CONFIG_RFKILL_INPUT is not set
+# CONFIG_RFKILL_REGULATOR is not set
+# CONFIG_RFKILL_GPIO is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_INTEL_MID_PTI is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_SENSORS_AK8975 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+CONFIG_UID_STAT=y
+# CONFIG_BMP085 is not set
+# CONFIG_WL127X_RFKILL is not set
+# CONFIG_APANIC is not set
+# CONFIG_JACK_MON is not set
+# CONFIG_UART_SELECT is not set
+# CONFIG_SEC_DEV_JACK is not set
+# CONFIG_FM34_WE395 is not set
+# CONFIG_AUDIENCE_ES305 is not set
+# CONFIG_2MIC_FM34_WE395 is not set
+# CONFIG_USBHUB_USB3503 is not set
+# CONFIG_PN544 is not set
+# CONFIG_STMPE811_ADC is not set
+# CONFIG_MPU_SENSORS_MPU3050 is not set
+# CONFIG_MPU_SENSORS_MPU6050 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_SAMSUNG_C2C is not set
+CONFIG_SEC_MODEM=y
+# CONFIG_UMTS_MODEM_XMM6260 is not set
+CONFIG_UMTS_MODEM_XMM6262=y
+# CONFIG_CDMA_MODEM_CBP71 is not set
+# CONFIG_CDMA_MODEM_CBP72 is not set
+# CONFIG_LTE_MODEM_CMC221 is not set
+# CONFIG_CDMA_MODEM_MDM6600 is not set
+# CONFIG_LINK_DEVICE_MIPI is not set
+# CONFIG_LINK_DEVICE_DPRAM is not set
+# CONFIG_LINK_DEVICE_USB is not set
+CONFIG_LINK_DEVICE_HSIC=y
+# CONFIG_LINK_DEVICE_C2C is not set
+# CONFIG_IPC_CMC22x_OLD_RFS is not set
+# CONFIG_SIPC_VER_5 is not set
+# CONFIG_SIM_DETECT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=y
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_RAID is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+# CONFIG_DM_FLAKEY is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_IFB is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=y
+# CONFIG_VETH is not set
+# CONFIG_MII is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NETDEV_10000=y
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_WIFI_CONTROL_FUNC=y
+# CONFIG_ATH_COMMON is not set
+CONFIG_BCM4334=y
+# CONFIG_BCM4330 is not set
+# CONFIG_BCM43241 is not set
+CONFIG_BROADCOM_WIFI_RESERVED_MEM=y
+# CONFIG_WLAN_COUNTRY_CODE is not set
+CONFIG_WLAN_REGION_CODE=100
+# CONFIG_HOSTAP is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_MWIFIEX is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_HSO is not set
+# CONFIG_USB_CDC_PHONET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+# CONFIG_PPPOE is not set
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+CONFIG_INPUT_KEYRESET=y
+# CONFIG_INPUT_FBSUSPEND is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_CYPRESS_TOUCH=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_MELFAS_GC is not set
+CONFIG_TOUCHSCREEN_MELFAS=y
+# CONFIG_TOUCHSCREEN_MMS152 is not set
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1 is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT1536E is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT1664S is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT540E is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT224 is not set
+# CONFIG_TOUCHSCREEN_BU21013 is not set
+# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_EXYNOS4 is not set
+# CONFIG_TOUCHSCREEN_PIXCIR is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MAX11801 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MMS114 is not set
+# CONFIG_MELFAS_TOUCHKEY is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2005 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_TOUCHSCREEN_ST1232 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+# CONFIG_TOUCHSCREEN_ZINITIX is not set
+# CONFIG_TOUCHSCREEN_MXT1386 is not set
+# CONFIG_TOUCHSCREEN_MXT768E is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_S7301 is not set
+# CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK is not set
+# CONFIG_EPEN_WACOM_G5SP is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_SENSORS_BH1721FVC is not set
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+CONFIG_INPUT_KEYCHORD=y
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+# CONFIG_INPUT_PCF8574 is not set
+# CONFIG_INPUT_PWM_BEEPER is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+# CONFIG_INPUT_ADXL34X is not set
+# CONFIG_OPTICAL_GP2A is not set
+# CONFIG_OPTICAL_WAKE_ENABLE is not set
+# CONFIG_INPUT_CMA3000 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVMEM=y
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+# CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH is not set
+CONFIG_SERIAL_S5PV210=y
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_S3C_MEM=y
+CONFIG_EXYNOS_MEM=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+CONFIG_HAVE_S3C2410_I2C=y
+CONFIG_I2C_S3C2410=y
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+CONFIG_SPI_S3C64XX=y
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+CONFIG_GPIO_EXYNOS4=y
+CONFIG_GPIO_PLAT_SAMSUNG=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X is not set
+# CONFIG_GPIO_WM8994 is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_BATTERY_MAX17043_FUELGAUGE is not set
+# CONFIG_BATTERY_MAX17042_FUELGAUGE is not set
+CONFIG_BATTERY_MAX17047_FUELGAUGE=y
+# CONFIG_BATTERY_SMB136_CHARGER is not set
+CONFIG_BATTERY_MAX77693_CHARGER=y
+CONFIG_BATTERY_WPC_CHARGER=y
+# CONFIG_BATTERY_SAMSUNG_P1X is not set
+# CONFIG_FUELGAUGE_DUMMY is not set
+# CONFIG_FUELGAUGE_MAX17048 is not set
+# CONFIG_CHARGER_DUMMY is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_SMB328 is not set
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ20Z75 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_BATTERY_S3C_ADC is not set
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_BATTERY_SAMSUNG=y
+# CONFIG_BATTERY_SAMSUNG_S2PLUS is not set
+# CONFIG_BATTERY_SEC_U1 is not set
+# CONFIG_BATTERY_SEC_PX is not set
+# CONFIG_CHARGER_MAX8922_U1 is not set
+# CONFIG_CHARGER_MAX8922_S2PLUS is not set
+# CONFIG_BATTERY_MAX17042_FUELGAUGE_U1 is not set
+# CONFIG_BATTERY_MAX17042_FUELGAUGE_PX is not set
+# CONFIG_SMB136_CHARGER is not set
+# CONFIG_SMB136_CHARGER_Q1 is not set
+# CONFIG_SMB328_CHARGER is not set
+# CONFIG_SMB347_CHARGER is not set
+# CONFIG_CHARGER_MANAGER is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+# CONFIG_CPU_THERMAL is not set
+# CONFIG_SENSORS_EXYNOS4_TMU is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_HAVE_S3C2410_WATCHDOG=y
+# CONFIG_S3C2410_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+CONFIG_MFD_SUPPORT=y
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS6105X is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC3589X is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_MAX8698 is not set
+CONFIG_MFD_MAX77686=y
+CONFIG_MFD_MAX77693=y
+# CONFIG_MFD_S5M_CORE is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_WM8350_I2C is not set
+CONFIG_MFD_WM8994=y
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13XXX is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_TPS65910 is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+# CONFIG_REGULATOR_MAX8952 is not set
+CONFIG_REGULATOR_MAX77686=y
+CONFIG_REGULATOR_MAX77693=y
+CONFIG_REGULATOR_WM8994=y
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_REGULATOR_ISL6271A is not set
+# CONFIG_REGULATOR_AD5398 is not set
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_RC_CORE=y
+CONFIG_LIRC=y
+CONFIG_RC_MAP=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+CONFIG_IR_RC5_SZ_DECODER=y
+CONFIG_IR_LIRC_CODEC=y
+# CONFIG_IR_IMON is not set
+# CONFIG_IR_MCEUSB is not set
+# CONFIG_IR_REDRAT3 is not set
+# CONFIG_IR_STREAMZAP is not set
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+
+#
+# Customize TV tuners
+#
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
+CONFIG_VIDEO_V4L2=y
+CONFIG_V4L2_MEM2MEM_DEV=y
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEOBUF2_MEMOPS=y
+CONFIG_VIDEOBUF2_CMA_PHYS=y
+# CONFIG_VIDEOBUF2_ION is not set
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_FIXED_MINOR_RANGES=y
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_VIDEO_IR_I2C=y
+
+#
+# Encoders, decoders, sensors and other helper chips
+#
+
+#
+# Audio decoders, processors and mixers
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# RDS decoders
+#
+# CONFIG_VIDEO_SAA6588 is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_ADV7180 is not set
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+# CONFIG_VIDEO_S5K3H2 is not set
+# CONFIG_VIDEO_S5K3H7 is not set
+# CONFIG_VIDEO_S5K4E5 is not set
+CONFIG_VIDEO_S5K6A3=y
+# CONFIG_S5K6A3_CSI_C is not set
+CONFIG_S5K6A3_CSI_D=y
+# CONFIG_VIDEO_M5MO is not set
+# CONFIG_VIDEO_M9MO is not set
+# CONFIG_VIDEO_S5K5BAFX is not set
+# CONFIG_VIDEO_S5K5CCGX_COMMON is not set
+# CONFIG_VIDEO_SR200PC20 is not set
+# CONFIG_VIDEO_SR200PC20M is not set
+# CONFIG_VIDEO_ISX012 is not set
+# CONFIG_VIDEO_SLP_S5K4ECGX is not set
+# CONFIG_VIDEO_SLP_DB8131M is not set
+# CONFIG_VIDEO_S5K4EA is not set
+CONFIG_VIDEO_S5C73M3=y
+CONFIG_VIDEO_S5C73M3_SPI=y
+# CONFIG_VIDEO_SLP_S5C73M3 is not set
+# CONFIG_VIDEO_IMPROVE_STREAMOFF is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+# CONFIG_VIDEO_AK881X is not set
+
+#
+# Camera sensor devices
+#
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_MT9V032 is not set
+# CONFIG_VIDEO_TCM825X is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# Miscelaneous helper chips
+#
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_VIDEO_SAMSUNG_S5P_FIMC is not set
+# CONFIG_VIDEO_S5P_MIPI_CSIS is not set
+CONFIG_SAMSUNG_MFC_DRIVERS=y
+CONFIG_USE_LEGACY_MFC=y
+# CONFIG_USE_V4L2_MFC is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+# CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_CX231XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_VIDEO_SAMSUNG=y
+CONFIG_VIDEO_SAMSUNG_V4L2=y
+CONFIG_VIDEO_FIMC=y
+CONFIG_VIDEO_FIMC_RANGE_NARROW=y
+# CONFIG_VIDEO_FIMC_RANGE_WIDE is not set
+# CONFIG_VIDEO_FIMC_DEBUG is not set
+CONFIG_VIDEO_FIMC_MIPI=y
+# CONFIG_VIDEO_FIMC_MIPI_IRQ_DEBUG is not set
+CONFIG_VIDEO_FIMC_DMA_AUTO=y
+# CONFIG_VIDEO_FIMC_FIFO is not set
+CONFIG_VIDEO_TVOUT=y
+# CONFIG_VIDEO_TVOUT_2CH_AUDIO is not set
+CONFIG_VIDEO_TVOUT_5_1CH_AUDIO=y
+# CONFIG_HDMI_CEC is not set
+CONFIG_HDMI_EARJACK_MUTE=y
+CONFIG_HDMI_HPD=y
+CONFIG_HDMI_SWITCH_HPD=y
+CONFIG_HDMI_14A_3D=y
+CONFIG_HDMI_PHY_32N=y
+CONFIG_TV_FB=y
+CONFIG_USER_ALLOC_TVOUT=y
+CONFIG_LSI_HDMI_AUDIO_CH_EVENT=y
+# CONFIG_TV_DEBUG is not set
+CONFIG_VIDEO_MFC5X=y
+CONFIG_VIDEO_MFC_MAX_INSTANCE=4
+# CONFIG_VIDEO_MFC5X_DEBUG is not set
+CONFIG_VIDEO_UMP=y
+# CONFIG_UMP_DED_ONLY is not set
+CONFIG_UMP_OSMEM_ONLY=y
+# CONFIG_UMP_VCM_ONLY is not set
+CONFIG_UMP_MEM_SIZE=1024
+# CONFIG_VIDEO_UMP_DEBUG is not set
+CONFIG_VIDEO_MALI400MP=y
+# CONFIG_MALI_DED_ONLY is not set
+# CONFIG_MALI_DED_MMU is not set
+CONFIG_MALI_OSMEM_ONLY=y
+# CONFIG_MALI_DED_OSMEM is not set
+# CONFIG_VIDEO_MALI400MP_DEBUG is not set
+# CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING is not set
+CONFIG_VIDEO_MALI400MP_DVFS=y
+CONFIG_VIDEO_FIMG2D=y
+# CONFIG_VIDEO_FIMG2D_DEBUG is not set
+CONFIG_VIDEO_FIMG2D4X=y
+# CONFIG_VIDEO_FIMG2D4X_DEBUG is not set
+CONFIG_VIDEO_JPEG_V2X=y
+CONFIG_JPEG_V2_1=y
+# CONFIG_JPEG_V2_2 is not set
+
+#
+# Reserved memory configurations
+#
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0=61464
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1=15360
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2=0
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3=0
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE=50176
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL=4096
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG=0
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT=0
+CONFIG_VIDEO_EXYNOS=y
+CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS=12080
+CONFIG_EXYNOS_MEDIA_DEVICE=y
+CONFIG_VIDEO_EXYNOS_FIMC_LITE=y
+
+#
+# Reserved memory configurations
+#
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE0=10240
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE1=10240
+# CONFIG_VIDEO_EXYNOS_MIPI_CSIS is not set
+# CONFIG_VIDEO_EXYNOS_TV is not set
+# CONFIG_VIDEO_EXYNOS_ROTATOR is not set
+CONFIG_VIDEO_EXYNOS_FIMC_IS=y
+# CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER is not set
+CONFIG_MEDIA_EXYNOS=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set
+
+#
+# Mhl(sii9244) device support
+#
+CONFIG_SAMSUNG_MHL=y
+CONFIG_SAMSUNG_USE_11PIN_CONNECTOR=y
+CONFIG_SAMSUNG_SMARTDOCK=y
+CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE=y
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_TDMB is not set
+# CONFIG_ISDBT_FC8100 is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+CONFIG_ION=y
+CONFIG_ION_EXYNOS=y
+CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE=71680
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_WMT_GE_ROPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_S5P=y
+CONFIG_FB_S5P_SPLASH_SCREEN=y
+# CONFIG_FB_S5P_LCD_INIT is not set
+# CONFIG_FB_S5P_DEBUG is not set
+# CONFIG_FB_S5P_TRACE_UNDERRUN is not set
+CONFIG_FB_S5P_DEFAULT_WINDOW=2
+CONFIG_FB_S5P_NR_BUFFERS=2
+# CONFIG_FB_S5P_VIRTUAL is not set
+CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD=8192
+CONFIG_FB_S5P_MDNIE=y
+# CONFIG_FB_MDNIE_PWM is not set
+CONFIG_FB_S5P_MIPI_DSIM=y
+# CONFIG_FB_S5P_S6C1372 is not set
+# CONFIG_FB_S5P_LD9040 is not set
+# CONFIG_FB_S5P_DUMMY_MIPI_LCD is not set
+CONFIG_FB_S5P_S6E8AA0=y
+# CONFIG_FB_S5P_S6D6AA1 is not set
+CONFIG_AID_DIMMING=y
+CONFIG_LCD_FREQ_SWITCH=y
+CONFIG_FB_S5P_EXTDSP=y
+# CONFIG_FB_S5P_EXTDSP_DEBUG is not set
+CONFIG_FB_S5P_EXTDSP_NR_BUFFERS=3
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_TMIO is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_L4F00242T03 is not set
+# CONFIG_LCD_LMS283GF05 is not set
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+# CONFIG_LCD_S6E63M0 is not set
+# CONFIG_LCD_MIPI_S6E63M0 is not set
+# CONFIG_LCD_MIPI_S6E8AB0 is not set
+# CONFIG_LCD_MIPI_TC358764 is not set
+# CONFIG_LCD_LD9040 is not set
+# CONFIG_LCD_WA101S is not set
+# CONFIG_LCD_LTE480WV is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_BACKLIGHT_PWM is not set
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_VERBOSE is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=y
+# CONFIG_SND_SOC_CACHE_LZO is not set
+CONFIG_SND_SOC_SAMSUNG=y
+CONFIG_SND_SAMSUNG_I2S=y
+CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811=y
+# CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER is not set
+CONFIG_SND_SOC_SAMSUNG_I2S_SEC=y
+# CONFIG_SND_SAMSUNG_NORMAL is not set
+# CONFIG_SND_SAMSUNG_LP is not set
+CONFIG_SND_SAMSUNG_ALP=y
+# CONFIG_SND_SAMSUNG_RP is not set
+CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP=1024
+# CONFIG_SND_SAMSUNG_RP_DEBUG is not set
+# CONFIG_SND_SAMSUNG_I2S_MASTER is not set
+CONFIG_SND_USE_SUB_MIC=y
+# CONFIG_SND_USE_THIRD_MIC is not set
+# CONFIG_SND_USE_STEREO_SPEAKER is not set
+# CONFIG_SND_USE_LINEOUT_SWITCH is not set
+CONFIG_SND_USE_MUIC_SWITCH=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_WM_HUBS=y
+CONFIG_SND_SOC_WM8994=y
+CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+CONFIG_HID_ACRUX=y
+# CONFIG_HID_ACRUX_FF is not set
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_PRODIKEYS=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DRAGONRISE=y
+# CONFIG_DRAGONRISE_FF is not set
+CONFIG_HID_EMS_FF=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KEYTOUCH=y
+CONFIG_HID_KYE=y
+CONFIG_HID_UCLOGIC=y
+CONFIG_HID_WALTOP=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LCPOWER=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWII_FF is not set
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_PICOLCD=y
+# CONFIG_HID_PICOLCD_FB is not set
+# CONFIG_HID_PICOLCD_BACKLIGHT is not set
+# CONFIG_HID_PICOLCD_LCD is not set
+# CONFIG_HID_PICOLCD_LEDS is not set
+CONFIG_HID_QUANTA=y
+CONFIG_HID_ROCCAT=y
+CONFIG_HID_ROCCAT_COMMON=y
+CONFIG_HID_ROCCAT_ARVO=y
+CONFIG_HID_ROCCAT_KONE=y
+CONFIG_HID_ROCCAT_KONEPLUS=y
+CONFIG_HID_ROCCAT_KOVAPLUS=y
+CONFIG_HID_ROCCAT_PYRA=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SMARTJOYPLUS=y
+# CONFIG_SMARTJOYPLUS_FF is not set
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+# CONFIG_THRUSTMASTER_FF is not set
+CONFIG_HID_WACOM=y
+CONFIG_HID_WACOM_POWER_SUPPLY=y
+CONFIG_HID_ZEROPLUS=y
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_HID_ZYDACRON=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB_ARCH_HAS_XHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_HOST_COMPLIANT_TEST is not set
+CONFIG_USB_HOST_NOTIFY=y
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_S5P=y
+CONFIG_USB_S5P_HSIC0=y
+CONFIG_USB_S5P_HSIC1=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_S5P=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_S3C_OTG_HOST is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+CONFIG_USB_PRINTER=y
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_REALTEK is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
+# CONFIG_USB_UAS is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=y
+# CONFIG_USB_SERIAL_CONSOLE is not set
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=y
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_SSU100 is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+# CONFIG_USB_QCOM_DIAG_BRIDGE is not set
+# CONFIG_USB_QCOM_MDM_BRIDGE is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+CONFIG_USB_GADGET_S3C_OTGD=y
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+
+#
+# NOTE: S3C OTG device role enables the controller driver below
+#
+CONFIG_USB_S3C_OTGD=y
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FUNCTIONFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_G_SLP is not set
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE=y
+CONFIG_USB_ANDROID_SAMSUNG_MTP=y
+CONFIG_USB_DUN_SUPPORT=y
+# CONFIG_USB_ANDROID is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+# CONFIG_USB_G_WEBCAM is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_OTG_WAKELOCK is not set
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_NOT_USE_SANITIZE=y
+# CONFIG_MMC_POLLING_WAIT_CMD23 is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+CONFIG_MMC_SELECTIVE_PACKED_CMD_POLICY=y
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_MSHCI=y
+# CONFIG_MMC_MSHCI_S3C_DMA_MAP is not set
+CONFIG_MMC_MSHCI_ASYNC_OPS=y
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_MMC_SDHCI_S3C_DMA=y
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_LEDS_SPFCW043 is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_LM3530 is not set
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+CONFIG_LEDS_AN30259A=y
+# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP5523 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_PWM is not set
+# CONFIG_LEDS_REGULATOR is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_MAX77693=y
+# CONFIG_LEDS_MAX8997 is not set
+CONFIG_LEDS_AAT1290A=y
+# CONFIG_LEDS_TRIGGERS is not set
+
+#
+# LED Triggers
+#
+CONFIG_NFC_DEVICES=y
+# CONFIG_PN544_NFC is not set
+CONFIG_PN65N_NFC=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# CONFIG_RTC_ALARM_BOOT is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_MAX77686=y
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_HAVE_S3C_RTC=y
+CONFIG_RTC_DRV_S3C=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# CONFIG_VIDEO_TM6000 is not set
+# CONFIG_USBIP_CORE is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_BRCMUTIL is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_R8712U is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Android
+#
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_RAM_CONSOLE=y
+CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE=128
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE=16
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE=8
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL=0x11d
+# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set
+CONFIG_ANDROID_TIMED_OUTPUT=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+# CONFIG_POHMELFS is not set
+# CONFIG_LINE6_USB is not set
+# CONFIG_USB_SERIAL_QUATECH2 is not set
+# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
+# CONFIG_VT6656 is not set
+# CONFIG_IIO is not set
+# CONFIG_XVMALLOC is not set
+# CONFIG_ZRAM is not set
+# CONFIG_FB_SM7XX is not set
+# CONFIG_LIRC_STAGING is not set
+# CONFIG_EASYCAP is not set
+CONFIG_MACH_NO_WESTBRIDGE=y
+# CONFIG_ATH6K_LEGACY is not set
+# CONFIG_USB_ENESTORAGE is not set
+# CONFIG_BCM_WIMAX is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_SPEAKUP is not set
+# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_VIBETONZ=y
+CONFIG_MOTOR_DRV_MAX77693=y
+# CONFIG_MOTOR_DRV_ISA1200 is not set
+CONFIG_SAMSUNG_MODULES=y
+CONFIG_FM_RADIO=y
+# CONFIG_FM_SI4709 is not set
+CONFIG_FM_SI4705=m
+CONFIG_SENSORS_CORE=y
+CONFIG_SENSORS_AK8975C=y
+# CONFIG_SENSORS_BMP180 is not set
+# CONFIG_SENSORS_CM3663 is not set
+# CONFIG_SENSORS_PAS2M110 is not set
+# CONFIG_SENSORS_BMA254 is not set
+# CONFIG_SENSORS_TAOS is not set
+# CONFIG_SENSORS_GP2A is not set
+# CONFIG_SENSORS_GP2A_ANALOG is not set
+CONFIG_SENSORS_CM36651=y
+# CONFIG_SENSORS_BH1721 is not set
+# CONFIG_SENSORS_K3DH is not set
+# CONFIG_SENSORS_K3G is not set
+CONFIG_SENSORS_LSM330DLC=y
+CONFIG_SENSORS_LPS331=y
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_SAMSUNG_PHONE_SVNET is not set
+CONFIG_ACCESSORY=y
+# CONFIG_30PIN_CONN is not set
+# CONFIG_MHL_SII9234 is not set
+# CONFIG_SEC_KEYBOARD_DOCK is not set
+# CONFIG_HPD_PULL is not set
+# CONFIG_SAMSUNG_MHL_9290 is not set
+# CONFIG_IR_REMOCON is not set
+# CONFIG_EXTCON is not set
+CONFIG_MOBICORE_SUPPORT=y
+# CONFIG_MOBICORE_DEBUG is not set
+CONFIG_MOBICORE_API=y
+CONFIG_IOMMU_SUPPORT=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+# CONFIG_EXT4_FS_XATTR is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=y
+CONFIG_WTL_ENCRYPTION_FILTER=y
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+# CONFIG_PRINTK_PID is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=1
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_DEBUG_LIST=y
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_DEBUG_PER_CPU_MAPS is not set
+CONFIG_LKDTM=y
+# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
+CONFIG_FAULT_INJECTION=y
+# CONFIG_FAILSLAB is not set
+# CONFIG_FAIL_PAGE_ALLOC is not set
+# CONFIG_FAIL_MAKE_REQUEST is not set
+# CONFIG_FAIL_IO_TIMEOUT is not set
+# CONFIG_FAULT_INJECTION_DEBUG_FS is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_EVENT_POWER_TRACING_DEPRECATED=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FUNCTION_GRAPH_TRACER=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+CONFIG_DYNAMIC_FTRACE=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_FTRACE_MCOUNT_RECORD=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_OLD_MCOUNT=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+CONFIG_DEBUG_S3C_UART=2
+# CONFIG_CACHE_PERF is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS_INTEG_OFFSET=0x20000000
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_S5P_DEV_ACE is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_ENC8=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=y
+CONFIG_TEXTSEARCH_BM=y
+CONFIG_TEXTSEARCH_FSM=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
deleted file mode 100644
index 2bf2243..0000000
--- a/arch/arm/configs/mxs_defconfig
+++ /dev/null
@@ -1,129 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-# CONFIG_NET_NS is not set
-CONFIG_PERF_EVENTS=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_BLK_DEV_INTEGRITY=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_MXS=y
-CONFIG_MACH_STMP378X_DEVB=y
-CONFIG_MACH_TX28=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT_VOLUNTARY=y
-CONFIG_AEABI=y
-CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_CAN=m
-CONFIG_CAN_RAW=m
-CONFIG_CAN_BCM=m
-CONFIG_CAN_DEV=m
-CONFIG_CAN_FLEXCAN=m
-# CONFIG_WIRELESS is not set
-CONFIG_DEVTMPFS=y
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-# CONFIG_BLK_DEV is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ENC28J60=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_TSC2007=m
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=m
-# CONFIG_I2C_COMPAT is not set
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_MXS=m
-CONFIG_SPI=y
-CONFIG_SPI_GPIO=m
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-# CONFIG_MFD_SUPPORT is not set
-CONFIG_DISPLAY_SUPPORT=m
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_MMC=y
-CONFIG_MMC_MXS=y
-CONFIG_RTC_CLASS=m
-CONFIG_RTC_DRV_DS1307=m
-CONFIG_DMADEVICES=y
-CONFIG_MXS_DMA=y
-CONFIG_EXT3_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_FSCACHE=m
-CONFIG_FSCACHE_STATS=y
-CONFIG_CACHEFILES=m
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PRINTK_TIME=y
-CONFIG_FRAME_WARN=2048
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOCKUP_DETECTOR=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_TIMER_STATS=y
-CONFIG_PROVE_LOCKING=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_STRICT_DEVMEM=y
-CONFIG_DEBUG_USER=y
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC7=m
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
deleted file mode 100644
index 7b63462..0000000
--- a/arch/arm/configs/omap1_defconfig
+++ /dev/null
@@ -1,286 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_IKCONFIG=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_ELF_CORE is not set
-# CONFIG_BASE_FULL is not set
-# CONFIG_SHMEM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-CONFIG_SLOB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP1=y
-CONFIG_OMAP_RESET_CLOCKS=y
-# CONFIG_OMAP_MUX is not set
-CONFIG_OMAP_MBOX_FWK=y
-CONFIG_OMAP_32K_TIMER=y
-CONFIG_OMAP_DM_TIMER=y
-CONFIG_ARCH_OMAP730=y
-CONFIG_ARCH_OMAP850=y
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_MACH_OMAP_INNOVATOR=y
-CONFIG_MACH_OMAP_H2=y
-CONFIG_MACH_OMAP_H3=y
-CONFIG_MACH_OMAP_HTCWIZARD=y
-CONFIG_MACH_HERALD=y
-CONFIG_MACH_OMAP_OSK=y
-CONFIG_MACH_OMAP_PERSEUS2=y
-CONFIG_MACH_OMAP_FSAMPLE=y
-CONFIG_MACH_VOICEBLUE=y
-CONFIG_MACH_OMAP_PALMTE=y
-CONFIG_MACH_OMAP_PALMZ71=y
-CONFIG_MACH_OMAP_PALMTT=y
-CONFIG_MACH_SX1=y
-CONFIG_MACH_NOKIA770=y
-CONFIG_MACH_AMS_DELTA=y
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER=y
-CONFIG_OMAP_ARM_216MHZ=y
-CONFIG_OMAP_ARM_195MHZ=y
-CONFIG_OMAP_ARM_192MHZ=y
-CONFIG_OMAP_ARM_182MHZ=y
-CONFIG_OMAP_ARM_168MHZ=y
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCCARD=y
-CONFIG_OMAP_CF=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=1f03 rootfstype=jffs2"
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_PM=y
-# CONFIG_SUSPEND is not set
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
-CONFIG_NETFILTER=y
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_HIDP=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_CONNECTOR=y
-# CONFIG_PROC_EVENTS is not set
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=3
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_NAND=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=2
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_SCSI=y
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_TUN=y
-CONFIG_PHYLIB=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_USB_CATC=y
-CONFIG_USB_KAWETH=y
-CONFIG_USB_PEGASUS=y
-CONFIG_USB_RTL8150=y
-CONFIG_USB_USBNET=y
-# CONFIG_USB_NET_AX8817X is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-CONFIG_PPP=y
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=y
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=3
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_OMAP_UWIRE=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_VIRTUAL=y
-CONFIG_FB_OMAP=y
-CONFIG_FB_OMAP_LCDC_EXTERNAL=y
-CONFIG_FB_OMAP_LCDC_HWA742=y
-CONFIG_FB_OMAP_MANUAL_UPDATE=y
-CONFIG_FB_OMAP_LCD_MIPID=y
-CONFIG_FB_OMAP_BOOTLOADER_INIT=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-CONFIG_FONT_6x11=y
-CONFIG_FONT_MINI_4x6=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-CONFIG_SND_DUMMY=y
-CONFIG_SND_USB_AUDIO=y
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_SERIAL=y
-CONFIG_USB_SERIAL_CONSOLE=y
-CONFIG_USB_SERIAL_PL2303=y
-CONFIG_USB_TEST=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-# CONFIG_USB_ETH_RNDIS is not set
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_FILE_STORAGE_TEST=y
-CONFIG_MMC=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_OMAP=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_OMAP=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=866
-CONFIG_FAT_DEFAULT_IOCHARSET="koi8-r"
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_866=y
-CONFIG_NLS_CODEPAGE_1251=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_NLS_ISO8859_5=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_KOI8_R=y
-CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_SECURITY=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_PCBC=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_ZLIB=y
-CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
deleted file mode 100644
index d5f00d7..0000000
--- a/arch/arm/configs/omap2plus_defconfig
+++ /dev/null
@@ -1,236 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_OMAP=y
-CONFIG_OMAP_RESET_CLOCKS=y
-CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_ERRATA_411920=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_LEDS=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_MISC=y
-CONFIG_PM_DEBUG=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_BT=m
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_CFG80211=m
-CONFIG_MAC80211=m
-CONFIG_MAC80211_RC_PID=y
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_CONNECTOR=y
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_OOPS=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_OMAP2=y
-CONFIG_MTD_ONENAND=y
-CONFIG_MTD_ONENAND_VERIFY_WRITE=y
-CONFIG_MTD_ONENAND_OMAP2=y
-CONFIG_MTD_UBI=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_MD=y
-CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-CONFIG_SMSC911X=y
-CONFIG_KS8851=y
-CONFIG_KS8851_MLL=y
-CONFIG_LIBERTAS=m
-CONFIG_LIBERTAS_USB=m
-CONFIG_LIBERTAS_SDIO=m
-CONFIG_LIBERTAS_DEBUG=y
-CONFIG_USB_USBNET=y
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_INPUT_JOYDEV=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_KEYBOARD_GPIO=y
-CONFIG_KEYBOARD_TWL4030=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_TWL4030_PWRBUTTON=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_OMAP24XX=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_TWL4030=y
-CONFIG_W1=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_WATCHDOG=y
-CONFIG_OMAP_WATCHDOG=y
-CONFIG_TWL4030_WATCHDOG=y
-CONFIG_REGULATOR_TWL4030=y
-CONFIG_REGULATOR_TPS65023=y
-CONFIG_REGULATOR_TPS6507X=y
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_FB_OMAP_LCD_VGA=y
-CONFIG_OMAP2_DSS=m
-CONFIG_OMAP2_DSS_RFBI=y
-CONFIG_OMAP2_DSS_SDI=y
-CONFIG_OMAP2_DSS_DSI=y
-CONFIG_FB_OMAP2=m
-CONFIG_PANEL_GENERIC_DPI=m
-CONFIG_PANEL_SHARP_LS037V7DW01=m
-CONFIG_PANEL_NEC_NL8048HL11_01B=m
-CONFIG_PANEL_TAAL=m
-CONFIG_PANEL_TPO_TD043MTEA1=m
-CONFIG_PANEL_ACX565AKM=m
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_PLATFORM=y
-CONFIG_DISPLAY_SUPPORT=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-CONFIG_LOGO=y
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_DEBUG=y
-CONFIG_SND_USB_AUDIO=m
-CONFIG_SND_SOC=m
-CONFIG_SND_OMAP_SOC=m
-CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_MON=y
-CONFIG_USB_WDM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_LIBUSUAL=y
-CONFIG_USB_TEST=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_DEBUG=y
-CONFIG_USB_GADGET_DEBUG_FILES=y
-CONFIG_USB_GADGET_DEBUG_FS=y
-CONFIG_USB_ZERO=m
-CONFIG_MMC=y
-CONFIG_MMC_UNSAFE_RESUME=y
-CONFIG_SDIO_UART=y
-CONFIG_MMC_OMAP=y
-CONFIG_MMC_OMAP_HS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_TWL92330=y
-CONFIG_RTC_DRV_TWL4030=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_QUOTA=y
-CONFIG_QFMT_V2=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_UBIFS_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
-CONFIG_PROVE_LOCKING=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SECURITY=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_CCITT=y
-CONFIG_CRC_T10DIF=y
-CONFIG_CRC_ITU_T=y
-CONFIG_CRC7=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/pcontrol_g20_defconfig b/arch/arm/configs/pcontrol_g20_defconfig
deleted file mode 100644
index c75c9fc..0000000
--- a/arch/arm/configs/pcontrol_g20_defconfig
+++ /dev/null
@@ -1,175 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE="/opt/arm-2010q1/bin/arm-none-linux-gnueabi-"
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TREE_PREEMPT_RCU=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_NAMESPACES=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_DEFAULT_DEADLINE=y
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9G20=y
-CONFIG_MACH_PCONTROL_G20=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 mem=128M mtdparts=atmel_nand:128k(bootstrap)ro,256k(uboot)ro,128k(env1)ro,128k(env2)ro,2M(linux),-(root) root=/dev/mmcblk0p1 rootwait rw"
-CONFIG_VFP=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_FW_LOADER is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHRAM=m
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_TCLIB=y
-CONFIG_EEPROM_AT24=m
-CONFIG_SCSI=m
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=m
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_NETDEVICES=y
-CONFIG_MACVLAN=m
-CONFIG_TUN=m
-CONFIG_SMSC_PHY=m
-CONFIG_BROADCOM_PHY=m
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
-CONFIG_SMSC911X=m
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_INPUT_POLLDEV=y
-CONFIG_INPUT_SPARSEKMAP=y
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=m
-CONFIG_KEYBOARD_MATRIX=m
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=m
-CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
-# CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_SERIAL_MAX3100=m
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_R3964=m
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-# CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_GPIO=m
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=m
-CONFIG_SPI_SPIDEV=m
-CONFIG_GPIO_SYSFS=y
-CONFIG_W1=m
-CONFIG_W1_MASTER_GPIO=m
-CONFIG_W1_SLAVE_DS2431=m
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-# CONFIG_MFD_SUPPORT is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=m
-CONFIG_USB_LIBUSUAL=y
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_USB_G_HID=m
-CONFIG_MMC=y
-CONFIG_MMC_UNSAFE_RESUME=y
-CONFIG_MMC_ATMELMCI=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_AUXDISPLAY=y
-CONFIG_UIO=y
-CONFIG_UIO_PDRV=y
-CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
-CONFIG_IIO=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V4=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ANSI_CPRNG=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/s5p64x0_defconfig b/arch/arm/configs/s5p64x0_defconfig
deleted file mode 100644
index ad6b61b..0000000
--- a/arch/arm/configs/s5p64x0_defconfig
+++ /dev/null
@@ -1,68 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S5P64X0=y
-CONFIG_S3C_BOOT_ERROR_RESET=y
-CONFIG_S3C_LOWLEVEL_UART_PORT=1
-CONFIG_MACH_SMDK6440=y
-CONFIG_MACH_SMDK6450=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_CPU_32v6K=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
-CONFIG_FPE_NWFPE=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_SAMSUNG=y
-CONFIG_SERIAL_SAMSUNG_CONSOLE=y
-CONFIG_HW_RANDOM=y
-# CONFIG_HWMON is not set
-CONFIG_DISPLAY_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_S3C_UART=1
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
deleted file mode 100644
index fea7e1f..0000000
--- a/arch/arm/configs/spear3xx_defconfig
+++ /dev/null
@@ -1,53 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_BOARD_SPEAR300_EVB=y
-CONFIG_BOARD_SPEAR310_EVB=y
-CONFIG_BOARD_SPEAR320_EVB=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig
deleted file mode 100644
index cef2e83..0000000
--- a/arch/arm/configs/spear6xx_defconfig
+++ /dev/null
@@ -1,49 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_ARCH_SPEAR6XX=y
-CONFIG_BOARD_SPEAR600_EVB=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
deleted file mode 100644
index 8845f1c..0000000
--- a/arch/arm/configs/tegra_defconfig
+++ /dev/null
@@ -1,146 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_ELF_CORE is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_TEGRA=y
-CONFIG_MACH_HARMONY=y
-CONFIG_MACH_KAEN=y
-CONFIG_MACH_PAZ00=y
-CONFIG_MACH_TRIMSLICE=y
-CONFIG_MACH_WARIO=y
-CONFIG_TEGRA_DEBUG_UARTD=y
-CONFIG_ARM_ERRATA_742230=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_HIGHMEM=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_VFP=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_INET_ESP=y
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_IPV6_OPTIMISTIC_DAD=y
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_IPV6_MIP6=y
-CONFIG_IPV6_TUNNEL=y
-CONFIG_IPV6_MULTIPLE_TABLES=y
-# CONFIG_WIRELESS is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_MISC_DEVICES=y
-CONFIG_AD525X_DPOT=y
-CONFIG_AD525X_DPOT_I2C=y
-CONFIG_ICS932S401=y
-CONFIG_APDS9802ALS=y
-CONFIG_ISL29003=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-CONFIG_R8169=y
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_TEGRA=y
-CONFIG_SENSORS_LM90=y
-CONFIG_MFD_TPS6586X=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_TPS6586X=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_MMC=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MMC_SDHCI_TEGRA=y
-CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
-CONFIG_IIO=y
-CONFIG_SENSORS_ISL29018=y
-CONFIG_SENSORS_AK8975=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_DNOTIFY is not set
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_SCHEDSTATS=y
-CONFIG_TIMER_STATS=y
-CONFIG_DEBUG_SLAB=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_VM=y
-CONFIG_DEBUG_SG=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
deleted file mode 100644
index f2de51f..0000000
--- a/arch/arm/configs/vexpress_defconfig
+++ /dev/null
@@ -1,140 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_CGROUPS=y
-CONFIG_CPUSETS=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-# CONFIG_NET_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_VEXPRESS=y
-CONFIG_ARCH_VEXPRESS_CA9X4=y
-# CONFIG_SWP_EMULATE is not set
-CONFIG_SMP=y
-CONFIG_VMSPLIT_2G=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
-CONFIG_VFP=y
-CONFIG_NEON=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_ARM_INTEGRATOR=y
-CONFIG_MISC_DEVICES=y
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_ATA=y
-# CONFIG_SATA_PMP is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIO_AMBAKMI=y
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_LEGACY_PTY_COUNT=16
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_ARMCLCD=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-# CONFIG_SND_DRIVERS is not set
-CONFIG_SND_ARMAACI=y
-CONFIG_HID_DRAGONRISE=y
-CONFIG_HID_GYRATION=y
-CONFIG_HID_TWINHAN=y
-CONFIG_HID_NTRIG=y
-CONFIG_HID_PANTHERLORD=y
-CONFIG_HID_PETALYNX=y
-CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
-CONFIG_HID_SUNPLUS=y
-CONFIG_HID_GREENASIA=y
-CONFIG_HID_SMARTJOYPLUS=y
-CONFIG_HID_TOPSEED=y
-CONFIG_HID_THRUSTMASTER=y
-CONFIG_HID_ZEROPLUS=y
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_ISP1760_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_MMC=y
-CONFIG_MMC_ARMMMCI=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_PL031=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 65c3f24..29035e8 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -293,4 +293,13 @@
.macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
+
+/* Utility macro for declaring string literals */
+ .macro string name:req, string
+ .type \name , #object
+\name:
+ .asciz "\string"
+ .size \name , . - \name
+ .endm
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index b4892a0..f428059 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -26,8 +26,8 @@
#include <linux/compiler.h>
#include <asm/system.h>
-#define smp_mb__before_clear_bit() mb()
-#define smp_mb__after_clear_bit() mb()
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()
/*
* These functions are the basis of our bit ops.
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index d5d8d5c..ce110c3 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -16,6 +16,7 @@
#include <asm/shmparam.h>
#include <asm/cachetype.h>
#include <asm/outercache.h>
+#include <mach/smc.h>
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -206,6 +207,12 @@ static inline void __flush_icache_all(void)
#define flush_cache_all() __cpuc_flush_kern_all()
+#ifndef CONFIG_SMP
+#define flush_all_cpu_caches() flush_cache_all()
+#else
+extern void flush_all_cpu_caches(void);
+#endif
+
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
{
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
@@ -249,7 +256,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr
* Harvard caches are synchronised for the user space address range.
* This is used for the ARM private sys_cacheflush system call.
*/
-#define flush_cache_user_range(vma,start,end) \
+#define flush_cache_user_range(start,end) \
__cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
/*
@@ -344,4 +351,37 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
flush_cache_all();
}
+/*
+ * Control the full line of zero function that must be enabled
+ * only when the slaves connected on cortex-A9 AXI master port support it.
+ * The L2-310 cache controller supports this feature.
+ */
+#ifdef CONFIG_CACHE_L2X0
+static inline void __enable_cache_foz(int enable)
+{
+ int val;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 1\n"
+ : "=r" (val));
+
+ /* enable/disable Foz */
+ if (enable)
+ val |= ((1<<3));
+ else
+ val &= (~(1<<3));
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_CP15(1, 0, 0, 1), val, 0);
+#else
+ asm volatile("mcr p15, 0, %0, c1, c0, 1" : : "r" (val));
+#endif
+}
+
+#define enable_cache_foz() __enable_cache_foz(1)
+#define disable_cache_foz() __enable_cache_foz(0)
+#else
+#define enable_cache_foz() do { } while (0)
+#define disable_cache_foz() do { } while (0)
+#endif
#endif
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 9f390ce..6615f03 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -10,6 +10,9 @@ struct dev_archdata {
#ifdef CONFIG_DMABOUNCE
struct dmabounce_device_info *dmabounce;
#endif
+#ifdef CONFIG_IOMMU_API
+ void *iommu; /* private IOMMU data */
+#endif
};
struct pdev_archdata {
diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h
new file mode 100644
index 0000000..4d27488
--- /dev/null
+++ b/arch/arm/include/asm/fiq_debugger.h
@@ -0,0 +1,64 @@
+/*
+ * arch/arm/include/asm/fiq_debugger.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_
+#define _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_
+
+#include <linux/serial_core.h>
+
+#define FIQ_DEBUGGER_NO_CHAR NO_POLL_CHAR
+#define FIQ_DEBUGGER_BREAK 0x00ff0100
+
+#define FIQ_DEBUGGER_FIQ_IRQ_NAME "fiq"
+#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal"
+#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup"
+
+/**
+ * struct fiq_debugger_pdata - fiq debugger platform data
+ * @uart_resume: used to restore uart state right before enabling
+ * the fiq.
+ * @uart_enable: Do the work necessary to communicate with the uart
+ * hw (enable clocks, etc.). This must be ref-counted.
+ * @uart_disable: Do the work necessary to disable the uart hw
+ * (disable clocks, etc.). This must be ref-counted.
+ * @uart_dev_suspend: called during PM suspend, generally not needed
+ * for real fiq mode debugger.
+ * @uart_dev_resume: called during PM resume, generally not needed
+ * for real fiq mode debugger.
+ */
+struct fiq_debugger_pdata {
+ int (*uart_init)(struct platform_device *pdev);
+ void (*uart_free)(struct platform_device *pdev);
+ int (*uart_resume)(struct platform_device *pdev);
+ int (*uart_getc)(struct platform_device *pdev);
+ void (*uart_putc)(struct platform_device *pdev, unsigned int c);
+ void (*uart_flush)(struct platform_device *pdev);
+ void (*uart_enable)(struct platform_device *pdev);
+ void (*uart_disable)(struct platform_device *pdev);
+
+ int (*uart_dev_suspend)(struct platform_device *pdev);
+ int (*uart_dev_resume)(struct platform_device *pdev);
+
+ void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq,
+ bool enable);
+ void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq);
+
+ void (*force_irq)(struct platform_device *pdev, unsigned int irq);
+ void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq);
+};
+
+#endif
diff --git a/arch/arm/include/asm/fiq_glue.h b/arch/arm/include/asm/fiq_glue.h
new file mode 100644
index 0000000..d54c29d
--- /dev/null
+++ b/arch/arm/include/asm/fiq_glue.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_FIQ_GLUE_H
+#define __ASM_FIQ_GLUE_H
+
+struct fiq_glue_handler {
+ void (*fiq)(struct fiq_glue_handler *h, void *regs, void *svc_sp);
+ void (*resume)(struct fiq_glue_handler *h);
+};
+
+int fiq_glue_register_handler(struct fiq_glue_handler *handler);
+
+#ifdef CONFIG_FIQ_GLUE
+void fiq_glue_resume(void);
+#else
+static inline void fiq_glue_resume(void) {}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
index 89ad180..2635c8b 100644
--- a/arch/arm/include/asm/hardirq.h
+++ b/arch/arm/include/asm/hardirq.h
@@ -5,7 +5,7 @@
#include <linux/threads.h>
#include <asm/irq.h>
-#define NR_IPI 5
+#define NR_IPI 6
typedef struct {
unsigned int __softirq_pending;
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index bfa706f..2a20876 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -57,6 +57,7 @@
#define L2X0_STNDBY_MODE_EN (1 << 0)
/* Registers shifts and masks */
+#define L2X0_CACHE_ID_REV_MASK (0x3f)
#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
#define L2X0_CACHE_ID_PART_L210 (1 << 6)
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
@@ -72,6 +73,8 @@
#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29
#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30
+#define REV_PL310_R2P0 4
+
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
#endif
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 7ecd793..6643d6c 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -17,15 +17,17 @@
#define TRACER_ACCESSED_BIT 0
#define TRACER_RUNNING_BIT 1
#define TRACER_CYCLE_ACC_BIT 2
+#define TRACER_TRACE_DATA_BIT 3
#define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT)
#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT)
#define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT)
+#define TRACER_TRACE_DATA BIT(TRACER_TRACE_DATA_BIT)
#define TRACER_TIMEOUT 10000
-#define etm_writel(t, v, x) \
- (__raw_writel((v), (t)->etm_regs + (x)))
-#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x)))
+#define etm_writel(t, id, v, x) \
+ (__raw_writel((v), (t)->etm_regs[(id)] + (x)))
+#define etm_readl(t, id, x) (__raw_readl((t)->etm_regs[(id)] + (x)))
/* CoreSight Management Registers */
#define CSMR_LOCKACCESS 0xfb0
@@ -113,11 +115,19 @@
#define ETMR_TRACEENCTRL 0x24
#define ETMTE_INCLEXCL BIT(24)
#define ETMR_TRACEENEVT 0x20
+
+#define ETMR_VIEWDATAEVT 0x30
+#define ETMR_VIEWDATACTRL1 0x34
+#define ETMR_VIEWDATACTRL2 0x38
+#define ETMR_VIEWDATACTRL3 0x3c
+#define ETMVDC3_EXCLONLY BIT(16)
+
#define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \
- ETMCTRL_DATA_DO_ADDR | \
ETMCTRL_BRANCH_OUTPUT | \
ETMCTRL_DO_CONTEXTID)
+#define ETMR_TRACEIDR 0x200
+
/* ETM management registers, "ETM Architecture", 3.5.24 */
#define ETMMR_OSLAR 0x300
#define ETMMR_OSLSR 0x304
@@ -140,14 +150,16 @@
#define ETBFF_TRIGIN BIT(8)
#define ETBFF_TRIGEVT BIT(9)
#define ETBFF_TRIGFL BIT(10)
+#define ETBFF_STOPFL BIT(12)
#define etb_writel(t, v, x) \
(__raw_writel((v), (t)->etb_regs + (x)))
#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x)))
-#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
-#define etm_unlock(t) \
- do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+#define etm_lock(t, id) \
+ do { etm_writel((t), (id), 0, CSMR_LOCKACCESS); } while (0)
+#define etm_unlock(t, id) \
+ do { etm_writel((t), (id), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
#define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0)
#define etb_unlock(t) \
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 0691f9d..b665ccb 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -37,10 +37,13 @@ extern void __iomem *gic_cpu_base_addr;
extern struct irq_chip gic_arch_extn;
void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
-void gic_secondary_init(unsigned int);
+void gic_secondary_init_base(unsigned int, void __iomem *, void __iomem *);
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
void gic_enable_ppi(unsigned int);
+
+#define gic_secondary_init(n) gic_secondary_init_base((n), NULL, NULL)
+
#endif
#endif
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
index 575fa81..2f2753f 100644
--- a/arch/arm/include/asm/hardware/pl330.h
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -165,6 +165,7 @@ struct pl330_req {
struct pl330_reqcfg *cfg;
/* Pointer to first xfer in the request. */
struct pl330_xfer *x;
+ unsigned int infiniteloop;
};
/*
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index c1062c3..c93a22a 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -4,22 +4,26 @@
/*
* HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
*/
-#define HWCAP_SWP 1
-#define HWCAP_HALF 2
-#define HWCAP_THUMB 4
-#define HWCAP_26BIT 8 /* Play it safe */
-#define HWCAP_FAST_MULT 16
-#define HWCAP_FPA 32
-#define HWCAP_VFP 64
-#define HWCAP_EDSP 128
-#define HWCAP_JAVA 256
-#define HWCAP_IWMMXT 512
-#define HWCAP_CRUNCH 1024
-#define HWCAP_THUMBEE 2048
-#define HWCAP_NEON 4096
-#define HWCAP_VFPv3 8192
-#define HWCAP_VFPv3D16 16384
-#define HWCAP_TLS 32768
+#define HWCAP_SWP (1 << 0)
+#define HWCAP_HALF (1 << 1)
+#define HWCAP_THUMB (1 << 2)
+#define HWCAP_26BIT (1 << 3) /* Play it safe */
+#define HWCAP_FAST_MULT (1 << 4)
+#define HWCAP_FPA (1 << 5)
+#define HWCAP_VFP (1 << 6)
+#define HWCAP_EDSP (1 << 7)
+#define HWCAP_JAVA (1 << 8)
+#define HWCAP_IWMMXT (1 << 9)
+#define HWCAP_CRUNCH (1 << 10)
+#define HWCAP_THUMBEE (1 << 11)
+#define HWCAP_NEON (1 << 12)
+#define HWCAP_VFPv3 (1 << 13)
+#define HWCAP_VFPv3D16 (1 << 14)
+#define HWCAP_TLS (1 << 15)
+#define HWCAP_VFPv4 (1 << 16)
+#define HWCAP_IDIVA (1 << 17)
+#define HWCAP_IDIVT (1 << 18)
+#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
/*
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 2721a58..28810c6 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -25,6 +25,9 @@ extern void migrate_irqs(void);
extern void asm_do_IRQ(unsigned int, struct pt_regs *);
void init_IRQ(void);
+void arch_trigger_all_cpu_backtrace(void);
+#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
+
#endif
#endif
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
new file mode 100644
index 0000000..bca864a
--- /dev/null
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/include/asm/mach/mmc.h
+ */
+#ifndef ASMARM_MACH_MMC_H
+#define ASMARM_MACH_MMC_H
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+struct embedded_sdio_data {
+ struct sdio_cis cis;
+ struct sdio_cccr cccr;
+ struct sdio_embedded_func *funcs;
+ int num_funcs;
+};
+
+struct mmc_platform_data {
+ unsigned int ocr_mask; /* available voltages */
+ int built_in; /* built-in device flag */
+ int card_present; /* card detect state */
+ u32 (*translate_vdd)(struct device *, unsigned int);
+ unsigned int (*status)(struct device *);
+ struct embedded_sdio_data *embedded_sdio;
+ int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
+};
+
+#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index af44a8f..2849f0b 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -246,6 +246,7 @@ static inline void *phys_to_virt(phys_addr_t x)
*/
#define __pa(x) __virt_to_phys((unsigned long)(x))
#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
+#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
/*
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index d838743..5adffd6 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -29,6 +29,7 @@ struct outer_cache_fns {
void (*flush_range)(unsigned long, unsigned long);
void (*flush_all)(void);
void (*inv_all)(void);
+ void (*clean_all)(void);
void (*disable)(void);
#ifdef CONFIG_OUTER_CACHE_SYNC
void (*sync)(void);
@@ -68,6 +69,12 @@ static inline void outer_inv_all(void)
outer_cache.inv_all();
}
+static inline void outer_clean_all(void)
+{
+ if (outer_cache.clean_all)
+ outer_cache.clean_all();
+}
+
static inline void outer_disable(void)
{
if (outer_cache.disable)
@@ -84,6 +91,7 @@ static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
{ }
static inline void outer_flush_all(void) { }
static inline void outer_inv_all(void) { }
+static inline void outer_clean_all(void) { }
static inline void outer_disable(void) { }
#endif
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index c4aa4e8..0f8e382 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -24,6 +24,8 @@ enum arm_perf_pmu_ids {
ARM_PERF_PMU_ID_V6MP,
ARM_PERF_PMU_ID_CA8,
ARM_PERF_PMU_ID_CA9,
+ ARM_PERF_PMU_ID_CA5,
+ ARM_PERF_PMU_ID_CA15,
ARM_NUM_PMU_IDS,
};
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
index 2b8c516..adbd5af 100644
--- a/arch/arm/include/asm/sections.h
+++ b/arch/arm/include/asm/sections.h
@@ -1 +1,9 @@
+#ifndef __ASM_ARM_SECTIONS_H
+#define __ASM_ARM_SECTIONS_H
+
#include <asm-generic/sections.h>
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+#endif /* __ASM_ARM_SECTIONS_H */
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index ee2ad8a..4b0294d 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -192,7 +192,9 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
/*
* Memory map description
*/
+#ifndef NR_BANKS
#define NR_BANKS 8
+#endif
struct membank {
phys_addr_t start;
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index e42d96a..74f288f 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -93,4 +93,6 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
*/
extern void show_local_irqs(struct seq_file *, int);
+extern void smp_send_all_cpu_backtrace(void);
+
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
index 265f908..0504364 100644
--- a/arch/arm/include/asm/tlb.h
+++ b/arch/arm/include/asm/tlb.h
@@ -198,7 +198,15 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long addr)
{
pgtable_page_dtor(pte);
- tlb_add_flush(tlb, addr);
+
+ /*
+ * With the classic ARM MMU, a pte page has two corresponding pmd
+ * entries, each covering 1MB.
+ */
+ addr &= PMD_MASK;
+ tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);
+ tlb_add_flush(tlb, addr + SZ_1M);
+
tlb_remove_page(tlb, pte);
}
diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/arm/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a5b31af..6dccbbf 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
+obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate_asm.o
obj-$(CONFIG_OF) += devtree.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 90c62cd..2cd0076 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -496,7 +496,7 @@ __und_usr:
blo __und_usr_unknown
3: ldrht r0, [r4]
add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
- orr r0, r0, r5, lsl #16
+ orr r0, r0, r5, lsl #16
#else
b __und_usr_unknown
#endif
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 1bec8b5..496b8b8 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/sysrq.h>
#include <linux/device.h>
#include <linux/clk.h>
@@ -36,26 +37,36 @@ MODULE_AUTHOR("Alexander Shishkin");
struct tracectx {
unsigned int etb_bufsz;
void __iomem *etb_regs;
- void __iomem *etm_regs;
+ void __iomem **etm_regs;
+ int etm_regs_count;
unsigned long flags;
int ncmppairs;
int etm_portsz;
+ u32 etb_fc;
+ unsigned long range_start;
+ unsigned long range_end;
+ unsigned long data_range_start;
+ unsigned long data_range_end;
+ bool dump_initial_etb;
struct device *dev;
struct clk *emu_clk;
struct mutex mutex;
};
-static struct tracectx tracer;
+static struct tracectx tracer = {
+ .range_start = (unsigned long)_stext,
+ .range_end = (unsigned long)_etext,
+};
static inline bool trace_isrunning(struct tracectx *t)
{
return !!(t->flags & TRACER_RUNNING);
}
-static int etm_setup_address_range(struct tracectx *t, int n,
+static int etm_setup_address_range(struct tracectx *t, int id, int n,
unsigned long start, unsigned long end, int exclude, int data)
{
- u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
+ u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
ETMAAT_NOVALCMP;
if (n < 1 || n > t->ncmppairs)
@@ -71,95 +82,155 @@ static int etm_setup_address_range(struct tracectx *t, int n,
flags |= ETMAAT_IEXEC;
/* first comparator for the range */
- etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
- etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+ etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2));
+ etm_writel(t, id, start, ETMR_COMP_VAL(n * 2));
/* second comparator is right next to it */
- etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
- etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
-
- flags = exclude ? ETMTE_INCLEXCL : 0;
- etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+ etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
+ etm_writel(t, id, end, ETMR_COMP_VAL(n * 2 + 1));
+
+ if (data) {
+ flags = exclude ? ETMVDC3_EXCLONLY : 0;
+ if (exclude)
+ n += 8;
+ etm_writel(t, id, flags | BIT(n), ETMR_VIEWDATACTRL3);
+ } else {
+ flags = exclude ? ETMTE_INCLEXCL : 0;
+ etm_writel(t, id, flags | (1 << n), ETMR_TRACEENCTRL);
+ }
return 0;
}
-static int trace_start(struct tracectx *t)
+static int trace_start_etm(struct tracectx *t, int id)
{
u32 v;
unsigned long timeout = TRACER_TIMEOUT;
- etb_unlock(t);
-
- etb_writel(t, 0, ETBR_FORMATTERCTRL);
- etb_writel(t, 1, ETBR_CTRL);
-
- etb_lock(t);
-
- /* configure etm */
v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
if (t->flags & TRACER_CYCLE_ACC)
v |= ETMCTRL_CYCLEACCURATE;
- etm_unlock(t);
+ if (t->flags & TRACER_TRACE_DATA)
+ v |= ETMCTRL_DATA_DO_ADDR;
+
+ etm_unlock(t, id);
- etm_writel(t, v, ETMR_CTRL);
+ etm_writel(t, id, v, ETMR_CTRL);
- while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+ while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
;
if (!timeout) {
dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
- etm_lock(t);
+ etm_lock(t, id);
return -EFAULT;
}
- etm_setup_address_range(t, 1, (unsigned long)_stext,
- (unsigned long)_etext, 0, 0);
- etm_writel(t, 0, ETMR_TRACEENCTRL2);
- etm_writel(t, 0, ETMR_TRACESSCTRL);
- etm_writel(t, 0x6f, ETMR_TRACEENEVT);
+ if (t->range_start || t->range_end)
+ etm_setup_address_range(t, id, 1,
+ t->range_start, t->range_end, 0, 0);
+ else
+ etm_writel(t, id, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
+
+ etm_writel(t, id, 0, ETMR_TRACEENCTRL2);
+ etm_writel(t, id, 0, ETMR_TRACESSCTRL);
+ etm_writel(t, id, 0x6f, ETMR_TRACEENEVT);
+
+ etm_writel(t, id, 0, ETMR_VIEWDATACTRL1);
+ etm_writel(t, id, 0, ETMR_VIEWDATACTRL2);
+
+ if (t->data_range_start || t->data_range_end)
+ etm_setup_address_range(t, id, 2, t->data_range_start,
+ t->data_range_end, 0, 1);
+ else
+ etm_writel(t, id, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
+
+ etm_writel(t, id, 0x6f, ETMR_VIEWDATAEVT);
v &= ~ETMCTRL_PROGRAM;
v |= ETMCTRL_PORTSEL;
- etm_writel(t, v, ETMR_CTRL);
+ etm_writel(t, id, v, ETMR_CTRL);
timeout = TRACER_TIMEOUT;
- while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
+ while (etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
;
if (!timeout) {
dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
- etm_lock(t);
+ etm_lock(t, id);
return -EFAULT;
}
- etm_lock(t);
+ etm_lock(t, id);
+ return 0;
+}
+
+static int trace_start(struct tracectx *t)
+{
+ int ret;
+ int id;
+ u32 etb_fc = t->etb_fc;
+
+ etb_unlock(t);
+
+ t->dump_initial_etb = false;
+ etb_writel(t, 0, ETBR_WRITEADDR);
+ etb_writel(t, etb_fc, ETBR_FORMATTERCTRL);
+ etb_writel(t, 1, ETBR_CTRL);
+
+ etb_lock(t);
+
+ /* configure etm(s) */
+ for (id = 0; id < t->etm_regs_count; id++) {
+ ret = trace_start_etm(t, id);
+ if (ret)
+ return ret;
+ }
t->flags |= TRACER_RUNNING;
return 0;
}
-static int trace_stop(struct tracectx *t)
+static int trace_stop_etm(struct tracectx *t, int id)
{
unsigned long timeout = TRACER_TIMEOUT;
- etm_unlock(t);
+ etm_unlock(t, id);
- etm_writel(t, 0x440, ETMR_CTRL);
- while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+ etm_writel(t, id, 0x441, ETMR_CTRL);
+ while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
;
if (!timeout) {
dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
- etm_lock(t);
+ etm_lock(t, id);
return -EFAULT;
}
- etm_lock(t);
+ etm_lock(t, id);
+ return 0;
+}
+
+static int trace_stop(struct tracectx *t)
+{
+ int id;
+ int ret;
+ unsigned long timeout = TRACER_TIMEOUT;
+ u32 etb_fc = t->etb_fc;
+
+ for (id = 0; id < t->etm_regs_count; id++) {
+ ret = trace_stop_etm(t, id);
+ if (ret)
+ return ret;
+ }
etb_unlock(t);
- etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
+ if (etb_fc) {
+ etb_fc |= ETBFF_STOPFL;
+ etb_writel(t, t->etb_fc, ETBR_FORMATTERCTRL);
+ }
+ etb_writel(t, etb_fc | ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
timeout = TRACER_TIMEOUT;
while (etb_readl(t, ETBR_FORMATTERCTRL) &
@@ -184,24 +255,15 @@ static int trace_stop(struct tracectx *t)
static int etb_getdatalen(struct tracectx *t)
{
u32 v;
- int rp, wp;
+ int wp;
v = etb_readl(t, ETBR_STATUS);
if (v & 1)
return t->etb_bufsz;
- rp = etb_readl(t, ETBR_READADDR);
wp = etb_readl(t, ETBR_WRITEADDR);
-
- if (rp > wp) {
- etb_writel(t, 0, ETBR_READADDR);
- etb_writel(t, 0, ETBR_WRITEADDR);
-
- return 0;
- }
-
- return wp - rp;
+ return wp;
}
/* sysrq+v will always stop the running trace and leave it at that */
@@ -234,21 +296,18 @@ static void etm_dump(void)
printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
printk(KERN_INFO "\n--- ETB buffer end ---\n");
- /* deassert the overflow bit */
- etb_writel(t, 1, ETBR_CTRL);
- etb_writel(t, 0, ETBR_CTRL);
-
- etb_writel(t, 0, ETBR_TRIGGERCOUNT);
- etb_writel(t, 0, ETBR_READADDR);
- etb_writel(t, 0, ETBR_WRITEADDR);
-
etb_lock(t);
}
static void sysrq_etm_dump(int key)
{
+ if (!mutex_trylock(&tracer.mutex)) {
+ printk(KERN_INFO "Tracing hardware busy\n");
+ return;
+ }
dev_dbg(tracer.dev, "Dumping ETB buffer\n");
etm_dump();
+ mutex_unlock(&tracer.mutex);
}
static struct sysrq_key_op sysrq_etm_op = {
@@ -275,6 +334,10 @@ static ssize_t etb_read(struct file *file, char __user *data,
struct tracectx *t = file->private_data;
u32 first = 0;
u32 *buf;
+ int wpos;
+ int skip;
+ long wlength;
+ loff_t pos = *ppos;
mutex_lock(&t->mutex);
@@ -286,31 +349,39 @@ static ssize_t etb_read(struct file *file, char __user *data,
etb_unlock(t);
total = etb_getdatalen(t);
+ if (total == 0 && t->dump_initial_etb)
+ total = t->etb_bufsz;
if (total == t->etb_bufsz)
first = etb_readl(t, ETBR_WRITEADDR);
+ if (pos > total * 4) {
+ skip = 0;
+ wpos = total;
+ } else {
+ skip = (int)pos % 4;
+ wpos = (int)pos / 4;
+ }
+ total -= wpos;
+ first = (first + wpos) % t->etb_bufsz;
+
etb_writel(t, first, ETBR_READADDR);
- length = min(total * 4, (int)len);
- buf = vmalloc(length);
+ wlength = min(total, DIV_ROUND_UP(skip + (int)len, 4));
+ length = min(total * 4 - skip, (int)len);
+ buf = vmalloc(wlength * 4);
- dev_dbg(t->dev, "ETB buffer length: %d\n", total);
+ dev_dbg(t->dev, "ETB read %ld bytes to %lld from %ld words at %d\n",
+ length, pos, wlength, first);
+ dev_dbg(t->dev, "ETB buffer length: %d\n", total + wpos);
dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
- for (i = 0; i < length / 4; i++)
+ for (i = 0; i < wlength; i++)
buf[i] = etb_readl(t, ETBR_READMEM);
- /* the only way to deassert overflow bit in ETB status is this */
- etb_writel(t, 1, ETBR_CTRL);
- etb_writel(t, 0, ETBR_CTRL);
-
- etb_writel(t, 0, ETBR_WRITEADDR);
- etb_writel(t, 0, ETBR_READADDR);
- etb_writel(t, 0, ETBR_TRIGGERCOUNT);
-
etb_lock(t);
- length -= copy_to_user(data, buf, length);
+ length -= copy_to_user(data, (u8 *)buf + skip, length);
vfree(buf);
+ *ppos = pos + length;
out:
mutex_unlock(&t->mutex);
@@ -347,28 +418,17 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
if (ret)
goto out;
+ mutex_lock(&t->mutex);
t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
if (!t->etb_regs) {
ret = -ENOMEM;
goto out_release;
}
+ t->dev = &dev->dev;
+ t->dump_initial_etb = true;
amba_set_drvdata(dev, t);
- etb_miscdev.parent = &dev->dev;
-
- ret = misc_register(&etb_miscdev);
- if (ret)
- goto out_unmap;
-
- t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
- if (IS_ERR(t->emu_clk)) {
- dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
- return -EFAULT;
- }
-
- clk_enable(t->emu_clk);
-
etb_unlock(t);
t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
@@ -377,6 +437,20 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
etb_writel(t, 0, ETBR_CTRL);
etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
etb_lock(t);
+ mutex_unlock(&t->mutex);
+
+ etb_miscdev.parent = &dev->dev;
+
+ ret = misc_register(&etb_miscdev);
+ if (ret)
+ goto out_unmap;
+
+ /* Get optional clock. Currently used to select clock source on omap3 */
+ t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
+ if (IS_ERR(t->emu_clk))
+ dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
+ else
+ clk_enable(t->emu_clk);
dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
@@ -384,10 +458,13 @@ out:
return ret;
out_unmap:
+ mutex_lock(&t->mutex);
amba_set_drvdata(dev, NULL);
iounmap(t->etb_regs);
+ t->etb_regs = NULL;
out_release:
+ mutex_unlock(&t->mutex);
amba_release_regions(dev);
return ret;
@@ -402,8 +479,10 @@ static int etb_remove(struct amba_device *dev)
iounmap(t->etb_regs);
t->etb_regs = NULL;
- clk_disable(t->emu_clk);
- clk_put(t->emu_clk);
+ if (!IS_ERR(t->emu_clk)) {
+ clk_disable(t->emu_clk);
+ clk_put(t->emu_clk);
+ }
amba_release_regions(dev);
@@ -447,7 +526,10 @@ static ssize_t trace_running_store(struct kobject *kobj,
return -EINVAL;
mutex_lock(&tracer.mutex);
- ret = value ? trace_start(&tracer) : trace_stop(&tracer);
+ if (!tracer.etb_regs)
+ ret = -ENODEV;
+ else
+ ret = value ? trace_start(&tracer) : trace_stop(&tracer);
mutex_unlock(&tracer.mutex);
return ret ? : n;
@@ -462,36 +544,50 @@ static ssize_t trace_info_show(struct kobject *kobj,
{
u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
int datalen;
+ int id;
+ int ret;
- etb_unlock(&tracer);
- datalen = etb_getdatalen(&tracer);
- etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
- etb_ra = etb_readl(&tracer, ETBR_READADDR);
- etb_st = etb_readl(&tracer, ETBR_STATUS);
- etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
- etb_lock(&tracer);
-
- etm_unlock(&tracer);
- etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
- etm_st = etm_readl(&tracer, ETMR_STATUS);
- etm_lock(&tracer);
+ mutex_lock(&tracer.mutex);
+ if (tracer.etb_regs) {
+ etb_unlock(&tracer);
+ datalen = etb_getdatalen(&tracer);
+ etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
+ etb_ra = etb_readl(&tracer, ETBR_READADDR);
+ etb_st = etb_readl(&tracer, ETBR_STATUS);
+ etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
+ etb_lock(&tracer);
+ } else {
+ etb_wa = etb_ra = etb_st = etb_fc = ~0;
+ datalen = -1;
+ }
- return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+ ret = sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
"ETBR_WRITEADDR:\t%08x\n"
"ETBR_READADDR:\t%08x\n"
"ETBR_STATUS:\t%08x\n"
- "ETBR_FORMATTERCTRL:\t%08x\n"
- "ETMR_CTRL:\t%08x\n"
- "ETMR_STATUS:\t%08x\n",
+ "ETBR_FORMATTERCTRL:\t%08x\n",
datalen,
tracer.ncmppairs,
etb_wa,
etb_ra,
etb_st,
- etb_fc,
+ etb_fc
+ );
+
+ for (id = 0; id < tracer.etm_regs_count; id++) {
+ etm_unlock(&tracer, id);
+ etm_ctrl = etm_readl(&tracer, id, ETMR_CTRL);
+ etm_st = etm_readl(&tracer, id, ETMR_STATUS);
+ etm_lock(&tracer, id);
+ ret += sprintf(buf + ret, "ETMR_CTRL:\t%08x\n"
+ "ETMR_STATUS:\t%08x\n",
etm_ctrl,
etm_st
);
+ }
+ mutex_unlock(&tracer.mutex);
+
+ return ret;
}
static struct kobj_attribute trace_info_attr =
@@ -530,42 +626,121 @@ static ssize_t trace_mode_store(struct kobject *kobj,
static struct kobj_attribute trace_mode_attr =
__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+static ssize_t trace_range_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%08lx %08lx\n",
+ tracer.range_start, tracer.range_end);
+}
+
+static ssize_t trace_range_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long range_start, range_end;
+
+ if (sscanf(buf, "%lx %lx", &range_start, &range_end) != 2)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ tracer.range_start = range_start;
+ tracer.range_end = range_end;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+
+static struct kobj_attribute trace_range_attr =
+ __ATTR(trace_range, 0644, trace_range_show, trace_range_store);
+
+static ssize_t trace_data_range_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ unsigned long range_start;
+ u64 range_end;
+ mutex_lock(&tracer.mutex);
+ range_start = tracer.data_range_start;
+ range_end = tracer.data_range_end;
+ if (!range_end && (tracer.flags & TRACER_TRACE_DATA))
+ range_end = 0x100000000ULL;
+ mutex_unlock(&tracer.mutex);
+ return sprintf(buf, "%08lx %08llx\n", range_start, range_end);
+}
+
+static ssize_t trace_data_range_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned long range_start;
+ u64 range_end;
+
+ if (sscanf(buf, "%lx %llx", &range_start, &range_end) != 2)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ tracer.data_range_start = range_start;
+ tracer.data_range_end = (unsigned long)range_end;
+ if (range_end)
+ tracer.flags |= TRACER_TRACE_DATA;
+ else
+ tracer.flags &= ~TRACER_TRACE_DATA;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+
+static struct kobj_attribute trace_data_range_attr =
+ __ATTR(trace_data_range, 0644,
+ trace_data_range_show, trace_data_range_store);
+
static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
int ret = 0;
+ void __iomem **new_regs;
+ int new_count;
- if (t->etm_regs) {
- dev_dbg(&dev->dev, "ETM already initialized\n");
- ret = -EBUSY;
+ mutex_lock(&t->mutex);
+ new_count = t->etm_regs_count + 1;
+ new_regs = krealloc(t->etm_regs,
+ sizeof(t->etm_regs[0]) * new_count, GFP_KERNEL);
+
+ if (!new_regs) {
+ dev_dbg(&dev->dev, "Failed to allocate ETM register array\n");
+ ret = -ENOMEM;
goto out;
}
+ t->etm_regs = new_regs;
ret = amba_request_regions(dev, NULL);
if (ret)
goto out;
- t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
- if (!t->etm_regs) {
+ t->etm_regs[t->etm_regs_count] =
+ ioremap_nocache(dev->res.start, resource_size(&dev->res));
+ if (!t->etm_regs[t->etm_regs_count]) {
ret = -ENOMEM;
goto out_release;
}
- amba_set_drvdata(dev, t);
+ amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]);
- mutex_init(&t->mutex);
- t->dev = &dev->dev;
- t->flags = TRACER_CYCLE_ACC;
+ t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA;
t->etm_portsz = 1;
- etm_unlock(t);
- (void)etm_readl(t, ETMMR_PDSR);
+ etm_unlock(t, t->etm_regs_count);
+ (void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
/* dummy first read */
- (void)etm_readl(&tracer, ETMMR_OSSRR);
+ (void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
- t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
- etm_writel(t, 0x440, ETMR_CTRL);
- etm_lock(t);
+ t->ncmppairs = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE) & 0xf;
+ etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
+ etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
+ etm_lock(t, t->etm_regs_count);
ret = sysfs_create_file(&dev->dev.kobj,
&trace_running_attr.attr);
@@ -581,36 +756,68 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
if (ret)
dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
- dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
+ ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
+
+ ret = sysfs_create_file(&dev->dev.kobj, &trace_data_range_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_data_range in sysfs\n");
+
+ dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n");
+
+ /* Enable formatter if there are multiple trace sources */
+ if (new_count > 1)
+ t->etb_fc = ETBFF_ENFCONT | ETBFF_ENFTC;
+
+ t->etm_regs_count = new_count;
out:
+ mutex_unlock(&t->mutex);
return ret;
out_unmap:
amba_set_drvdata(dev, NULL);
- iounmap(t->etm_regs);
+ iounmap(t->etm_regs[t->etm_regs_count]);
out_release:
amba_release_regions(dev);
+ mutex_unlock(&t->mutex);
return ret;
}
static int etm_remove(struct amba_device *dev)
{
- struct tracectx *t = amba_get_drvdata(dev);
+ int i;
+ struct tracectx *t = &tracer;
+ void __iomem *etm_regs = amba_get_drvdata(dev);
+
+ sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
+ sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
+ sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+ sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
+ sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr);
amba_set_drvdata(dev, NULL);
- iounmap(t->etm_regs);
- t->etm_regs = NULL;
+ mutex_lock(&t->mutex);
+ for (i = 0; i < t->etm_regs_count; i++)
+ if (t->etm_regs[i] == etm_regs)
+ break;
+ for (; i < t->etm_regs_count - 1; i++)
+ t->etm_regs[i] = t->etm_regs[i + 1];
+ t->etm_regs_count--;
+ if (!t->etm_regs_count) {
+ kfree(t->etm_regs);
+ t->etm_regs = NULL;
+ }
+ mutex_unlock(&t->mutex);
+ iounmap(etm_regs);
amba_release_regions(dev);
- sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
- sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
- sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
-
return 0;
}
@@ -619,6 +826,10 @@ static struct amba_id etm_ids[] = {
.id = 0x0003b921,
.mask = 0x0007ffff,
},
+ {
+ .id = 0x0003b950,
+ .mask = 0x0007ffff,
+ },
{ 0, 0 },
};
@@ -636,6 +847,8 @@ static int __init etm_init(void)
{
int retval;
+ mutex_init(&tracer.mutex);
+
retval = amba_driver_register(&etb_driver);
if (retval) {
printk(KERN_ERR "Failed to register etb\n");
diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c
new file mode 100644
index 0000000..354cefc
--- /dev/null
+++ b/arch/arm/kernel/hibernate.c
@@ -0,0 +1,470 @@
+/*
+ * Hibernation support specific for ARM
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/sections.h>
+
+/*
+ * Image of the saved processor state
+ *
+ * coprocessor 15 registers(RW)
+ */
+struct saved_context_cortex_a8 {
+ /* CR0 */
+ u32 cssr; /* Cache Size Selection */
+ /* CR1 */
+ u32 cr; /* Control */
+ u32 cacr; /* Coprocessor Access Control */
+ /* CR2 */
+ u32 ttb_0r; /* Translation Table Base 0 */
+ u32 ttb_1r; /* Translation Table Base 1 */
+ u32 ttbcr; /* Translation Talbe Base Control */
+ /* CR3 */
+ u32 dacr; /* Domain Access Control */
+ /* CR5 */
+ u32 d_fsr; /* Data Fault Status */
+ u32 i_fsr; /* Instruction Fault Status */
+ u32 d_afsr; /* Data Auxilirary Fault Status */ ;
+ u32 i_afsr; /* Instruction Auxilirary Fault Status */;
+ /* CR6 */
+ u32 d_far; /* Data Fault Address */
+ u32 i_far; /* Instruction Fault Address */
+ /* CR7 */
+ u32 par; /* Physical Address */
+ /* CR9 */ /* FIXME: Are they necessary? */
+ u32 pmcontrolr; /* Performance Monitor Control */
+ u32 cesr; /* Count Enable Set */
+ u32 cecr; /* Count Enable Clear */
+ u32 ofsr; /* Overflow Flag Status */
+ u32 sir; /* Software Increment */
+ u32 pcsr; /* Performance Counter Selection */
+ u32 ccr; /* Cycle Count */
+ u32 esr; /* Event Selection */
+ u32 pmcountr; /* Performance Monitor Count */
+ u32 uer; /* User Enable */
+ u32 iesr; /* Interrupt Enable Set */
+ u32 iecr; /* Interrupt Enable Clear */
+ u32 l2clr; /* L2 Cache Lockdown */
+ /* CR10 */
+ u32 d_tlblr; /* Data TLB Lockdown Register */
+ u32 i_tlblr; /* Instruction TLB Lockdown Register */
+ u32 prrr; /* Primary Region Remap Register */
+ u32 nrrr; /* Normal Memory Remap Register */
+ /* CR11 */
+ u32 pleuar; /* PLE User Accessibility */
+ u32 plecnr; /* PLE Channel Number */
+ u32 plecr; /* PLE Control */
+ u32 pleisar; /* PLE Internal Start Address */
+ u32 pleiear; /* PLE Internal End Address */
+ u32 plecidr; /* PLE Context ID */
+ /* CR12 */
+ u32 snsvbar; /* Secure or Nonsecure Vector Base Address */
+ /* CR13 */
+ u32 fcse; /* FCSE PID */
+ u32 cid; /* Context ID */
+ u32 urwtpid; /* User read/write Thread and Process ID */
+ u32 urotpid; /* User read-only Thread and Process ID */
+ u32 potpid; /* Privileged only Thread and Process ID */
+} __packed;
+
+struct saved_context_cortex_a9 {
+ /* CR0 */
+ u32 cssr; /* Cache Size Selection */
+ /* CR1 */
+ u32 cr;
+ u32 actlr;
+ u32 cacr;
+ u32 sder;
+ u32 vcr;
+ /* CR2 */
+ u32 ttb_0r; /* Translation Table Base 0 */
+ u32 ttb_1r; /* Translation Table Base 1 */
+ u32 ttbcr; /* Translation Talbe Base Control */
+ /* CR3 */
+ u32 dacr; /* Domain Access Control */
+ /* CR5 */
+ u32 d_fsr; /* Data Fault Status */
+ u32 i_fsr; /* Instruction Fault Status */
+ u32 d_afsr; /* Data Auxilirary Fault Status */ ;
+ u32 i_afsr; /* Instruction Auxilirary Fault Status */;
+ /* CR6 */
+ u32 d_far; /* Data Fault Address */
+ u32 i_far; /* Instruction Fault Address */
+ /* CR7 */
+ u32 par; /* Physical Address */
+ /* CR9 */ /* FIXME: Are they necessary? */
+ u32 pmcontrolr; /* Performance Monitor Control */
+ u32 cesr; /* Count Enable Set */
+ u32 cecr; /* Count Enable Clear */
+ u32 ofsr; /* Overflow Flag Status */
+ u32 pcsr; /* Performance Counter Selection */
+ u32 ccr; /* Cycle Count */
+ u32 esr; /* Event Selection */
+ u32 pmcountr; /* Performance Monitor Count */
+ u32 uer; /* User Enable */
+ u32 iesr; /* Interrupt Enable Set */
+ u32 iecr; /* Interrupt Enable Clear */
+ /* CR10 */
+ u32 d_tlblr; /* Data TLB Lockdown Register */
+ u32 prrr; /* Primary Region Remap Register */
+ u32 nrrr; /* Normal Memory Remap Register */
+ /* CR11 */
+ /* CR12 */
+ u32 vbar;
+ u32 mvbar;
+ u32 vir;
+ /* CR13 */
+ u32 fcse; /* FCSE PID */
+ u32 cid; /* Context ID */
+ u32 urwtpid; /* User read/write Thread and Process ID */
+ u32 urotpid; /* User read-only Thread and Process ID */
+ u32 potpid; /* Privileged only Thread and Process ID */
+ /* CR15 */
+ u32 mtlbar;
+} __packed;
+
+union saved_context {
+ struct saved_context_cortex_a8 cortex_a8;
+ struct saved_context_cortex_a9 cortex_a9;
+};
+
+/* Used in hibernate_asm.S */
+#define USER_CONTEXT_SIZE (15 * sizeof(u32))
+unsigned long saved_context_r0[USER_CONTEXT_SIZE];
+unsigned long saved_cpsr;
+unsigned long saved_context_r13_svc;
+unsigned long saved_context_r14_svc;
+unsigned long saved_spsr_svc;
+
+static union saved_context saved_context;
+
+/*
+ * pfn_is_nosave - check if given pfn is in the 'nosave' section
+ */
+int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin)
+ >> PAGE_SHIFT;
+ unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end))
+ >> PAGE_SHIFT;
+
+ return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
+
+#define PART_NUM_CORTEX_A8 (0xC08)
+#define PART_NUM_CORTEX_A9 (0xC09)
+
+static inline u32 arm_primary_part_number(void)
+{
+ u32 id;
+
+ asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r"(id));
+
+ /* Is this ARM? */
+ if ((id & 0xff000000) != 0x41000000)
+ return UINT_MAX;
+
+ id >>= 4;
+ id &= 0xfff;
+ return id;
+}
+
+static inline void __save_processor_state_a8(
+ struct saved_context_cortex_a8 *ctxt)
+{
+ /* CR0 */
+ asm volatile ("mrc p15, 2, %0, c0, c0, 0" : "=r"(ctxt->cssr));
+ /* CR1 */
+ asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r"(ctxt->cr));
+ asm volatile ("mrc p15, 0, %0, c1, c0, 2" : "=r"(ctxt->cacr));
+ /* CR2 */
+ asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ctxt->ttb_0r));
+ asm volatile ("mrc p15, 0, %0, c2, c0, 1" : "=r"(ctxt->ttb_1r));
+ asm volatile ("mrc p15, 0, %0, c2, c0, 2" : "=r"(ctxt->ttbcr));
+ /* CR3 */
+ asm volatile ("mrc p15, 0, %0, c3, c0, 0" : "=r"(ctxt->dacr));
+ /* CR5 */
+ asm volatile ("mrc p15, 0, %0, c5, c0, 0" : "=r"(ctxt->d_fsr));
+ asm volatile ("mrc p15, 0, %0, c5, c0, 1" : "=r"(ctxt->i_fsr));
+ asm volatile ("mrc p15, 0, %0, c5, c1, 0" : "=r"(ctxt->d_afsr));
+ asm volatile ("mrc p15, 0, %0, c5, c1, 1" : "=r"(ctxt->i_afsr));
+ /* CR6 */
+ asm volatile ("mrc p15, 0, %0, c6, c0, 0" : "=r"(ctxt->d_far));
+ asm volatile ("mrc p15, 0, %0, c6, c0, 2" : "=r"(ctxt->i_far));
+ /* CR7 */
+ asm volatile ("mrc p15, 0, %0, c7, c4, 0" : "=r"(ctxt->par));
+ /* CR9 */
+ asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(ctxt->pmcontrolr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 1" : "=r"(ctxt->cesr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 2" : "=r"(ctxt->cecr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 3" : "=r"(ctxt->ofsr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 4" : "=r"(ctxt->sir));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 5" : "=r"(ctxt->pcsr));
+ asm volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(ctxt->ccr));
+ asm volatile ("mrc p15, 0, %0, c9, c13, 1" : "=r"(ctxt->esr));
+ asm volatile ("mrc p15, 0, %0, c9, c13, 2" : "=r"(ctxt->pmcountr));
+ asm volatile ("mrc p15, 0, %0, c9, c14, 0" : "=r"(ctxt->uer));
+ asm volatile ("mrc p15, 0, %0, c9, c14, 1" : "=r"(ctxt->iesr));
+ asm volatile ("mrc p15, 0, %0, c9, c14, 2" : "=r"(ctxt->iecr));
+ asm volatile ("mrc p15, 1, %0, c9, c0, 0" : "=r"(ctxt->l2clr));
+ /* CR10 */
+ asm volatile ("mrc p15, 0, %0, c10, c0, 0" : "=r"(ctxt->d_tlblr));
+ asm volatile ("mrc p15, 0, %0, c10, c0, 1" : "=r"(ctxt->i_tlblr));
+ asm volatile ("mrc p15, 0, %0, c10, c2, 0" : "=r"(ctxt->prrr));
+ asm volatile ("mrc p15, 0, %0, c10, c2, 1" : "=r"(ctxt->nrrr));
+ /* CR11 */
+ asm volatile ("mrc p15, 0, %0, c11, c1, 0" : "=r"(ctxt->pleuar));
+ asm volatile ("mrc p15, 0, %0, c11, c2, 0" : "=r"(ctxt->plecnr));
+ asm volatile ("mrc p15, 0, %0, c11, c4, 0" : "=r"(ctxt->plecr));
+ asm volatile ("mrc p15, 0, %0, c11, c5, 0" : "=r"(ctxt->pleisar));
+ asm volatile ("mrc p15, 0, %0, c11, c7, 0" : "=r"(ctxt->pleiear));
+ asm volatile ("mrc p15, 0, %0, c11, c15, 0" : "=r"(ctxt->plecidr));
+ /* CR12 */
+ asm volatile ("mrc p15, 0, %0, c12, c0, 0" : "=r"(ctxt->snsvbar));
+ /* CR13 */
+ asm volatile ("mrc p15, 0, %0, c13, c0, 0" : "=r"(ctxt->fcse));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 1" : "=r"(ctxt->cid));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 2" : "=r"(ctxt->urwtpid));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 3" : "=r"(ctxt->urotpid));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 4" : "=r"(ctxt->potpid));
+}
+
+static inline void __save_processor_state_a9(
+ struct saved_context_cortex_a9 *ctxt)
+{
+ /* CR0 */
+ asm volatile ("mrc p15, 2, %0, c0, c0, 0" : "=r"(ctxt->cssr));
+ /* CR1 */
+ asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r"(ctxt->cr));
+ asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r"(ctxt->actlr));
+ asm volatile ("mrc p15, 0, %0, c1, c0, 2" : "=r"(ctxt->cacr));
+#ifndef CONFIG_ARM_TRUSTZONE
+ asm volatile ("mrc p15, 0, %0, c1, c1, 1" : "=r"(ctxt->sder));
+ asm volatile ("mrc p15, 0, %0, c1, c1, 3" : "=r"(ctxt->vcr));
+#endif
+ /* CR2 */
+ asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ctxt->ttb_0r));
+ asm volatile ("mrc p15, 0, %0, c2, c0, 1" : "=r"(ctxt->ttb_1r));
+ asm volatile ("mrc p15, 0, %0, c2, c0, 2" : "=r"(ctxt->ttbcr));
+ /* CR3 */
+ asm volatile ("mrc p15, 0, %0, c3, c0, 0" : "=r"(ctxt->dacr));
+ /* CR5 */
+ asm volatile ("mrc p15, 0, %0, c5, c0, 0" : "=r"(ctxt->d_fsr));
+ asm volatile ("mrc p15, 0, %0, c5, c0, 1" : "=r"(ctxt->i_fsr));
+ asm volatile ("mrc p15, 0, %0, c5, c1, 0" : "=r"(ctxt->d_afsr));
+ asm volatile ("mrc p15, 0, %0, c5, c1, 1" : "=r"(ctxt->i_afsr));
+ /* CR6 */
+ asm volatile ("mrc p15, 0, %0, c6, c0, 0" : "=r"(ctxt->d_far));
+ asm volatile ("mrc p15, 0, %0, c6, c0, 2" : "=r"(ctxt->i_far));
+ /* CR7 */
+ asm volatile ("mrc p15, 0, %0, c7, c4, 0" : "=r"(ctxt->par));
+ /* CR9 */
+ asm volatile ("mrc p15, 0, %0, c9, c12, 0" : "=r"(ctxt->pmcontrolr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 1" : "=r"(ctxt->cesr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 2" : "=r"(ctxt->cecr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 3" : "=r"(ctxt->ofsr));
+ asm volatile ("mrc p15, 0, %0, c9, c12, 5" : "=r"(ctxt->pcsr));
+ asm volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(ctxt->ccr));
+ asm volatile ("mrc p15, 0, %0, c9, c13, 1" : "=r"(ctxt->esr));
+ asm volatile ("mrc p15, 0, %0, c9, c13, 2" : "=r"(ctxt->pmcountr));
+ asm volatile ("mrc p15, 0, %0, c9, c14, 0" : "=r"(ctxt->uer));
+ asm volatile ("mrc p15, 0, %0, c9, c14, 1" : "=r"(ctxt->iesr));
+ asm volatile ("mrc p15, 0, %0, c9, c14, 2" : "=r"(ctxt->iecr));
+ /* CR10 */
+ asm volatile ("mrc p15, 0, %0, c10, c0, 0" : "=r"(ctxt->d_tlblr));
+ asm volatile ("mrc p15, 0, %0, c10, c2, 0" : "=r"(ctxt->prrr));
+ asm volatile ("mrc p15, 0, %0, c10, c2, 1" : "=r"(ctxt->nrrr));
+ /* CR11 */
+ /* CR12 */
+ asm volatile ("mrc p15, 0, %0, c12, c0, 0" : "=r"(ctxt->vbar));
+#ifndef CONFIG_ARM_TRUSTZONE
+ asm volatile ("mrc p15, 0, %0, c12, c0, 1" : "=r"(ctxt->mvbar));
+ asm volatile ("mrc p15, 0, %0, c12, c1, 1" : "=r"(ctxt->vir));
+#endif
+ /* CR13 */
+ asm volatile ("mrc p15, 0, %0, c13, c0, 0" : "=r"(ctxt->fcse));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 1" : "=r"(ctxt->cid));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 2" : "=r"(ctxt->urwtpid));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 3" : "=r"(ctxt->urotpid));
+ asm volatile ("mrc p15, 0, %0, c13, c0, 4" : "=r"(ctxt->potpid));
+ /* CR15*/
+#ifndef CONFIG_ARM_TRUSTZONE
+ asm volatile ("mrc p15, 5, %0, c15, c7, 2" : "=r"(ctxt->mtlbar));
+#endif
+}
+
+static inline void __save_processor_state(union saved_context *ctxt)
+{
+ switch (arm_primary_part_number()) {
+ case PART_NUM_CORTEX_A8:
+ __save_processor_state_a8(&ctxt->cortex_a8);
+ break;
+ case PART_NUM_CORTEX_A9:
+ __save_processor_state_a9(&ctxt->cortex_a9);
+ break;
+ default:
+ WARN(true, "Hibernation is not supported for this processor.(%d)",
+ arm_primary_part_number());
+ }
+}
+
+static inline void __restore_processor_state_a8(
+ struct saved_context_cortex_a8 *ctxt)
+{
+ /* CR0 */
+ asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r"(ctxt->cssr));
+ /* CR1 */
+ asm volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r"(ctxt->cr));
+ asm volatile ("mcr p15, 0, %0, c1, c0, 2" : : "r"(ctxt->cacr));
+ /* CR2 */
+ asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ctxt->ttb_0r));
+ asm volatile ("mcr p15, 0, %0, c2, c0, 1" : : "r"(ctxt->ttb_1r));
+ asm volatile ("mcr p15, 0, %0, c2, c0, 2" : : "r"(ctxt->ttbcr));
+ /* CR3 */
+ asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r"(ctxt->dacr));
+ /* CR5 */
+ asm volatile ("mcr p15, 0, %0, c5, c0, 0" : : "r"(ctxt->d_fsr));
+ asm volatile ("mcr p15, 0, %0, c5, c0, 1" : : "r"(ctxt->i_fsr));
+ asm volatile ("mcr p15, 0, %0, c5, c1, 0" : : "r"(ctxt->d_afsr));
+ asm volatile ("mcr p15, 0, %0, c5, c1, 1" : : "r"(ctxt->i_afsr));
+ /* CR6 */
+ asm volatile ("mcr p15, 0, %0, c6, c0, 0" : : "r"(ctxt->d_far));
+ asm volatile ("mcr p15, 0, %0, c6, c0, 2" : : "r"(ctxt->i_far));
+ /* CR7 */
+ asm volatile ("mcr p15, 0, %0, c7, c4, 0" : : "r"(ctxt->par));
+ /* CR9 */
+ asm volatile ("mcr p15, 0, %0, c9, c12, 0" : : "r"(ctxt->pmcontrolr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 1" : : "r"(ctxt->cesr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 2" : : "r"(ctxt->cecr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 3" : : "r"(ctxt->ofsr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 4" : : "r"(ctxt->sir));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 5" : : "r"(ctxt->pcsr));
+ asm volatile ("mcr p15, 0, %0, c9, c13, 0" : : "r"(ctxt->ccr));
+ asm volatile ("mcr p15, 0, %0, c9, c13, 1" : : "r"(ctxt->esr));
+ asm volatile ("mcr p15, 0, %0, c9, c13, 2" : : "r"(ctxt->pmcountr));
+ asm volatile ("mcr p15, 0, %0, c9, c14, 0" : : "r"(ctxt->uer));
+ asm volatile ("mcr p15, 0, %0, c9, c14, 1" : : "r"(ctxt->iesr));
+ asm volatile ("mcr p15, 0, %0, c9, c14, 2" : : "r"(ctxt->iecr));
+ asm volatile ("mcr p15, 1, %0, c9, c0, 0" : : "r"(ctxt->l2clr));
+ /* CR10 */
+ asm volatile ("mcr p15, 0, %0, c10, c0, 0" : : "r"(ctxt->d_tlblr));
+ asm volatile ("mcr p15, 0, %0, c10, c0, 1" : : "r"(ctxt->i_tlblr));
+ asm volatile ("mcr p15, 0, %0, c10, c2, 0" : : "r"(ctxt->prrr));
+ asm volatile ("mcr p15, 0, %0, c10, c2, 1" : : "r"(ctxt->nrrr));
+ /* CR11 */
+ asm volatile ("mcr p15, 0, %0, c11, c1, 0" : : "r"(ctxt->pleuar));
+ asm volatile ("mcr p15, 0, %0, c11, c2, 0" : : "r"(ctxt->plecnr));
+ asm volatile ("mcr p15, 0, %0, c11, c4, 0" : : "r"(ctxt->plecr));
+ asm volatile ("mcr p15, 0, %0, c11, c5, 0" : : "r"(ctxt->pleisar));
+ asm volatile ("mcr p15, 0, %0, c11, c7, 0" : : "r"(ctxt->pleiear));
+ asm volatile ("mcr p15, 0, %0, c11, c15, 0" : : "r"(ctxt->plecidr));
+ /* CR12 */
+ asm volatile ("mcr p15, 0, %0, c12, c0, 0" : : "r"(ctxt->snsvbar));
+ /* CR13 */
+ asm volatile ("mcr p15, 0, %0, c13, c0, 0" : : "r"(ctxt->fcse));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 1" : : "r"(ctxt->cid));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 2" : : "r"(ctxt->urwtpid));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 3" : : "r"(ctxt->urotpid));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 4" : : "r"(ctxt->potpid));
+}
+
+static inline void __restore_processor_state_a9(
+ struct saved_context_cortex_a9 *ctxt)
+{
+ /* CR0 */
+ asm volatile ("mcr p15, 2, %0, c0, c0, 0" : : "r"(ctxt->cssr));
+ /* CR1 */
+ asm volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r"(ctxt->cr));
+ asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r"(ctxt->actlr));
+ asm volatile ("mcr p15, 0, %0, c1, c0, 2" : : "r"(ctxt->cacr));
+#ifndef CONFIG_ARM_TRUSTZONE
+ asm volatile ("mcr p15, 0, %0, c1, c1, 1" : : "r"(ctxt->sder));
+ asm volatile ("mcr p15, 0, %0, c1, c1, 3" : : "r"(ctxt->vcr));
+#endif
+ /* CR2 */
+ asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ctxt->ttb_0r));
+ asm volatile ("mcr p15, 0, %0, c2, c0, 1" : : "r"(ctxt->ttb_1r));
+ asm volatile ("mcr p15, 0, %0, c2, c0, 2" : : "r"(ctxt->ttbcr));
+ /* CR3 */
+ asm volatile ("mcr p15, 0, %0, c3, c0, 0" : : "r"(ctxt->dacr));
+ /* CR5 */
+ asm volatile ("mcr p15, 0, %0, c5, c0, 0" : : "r"(ctxt->d_fsr));
+ asm volatile ("mcr p15, 0, %0, c5, c0, 1" : : "r"(ctxt->i_fsr));
+ asm volatile ("mcr p15, 0, %0, c5, c1, 0" : : "r"(ctxt->d_afsr));
+ asm volatile ("mcr p15, 0, %0, c5, c1, 1" : : "r"(ctxt->i_afsr));
+ /* CR6 */
+ asm volatile ("mcr p15, 0, %0, c6, c0, 0" : : "r"(ctxt->d_far));
+ asm volatile ("mcr p15, 0, %0, c6, c0, 2" : : "r"(ctxt->i_far));
+ /* CR7 */
+ asm volatile ("mcr p15, 0, %0, c7, c4, 0" : : "r"(ctxt->par));
+ /* CR9 */
+ asm volatile ("mcr p15, 0, %0, c9, c12, 0" : : "r"(ctxt->pmcontrolr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 1" : : "r"(ctxt->cesr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 2" : : "r"(ctxt->cecr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 3" : : "r"(ctxt->ofsr));
+ asm volatile ("mcr p15, 0, %0, c9, c12, 5" : : "r"(ctxt->pcsr));
+ asm volatile ("mcr p15, 0, %0, c9, c13, 0" : : "r"(ctxt->ccr));
+ asm volatile ("mcr p15, 0, %0, c9, c13, 1" : : "r"(ctxt->esr));
+ asm volatile ("mcr p15, 0, %0, c9, c13, 2" : : "r"(ctxt->pmcountr));
+ asm volatile ("mcr p15, 0, %0, c9, c14, 0" : : "r"(ctxt->uer));
+ asm volatile ("mcr p15, 0, %0, c9, c14, 1" : : "r"(ctxt->iesr));
+ asm volatile ("mcr p15, 0, %0, c9, c14, 2" : : "r"(ctxt->iecr));
+ /* CR10 */
+ asm volatile ("mcr p15, 0, %0, c10, c0, 0" : : "r"(ctxt->d_tlblr));
+ asm volatile ("mcr p15, 0, %0, c10, c2, 0" : : "r"(ctxt->prrr));
+ asm volatile ("mcr p15, 0, %0, c10, c2, 1" : : "r"(ctxt->nrrr));
+ /* CR11 */
+ /* CR12 */
+ asm volatile ("mcr p15, 0, %0, c12, c0, 0" : : "r"(ctxt->vbar));
+#ifndef CONFIG_ARM_TRUSTZONE
+ asm volatile ("mcr p15, 0, %0, c12, c0, 1" : : "r"(ctxt->mvbar));
+ asm volatile ("mcr p15, 0, %0, c12, c1, 1" : : "r"(ctxt->vir));
+#endif
+ /* CR13 */
+ asm volatile ("mcr p15, 0, %0, c13, c0, 0" : : "r"(ctxt->fcse));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 1" : : "r"(ctxt->cid));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 2" : : "r"(ctxt->urwtpid));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 3" : : "r"(ctxt->urotpid));
+ asm volatile ("mcr p15, 0, %0, c13, c0, 4" : : "r"(ctxt->potpid));
+ /* CR15 */
+#ifndef CONFIG_ARM_TRUSTZONE
+ asm volatile ("mcr p15, 5, %0, c15, c7, 2" : : "r"(ctxt->mtlbar));
+#endif
+}
+
+static inline void __restore_processor_state(union saved_context *ctxt)
+{
+ switch (arm_primary_part_number()) {
+ case PART_NUM_CORTEX_A8:
+ __restore_processor_state_a8(&ctxt->cortex_a8);
+ break;
+ case PART_NUM_CORTEX_A9:
+ __restore_processor_state_a9(&ctxt->cortex_a9);
+ break;
+ default:
+ WARN(true, "Hibernation is not supported for this processor.(%d)",
+ arm_primary_part_number());
+ }
+}
+
+void save_processor_state(void)
+{
+ preempt_disable();
+ __save_processor_state(&saved_context);
+}
+
+void restore_processor_state(void)
+{
+ __restore_processor_state(&saved_context);
+ preempt_enable();
+}
diff --git a/arch/arm/kernel/hibernate_asm.S b/arch/arm/kernel/hibernate_asm.S
new file mode 100644
index 0000000..9538789
--- /dev/null
+++ b/arch/arm/kernel/hibernate_asm.S
@@ -0,0 +1,139 @@
+/*
+ * Hibernation support specific for ARM
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/linkage.h>
+ .text
+ENTRY(swsusp_arch_suspend)
+ /*
+ * Save current program status register
+ */
+ ldr r3, .Lsaved_cpsr
+ mrs r0, cpsr
+ str r0, [r3]
+
+ /*
+ * Change to system(user) mode
+ */
+ mov r1, r0
+ orr r1, r1, #0x1f
+ msr cpsr_c, r1
+
+ /*
+ * Save User context
+ */
+ ldr r3, .Lsaved_context_r0
+ stmia r3, {r0-r14}
+
+ /*
+ * Go back to original SVC mode
+ */
+ msr cpsr_c, r0
+
+ /*
+ * Save SVC context
+ */
+ ldr r3, .Lsaved_context_r13_svc
+ stmia r3, {r13-r14}
+ ldr r3, .Lsaved_spsr_svc
+ mrs r1, spsr
+ str r1, [r3]
+
+ bl swsusp_save
+
+ /*
+ * Restore return address
+ */
+ ldr r3, .Lsaved_context_r14_svc
+ ldr lr, [r3]
+ mov pc, lr
+ENDPROC(swsusp_arch_suspend)
+
+ENTRY(swsusp_arch_resume)
+ /*
+ * Restore_pblist is the starting point for loaded pages
+ */
+ ldr r0, .Lrestore_pblist
+ ldr r6, [r0]
+
+.Lcopy_loop:
+ ldr r4, [r6] /* src IOW present address */
+ ldr r5, [r6, #4] /* dst IOW original address*/
+
+ /* No. of entries in one page, where each entry is 4 bytes */
+ mov r9, #1024
+
+.Lcopy_one_page:
+ /*
+ * This loop could be optimized by using stm and ldm.
+ */
+ ldr r8, [r4], #4
+ str r8, [r5], #4
+ subs r9, r9, #1
+ bne .Lcopy_one_page
+
+ /*
+ * The last field of struct pbe is a pointer to the next pbe structure
+ */
+ ldr r6, [r6, #8]
+ cmp r6, #0
+ bne .Lcopy_loop
+
+ /*
+ * Restore SVC context
+ */
+ ldr r3, .Lsaved_context_r13_svc
+ ldmia r3, {r13-r14}
+ ldr r3, .Lsaved_spsr_svc
+ ldr r1, [r3]
+ msr spsr_cxsf, r1
+
+ mrs r0, cpsr /* Save current mode into r0 */
+
+ /*
+ * Change to system(user) mode
+ */
+ mov r1, r0
+ orr r1, r1, #0x1f
+ msr cpsr_c, r1
+
+ /*
+ * Restore User context
+ */
+ ldr r3, .Lsaved_context_r0
+ ldmia r3, {r0-r14}
+ ldr r3, .Lsaved_cpsr
+ ldr r1, [r3]
+ msr cpsr_cxsf, r1
+
+ msr cpsr_c, r0 /* Restore original mode from r0 */
+
+ /*
+ * Flush TLB (Invalidate unified TLB unlocked entries)
+ */
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0
+
+ /* Set the return value */
+ mov r0, #0
+
+ /* Restore return address */
+ ldr r3, .Lsaved_context_r14_svc
+ ldr lr, [r3]
+ mov pc, lr
+ENDPROC(swsusp_arch_resume)
+ .align 4
+.Lsaved_context_r0: .long saved_context_r0
+.Lsaved_cpsr: .long saved_cpsr
+.Lsaved_context_r13_svc: .long saved_context_r13_svc
+.Lsaved_context_r14_svc: .long saved_context_r14_svc
+.Lsaved_spsr_svc: .long saved_spsr_svc
+.Lrestore_pblist: .long restore_pblist
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
index 0f107dc..136e837 100644
--- a/arch/arm/kernel/leds.c
+++ b/arch/arm/kernel/leds.c
@@ -9,6 +9,8 @@
*/
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
#include <linux/sysdev.h>
#include <linux/syscore_ops.h>
@@ -101,6 +103,25 @@ static struct syscore_ops leds_syscore_ops = {
.resume = leds_resume,
};
+static int leds_idle_notifier(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ switch (val) {
+ case IDLE_START:
+ leds_event(led_idle_start);
+ break;
+ case IDLE_END:
+ leds_event(led_idle_end);
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block leds_idle_nb = {
+ .notifier_call = leds_idle_notifier,
+};
+
static int __init leds_init(void)
{
int ret;
@@ -109,8 +130,12 @@ static int __init leds_init(void)
ret = sysdev_register(&leds_device);
if (ret == 0)
ret = sysdev_create_file(&leds_device, &attr_event);
- if (ret == 0)
+
+ if (ret == 0) {
register_syscore_ops(&leds_syscore_ops);
+ idle_notifier_register(&leds_idle_nb);
+ }
+
return ret;
}
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 2b5b142..3132699 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -662,6 +662,12 @@ init_hw_perf_events(void)
case 0xC090: /* Cortex-A9 */
armpmu = armv7_a9_pmu_init();
break;
+ case 0xC050: /* Cortex-A5 */
+ armpmu = armv7_a5_pmu_init();
+ break;
+ case 0xC0F0: /* Cortex-A15 */
+ armpmu = armv7_a15_pmu_init();
+ break;
}
/* Intel CPUs [xscale]. */
} else if (0x69 == implementor) {
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 4372763..462aefb 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -17,17 +17,23 @@
*/
#ifdef CONFIG_CPU_V7
-/* Common ARMv7 event types */
+/*
+ * Common ARMv7 event types
+ *
+ * Note: An implementation may not be able to count all of these events
+ * but the encodings are considered to be `reserved' in the case that
+ * they are not available.
+ */
enum armv7_perf_types {
ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
ARMV7_PERFCTR_IFETCH_MISS = 0x01,
ARMV7_PERFCTR_ITLB_MISS = 0x02,
- ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
- ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
+ ARMV7_PERFCTR_DCACHE_REFILL = 0x03, /* L1 */
+ ARMV7_PERFCTR_DCACHE_ACCESS = 0x04, /* L1 */
ARMV7_PERFCTR_DTLB_REFILL = 0x05,
ARMV7_PERFCTR_DREAD = 0x06,
ARMV7_PERFCTR_DWRITE = 0x07,
-
+ ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
ARMV7_PERFCTR_EXC_TAKEN = 0x09,
ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
ARMV7_PERFCTR_CID_WRITE = 0x0B,
@@ -39,21 +45,30 @@ enum armv7_perf_types {
*/
ARMV7_PERFCTR_PC_WRITE = 0x0C,
ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
+ ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
+
+ /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
-
- ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
+ ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
+ ARMV7_PERFCTR_MEM_ACCESS = 0x13,
+ ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
+ ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
+ ARMV7_PERFCTR_L2_DCACHE_ACCESS = 0x16,
+ ARMV7_PERFCTR_L2_DCACHE_REFILL = 0x17,
+ ARMV7_PERFCTR_L2_DCACHE_WB = 0x18,
+ ARMV7_PERFCTR_BUS_ACCESS = 0x19,
+ ARMV7_PERFCTR_MEMORY_ERROR = 0x1A,
+ ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
+ ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
+ ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
ARMV7_PERFCTR_CPU_CYCLES = 0xFF
};
/* ARMv7 Cortex-A8 specific event types */
enum armv7_a8_perf_types {
- ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
-
- ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
-
ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
@@ -138,6 +153,39 @@ enum armv7_a9_perf_types {
ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
};
+/* ARMv7 Cortex-A5 specific event types */
+enum armv7_a5_perf_types {
+ ARMV7_PERFCTR_IRQ_TAKEN = 0x86,
+ ARMV7_PERFCTR_FIQ_TAKEN = 0x87,
+
+ ARMV7_PERFCTR_EXT_MEM_RQST = 0xc0,
+ ARMV7_PERFCTR_NC_EXT_MEM_RQST = 0xc1,
+ ARMV7_PERFCTR_PREFETCH_LINEFILL = 0xc2,
+ ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
+ ARMV7_PERFCTR_ENTER_READ_ALLOC = 0xc4,
+ ARMV7_PERFCTR_READ_ALLOC = 0xc5,
+
+ ARMV7_PERFCTR_STALL_SB_FULL = 0xc9,
+};
+
+/* ARMv7 Cortex-A15 specific event types */
+enum armv7_a15_perf_types {
+ ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS = 0x40,
+ ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS = 0x41,
+ ARMV7_PERFCTR_L1_DCACHE_READ_REFILL = 0x42,
+ ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL = 0x43,
+
+ ARMV7_PERFCTR_L1_DTLB_READ_REFILL = 0x4C,
+ ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL = 0x4D,
+
+ ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS = 0x50,
+ ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS = 0x51,
+ ARMV7_PERFCTR_L2_DCACHE_READ_REFILL = 0x52,
+ ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL = 0x53,
+
+ ARMV7_PERFCTR_SPEC_PC_WRITE = 0x76,
+};
+
/*
* Cortex-A8 HW events mapping
*
@@ -207,11 +255,6 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
},
},
[C(DTLB)] = {
- /*
- * Only ITLB misses and DTLB refills are supported.
- * If users want the DTLB refills misses a raw counter
- * must be used.
- */
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
@@ -323,11 +366,6 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
},
},
[C(DTLB)] = {
- /*
- * Only ITLB misses and DTLB refills are supported.
- * If users want the DTLB refills misses a raw counter
- * must be used.
- */
[C(OP_READ)] = {
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
[C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
@@ -374,6 +412,242 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
};
/*
+ * Cortex-A5 HW events mapping
+ */
+static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_DCACHE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ /*
+ * The prefetch counters don't differentiate between the I
+ * side and the D side.
+ */
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+/*
+ * Cortex-A15 HW events mapping
+ */
+static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
+};
+
+static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ /*
+ * Not all performance counters differentiate between read
+ * and write accesses/misses so we're not always strictly
+ * correct, but it's the best we can do. Writes and reads get
+ * combined in these cases.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)]
+ = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DTLB_READ_REFILL,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(BPU)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+};
+
+/*
* Perf Events counters
*/
enum armv7_counters {
@@ -905,6 +1179,26 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
armv7pmu.num_events = armv7_read_num_pmnc_events();
return &armv7pmu;
}
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA5;
+ armv7pmu.name = "ARMv7 Cortex-A5";
+ armv7pmu.cache_map = &armv7_a5_perf_cache_map;
+ armv7pmu.event_map = &armv7_a5_perf_map;
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
+ return &armv7pmu;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA15;
+ armv7pmu.name = "ARMv7 Cortex-A15";
+ armv7pmu.cache_map = &armv7_a15_perf_cache_map;
+ armv7pmu.event_map = &armv7_a15_perf_map;
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
+ return &armv7pmu;
+}
#else
static const struct arm_pmu *__init armv7_a8_pmu_init(void)
{
@@ -915,4 +1209,14 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
{
return NULL;
}
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+ return NULL;
+}
#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 74ae833..e5cfa6a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -30,9 +30,9 @@
#include <linux/uaccess.h>
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
+#include <linux/console.h>
#include <asm/cacheflush.h>
-#include <asm/leds.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/thread_notify.h>
@@ -62,6 +62,18 @@ static volatile int hlt_counter;
#include <mach/system.h>
+#ifdef CONFIG_SMP
+void arch_trigger_all_cpu_backtrace(void)
+{
+ smp_send_all_cpu_backtrace();
+}
+#else
+void arch_trigger_all_cpu_backtrace(void)
+{
+ dump_stack();
+}
+#endif
+
void disable_hlt(void)
{
hlt_counter++;
@@ -91,8 +103,37 @@ static int __init hlt_setup(char *__unused)
__setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup);
+#ifdef CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART
+void arm_machine_flush_console(void)
+{
+ printk("\n");
+ pr_emerg("Restarting %s\n", linux_banner);
+ if (console_trylock()) {
+ console_unlock();
+ return;
+ }
+
+ mdelay(50);
+
+ local_irq_disable();
+ if (!console_trylock())
+ pr_emerg("arm_restart: Console was locked! Busting\n");
+ else
+ pr_emerg("arm_restart: Console was locked!\n");
+ console_unlock();
+}
+#else
+void arm_machine_flush_console(void)
+{
+}
+#endif
+
void arm_machine_restart(char mode, const char *cmd)
{
+ /* Flush the console to make sure all the relevant messages make it
+ * out to the console drivers */
+ arm_machine_flush_console();
+
/* Disable interrupts first */
local_irq_disable();
local_fiq_disable();
@@ -182,8 +223,8 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
+ idle_notifier_call_chain(IDLE_START);
tick_nohz_stop_sched_tick(1);
- leds_event(led_idle_start);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
@@ -210,8 +251,8 @@ void cpu_idle(void)
local_irq_enable();
}
}
- leds_event(led_idle_end);
tick_nohz_restart_sched_tick();
+ idle_notifier_call_chain(IDLE_END);
preempt_enable_no_resched();
schedule();
preempt_disable();
@@ -254,6 +295,77 @@ void machine_restart(char *cmd)
arm_pm_restart(reboot_mode, cmd);
}
+/*
+ * dump a block of kernel memory from around the given address
+ */
+static void show_data(unsigned long addr, int nbytes, const char *name)
+{
+ int i, j;
+ int nlines;
+ u32 *p;
+
+ /*
+ * don't attempt to dump non-kernel addresses or
+ * values that are probably just small negative numbers
+ */
+ if (addr < PAGE_OFFSET || addr > -256UL)
+ return;
+
+ printk("\n%s: %#lx:\n", name, addr);
+
+ /*
+ * round address down to a 32 bit boundary
+ * and always dump a multiple of 32 bytes
+ */
+ p = (u32 *)(addr & ~(sizeof(u32) - 1));
+ nbytes += (addr & (sizeof(u32) - 1));
+ nlines = (nbytes + 31) / 32;
+
+
+ for (i = 0; i < nlines; i++) {
+ /*
+ * just display low 16 bits of address to keep
+ * each line of the dump < 80 characters
+ */
+ printk("%04lx ", (unsigned long)p & 0xffff);
+ for (j = 0; j < 8; j++) {
+ u32 data;
+ if (probe_kernel_address(p, data)) {
+ printk(" ********");
+ } else {
+ printk(" %08x", data);
+ }
+ ++p;
+ }
+ printk("\n");
+ }
+}
+
+static void show_extra_register_data(struct pt_regs *regs, int nbytes)
+{
+ mm_segment_t fs;
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ show_data(regs->ARM_pc - nbytes, nbytes * 2, "PC");
+ show_data(regs->ARM_lr - nbytes, nbytes * 2, "LR");
+ show_data(regs->ARM_sp - nbytes, nbytes * 2, "SP");
+ show_data(regs->ARM_ip - nbytes, nbytes * 2, "IP");
+ show_data(regs->ARM_fp - nbytes, nbytes * 2, "FP");
+ show_data(regs->ARM_r0 - nbytes, nbytes * 2, "R0");
+ show_data(regs->ARM_r1 - nbytes, nbytes * 2, "R1");
+ show_data(regs->ARM_r2 - nbytes, nbytes * 2, "R2");
+ show_data(regs->ARM_r3 - nbytes, nbytes * 2, "R3");
+ show_data(regs->ARM_r4 - nbytes, nbytes * 2, "R4");
+ show_data(regs->ARM_r5 - nbytes, nbytes * 2, "R5");
+ show_data(regs->ARM_r6 - nbytes, nbytes * 2, "R6");
+ show_data(regs->ARM_r7 - nbytes, nbytes * 2, "R7");
+ show_data(regs->ARM_r8 - nbytes, nbytes * 2, "R8");
+ show_data(regs->ARM_r9 - nbytes, nbytes * 2, "R9");
+ show_data(regs->ARM_r10 - nbytes, nbytes * 2, "R10");
+ set_fs(fs);
+}
+
void __show_regs(struct pt_regs *regs)
{
unsigned long flags;
@@ -313,6 +425,8 @@ void __show_regs(struct pt_regs *regs)
printk("Control: %08x%s\n", ctrl, buf);
}
#endif
+
+ show_extra_register_data(regs, 128);
}
void show_regs(struct pt_regs * regs)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index acbb447..7cc11c0 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -979,6 +979,10 @@ static const char *hwcap_str[] = {
"neon",
"vfpv3",
"vfpv3d16",
+ "tls",
+ "vfpv4",
+ "idiva",
+ "idivt",
NULL
};
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e7f92a4..6893ec9 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -40,6 +40,8 @@
#include <asm/ptrace.h>
#include <asm/localtimer.h>
+#include <mach/sec_debug.h>
+
/*
* as from 2.5, kernels no longer have an init_tasks structure
* so we need some other way of telling a new secondary core
@@ -53,6 +55,7 @@ enum ipi_msg_type {
IPI_CALL_FUNC,
IPI_CALL_FUNC_SINGLE,
IPI_CPU_STOP,
+ IPI_CPU_BACKTRACE,
};
int __cpuinit __cpu_up(unsigned int cpu)
@@ -271,6 +274,20 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
}
/*
+ * Skip the secondary calibration on architectures sharing clock
+ * with primary cpu. Archs can use ARCH_SKIP_SECONDARY_CALIBRATE
+ * for this.
+ */
+static inline int skip_secondary_calibrate(void)
+{
+#ifdef CONFIG_ARCH_SKIP_SECONDARY_CALIBRATE
+ return 0;
+#else
+ return -ENXIO;
+#endif
+}
+
+/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
@@ -301,19 +318,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
*/
platform_secondary_init(cpu);
- /*
- * Enable local interrupts.
- */
notify_cpu_starting(cpu);
- local_irq_enable();
- local_fiq_enable();
- /*
- * Setup the percpu timer for this CPU.
- */
- percpu_timer_setup();
-
- calibrate_delay();
+ if (skip_secondary_calibrate())
+ calibrate_delay();
smp_store_cpu_info(cpu);
@@ -323,8 +331,14 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
* before we continue.
*/
set_cpu_online(cpu, true);
- while (!cpu_active(cpu))
- cpu_relax();
+
+ /*
+ * Setup the percpu timer for this CPU.
+ */
+ percpu_timer_setup();
+
+ local_irq_enable();
+ local_fiq_enable();
/*
* OK, it's off to the idle thread for us
@@ -405,6 +419,7 @@ static const char *ipi_types[NR_IPI] = {
S(IPI_CALL_FUNC, "Function call interrupts"),
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
S(IPI_CPU_STOP, "CPU stop interrupts"),
+ S(IPI_CPU_BACKTRACE, "CPU backtrace"),
};
void show_ipi_list(struct seq_file *p, int prec)
@@ -445,9 +460,7 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
static void ipi_timer(void)
{
struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
- irq_enter();
evt->event_handler(evt);
- irq_exit();
}
#ifdef CONFIG_LOCAL_TIMERS
@@ -458,8 +471,13 @@ asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
if (local_timer_ack()) {
__inc_irq_stat(cpu, local_timer_irqs);
+ sec_debug_irq_log(0, do_local_timer, 1);
+ irq_enter();
ipi_timer();
- }
+ irq_exit();
+ sec_debug_irq_log(0, do_local_timer, 2);
+ } else
+ sec_debug_irq_log(0, do_local_timer, 3);
set_irq_regs(old_regs);
}
@@ -551,10 +569,65 @@ static void ipi_cpu_stop(unsigned int cpu)
local_fiq_disable();
local_irq_disable();
+ flush_cache_all();
+ local_flush_tlb_all();
+
while (1)
cpu_relax();
}
+static cpumask_t backtrace_mask;
+static DEFINE_RAW_SPINLOCK(backtrace_lock);
+
+/* "in progress" flag of arch_trigger_all_cpu_backtrace */
+static unsigned long backtrace_flag;
+
+void smp_send_all_cpu_backtrace(void)
+{
+ unsigned int this_cpu = smp_processor_id();
+ int i;
+
+ if (test_and_set_bit(0, &backtrace_flag))
+ /*
+ * If there is already a trigger_all_cpu_backtrace() in progress
+ * (backtrace_flag == 1), don't output double cpu dump infos.
+ */
+ return;
+
+ cpumask_copy(&backtrace_mask, cpu_online_mask);
+ cpu_clear(this_cpu, backtrace_mask);
+
+ pr_info("Backtrace for cpu %d (current):\n", this_cpu);
+ dump_stack();
+
+ pr_info("\nsending IPI to all other CPUs:\n");
+ smp_cross_call(&backtrace_mask, IPI_CPU_BACKTRACE);
+
+ /* Wait for up to 10 seconds for all other CPUs to do the backtrace */
+ for (i = 0; i < 10 * 1000; i++) {
+ if (cpumask_empty(&backtrace_mask))
+ break;
+ mdelay(1);
+ }
+
+ clear_bit(0, &backtrace_flag);
+ smp_mb__after_clear_bit();
+}
+
+/*
+ * ipi_cpu_backtrace - handle IPI from smp_send_all_cpu_backtrace()
+ */
+static void ipi_cpu_backtrace(unsigned int cpu, struct pt_regs *regs)
+{
+ if (cpu_isset(cpu, backtrace_mask)) {
+ raw_spin_lock(&backtrace_lock);
+ pr_warning("IPI backtrace for cpu %d\n", cpu);
+ show_regs(regs);
+ raw_spin_unlock(&backtrace_lock);
+ cpu_clear(cpu, backtrace_mask);
+ }
+}
+
/*
* Main handler for inter-processor interrupts
*/
@@ -566,9 +639,13 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
+ sec_debug_irq_log(ipinr, do_IPI, 1);
+
switch (ipinr) {
case IPI_TIMER:
+ irq_enter();
ipi_timer();
+ irq_exit();
break;
case IPI_RESCHEDULE:
@@ -576,15 +653,25 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
break;
case IPI_CALL_FUNC:
+ irq_enter();
generic_smp_call_function_interrupt();
+ irq_exit();
break;
case IPI_CALL_FUNC_SINGLE:
+ irq_enter();
generic_smp_call_function_single_interrupt();
+ irq_exit();
break;
case IPI_CPU_STOP:
+ irq_enter();
ipi_cpu_stop(cpu);
+ irq_exit();
+ break;
+
+ case IPI_CPU_BACKTRACE:
+ ipi_cpu_backtrace(cpu, regs);
break;
default:
@@ -592,6 +679,9 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
cpu, ipinr);
break;
}
+
+ sec_debug_irq_log(ipinr, do_IPI, 2);
+
set_irq_regs(old_regs);
}
@@ -627,3 +717,13 @@ int setup_profiling_timer(unsigned int multiplier)
{
return -EINVAL;
}
+
+static void flush_all_cpu_cache(void *info)
+{
+ flush_cache_all();
+}
+
+void flush_all_cpu_caches(void)
+{
+ on_each_cpu(flush_all_cpu_cache, NULL, 1);
+}
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index cb7dd40..1936649 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -15,12 +15,18 @@
#include <asm/cacheflush.h>
#include <asm/cputype.h>
+#include <plat/cpu.h>
+
#define SCU_CTRL 0x00
#define SCU_CONFIG 0x04
#define SCU_CPU_STATUS 0x08
#define SCU_INVALIDATE 0x0c
#define SCU_FPGA_REVISION 0x10
+#ifdef CONFIG_MACH_PX
+extern void logbuf_force_unlock(void);
+#endif
+
/*
* Get the number of CPU cores from the SCU configuration
*/
@@ -33,7 +39,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base)
/*
* Enable the SCU
*/
-void __init scu_enable(void __iomem *scu_base)
+void scu_enable(void __iomem *scu_base)
{
u32 scu_ctrl;
@@ -51,6 +57,10 @@ void __init scu_enable(void __iomem *scu_base)
if (scu_ctrl & 1)
return;
+ if ((soc_is_exynos4412() && (samsung_rev() >= EXYNOS4412_REV_1_0)) ||
+ soc_is_exynos4210())
+ scu_ctrl |= (1<<3);
+
scu_ctrl |= 1;
__raw_writel(scu_ctrl, scu_base + SCU_CTRL);
@@ -59,6 +69,10 @@ void __init scu_enable(void __iomem *scu_base)
* initialised is visible to the other CPUs.
*/
flush_cache_all();
+
+#ifdef CONFIG_MACH_PX
+ logbuf_force_unlock();
+#endif
}
/*
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 381d23a..b3337e7 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -94,20 +94,19 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
if (tsk != current) {
#ifdef CONFIG_SMP
/*
- * What guarantees do we have here that 'tsk' is not
- * running on another CPU? For now, ignore it as we
- * can't guarantee we won't explode.
+ * What guarantees do we have here that 'tsk'
+ * is not running on another CPU?
+ *
+ * We guarantee that this function will be used for
+ * latencytop only :-)
*/
- if (trace->nr_entries < trace->max_entries)
- trace->entries[trace->nr_entries++] = ULONG_MAX;
- return;
-#else
+ /* BUG(); */
+#endif
data.no_sched_functions = 1;
frame.fp = thread_saved_fp(tsk);
frame.sp = thread_saved_sp(tsk);
frame.lr = 0; /* recovered from the stack */
frame.pc = thread_saved_pc(tsk);
-#endif
} else {
register unsigned long current_sp asm ("sp");
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 6807cb1..56b2715 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -451,7 +451,9 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
if (end > vma->vm_end)
end = vma->vm_end;
- flush_cache_user_range(vma, start, end);
+ up_read(&mm->mmap_sem);
+ flush_cache_user_range(start, end);
+ return;
}
up_read(&mm->mmap_sem);
}
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 66a477a..54daeae 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -68,6 +68,15 @@
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldr1w \src, \reg1, \abort
+ ldr1w \src, \reg2, \abort
+ strd \reg1, \reg2, [\dst, \offset]
+ .endr
+ add \dst, \dst, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 805e3f8..f2b5885 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -66,6 +66,7 @@
* than one 32bit instruction in Thumb-2)
*/
+#define PLDSIZE (CONFIG_ARM_PLD_SIZE)
enter r4, lr
@@ -90,19 +91,46 @@
CALGN( add pc, r4, ip )
PLD( pld [r1, #0] )
-2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
+
+#if (PLDSIZE == 64)
+2: PLD( cmp r2, #32)
+ PLD( blt .32copy)
+
+.64copy:
+ PLD( subs r2, r2, #(PLDSIZE*3+32) )
+ PLD( pld [r1, #PLDSIZE-4] )
PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
+ PLD( pld [r1, #PLDSIZE*2-4] )
+ PLD( pld [r1, #PLDSIZE*3-4] )
+3: PLD( pld [r1, #PLDSIZE*4-4] )
+4: cpy8w r0, r1, r4, r5, abort=20f
+ cpy8w r0, r1, r4, r5, abort=20f
+ subs r2, r2, #PLDSIZE
+ bge 3b
+ PLD( cmn r2, #(PLDSIZE*3) )
+ PLD( bge 4b )
+
+ PLD( cmn r2, #(PLDSIZE*4-32) )
+ PLD( blt 5f)
+
+.32copy:
+ cpy8w r0, r1, r4, r5, abort=20f
+#else
+2: PLD( subs r2, r2, #(PLDSIZE*3) )
+ PLD( pld [r1, #(PLDSIZE-4)] )
+ PLD( blt 4f )
+ PLD( pld [r1, #(PLDSIZE*2-4)] )
+ PLD( pld [r1, #(PLDSIZE*3-4)] )
+
+3: PLD( pld [r1, #(PLDSIZE*4-4)] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #PLDSIZE
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
-3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
bge 3b
- PLD( cmn r2, #96 )
+ PLD( cmn r2, #(PLDSIZE*3) )
PLD( bge 4b )
+#endif
5: ands ip, r2, #28
rsb ip, ip, #32
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index d066df6..e32788b 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -71,6 +71,15 @@
str1w \ptr, \reg8, \abort
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldrd \reg1, \reg2, [\src, \offset]
+ str1w \dst, \reg1, \abort
+ str1w \dst, \reg2, \abort
+ .endr
+ add \src, \src, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
strusr \reg, \ptr, 1, \cond, abort=\abort
.endm
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index a9b9e22..7ffda59 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -40,6 +40,15 @@
stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
.endm
+ .macro cpy8w dst src reg1 reg2 abort
+ .irp offset, #0, #8, #16, #24
+ ldrd \reg1, \reg2, [\src, \offset]
+ strd \reg1, \reg2, [\dst, \offset]
+ .endr
+ add \src, \src, #32
+ add \dst, \dst, #32
+ .endm
+
.macro str1b ptr reg cond=al abort
str\cond\()b \reg, [\ptr], #1
.endm
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
new file mode 100644
index 0000000..3903ef6
--- /dev/null
+++ b/arch/arm/mach-exynos/Kconfig
@@ -0,0 +1,1706 @@
+# arch/arm/mach-exynos/Kconfig
+#
+# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the EXYNOS
+
+if ARCH_EXYNOS
+
+choice
+ prompt "EXYNOS system type"
+ default ARCH_EXYNOS4
+
+config ARCH_EXYNOS4
+ bool "Samsung Exynos4"
+ select ARM_ERRATA_743622
+ select ARM_ERRATA_751472
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369
+ help
+ Samsung EXYNOS4 series based systems
+
+config ARCH_EXYNOS5
+ bool "Samsung Exynos5"
+ select ARM_ERRATA_761171
+ select ARM_ERRATA_762974
+ select ARM_ERRATA_763722
+ select HAVE_EXYNOS5_HSI2C if I2C
+ help
+ Samsung EXYNOS5 series based systems
+
+endchoice
+
+config CPU_EXYNOS4210
+ bool
+ select S3C_PL330_DMA
+ select PL310_ERRATA_727915
+ select ARM_ERRATA_753970
+ help
+ Enable EXYNOS4210 CPU support
+
+config CPU_EXYNOS4212
+ bool
+ select S3C_PL330_DMA
+ help
+ Enable EXYNOS4212 CPU support
+
+config CPU_EXYNOS4412
+ bool
+ select S3C_PL330_DMA
+ select ARM_ERRATA_761320
+ help
+ Enable EXYNOS4412 CPU support
+
+config CPU_EXYNOS5210
+ bool
+ select S3C_PL330_DMA
+ help
+ Enable EXYNOS5210 CPU support
+
+config S5PV310_HI_ARMCLK_THAN_1_2GHZ
+ bool "Enable the higher ARM clock than 1.2GHz"
+ default n
+ help
+ S5PV310 has different max arm clock. (i.e. 1.0GHz, 1.2GHz and 1.4GHz etc.)
+ If you are using the chip to work at the high clock than 1.2GHz,
+ activate this option.
+
+choice
+ prompt "EXYNOS5210 core type"
+ depends on CPU_EXYNOS5210
+ default CPU_A15
+
+config CPU_EXYNOS5210_A15
+ bool "A15 core"
+ help
+ A15 dual core CPU support
+
+config CPU_EXYNOS5210_A5_IOP
+ bool "A5 IOP core"
+ help
+ A5 single core CPU support
+endchoice
+
+config CPU_EXYNOS5250
+ bool
+ select S3C_PL330_DMA
+ help
+ Enable EXYNOS5250 CPU support
+
+config EXYNOS_CONTENT_PATH_PROTECTION
+ bool "Exynos Content Path Protection"
+ depends on (ARM_TRUSTZONE && (ARCH_EXYNOS4 || ARCH_EXYNOS5))
+ default n
+ help
+ Enable content path protection of EXYNOS.
+
+config EXYNOS4_PM
+ bool "Exynos4 Power Management"
+ depends on (PM && ARCH_EXYNOS4)
+ default y
+ help
+ Enable suspend and resume for Exynos4 series.
+
+config EXYNOS5_PM
+ bool "Exynos5 Power Management"
+ depends on (PM && ARCH_EXYNOS5)
+ default y
+ help
+ Enable suspend and resume for Exynos5 series.
+
+config EXYNOS4_CPUIDLE
+ bool "Exynos4 CPUIDLE Feature"
+ depends on (CPU_IDLE && ARCH_EXYNOS4)
+ default y
+ help
+ Enable CPUIDLE for Exynos4 series.
+
+config EXYNOS4_LOWPWR_IDLE
+ bool "Exynos4 Lowpower IDLE Feature"
+ depends on EXYNOS4_CPUIDLE
+ default y
+ help
+ Enable Low power IDLE for Exynos4 series.
+
+config EXYNOS5_CPUIDLE
+ bool "Exynos5 CPUIDLE Feature"
+ depends on (CPU_IDLE && ARCH_EXYNOS5)
+ default y
+ help
+ Enable CPUIDLE for Exynos5 series.
+
+config EXYNOS5_LOWPWR_IDLE
+ bool "Exynos5 Lowpower IDLE Feature"
+ depends on EXYNOS5_CPUIDLE
+ default y
+ help
+ Enable Low power IDLE for Exynos5 series.
+
+config EXYNOS_MCT
+ bool
+ default y
+ help
+ Use MCT (Multi Core Timer) as kernel timers
+
+config EXYNOS5_DEV_AHCI
+ bool
+ help
+ Compile in platform device definitions for AHCI SATA3.0
+
+config EXYNOS4_DEV_AHCI
+ bool
+ help
+ Compile in platform device definitions for AHCI
+
+config EXYNOS4_SETUP_FIMD0
+ bool
+ help
+ Common setup code for FIMD0.
+
+config EXYNOS4_SETUP_FIMD
+ bool
+ help
+ Common setup code for FIMD.
+
+config EXYNOS4_SETUP_DP
+ bool
+ help
+ Common setup code for DP.
+
+config EXYNOS_DEV_SYSMMU
+ bool
+ help
+ Common setup code for SYSTEM MMU in EXYNOS
+
+config EXYNOS_DEV_PD
+ bool
+ select SAMSUNG_PD
+ help
+ Compile in platform device definitions for Power Domain
+
+config EXYNOS4_DEV_DWMCI
+ bool
+ help
+ Compile in platform device definitions for DWMCI
+
+config EXYNOS4_DEV_FIMC_LITE
+ bool
+ help
+ Compile in platform device definitions for FIMC_LITE
+
+config EXYNOS4_DEV_FIMC_IS
+ bool
+ depends on (VIDEO_EXYNOS_FIMC_IS || VIDEO_EXYNOS5_FIMC_IS)
+ default y
+ help
+ Compile in platform device definition for FIMC-IS
+
+config EXYNOS4_SETUP_HDMI
+ bool
+ help
+ Common setup code for hdmi
+
+config EXYNOS4_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+config EXYNOS4_SETUP_I2C2
+ bool
+ help
+ Common setup code for i2c bus 2.
+
+config EXYNOS4_SETUP_I2C3
+ bool
+ help
+ Common setup code for i2c bus 3.
+
+config EXYNOS4_SETUP_I2C4
+ bool
+ help
+ Common setup code for i2c bus 4.
+
+config EXYNOS4_SETUP_I2C5
+ bool
+ help
+ Common setup code for i2c bus 5.
+
+config EXYNOS4_SETUP_I2C6
+ bool
+ help
+ Common setup code for i2c bus 6.
+
+config EXYNOS4_SETUP_I2C7
+ bool
+ help
+ Common setup code for i2c bus 7.
+
+config EXYNOS5_SETUP_HSI2C0
+ bool
+ help
+ Common setup code for hs-i2c bus 0.
+
+config EXYNOS5_SETUP_HSI2C1
+ bool
+ help
+ Common setup code for hs-i2c bus 1.
+
+config EXYNOS5_SETUP_HSI2C2
+ bool
+ help
+ Common setup code for hs-i2c bus 2.
+
+config EXYNOS5_DEV_HSI2C0
+ bool
+ help
+ Compile in platform device definitions for HS-I2C channel 0
+
+config EXYNOS5_DEV_HSI2C1
+ bool
+ help
+ Compile in platform device definitions for HS-I2C channel 1
+
+config EXYNOS5_DEV_HSI2C2
+ bool
+ help
+ Compile in platform device definitions for HS-I2C channel 2
+
+config EXYNOS5_DEV_HSI2C3
+ bool
+ help
+ Compile in platform device definitions for HS-I2C channel 3
+
+config EXYNOS5_SETUP_HSI2C3
+ bool
+ help
+ Common setup code for hs-i2c bus 3.
+
+config EXYNOS4_SETUP_KEYPAD
+ bool
+ help
+ Common setup code for keypad.
+
+config EXYNOS4_SETUP_MFC
+ bool
+ help
+ Common setup code for MFC.
+
+config EXYNOS4_SETUP_SDHCI
+ bool
+ select EXYNOS4_SETUP_SDHCI_GPIO
+ help
+ Internal helper functions for EXYNOS4 based SDHCI systems.
+
+config EXYNOS4_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for SDHCI gpio.
+
+config EXYNOS4_SETUP_MSHCI
+ bool
+ select EXYNOS4_SETUP_MSHCI_GPIO
+ help
+ Internal helper functions for EXYNOS4 based MSHCI systems.
+
+config EXYNOS4_SETUP_MSHCI_GPIO
+ bool
+ help
+ Common setup code for MSHCI gpio.
+
+config EXYNOS4_SETUP_FIMC
+ bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
+ help
+ Common setup code for the camera interfaces.
+
+config EXYNOS4_SETUP_FIMC0
+ bool
+ depends on VIDEO_FIMC
+ default y
+ help
+ Common setup code for the camera interfaces.
+
+config EXYNOS4_SETUP_FIMC1
+ bool
+ depends on VIDEO_FIMC
+ default y
+ help
+ Common setup code for the camera interfaces.
+
+config EXYNOS4_SETUP_FIMC2
+ bool
+ depends on VIDEO_FIMC
+ default y
+ help
+ Common setup code for the camera interfaces.
+
+config EXYNOS4_SETUP_FIMC3
+ bool
+ depends on VIDEO_FIMC
+ default y
+ help
+ Common setup code for the camera interfaces.
+
+config EXYNOS4_SETUP_FIMC_IS
+ bool
+ depends on (VIDEO_EXYNOS_FIMC_IS || VIDEO_EXYNOS5_FIMC_IS)
+ default y
+ help
+ Common setup code for the FIMC-IS
+
+config EXYNOS4_SETUP_USB_PHY
+ bool
+ help
+ Common setup code for USB PHY controller
+
+config EXYNOS4_SETUP_CSIS
+ bool
+ depends on VIDEO_FIMC_MIPI
+ default y
+ help
+ Common setup code for MIPI-CSIS
+
+config EXYNOS4_SETUP_FB_S5P
+ bool
+ default n
+ help
+ Setup code for EXYNOS4 FIMD
+
+config EXYNOS4_SETUP_TVOUT
+ bool
+ default y
+ help
+ Common setup code for TVOUT
+
+config EXYNOS4_SETUP_THERMAL
+ bool "Use thermal management for exynos4"
+ depends on CPU_FREQ
+ help
+ Common setup code for Exynos4 TMU
+
+config EXYNOS_SETUP_THERMAL
+ bool "Use thermal management"
+ depends on CPU_FREQ
+ help
+ Common setup code for TMU
+
+config TMU_DEBUG
+ bool "Thermal management Debug"
+ depends on EXYNOS_SETUP_THERMAL
+ help
+ TMU debugging message on
+
+config EXYNOS4_SETUP_MIPI_DSI
+ bool
+ depends on FB_S5P_MIPI_DSIM
+ default y
+ help
+ Common setup code for MIPI_DSIM.
+
+config EXYNOS4_SETUP_MIPI_DSIM
+ bool
+ depends on FB_MIPI_DSIM
+ default y
+ help
+ Common setup code for MIPI_DSIM to support mainline style fimd.
+
+config EXYNOS4_SETUP_JPEG
+ bool
+ depends on VIDEO_JPEG_V2X
+ default y
+ help
+ Common setup code for JPEG
+
+config EXYNOS5_DEV_GSC
+ bool
+ depends on VIDEO_EXYNOS_GSCALER
+ default y
+ help
+ Compile in platform device definitions for GSC
+
+config EXYNOS5_DEV_FIMC_IS
+ bool
+ depends on VIDEO_EXYNOS5_FIMC_IS
+ default y
+ help
+ Compile in platform device definition for FIMC-IS
+
+config EXYNOS5_SETUP_GSC
+ bool
+ depends on VIDEO_EXYNOS_GSCALER
+ default y
+ help
+ Common setup code for GSC
+
+config EXYNOS4_ENABLE_CLOCK_DOWN
+ bool "ARM core clock down feature enable"
+ depends on EXYNOS4_CPUIDLE
+ default n
+ help
+ ARM core clock down in idle time.
+
+config EXYNOS5_ENABLE_CLOCK_DOWN
+ bool "ARM core clock down feature enable"
+ depends on EXYNOS5_CPUIDLE
+ default n
+ help
+ ARM core clock down in idle time.
+
+config EXYNOS4_CPUFREQ
+ def_bool y
+ depends on CPU_FREQ && ARCH_EXYNOS4
+ help
+ Exynos4 cpufreq support
+
+config EXYNOS5_CPUFREQ
+ def_bool y
+ depends on CPU_FREQ && ARCH_EXYNOS5
+ help
+ Exynos5 cpufreq support
+
+choice
+ prompt "Max CPU frequency"
+ depends on EXYNOS4_CPUFREQ
+ default EXYNOS4X12_1400MHZ_SUPPORT if (CPU_EXYNOS4212 || CPU_EXYNOS4412)
+ default EXYNOS4210_1400MHZ_SUPPORT if CPU_EXYNOS4210
+
+config EXYNOS4210_1200MHZ_SUPPORT
+ bool "Max 1200MHz CPUFREQ LEVEL"
+ depends on EXYNOS4_CPUFREQ && CPU_EXYNOS4210
+ help
+ Max 1.2Ghz support
+
+config EXYNOS4210_1400MHZ_SUPPORT
+ bool "Max 1400MHz CPUFREQ LEVEL"
+ depends on EXYNOS4_CPUFREQ && CPU_EXYNOS4210
+ help
+ Max 1.4Ghz support
+
+config EXYNOS4X12_1500MHZ_SUPPORT
+ bool "Max 1500MHz CPUFREQ LEVEL"
+ depends on EXYNOS4_CPUFREQ && (CPU_EXYNOS4212 || CPU_EXYNOS4412)
+ help
+ Max 1.5Ghz support
+
+config EXYNOS4X12_1400MHZ_SUPPORT
+ bool "Max 1400MHz CPUFREQ LEVEL"
+ depends on EXYNOS4_CPUFREQ && (CPU_EXYNOS4212 || CPU_EXYNOS4412)
+ help
+ Max 1.4Ghz support
+
+config EXYNOS4X12_1200MHZ_SUPPORT
+ bool "Max 1200MHz CPUFREQ LEVEL"
+ depends on EXYNOS4_CPUFREQ && (CPU_EXYNOS4212 || CPU_EXYNOS4412)
+ help
+ Max 1.2Ghz support
+
+config EXYNOS4X12_1000MHZ_SUPPORT
+ bool "Max 1000MHz CPUFREQ LEVEL"
+ depends on EXYNOS4_CPUFREQ && (CPU_EXYNOS4212 || CPU_EXYNOS4412)
+ help
+ Max 1.0Ghz support
+
+endchoice
+
+config MIDAS_COMMON
+ bool
+ help
+ Support common devices of MIDAS boards
+
+menu "Support dynamic CPU Hotplug"
+ depends on HOTPLUG_CPU && SMP
+
+config EXYNOS_PM_HOTPLUG
+ bool "EXYNOS Dynamic Hotplug"
+ help
+ Dynamic CPU HOTLUG for EXYNOS series
+
+choice
+ prompt "Dynamic CPU HOTPLUG Policy"
+ depends on EXYNOS_PM_HOTPLUG
+ default DVFS_NR_RUNNING_POLICY if (CPU_EXYNOS4212 || CPU_EXYNOS4412 || CPU_EXYNOS5250)
+
+config STAND_ALONE_POLICY
+ bool "Stand alone policy CPU hotplug"
+ depends on EXYNOS_PM_HOTPLUG
+ help
+ PM hotplug policy. This is for exynos4210
+ Enable to use pm hotplug, then it uses stand-hotplug.c file.
+ Avg-load is calculated with both cpu frequency aspect
+ and run queue status.
+
+config LEGACY_HOTPLUG_POLICY
+ bool "Legacy policy CPU hotplug"
+ depends on EXYNOS_PM_HOTPLUG
+ help
+ PM hotplug policy. This is for exynos4210
+ Enable to use pm hotplug, then it uses pm-hotplug.c file.
+ Avg-load is calculated with only cpu utilization of cpu
+ frequency at that time.
+
+config WITH_DVFS_POLICY
+ depends on EXYNOS4_CPUFREQ
+ bool "Intergrated DVFS CPU hotplug"
+
+config DVFS_NR_RUNNING_POLICY
+ depends on (EXYNOS4_CPUFREQ || EXYNOS5_CPUFREQ)
+ bool "DVFS-nr_running CPU hotplug"
+
+config NR_RUNNING_POLICY
+ bool "nr_running CPU hotplug"
+
+endchoice
+endmenu
+
+menu "Busfreq Model"
+ depends on EXYNOS4_CPUFREQ || EXYNOS5_CPUFREQ
+
+config BUSFREQ
+ bool "Busfreq with PPC/PPMU"
+ depends on EXYNOS4_CPUFREQ
+
+config BUSFREQ_QOS
+ bool "QoS with Busfreq"
+ depends on BUSFREQ
+ default n
+
+config BUSFREQ_OPP
+ bool "Busfreq with OPP"
+ depends on EXYNOS4_CPUFREQ || EXYNOS5_CPUFREQ
+
+config DEVFREQ_BUS
+ bool "Busfreq support with Devfreq framework & Simple-Ondemand"
+ depends on EXYNOS4_CPUFREQ
+ select PM_DEVFREQ
+ select ARM_EXYNOS4_BUS_DEVFREQ
+
+choice
+ prompt "QoS LEVEL By Resolution"
+ depends on BUSFREQ_QOS || BUSFREQ_OPP
+ default BUSFREQ_QOS_LEVEL_NONE
+
+config BUSFREQ_QOS_NONE
+ bool "QoS Setting is not required"
+
+config BUSFREQ_QOS_1024X600
+ bool "QoS for 1024x600 (like P2)"
+
+config BUSFREQ_QOS_1280X720
+ bool "QoS for 1280x720 (like M0/T0)"
+
+config BUSFREQ_QOS_1280X800
+ bool "QoS for 1280x800 or 800x1280 (like Q1/P8)"
+
+endchoice
+
+endmenu
+
+config BUSFREQ_DEBUG
+ bool "BUSFREQ sysfs support"
+ default n
+
+config GPIO_MIDAS_01_BD
+ bool "GPIO configuration for Midas 01 BD"
+ depends on MACH_SLP_MIDAS
+
+config GPIO_MIDAS_02_BD
+ bool "GPIO configuration for Midas 02 BD"
+ depends on MACH_SLP_MIDAS
+
+config BUSFREQ_L2_160M
+ bool "Busfreq L2 level use 160MHz"
+ default n
+ help
+ Busfreq uses 160MHz for L2, not 133MHz. Optimize busfreq
+ dvfs level transition for LCD high resolution.
+ This enable 160MHz of L2 level. Q1 has high LCD resolution,
+ so uses busfreq dvfs L2 as 160MHz.
+
+config SEC_THERMISTOR
+ bool "Use external thermistor with ADC"
+ depends on SAMSUNG_DEV_ADC
+ default n
+ help
+ Use thermistor driver for U1 & U1 Premium.
+ U1 has two thermistors. this device driver use one of those
+ to check system temperature.
+
+config EXYNOS_SYSREG_PM
+ bool "PM Support for System Registers"
+ depends on CPU_EXYNOS4210 || CPU_EXYNOS4412 || CPU_EXYNOS4212
+ default n
+ help
+ Use System Register save/restore for suspend-to-RAM
+ Some boards have this code hard coded in device drivers(FB);
+ however, this is better supported at SoC support code.
+ Currently, SLP kernel depends on this.
+
+config ANDROID_WIP
+ bool "work in progress hacks for android"
+ default n
+ help
+ This enables 'work in progress' hacks for android issues.
+ Please remove it later.
+
+# machine support
+
+menu "EXYNOS4 Machines"
+ depends on ARCH_EXYNOS4
+
+config MACH_SMDKC210
+ bool "SMDKC210"
+ select CPU_EXYNOS4210
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_I2C1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_HWMON if S3C_ADC
+ select S5P_GPIO_INT
+ select S5P_DEV_FIMD0
+ select S5P_DEV_FIMD_S5P
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_ROTATOR
+ select S5P_DEV_USBGADGET
+ select S5P_DEV_JPEG
+ select S5P_DEV_THERMAL
+ select S5P_DEV_USB_EHCI
+ select S5P_SYSTEM_MMU
+ select EXYNOS_DEV_PD
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_KEYPAD
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_FB_S5P
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS4_SETUP_MFC
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select SAMSUNG_DEV_TS1
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_BACKLIGHT
+ help
+ Machine support for Samsung SMDKC210
+
+config MACH_SMDKV310
+ bool "SMDKV310"
+ select CPU_EXYNOS4210
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_I2C1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_HWMON if S3C_ADC
+ select S5P_GPIO_INT
+ select S5P_DEV_FIMD0
+ select S5P_DEV_FIMD_S5P
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_ROTATOR
+ select S5P_DEV_USBGADGET
+ select S5P_DEV_JPEG
+ select S5P_DEV_THERMAL
+ select S5P_DEV_USB_EHCI
+ select S5P_SYSTEM_MMU
+ select EXYNOS_DEV_PD
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_KEYPAD
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_FB_S5P
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS4_DEV_AHCI
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select SAMSUNG_DEV_TS1
+ help
+ Machine support for Samsung SMDKV310
+
+config MACH_ARMLEX4210
+ bool "ARMLEX4210"
+ select CPU_EXYNOS4210
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S5P_SYSTEM_MMU
+ select EXYNOS4_DEV_AHCI
+ select EXYNOS4_SETUP_SDHCI
+ help
+ Machine support for Samsung ARMLEX4210 based on EXYNOS4210
+
+config MACH_UNIVERSAL_C210
+ bool "Mobile UNIVERSAL_C210 Board"
+ select CPU_EXYNOS4210
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C5
+ select S5P_DEV_ONENAND
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_SDHCI
+ help
+ Machine support for Samsung Mobile Universal S5PC210 Reference
+ Board.
+
+config MACH_NURI
+ bool "Mobile NURI Board"
+ select CPU_EXYNOS4210
+ select S3C_DEV_WDT
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C3
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select S5P_DEV_USB_EHCI
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C4
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for Samsung Mobile NURI Board.
+
+config MACH_U1
+ bool "U1 board"
+ select CPU_EXYNOS4210
+ select S5P_GPIO_INT
+ select S5P_DEV_FIMD0
+ select S5P_DEV_FIMD_S5P
+ select S5P_DEV_TVOUT
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_USB_EHCI
+ select S5P_SYSTEM_MMU
+ select S5P_DEV_USBGADGET
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C3
+ select S3C_DEV_I2C5
+ select S3C_DEV_I2C6
+ select S3C_DEV_I2C7
+ select S3C_DEV_I2C8_EMUL
+ select S3C_DEV_I2C9_EMUL
+ select EXYNOS4_DEV_MSHC
+ select EXYNOS4_MSHC_MPLL_40MHZ
+ select EXYNOS4_MSHC_DDR
+ select EXYNOS4_MSHC_8BIT
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select SAMSUNG_DEV_TS1
+ select EXYNOS_DEV_PD
+ select S5P_SYSTEM_MMU
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C6
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_MSHCI
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS4_SETUP_FB_S5P
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS4_SETUP_THERMAL
+ help
+ Machine support for U1 Board
+
+choice
+ prompt "U1 board"
+ depends on MACH_U1
+ default MACH_U1_BD
+
+config MACH_U1_BD
+ bool "U1 Board"
+
+config MACH_U1CAMERA_BD
+ bool "U1CAMERA Board"
+
+config MACH_Q1_BD
+ bool "Q1 Board"
+
+endchoice
+
+config MACH_PX
+ bool "PX board"
+ select CPU_EXYNOS4210
+ select S5P_GPIO_INT
+ select S5P_DEV_FIMD0
+ select S5P_DEV_FIMD_S5P
+ select S5P_DEV_TVOUT
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_USB_EHCI
+ select S5P_SYSTEM_MMU
+ select S5P_DEV_USBGADGET
+ select S5P_DEV_THERMAL
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C3
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select S3C_DEV_I2C6
+ select S3C_DEV_I2C7
+ select S3C_DEV_I2C9_EMUL
+ select EXYNOS4_DEV_MSHC
+ select EXYNOS4_MSHC_MPLL_40MHZ
+ select EXYNOS4_MSHC_DDR
+ select EXYNOS4_MSHC_8BIT
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select SAMSUNG_DEV_TS1
+ select EXYNOS_DEV_PD
+ select S5P_SYSTEM_MMU
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C4
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C6
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_MSHCI
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS4_SETUP_FB_S5P
+ select EXYNOS4_SETUP_USB_PHY
+ help
+ Machine support for PX Board
+choice
+ prompt "PX board"
+ depends on MACH_PX
+ default MACH_P4
+
+config MACH_P4
+ bool "P4 board"
+
+config MACH_P2
+ bool "P2 board"
+
+config MACH_P8
+ bool "P8 board"
+
+config MACH_P8LTE
+ bool "P8 LTE board"
+ select S3C64XX_DEV_SPI0
+
+endchoice
+
+choice
+ prompt "LCD panel select"
+ depends on MACH_U1
+ default PANEL_U1
+
+config PANEL_U1
+ bool "U1/Q1 default panel"
+
+endchoice
+
+config PANEL_S2PLUS
+ bool "s2plus panel"
+
+if MACH_U1 || MACH_C1 || MACH_C1VZW || MACH_M0 || MACH_P4 || MACH_P2 || MACH_P4NOTE || MACH_T0
+source "arch/arm/mach-exynos/Kconfig.local"
+endif
+
+config MACH_SMDK4X12
+ bool "SMDK4X12 board"
+ select CPU_EXYNOS4212
+ select CPU_EXYNOS4412
+ select S3C_DEV_WDT
+ select S3C_DEV_RTC
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_I2C3
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select S3C_DEV_I2C7
+ select S5P_DEV_I2C_HDMIPHY
+ select S5P_GPIO_INT
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_FIMD0
+ select S5P_DEV_FIMD_S5P
+ select S5P_DEV_USB_EHCI
+ select S5P_DEV_USBGADGET
+ select S5P_DEV_USB_SWITCH
+ select S5P_DEV_THERMAL
+ select S5P_SYSTEM_MMU
+ select EXYNOS_DEV_PD
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_FB_S5P
+ select EXYNOS4_SETUP_FIMD0
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C2
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C4
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS4_SETUP_KEYPAD
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS4_DEV_FIMC_LITE
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_KEYPAD
+ help
+ Machine support for Samsung SMDK4X12
+
+config MACH_MIDAS
+ bool "MIDAS board"
+ select CPU_EXYNOS4212
+ select CPU_EXYNOS4412
+ select S3C_DEV_WDT
+ select S3C_DEV_RTC
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select SAMSUNG_DEV_ADC
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C3
+ select S3C_DEV_I2C6
+ select S3C_DEV_I2C7
+ select S5P_GPIO_INT
+ select S5P_DEV_MFC
+ select S5P_DEV_TVOUT
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_FIMD_S5P
+ select S5P_DEV_USB_EHCI
+ select S5P_DEV_USBGADGET
+ select EXYNOS4_DEV_MSHC
+ select EXYNOS4_SETUP_MSHCI
+ select EXYNOS4_MSHC_MPLL_40MHZ
+ select EXYNOS4_MSHC_DDR
+ select EXYNOS4_MSHC_8BIT
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_DEV_FIMC_LITE
+ select EXYNOS4_SETUP_FB_S5P
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C4
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C6
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS4_SETUP_MFC
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_PWM
+ select EXYNOS_DEV_PD
+ select EXYNOS4_SETUP_MFC
+ select MIDAS_COMMON
+ help
+ Machine support for Samsung midas board
+
+choice
+ prompt "EXYNOS4212 board"
+ depends on MACH_MIDAS
+ default MACH_MIDAS_02_BD
+
+config MACH_MIDAS_01_BD
+ bool "Midas Rev 0.1 board"
+
+config MACH_MIDAS_02_BD
+ bool "Midas Rev 0.2 board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+
+config MACH_M0
+ bool "M0 board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select MIDAS_COMMON_BD
+
+config MACH_M3
+ bool "M3 board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select MIDAS_COMMON_BD
+
+config MACH_C1
+ bool "C1 board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select MIDAS_COMMON_BD
+
+config MACH_C1VZW
+ bool "C1 VZW board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select MIDAS_COMMON_BD
+
+config MACH_C1CTC
+ bool "C1 CTC board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select MIDAS_COMMON_BD
+
+config MACH_JENGA
+ bool "Jenga board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select MIDAS_COMMON_BD
+
+config MACH_S2PLUS
+ bool "S2PLUS board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select PANEL_S2PLUS
+ select MIDAS_COMMON_BD
+
+config MACH_S2PLUS
+ bool "S2 Plus board"
+ select S3C_DEV_I2C4
+ select MIDAS_COMMON_BD
+
+config MACH_P4NOTE
+ bool "P4 Note board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select P4NOTE_00_BD
+
+config MACH_GC1
+ bool "Galuxy Camera board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select GC1_00_BD
+
+config MACH_T0
+ bool "T0 board"
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select T0_00_BD
+
+endchoice
+
+config MIDAS_COMMON_BD
+ bool "Midas default common Board"
+
+config P4NOTE_00_BD
+ bool "P4 Note PQ common Board"
+
+config GC1_00_BD
+ bool "Galaxy Camera common Board"
+
+config T0_00_BD
+ bool "T0 common Board"
+
+config WRITEBACK_ENABLED
+ bool "Samsung Writeback Enable"
+ help
+ This option enables writeback operations. It can
+ support fimd streams data to fimc destinations ram.
+ writeback operations support final blended stream.
+ when enable this options.
+
+endmenu
+
+menu "EXYNOS5 Machines"
+ depends on ARCH_EXYNOS5
+
+config MACH_SMDK5210
+ bool "SMDK5210 board"
+ select CPU_EXYNOS5210
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S5P_DEV_DP
+ select S5P_DEV_FIMD1
+ select S5P_DEV_MFC
+ select S5P_DEV_USB_EHCI
+ select EXYNOS_DEV_PD
+ select EXYNOS4_SETUP_DP
+ select EXYNOS4_SETUP_FIMD
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C2
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_USB_PHY
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_PWM
+ select S5P_DEV_I2C_HDMIPHY
+ select EXYNOS_DEV_SS_UDC
+ help
+ Machine support for Samsung SMDK5210
+
+config MACH_SMDK5250
+ bool "SMDK5250 board"
+ select CPU_EXYNOS5250
+ select S3C_DEV_HWMON if S3C_ADC
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select S3C_DEV_I2C7
+ select S5P_GPIO_INT
+ select S5P_DEV_DP
+ select EXYNOS_DEV_SYSMMU
+ select S5P_DEV_FIMD1
+ select S5P_DEV_USB_EHCI
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_ROTATOR
+ select S5P_DEV_USBGADGET
+ select S5P_DEV_I2C_HDMIPHY
+ select S5P_DEV_THERMAL
+ select S5P_DEV_USB_SWITCH
+ select EXYNOS_DEV_PD
+ select EXYNOS4_DEV_FIMC_LITE
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C2
+ select EXYNOS4_SETUP_I2C4
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_DP
+ select EXYNOS4_SETUP_FIMD
+ select EXYNOS4_SETUP_USB_PHY
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS5_DEV_AHCI
+ select EXYNOS5_DEV_DWMCI2
+ select EXYNOS_DEV_SS_UDC
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for Samsung SMDK5250
+
+config MACH_P10
+ bool "P10 board"
+ select CPU_EXYNOS5250
+ select S3C_DEV_HWMON if S3C_ADC
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C3
+ select S3C_DEV_I2C4
+ select S3C_DEV_I2C5
+ select S3C_DEV_I2C7
+ select S5P_GPIO_INT
+ select S5P_DEV_DP
+ select EXYNOS_DEV_SYSMMU
+ select S5P_DEV_FIMD1
+ select S5P_DEV_USB_EHCI
+ select S5P_DEV_TV
+ select S5P_DEV_USBGADGET
+ select S5P_DEV_MFC
+ select S5P_DEV_FIMG2D
+ select S5P_DEV_ROTATOR
+ select S5P_DEV_I2C_HDMIPHY
+ select EXYNOS_DEV_PD
+ select EXYNOS4_DEV_FIMC_LITE
+ select EXYNOS4_SETUP_I2C1
+ select EXYNOS4_SETUP_I2C3
+ select EXYNOS4_SETUP_I2C4
+ select EXYNOS4_SETUP_I2C5
+ select EXYNOS4_SETUP_I2C7
+ select EXYNOS4_SETUP_DP
+ select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_DEV_DWMCI
+ select EXYNOS4_SETUP_FIMD
+ select EXYNOS4_SETUP_USB_PHY
+ select SAMSUNG_DEV_BACKLIGHT
+ select SAMSUNG_DEV_PWM
+ select EXYNOS4_SETUP_MFC
+ select EXYNOS_DEV_SS_UDC
+ select SAMSUNG_DEV_ADC
+ select EXYNOS4_SETUP_THERMAL
+ help
+ Machine support for Samsung P10 board
+
+choice
+ prompt "P10 board"
+ depends on MACH_P10
+ default MACH_P10_00_BD
+
+config MACH_P10_00_BD
+ bool "P10 Rev 0.0 board"
+
+config MACH_P10_LTE_00_BD
+ bool "P10 LTE Rev 0.0 board"
+
+config MACH_P10_WIFI_00_BD
+ bool "P10 WIFI Rev 0.0 board"
+
+config MACH_P10_LUNGO_01_BD
+ bool "P10 lungo Rev 0.1 board"
+
+config MACH_P10_LUNGO_WIFI_01_BD
+ bool "P10 lungo Wifi Rev 0.1 board"
+
+endchoice
+choice
+ prompt "P10 DP version"
+ depends on MACH_P10
+ default MACH_P10_DP_01
+
+config MACH_P10_DP_00
+ bool "P10 DP 0.0(evt0.0)"
+
+config MACH_P10_DP_01
+ bool "P10 DP 0.1(evt0.1)"
+
+endchoice
+choice
+ prompt "DP FrameRate of P10"
+ depends on MACH_P10
+ default DP_40HZ_P10
+
+config DP_40HZ_P10
+ bool "support 40HZ for DP of P10"
+
+config DP_60HZ_P10
+ bool "support 60HZ for DP of P10"
+
+endchoice
+endmenu
+
+config EXYNOS5_DEV_BTS
+ bool "Support BTS driver"
+ select S5P_BTS
+ help
+ Compile in platform device definitions for BTS devices
+
+menu "MMC/SD slot setup"
+depends on PLAT_S5P
+
+comment "SELECT SYNOPSYS CONTROLLER INTERFACE DRIVER"
+config EXYNOS4_DEV_DWMCI
+ bool "DWMCI"
+ depends on PLAT_S5P && MMC_DW
+ default n
+ help
+ IF DWMCI is used, SDHC channel 0 is disabled.
+
+config EXYNOS5_DEV_DWMCI1
+ bool
+ help
+ Compile in platform device definitions for DWMCI channel 1
+
+config EXYNOS5_DEV_DWMCI2
+ bool
+ help
+ Compile in platform device definitions for DWMCI channel 2
+
+config EXYNOS5_DEV_DWMCI3
+ bool
+ help
+ Compile in platform device definitions for DWMCI channel 3
+
+config EXYNOS4_DEV_MSHC
+ bool "MSHCI"
+ depends on PLAT_S5P
+ default n
+ help
+ IF MSHC is used, SDHC channel 0 is disabled.
+
+choice
+ prompt "Use Special PLL for MSHC"
+ depends on PLAT_S5P && EXYNOS4_DEV_MSHC
+ help
+ This feature change MMC4OUT's clock source between MPLL and EPLL
+ default EXYNOS4_MSHC_MPLL_40MHZ
+
+config EXYNOS4_MSHC_MPLL_40MHZ
+ bool "MPLL"
+
+config EXYNOS4_MSHC_VPLL_46MHZ
+ bool "VPLL"
+
+config EXYNOS4_MSHC_EPLL_45MHZ
+ bool "EPLL"
+endchoice
+
+comment "Use 8-bit bus width"
+
+config EXYNOS4_MSHC_8BIT
+ bool "MSHC with 8-bit bus"
+ depends on PLAT_S5P && EXYNOS4_DEV_MSHC
+ default n
+ help
+ IF MSHC uses 8-bit bus, SDHC channel 1 is disabled.
+
+config EXYNOS4_SDHCI_CH0_8BIT
+ bool "SDHC Channel 0 with 8-bit bus"
+ depends on PLAT_S5P && !EXYNOS4_DEV_DWMCI && !EXYNOS4_DEV_MSHC
+ default n
+ help
+ Support HSMMC Channel 0 8-bit bus.
+ If selected, Channel 1 is disabled.
+
+config EXYNOS4_SDHCI_CH2_8BIT
+ bool "SDHC Channel 2 with 8-bit bus"
+ help
+ Support HSMMC Channel 2 8-bit bus.
+ If selected, Channel 3 is disabled.
+
+comment "Use DDR"
+ depends on PLAT_S5P && EXYNOS4_DEV_MSHC
+config EXYNOS4_MSHC_DDR
+ depends on PLAT_S5P && EXYNOS4_DEV_MSHC
+ bool "MSHC with DDR mode"
+ default n
+ help
+ Enabling DDR(Dual Data Rate) mode.
+
+endmenu
+
+comment "Miscellaneous drivers"
+config WAKEUP_ASSIST
+ bool "Wakeup assist driver"
+ depends on PM
+ help
+ If the wakeup time is too slow, toggling POWER butten shortly causes to
+ ignore report of key event. It makes the android system not execute wake
+ up codes.
+
+ If selected, the wakeup assistant driver will report POWER key event
+ directly
+endif
+
+config EXYNOS_C2C
+ bool "C2C device support"
+ depends on SAMSUNG_C2C
+ default y
+ help
+ Add C2C device driver
+
+config S3C64XX_DEV_SPI0
+ bool
+ depends on S3C64XX_DEV_SPI
+ default n
+ help
+ Samsung S3C64XX series type SPI
+
+config EXYNOS_DEV_C2C
+ bool
+ depends on EXYNOS_C2C
+ default y
+
+comment "Debugging Feature"
+menuconfig SEC_DEBUG
+ bool "Samsung TN Ramdump Feature"
+ default y
+ help
+ Samsung TN Ramdump Feature. Use INFORM3 and magic number at 0xc0000000.
+
+if SEC_DEBUG
+config SEC_DEBUG_SCHED_LOG
+ bool "Samsung Scheduler Logging Feature"
+ default n
+ help
+ Samsung Scheduler Logging Feature for Debug use.
+
+config SEC_DEBUG_SOFTIRQ_LOG
+ bool "Samsung Softirq Logging Feature"
+ default n
+ depends on SEC_DEBUG_SCHED_LOG
+ help
+ Samsung Softirq Logging Feature for Debug use.
+ This option enables us to log softirq enter/exit.
+ It is not only hard-irq which results in scheduler lockup,
+ To be more clear we need to see also softirq logs.
+
+config SEC_DEBUG_SCHED_LOG_NONCACHED
+ bool "Samsung Scheduler Logging on noncached buf"
+ depends on SEC_DEBUG_SCHED_LOG
+ default n
+ help
+ This option enables sec_debug_sched_log_noncached support.
+ It can support non-cached sched log in RAM dump and We don't
+ need to concern cache flush status for analyzing sudden
+ lockup issue.
+
+config SEC_DEBUG_SEMAPHORE_LOG
+ bool "Samsung Semaphore Logging Feature"
+ default n
+ help
+ Samsung Semaphore Logging Feature for Debug use.
+
+config SEC_DEBUG_USER
+ bool "Panic on Userspace fault"
+ default y
+ help
+ Panic on Userspace fault
+
+config SEC_DEBUG_PM_TEMP
+ bool "Temporary Logging for Sleep/Wakeup Issue"
+ default n
+ help
+ Verbose Log on Sleep/Wakeup.
+
+config SEC_DEBUG_IRQ_EXIT_LOG
+ bool "Temporary Logging for IRQ delay"
+ default n
+ help
+ Verbose Logging for IRQ delay.
+
+config SEC_DEBUG_AUXILIARY_LOG
+ bool "Samsung Auxiliary Logging on noncached buf"
+ default n
+ help
+ This option enables sec_auxiliary_log support.
+ we can log repeated information insuitable for kernel log like DVFS
+ or power domain control information.
+ It can support non-cached auxiliary log in RAM dump and We don't
+ need to concern cache flush status for analyzing sudden
+ system hang issue.
+
+config SEC_DEBUG_FUPLOAD_DUMP_MORE
+ bool "Dump more information at forced upload"
+ default n
+ help
+ More information is printed out when a forced upload happens.
+ It uses customized dump functions instead of panic call.
+
+config SEC_DEBUG_LIST_CORRUPTION
+ bool "Panic when list corruption detected"
+ default n
+ help
+ Panic when list structure corruption detected.
+ Sometimes list corruptions are reported.
+ But it reports only with WARN level.
+ This will immediately stop the system.
+
+config SEC_DEBUG_SYSRQ_B
+ bool "Panic when sysrq(b) detected"
+ default n
+ help
+ Panic when sysrq('b') detected.
+ In current debuggin feature sysrq('b') will anyway lead us to upload
+ with unknown reset, we are not handling debug flags for this.
+ With this feature we can find out what situation sysrq('b') is used.
+
+menuconfig SEC_WATCHDOG_RESET
+ bool "S5PV310 watchdog reset to exit from lockup"
+ depends on (CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412)
+ default n
+ help
+ Use watchdog reset to exit from lockup
+
+if SEC_WATCHDOG_RESET
+config SEC_WATCHDOG_PET_TIME
+ int "sec watchdog kicking time interval value"
+ default 5
+endif
+
+endif
+
+config SEC_LOG
+ default n
+ bool "Enable support for sec_log" if EMBEDDED
+ depends on PRINTK
+ help
+ This option enables sec_log support. This provides combined
+ log buffer for both bootloader and kernel. It also preserves
+ previous content before reboot.
+
+config SEC_LOG_NONCACHED
+ default n
+ bool "Enable non cached kernel sec_log support" if EMBEDDED
+ depends on SEC_LOG
+ help
+ This option enables sec_non_cached_klog support. It can
+ support non-cached kernel log in RAM dump and We don't need
+ to concern cache flush status for analyzing sudden lockup
+ issue.
+
+config SEC_LOG_LAST_KMSG
+ default n
+ bool "Enable /proc/last_kmsg support" if EMBEDDED
+ depends on SEC_LOG
+ help
+ This option enables /proc/last_kmsg support.
+
+if SEC_MODEM
+comment "Samsung Modem Feature"
+
+config LTE_VIA_SWITCH
+ bool
+ default n
+
+choice
+ prompt "SEC MODEM CONFIG"
+ depends on SEC_MODEM
+ default SEC_MODEM_M0_C2C
+
+config SEC_MODEM_M0_C2C
+ bool "M0 with xmm6262 c2c"
+ select UMTS_MODEM_XMM6262
+ select LINK_DEVICE_HSIC
+ select LINK_DEVICE_C2C
+ select SAMSUNG_C2C
+ select C2C_DEUBG
+
+config SEC_MODEM_M0
+ bool "M0 with xmm6262"
+ select UMTS_MODEM_XMM6262
+ select LINK_DEVICE_HSIC
+
+config SEC_MODEM_M0_CTC
+ bool "M0 CTC with MDM6600"
+ select CDMA_MODEM_MDM6600
+ select LINK_DEVICE_DPRAM
+ select USBHUB_USB3503
+
+config SEC_MODEM_M1
+ bool "M1 with cmc221"
+ select LTE_MODEM_CMC221
+ select LINK_DEVICE_DPRAM
+ select LINK_DEVICE_USB
+ select USBHUB_USB3503
+
+config SEC_MODEM_C1
+ bool "C1 with cmc221"
+ select LTE_MODEM_CMC221
+ select LINK_DEVICE_DPRAM
+ select LINK_DEVICE_USB
+ select USBHUB_USB3503
+
+config SEC_MODEM_C1_VZW
+ bool "C1 with CMC221 and CBP7.2"
+ select CDMA_MODEM_CBP72
+ select LTE_MODEM_CMC221
+ select LTE_VIA_SWITCH
+ select LINK_DEVICE_DPRAM
+ select LINK_DEVICE_USB
+ select USBHUB_USB3503
+
+config SEC_MODEM_C1_LGT
+ bool "C1 with CMC221 and CBP7.2"
+ select CDMA_MODEM_CBP72
+ select LTE_MODEM_CMC221
+ select LTE_VIA_SWITCH
+ select LINK_DEVICE_DPRAM
+ select LINK_DEVICE_USB
+ select USBHUB_USB3503
+
+config SEC_MODEM_C1_CTC
+ bool "C1 with MDM6600"
+ select CDMA_MODEM_MDM6600
+ select LINK_DEVICE_DPRAM
+ select USBHUB_USB3503
+
+config SEC_MODEM_M2
+ bool "M2 with MDM9x15"
+
+config SEC_MODEM_U1
+ bool "U1 with xmm6260"
+ select UMTS_MODEM_XMM6260
+ select LINK_DEVICE_HSIC
+
+config SEC_MODEM_JENGA
+ bool "JENGA with xmm6262"
+ select UMTS_MODEM_XMM6262
+ select LINK_DEVICE_HSIC
+
+config SEC_MODEM_S2PLUS
+ bool "S2PLUS with xmm6262"
+ select UMTS_MODEM_XMM6262
+ select LINK_DEVICE_HSIC
+
+config SEC_MODEM_U1_LGT
+ bool "U1 with mdm6600"
+ select CDMA_MODEM_MDM6600
+ select LINK_DEVICE_DPRAM
+
+config SEC_MODEM_GAIA
+ bool "GAIA with cmc221"
+ select LTE_MODEM_CMC221
+ select LINK_DEVICE_DPRAM
+
+endchoice
+
+endif
+
+if BT
+config BT_CSR8811
+ bool "Enable CSR8811 driver"
+ default n
+
+config BT_BCM4330
+ bool "Enable BCM4330 driver"
+ default n
+
+config BT_BCM4334
+ bool "Enable BCM4334 driver"
+ default n
+ help
+ Adds BCM4334 RFKILL driver for Broadcom BCM4334 chipset
+
+config BT_BCM43241
+ bool "Enable BCM43241 driver"
+ default n
+ help
+ Adds BCM43241 RFKILL driver for Broadcom BCM4334 chipset
+
+config BT_MGMT
+ bool "Bluetooth Mgmt"
+ default n
+ help
+ This is for bluetooth mgmt
+endif
+
+comment "Qualcomm Modem Feature"
+config QC_MODEM
+ bool "Qualcomm modem support"
+ default n
+
+config MSM_SUBSYSTEM_RESTART
+ bool "QC Modem restart handler"
+ default n
+
+config QC_MODEM_MDM9X15
+ bool "support QC mdm9x15 modem"
+ default n
+
+if QC_MODEM
+choice
+ prompt "QC MODEM CONFIG"
+ depends on QC_MODEM
+ default QC_MODEM_M3
+
+config QC_MODEM_M3
+ bool "M3 support QMI inteface over HSIC"
+ select MODEM_SUPPORT_QMI_INTERFACE
+ select MSM_SUBSYSTEM_RESTART
+ select USB_QCOM_DIAG_BRIDGE
+ select USB_QCOM_MDM_BRIDGE
+ select QC_MODEM_MDM9X15
+ select MSM_RMNET_USB
+
+endchoice
+endif
+
+config SAMSUNG_PRODUCT_SHIP
+ bool "set up for product shippling"
+ default n
diff --git a/arch/arm/mach-exynos/Kconfig.local b/arch/arm/mach-exynos/Kconfig.local
new file mode 100644
index 0000000..0e22814
--- /dev/null
+++ b/arch/arm/mach-exynos/Kconfig.local
@@ -0,0 +1,136 @@
+choice
+ prompt "Target Locale"
+ default TARGET_LOCALE_EUR
+
+config TARGET_LOCALE_EUR
+ bool "Europe Open"
+
+config TARGET_LOCALE_LTN
+ bool "Latin"
+
+config TARGET_LOCALE_KOR
+ bool "Kor"
+
+config TARGET_LOCALE_NAATT_TEMP
+ bool "NAGSM"
+
+config TARGET_LOCALE_P2EUR_TEMP
+ bool "P2EUR"
+
+config TARGET_LOCALE_P2TMO_TEMP
+ bool "P2TMO"
+
+config TARGET_LOCALE_EUR_U1_NFC
+ bool "Europe Open NFC"
+
+config TARGET_LOCALE_NTT
+ bool "JPN"
+
+config TARGET_LOCALE_CHN
+ bool "Chinese"
+
+config TARGET_LOCALE_USA
+ bool "USA"
+
+endchoice
+
+choice
+ prompt "C1 USA Target Carrier"
+ depends on MACH_C1 && (TARGET_LOCALE_EUR || TARGET_LOCALE_USA)
+ default MACH_C1_USA_ATT
+
+config MACH_C1_USA_ATT
+ bool "ATT"
+
+config MACH_C1_USA_VZW
+ bool "VZW"
+endchoice
+
+choice
+ prompt "U1 KOR Target Carrier"
+ depends on MACH_U1 && TARGET_LOCALE_KOR
+ default MACH_U1_KOR_SKT
+
+config MACH_U1_KOR_SKT
+ bool "SKT"
+
+config MACH_U1_KOR_KT
+ bool "KT"
+
+config MACH_U1_KOR_LGT
+ bool "LG U+"
+endchoice
+
+choice
+ prompt "C1 KOR Target Carrier"
+ depends on (MACH_C1 || MACH_C1VZW) && TARGET_LOCALE_KOR
+ default MACH_C1_KOR_SKT
+
+config MACH_C1_KOR_SKT
+ bool "SKT"
+
+config MACH_C1_KOR_KT
+ bool "KT"
+
+config MACH_C1_KOR_LGT
+ bool "LG U+"
+endchoice
+
+choice
+ prompt "M0 KOR Target Carrier"
+ depends on MACH_M0 && TARGET_LOCALE_KOR
+ default MACH_M0_KOR_SKT
+
+config MACH_M0_KOR_SKT
+ bool "SKT"
+
+config MACH_M0_KOR_KT
+ bool "KT"
+
+config MACH_M0_KOR_LGT
+ bool "LG U+"
+endchoice
+
+choice
+ prompt "P4 KOR Target Carrier"
+ depends on MACH_P4 && TARGET_LOCALE_KOR
+ default MACH_P4_KOR_ANY
+
+config MACH_P4_KOR_ANY
+ bool "P4 KOR OPEN Board"
+endchoice
+
+choice
+ prompt "M0 Chinese Target Carrier"
+ depends on MACH_M0 && TARGET_LOCALE_CHN
+
+config MACH_M0_CMCC
+ bool "M0 CHN CMCC board"
+
+config MACH_M0_CHNOPEN
+ bool "M0 CHN OPEN board"
+
+config MACH_M0_HKTW
+ bool "M0 CHN HKTW board"
+
+config MACH_M0_CTC
+ bool "M0 CHN CTC board"
+endchoice
+
+choice
+ prompt "Q1 Chinese Target Carrier"
+ depends on MACH_U1 && TARGET_LOCALE_CHN
+
+config MACH_Q1_CMCC_BD
+ bool "Q1 CHN CMCC board"
+endchoice
+
+
+menu "M0 CTC based models"
+ depends on MACH_M0_CTC && TARGET_LOCALE_CHN
+
+config MACH_M0_GRANDECTC
+ bool "M0 CHN GRANDE CTC board"
+endmenu
+
+
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
new file mode 100644
index 0000000..cf1d352
--- /dev/null
+++ b/arch/arm/mach-exynos/Makefile
@@ -0,0 +1,224 @@
+# arch/arm/mach-exynos/Makefile
+#
+# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+ifneq ($(CONFIG_CMA),y)
+obj-y := reserve_mem-exynos4.o
+endif
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for EXYNOS system
+
+obj-y += init.o irq-combiner.o dma.o irq-eint.o ppmu.o
+obj-$(CONFIG_ARM_TRUSTZONE) += irq-sgi.o
+obj-$(CONFIG_ARCH_EXYNOS4) += exynos4-smc.o cpu-exynos4.o clock-exynos4.o pmu-exynos4.o ppc.o
+
+CFLAGS_exynos4-smc.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+obj-$(CONFIG_ARCH_EXYNOS5) += cpu-exynos5.o clock-exynos5.o pmu-exynos5.o
+
+obj-y += clock-domain.o
+obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
+obj-$(CONFIG_CPU_EXYNOS4212) += clock-exynos4212.o
+obj-$(CONFIG_EXYNOS4_PM) += pm-exynos4.o sleep-exynos4.o
+AFLAGS_sleep-exynos4.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+
+obj-$(CONFIG_EXYNOS5_PM) += pm-exynos5.o sleep-exynos5.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_EXYNOS4_CPUFREQ) += asv.o asv-4210.o asv-4x12.o
+obj-$(CONFIG_EXYNOS4_CPUFREQ) += cpufreq-4210.o cpufreq-4x12.o
+obj-$(CONFIG_EXYNOS5_CPUFREQ) += asv.o asv-5250.o
+obj-$(CONFIG_EXYNOS5_CPUFREQ) += cpufreq-5250.o
+obj-$(CONFIG_EXYNOS4_CPUIDLE) += cpuidle-exynos4.o idle-exynos4.o
+AFLAGS_idle-exynos4.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
+
+obj-$(CONFIG_EXYNOS5_CPUIDLE) += cpuidle-exynos5.o idle-exynos5.o
+
+obj-$(CONFIG_BUSFREQ) += busfreq.o
+obj-$(CONFIG_BUSFREQ_OPP) += dev.o
+ifeq ($(CONFIG_BUSFREQ_OPP),y)
+obj-$(CONFIG_ARCH_EXYNOS4) += busfreq_opp_exynos4.o busfreq_opp_4x12.o
+obj-$(CONFIG_ARCH_EXYNOS5) += busfreq_opp_exynos5.o busfreq_opp_5250.o
+endif
+
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+
+obj-$(CONFIG_EXYNOS_MCT) += mct.o
+
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+
+obj-$(CONFIG_STAND_ALONE_POLICY) += stand-hotplug.o
+obj-$(CONFIG_LEGACY_HOTPLUG_POLICY) += pm-hotplug.o
+obj-$(CONFIG_WITH_DVFS_POLICY) += dvfs-hotplug.o
+obj-$(CONFIG_DVFS_NR_RUNNING_POLICY) += dynamic-dvfs-nr_running-hotplug.o
+obj-$(CONFIG_NR_RUNNING_POLICY) += dynamic-nr_running-hotplug.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDKC210) += mach-smdkv310.o
+obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
+obj-$(CONFIG_MACH_ARMLEX4210) += mach-armlex4210.o
+obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
+ifeq ($(CONFIG_MACH_U1CAMERA_BD),y)
+obj-$(CONFIG_MACH_U1) += mach-u1cam.o
+else
+obj-$(CONFIG_MACH_U1) += mach-u1.o
+endif
+obj-$(CONFIG_MACH_U1) += sec-common.o sec-switch_max8997.o
+obj-$(CONFIG_MACH_U1_BD) += u1-gpio.o board-gps-gsd4t.o
+obj-$(CONFIG_MACH_Q1_BD) += q1-gpio.o board-gps-bcm475x.o
+obj-$(CONFIG_MACH_U1CAMERA_BD) += u1camera-gpio.o board-gps-bcm475x.o
+obj-$(CONFIG_MACH_U1) += u1-wlan.o
+obj-$(CONFIG_MACH_PX) += mach-px.o sec-common.o board-gps-bcm475x.o px-switch.o
+obj-$(CONFIG_MACH_P2) += p2-gpio.o
+obj-$(CONFIG_MACH_P4) += p4-gpio.o
+obj-$(CONFIG_MACH_P8) += p8-gpio.o
+obj-$(CONFIG_MACH_P10) += board-p10-wlan.o board-gps-bcm475x.o
+obj-$(CONFIG_PANEL_U1) += u1-panel.o u1-panel_a2.o u1-panel_m2.o
+obj-$(CONFIG_PANEL_S2PLUS) += s2plus-panel.o
+obj-$(CONFIG_MACH_U1) += u1_regulator_consumer.o
+obj-$(CONFIG_MACH_PX) += u1_regulator_consumer.o
+obj-$(CONFIG_MACH_NURI) += mach-nuri.o
+obj-$(CONFIG_MACH_SMDK4X12) += mach-smdk4x12.o
+ifeq ($(CONFIG_MACH_P4NOTE),y)
+obj-$(CONFIG_MACH_MIDAS) += mach-p4notepq.o px-switch.o p4note-jack.o
+else
+obj-$(CONFIG_MACH_MIDAS) += mach-midas.o
+endif
+obj-$(CONFIG_MACH_SMDK5210) += mach-smdk5210.o
+obj-$(CONFIG_MACH_SMDK5250) += mach-smdk5250.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-mmc.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-display.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-power.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-audio.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-usb.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-input.o
+obj-$(CONFIG_MACH_SMDK5250) += board-smdk5250-spi.o
+
+obj-$(CONFIG_MACH_P4NOTE) += p4-input.o
+
+obj-$(CONFIG_MIDAS_COMMON) += sec-common.o board-gps-bcm475x.o \
+ midas-tsp.o board-midas-wlan.o \
+ midas-camera.o midas-thermistor.o \
+ midas-mhl.o midas-lcd.o midas-sound.o
+
+obj-$(CONFIG_P4NOTE_00_BD) += p4note-gpio.o p4note-power.o
+obj-$(CONFIG_GC1_00_BD) += gc1-gpio.o gc1-power.o
+obj-$(CONFIG_T0_00_BD) += midas-gpio.o midas-power.o
+obj-$(CONFIG_MIDAS_COMMON_BD) += midas-gpio.o midas-power.o
+obj-$(CONFIG_EXTCON) += midas-extcon.o
+
+obj-$(CONFIG_NAPLES_COMMON) += naples-gpio.o sec-common.o midas-gps.o \
+ naples-power.o naples-tsp.o board-midas-wlan.o \
+ naples-camera.o midas-thermistor.o \
+ midas-mhl.o
+
+obj-$(CONFIG_PN65N_NFC) += midas-nfc.o
+obj-$(CONFIG_MACH_MIDAS) += midas-sensor.o
+obj-$(CONFIG_LEDS_LP5521) += midas-leds.o
+
+obj-$(CONFIG_MACH_U1) += sec-reboot.o
+obj-$(CONFIG_MACH_PX) += sec-reboot.o
+obj-$(CONFIG_MACH_MIDAS) += sec-reboot.o
+
+obj-$(CONFIG_MACH_P10) += mach-p10.o p10-gpio.o sec-common.o p10-input.o \
+ p10-switch.o p10-battery.o midas-sound.o p10-mhl.o
+
+# device support
+
+obj-$(CONFIG_ARCH_EXYNOS) += dev-audio.o
+obj-$(CONFIG_EXYNOS5_DEV_AHCI) += dev-ahci-exynos5.o
+obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
+obj-$(CONFIG_EXYNOS_DEV_PD) += dev-pd.o
+ifeq ($(CONFIG_EXYNOS_DEV_PD),y)
+obj-$(CONFIG_ARCH_EXYNOS4) += dev-pd-exynos4.o
+obj-$(CONFIG_ARCH_EXYNOS5) += dev-pd-exynos5.o
+endif
+obj-$(CONFIG_S5P_SYSTEM_MMU) += dev-sysmmu-exynos4.o
+obj-$(CONFIG_EXYNOS_DEV_SYSMMU) += dev-sysmmu.o
+obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
+obj-$(CONFIG_EXYNOS_DEV_C2C) += dev-c2c.o
+obj-$(CONFIG_EXYNOS4_DEV_FIMC_IS) += dev-fimc-is.o
+obj-$(CONFIG_EXYNOS4_DEV_FIMC_LITE) += dev-fimc-lite.o
+obj-$(CONFIG_EXYNOS5_DEV_GSC) += dev-gsc.o
+
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC0) += setup-fimc0.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC1) += setup-fimc1.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC2) += setup-fimc2.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC3) += setup-fimc3.o
+obj-$(CONFIG_EXYNOS4_SETUP_CSIS) += setup-csis.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMD) += setup-fimd.o
+obj-$(CONFIG_EXYNOS4_SETUP_DP) += setup-dp.o
+obj-$(CONFIG_EXYNOS4_SETUP_FIMC_IS) += setup-fimc-is.o
+obj-$(CONFIG_EXYNOS5_SETUP_GSC) += setup-gsc.o
+obj-$(CONFIG_EXYNOS4_SETUP_HDMI) += setup-hdmi.o
+obj-y += setup-i2c0.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C4) += setup-i2c4.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o
+obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
+obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
+obj-$(CONFIG_EXYNOS4_SETUP_MFC) += setup-mfc.o
+obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_EXYNOS4_SETUP_MSHCI) += setup-mshci.o
+obj-$(CONFIG_EXYNOS4_SETUP_MSHCI_GPIO) += setup-mshci-gpio.o
+
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+
+obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
+obj-$(CONFIG_EXYNOS4_SETUP_FB_S5P) += setup-fb-s5p.o
+obj-$(CONFIG_EXYNOS4_SETUP_TVOUT) += setup-tvout.o
+obj-$(CONFIG_EXYNOS4_SETUP_JPEG) += setup-jpeg.o
+obj-$(CONFIG_EXYNOS4_SETUP_THERMAL) += tmu.o
+obj-$(CONFIG_EXYNOS_SETUP_THERMAL) += tmu_exynos.o
+obj-$(CONFIG_EXYNOS4_SETUP_MIPI_DSI) += setup-dsim.o
+obj-$(CONFIG_EXYNOS4_SETUP_MIPI_DSIM) += setup-mipidsim.o
+obj-$(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) += secmem-allocdev.o
+obj-$(CONFIG_EXYNOS_C2C) += setup-c2c.o
+obj-$(CONFIG_SEC_MODEM_M0_C2C) += board-midas-modems.o
+ifeq ($(CONFIG_MACH_P4NOTE),y)
+obj-$(CONFIG_SEC_MODEM_M0) += board-p4notepq-modems.o
+else
+obj-$(CONFIG_SEC_MODEM_M0) += board-m0-modems.o
+endif
+obj-$(CONFIG_SEC_MODEM_M0_TD) += board-m0-td-modems.o
+obj-$(CONFIG_SEC_MODEM_M0_CTC) += board-m0ctc-modems.o
+#obj-$(CONFIG_SEC_MODEM_M1) += board-m1-modems.o
+obj-$(CONFIG_SEC_MODEM_GAIA) += board-gaia-modems.o
+obj-$(CONFIG_SEC_MODEM_M1) += board-c1-modems.o
+obj-$(CONFIG_SEC_MODEM_C1) += board-c1-modems.o
+obj-$(CONFIG_SEC_MODEM_C1_VZW) += board-c1vzw-modems.o
+obj-$(CONFIG_SEC_MODEM_C1_LGT) += board-c1lgt-modems.o
+obj-$(CONFIG_SEC_MODEM_C1_CTC) += board-c1ctc-modems.o
+obj-$(CONFIG_SEC_MODEM_U1) += board-u1-modems.o
+obj-$(CONFIG_SEC_MODEM_JENGA) += board-jenga-modems.o
+obj-$(CONFIG_SEC_MODEM_S2PLUS) += board-s2plus-modems.o
+obj-$(CONFIG_SEC_MODEM_U1_LGT) += board-u1-lgt-modems.o
+obj-$(CONFIG_SEC_DEBUG) += sec_debug.o sec_getlog.o sec_gaf.o
+obj-$(CONFIG_SEC_WATCHDOG_RESET) += sec_watchdog.o
+obj-$(CONFIG_SEC_LOG) += sec_log.o
+obj-$(CONFIG_EXYNOS5_DEV_BTS) += bts.o
+
+obj-$(CONFIG_WAKEUP_ASSIST) += wakeup_assist.o
+obj-$(CONFIG_BT_CSR8811) += board-bluetooth-csr8811.o
+obj-$(CONFIG_ION_EXYNOS) += dev-ion.o
+obj-$(CONFIG_MFD_MAX77693) += sec-switch.o
+obj-$(CONFIG_BT_BCM4330) += board-bluetooth-bcm4330.o
+obj-$(CONFIG_BT_BCM4334) += board-bluetooth-bcm4334.o
+obj-$(CONFIG_BT_BCM43241) += board-bluetooth-bcm43241.o
+obj-$(CONFIG_GPS_BCM47511) += bcm47511.o
+obj-$(CONFIG_SEC_THERMISTOR) += sec_thermistor.o
+obj-$(CONFIG_EXYNOS_SYSREG_PM) += sysreg.o
+
+obj-$(CONFIG_QC_MODEM_MDM9X15) += mdm2.o mdm_common.o mdm_device.o
+obj-$(CONFIG_MSM_SUBSYSTEM_RESTART) += subsystem_notif.o subsystem_restart.o
diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot
index d65956f..d65956f 100644
--- a/arch/arm/mach-exynos4/Makefile.boot
+++ b/arch/arm/mach-exynos/Makefile.boot
diff --git a/arch/arm/mach-exynos/asv-4210.c b/arch/arm/mach-exynos/asv-4210.c
new file mode 100644
index 0000000..a3ef512
--- /dev/null
+++ b/arch/arm/mach-exynos/asv-4210.c
@@ -0,0 +1,457 @@
+/* linux/arch/arm/mach-exynos/asv-4210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4210 - ASV(Adaptive Supply Voltage) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#include <mach/regs-iem.h>
+#include <mach/regs-clock.h>
+#include <mach/cpufreq.h>
+#include <mach/asv.h>
+
+enum target_asv {
+ EXYNOS4210_1000,
+ EXYNOS4210_1200,
+ EXYNOS4210_1400,
+ EXYNOS4210_SINGLE_1200,
+};
+
+struct asv_judge_table exynos4210_1200_limit[] = {
+ /* HPM , IDS */
+ {8 , 4},
+ {11 , 8},
+ {14 , 12},
+ {18 , 17},
+ {21 , 27},
+ {23 , 45},
+ {25 , 55},
+};
+
+static struct asv_judge_table exynos4210_1400_limit[] = {
+ /* HPM , IDS */
+ {13 , 8},
+ {17 , 12},
+ {22 , 32},
+ {26 , 52},
+};
+
+static struct asv_judge_table exynos4210_single_1200_limit[] = {
+ /* HPM , IDS */
+ {8 , 4},
+ {14 , 12},
+ {21 , 27},
+ {25 , 55},
+};
+
+static int exynos4210_check_vdd_arm(void)
+{
+#if defined(CONFIG_REGULATOR)
+ struct regulator *arm_regulator;
+ int ret;
+
+ arm_regulator = regulator_get(NULL, "vdd_arm");
+ if (IS_ERR(arm_regulator)) {
+ pr_err("%s failed to get resource %s\n", __func__, "vdd_arm");
+ return -EINVAL;
+ }
+
+ /* Set vdd_arm to 1.2V to get hpm value */
+ ret = regulator_get_voltage(arm_regulator);
+ if (ret != 1200000) {
+ pr_info("%s: current vdd_arm(%duV), set vdd_arm (1.2V)\n",
+ __func__, ret);
+ ret = regulator_set_voltage(arm_regulator, 1200000, 1200000);
+ if (ret < 0) {
+ pr_err("%s: fail to set vdd_arm(%d)\n", __func__, ret);
+ return -EINVAL;
+ }
+ } else {
+ pr_info("%s: current vdd_arm(%duV)\n", __func__, ret);
+ }
+
+ regulator_put(arm_regulator);
+#endif
+ return 0;
+}
+static int exynos4210_hpm_clk_enable(void)
+{
+ struct clk *clk_iec;
+ struct clk *clk_apc;
+ struct clk *clk_hpm;
+
+ /* IEC clock gate enable */
+ clk_iec = clk_get(NULL, "iec");
+ if (IS_ERR(clk_iec)) {
+ printk(KERN_ERR"ASV : IEM IEC clock get error\n");
+ return -EINVAL;
+ }
+ clk_enable(clk_iec);
+
+ /* APC clock gate enable */
+ clk_apc = clk_get(NULL, "apc");
+ if (IS_ERR(clk_apc)) {
+ printk(KERN_ERR"ASV : IEM APC clock get error\n");
+ return -EINVAL;
+ }
+ clk_enable(clk_apc);
+
+ /* hpm clock gate enalbe */
+ clk_hpm = clk_get(NULL, "hpm");
+ if (IS_ERR(clk_hpm)) {
+ printk(KERN_ERR"ASV : HPM clock get error\n");
+ return -EINVAL;
+ }
+ clk_enable(clk_hpm);
+ return 0;
+}
+
+
+static int exynos4210_hpm_clk_disble(void)
+{
+ struct clk *clk_iec;
+ struct clk *clk_apc;
+ struct clk *clk_hpm;
+
+ /* IEC clock gate enable */
+ clk_iec = clk_get(NULL, "iec");
+ if (IS_ERR(clk_iec)) {
+ printk(KERN_ERR"ASV : IEM IEC clock get error\n");
+ return -EINVAL;
+ }
+ clk_disable(clk_iec);
+
+ /* APC clock gate enable */
+ clk_apc = clk_get(NULL, "apc");
+ if (IS_ERR(clk_apc)) {
+ printk(KERN_ERR"ASV : IEM APC clock get error\n");
+ return -EINVAL;
+ }
+ clk_disable(clk_apc);
+
+ /* hpm clock gate enalbe */
+ clk_hpm = clk_get(NULL, "hpm");
+ if (IS_ERR(clk_hpm)) {
+ printk(KERN_ERR"ASV : HPM clock get error\n");
+ return -EINVAL;
+ }
+ clk_disable(clk_hpm);
+ return 0;
+}
+
+
+static int exynos4210_asv_pre_clock_init(void)
+{
+ struct clk *clk_hpm;
+ struct clk *clk_copy;
+ struct clk *clk_parent;
+ unsigned int tmp;
+
+ if(exynos4210_hpm_clk_enable())
+ return -EINVAL;
+
+ /* Change Divider - CPU1 */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1);
+ tmp &= ~((0x7 << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) |
+ (0x7 << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT));
+ tmp |= ((0x0 << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) |
+ (0x3 << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT));
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
+
+ /* HPM SCLKMPLL */
+ tmp = __raw_readl(EXYNOS4_CLKSRC_CPU);
+ tmp &= ~(0x1 << EXYNOS4_CLKSRC_CPU_MUXHPM_SHIFT);
+ tmp |= 0x1 << EXYNOS4_CLKSRC_CPU_MUXHPM_SHIFT;
+ __raw_writel(tmp, EXYNOS4_CLKSRC_CPU);
+
+ /* PWI clock setting */
+ clk_copy = clk_get(NULL, "sclk_pwi");
+ if (IS_ERR(clk_copy)) {
+ pr_info("EXYNOS4210: ASV : SCLK_PWI clock get error\n");
+ return -EINVAL;
+ } else {
+ clk_parent = clk_get(NULL, "xusbxti");
+
+ if (IS_ERR(clk_parent)) {
+ pr_info("EXYNOS4210: ASV: MOUT_APLL clock get error\n");
+ clk_put(clk_copy);
+ return -EINVAL;
+ }
+ if (clk_set_parent(clk_copy, clk_parent))
+ pr_info("EXYNOS4210: ASV: Unable to set parent %s of clock %s.\n",
+ clk_parent->name, clk_copy->name);
+
+ clk_put(clk_parent);
+ }
+ clk_set_rate(clk_copy, 4800000);
+
+ clk_put(clk_copy);
+
+ /* HPM clock setting */
+ clk_copy = clk_get(NULL, "dout_copy");
+ if (IS_ERR(clk_copy)) {
+ pr_info("EXYNOS4210: ASV: DOUT_COPY clock get error\n");
+ return -EINVAL;
+ } else {
+ clk_parent = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(clk_parent)) {
+ pr_info("EXYNOS4210: ASV: MOUT_MPLL clock get error\n");
+ clk_put(clk_copy);
+ return -EINVAL;
+ }
+ if (clk_set_parent(clk_copy, clk_parent))
+ pr_info("EXYNOS4210: ASV: Unable to set parent %s of clock %s.\n",
+ clk_parent->name, clk_copy->name);
+
+ clk_put(clk_parent);
+ }
+
+ clk_set_rate(clk_copy, (400 * 1000 * 1000));
+
+ clk_put(clk_copy);
+
+ clk_hpm = clk_get(NULL, "sclk_hpm");
+ if (IS_ERR(clk_hpm)) {
+ pr_info("EXYNOS4210: ASV: Fail to get sclk_hpm\n");
+ return -EINVAL;
+ }
+
+ clk_set_rate(clk_hpm, (200 * 1000 * 1000));
+
+ clk_put(clk_hpm);
+
+ return 0;
+}
+
+static int exynos4210_asv_pre_clock_setup(void)
+{
+ /* APLL_CON0 level register */
+ __raw_writel(0x80FA0601, EXYNOS4_APLL_CON0L8);
+ __raw_writel(0x80C80601, EXYNOS4_APLL_CON0L7);
+ __raw_writel(0x80C80602, EXYNOS4_APLL_CON0L6);
+ __raw_writel(0x80C80604, EXYNOS4_APLL_CON0L5);
+ __raw_writel(0x80C80601, EXYNOS4_APLL_CON0L4);
+ __raw_writel(0x80C80601, EXYNOS4_APLL_CON0L3);
+ __raw_writel(0x80C80601, EXYNOS4_APLL_CON0L2);
+ __raw_writel(0x80C80601, EXYNOS4_APLL_CON0L1);
+
+ /* IEM Divider register */
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L8);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L7);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L6);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L5);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L4);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L3);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L2);
+ __raw_writel(0x00500000, EXYNOS4_CLKDIV_IEM_L1);
+
+ return 0;
+}
+
+static int exynos4210_find_group(struct samsung_asv *asv_info,
+ enum target_asv exynos4_target)
+{
+ unsigned int ret = 0;
+ unsigned int i;
+
+ if (exynos4_target == EXYNOS4210_1200) {
+ ret = ARRAY_SIZE(exynos4210_1200_limit);
+
+ for (i = 0; i < ARRAY_SIZE(exynos4210_1200_limit); i++) {
+ if (asv_info->hpm_result <= exynos4210_1200_limit[i].hpm_limit ||
+ asv_info->ids_result <= exynos4210_1200_limit[i].ids_limit) {
+ ret = i;
+ break;
+ }
+ }
+ } else if (exynos4_target == EXYNOS4210_1400) {
+ ret = ARRAY_SIZE(exynos4210_1400_limit);
+
+ for (i = 0; i < ARRAY_SIZE(exynos4210_1400_limit); i++) {
+ if (asv_info->hpm_result <= exynos4210_1400_limit[i].hpm_limit ||
+ asv_info->ids_result <= exynos4210_1400_limit[i].ids_limit) {
+ ret = i;
+ break;
+ }
+ }
+ } else if (exynos4_target == EXYNOS4210_SINGLE_1200) {
+ ret = ARRAY_SIZE(exynos4210_single_1200_limit);
+
+ for (i = 0; i < ARRAY_SIZE(exynos4210_single_1200_limit); i++) {
+ if (asv_info->hpm_result <= exynos4210_single_1200_limit[i].hpm_limit ||
+ asv_info->ids_result <= exynos4210_single_1200_limit[i].ids_limit) {
+ ret = i;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int exynos4210_get_hpm(struct samsung_asv *asv_info)
+{
+ unsigned int i;
+ unsigned int tmp;
+ unsigned int hpm_delay = 0;
+ void __iomem *iem_base;
+
+ iem_base = ioremap(EXYNOS4_PA_IEM, (128 * 1024));
+
+ if (!iem_base) {
+ pr_info("EXYNOS: ioremap fail\n");
+ return -EPERM;
+ }
+
+ /* Clock setting to get asv value */
+ if (!asv_info->pre_clock_init) {
+ pr_info("EXYNOS: No Pre-setup function\n");
+ goto err;
+ } else {
+ if (asv_info->pre_clock_init()) {
+ pr_info("EXYNOS: pre_clock_init function fail");
+ goto err;
+ } else {
+ /* HPM enable */
+ tmp = __raw_readl(iem_base + EXYNOS4_APC_CONTROL);
+ tmp |= APC_HPM_EN;
+ __raw_writel(tmp, (iem_base + EXYNOS4_APC_CONTROL));
+
+ asv_info->pre_clock_setup();
+
+ /* IEM enable */
+ tmp = __raw_readl(iem_base + EXYNOS4_IECDPCCR);
+ tmp |= IEC_EN;
+ __raw_writel(tmp, (iem_base + EXYNOS4_IECDPCCR));
+ }
+ }
+
+ /* Get HPM Delay value */
+ for (i = 0; i < LOOP_CNT; i++) {
+ tmp = __raw_readb(iem_base + EXYNOS4_APC_DBG_DLYCODE);
+ hpm_delay += tmp;
+ }
+
+ hpm_delay /= LOOP_CNT;
+ hpm_delay --;
+ /* Store result of hpm value */
+ asv_info->hpm_result = hpm_delay;
+
+ pr_info("EXYNOS4: HPM value = %d\n", hpm_delay);
+
+ /* HPM SCLKAPLL */
+ tmp = __raw_readl(EXYNOS4_CLKSRC_CPU);
+ tmp &= ~(0x1 << EXYNOS4_CLKSRC_CPU_MUXHPM_SHIFT);
+ tmp |= 0x0 << EXYNOS4_CLKSRC_CPU_MUXHPM_SHIFT;
+ __raw_writel(tmp, EXYNOS4_CLKSRC_CPU);
+
+ if(exynos4210_hpm_clk_disble())
+ return -EPERM;
+ return 0;
+
+err:
+ iounmap(iem_base);
+ return -EPERM;
+}
+
+static int exynos4210_get_ids(struct samsung_asv *asv_info)
+{
+ unsigned int pkg_id_val;
+
+ if (!asv_info->ids_offset || !asv_info->ids_mask) {
+ pr_info("EXYNOS4: No ids_offset or No ids_mask\n");
+ return -EPERM;
+ }
+
+ pkg_id_val = __raw_readl(S5P_VA_CHIPID + 0x4);
+ asv_info->pkg_id = pkg_id_val;
+ asv_info->ids_result = ((pkg_id_val >> asv_info->ids_offset) &
+ asv_info->ids_mask);
+
+ pr_info("EXYNOS4: IDS value = %d\n", asv_info->ids_result);
+ return 0;
+}
+
+#define PACK_ID 8
+#define PACK_MASK 0x3
+
+static int exynos4210_asv_store_result(struct samsung_asv *asv_info)
+{
+ unsigned int result_grp;
+ char *support_freq;
+
+ /* Single chip is only support 1.2GHz */
+ if (!((samsung_cpu_id >> PACK_ID) & PACK_MASK)) {
+ result_grp = exynos4210_find_group(asv_info, EXYNOS4210_SINGLE_1200);
+ result_grp |= SUPPORT_1200MHZ;
+ support_freq = "1.2GHz";
+
+ goto set_reg;
+ }
+
+ /* Check support freq */
+ switch (asv_info->pkg_id & 0x7) {
+ /* Support 1.2GHz */
+ case 1:
+ case 7:
+ result_grp = exynos4210_find_group(asv_info, EXYNOS4210_1200);
+ result_grp |= SUPPORT_1200MHZ;
+ support_freq = "1.2GHz";
+ break;
+ /* Support 1.4GHz */
+ case 5:
+ result_grp = exynos4210_find_group(asv_info, EXYNOS4210_1400);
+ result_grp |= SUPPORT_1400MHZ;
+ support_freq = "1.4GHz";
+ break;
+ /* Defalut support 1.0GHz */
+ default:
+ result_grp = exynos4210_find_group(asv_info, EXYNOS4210_1000);
+ result_grp |= SUPPORT_1000MHZ;
+ support_freq = "1.0GHz";
+ break;
+ }
+
+set_reg:
+ exynos_result_of_asv = result_grp;
+
+ pr_info(KERN_INFO "Support %s\n", support_freq);
+ pr_info(KERN_INFO "ASV Group for This Exynos4210 is 0x%x\n", exynos_result_of_asv);
+
+ return 0;
+}
+
+int exynos4210_asv_init(struct samsung_asv *asv_info)
+{
+ pr_info("EXYNOS4210: Adaptive Support Voltage init\n");
+
+ exynos_result_of_asv = 0;
+
+ asv_info->ids_offset = 24;
+ asv_info->ids_mask = 0xFF;
+
+ asv_info->get_ids = exynos4210_get_ids;
+ asv_info->get_hpm = exynos4210_get_hpm;
+ asv_info->check_vdd_arm = exynos4210_check_vdd_arm;
+ asv_info->pre_clock_init = exynos4210_asv_pre_clock_init;
+ asv_info->pre_clock_setup = exynos4210_asv_pre_clock_setup;
+ asv_info->store_result = exynos4210_asv_store_result;
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/asv-4x12.c b/arch/arm/mach-exynos/asv-4x12.c
new file mode 100644
index 0000000..5eeaf20
--- /dev/null
+++ b/arch/arm/mach-exynos/asv-4x12.c
@@ -0,0 +1,190 @@
+/* linux/arch/arm/mach-exynos/asv-4x12.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4X12 - ASV(Adaptive Supply Voltage) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/asv.h>
+#include <mach/map.h>
+#include <plat/cpu.h>
+
+/* ASV function for Fused Chip */
+#define IDS_ARM_OFFSET 24
+#define IDS_ARM_MASK 0xFF
+#define HPM_OFFSET 12
+#define HPM_MASK 0x1F
+
+#define FUSED_SG_OFFSET 3
+#define ORIG_SG_OFFSET 17
+#define ORIG_SG_MASK 0xF
+#define MOD_SG_OFFSET 21
+#define MOD_SG_MASK 0x7
+
+#define DEFAULT_ASV_GROUP 1
+
+#define CHIP_ID_REG (S5P_VA_CHIPID + 0x4)
+
+struct asv_judge_table exynos4x12_limit[] = {
+ /* HPM, IDS */
+ { 0, 0}, /* Reserved Group */
+ { 0, 0}, /* Reserved Group */
+ { 14, 9},
+ { 16, 14},
+ { 18, 17},
+ { 20, 20},
+ { 21, 24},
+ { 22, 30},
+ { 23, 34},
+ { 24, 39},
+ {100, 100},
+ {999, 999}, /* Reserved Group */
+};
+
+struct asv_judge_table exynos4212_limit[] = {
+ /* HPM, IDS */
+ { 0, 0}, /* Reserved Group */
+ { 17, 12},
+ { 18, 13},
+ { 20, 14},
+ { 22, 18},
+ { 24, 22},
+ { 25, 29},
+ { 26, 31},
+ { 27, 35},
+ { 28, 39},
+ {100, 100},
+ {999, 999}, /* Reserved Group */
+};
+
+static int exynos4x12_get_hpm(struct samsung_asv *asv_info)
+{
+ asv_info->hpm_result = (asv_info->pkg_id >> HPM_OFFSET) & HPM_MASK;
+
+ return 0;
+}
+
+static int exynos4x12_get_ids(struct samsung_asv *asv_info)
+{
+ asv_info->ids_result = (asv_info->pkg_id >> IDS_ARM_OFFSET) & IDS_ARM_MASK;
+
+ return 0;
+}
+
+static void exynos4x12_pre_set_abb(void)
+{
+ switch (exynos_result_of_asv) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ exynos4x12_set_abb(ABB_MODE_100V);
+ break;
+
+ default:
+ exynos4x12_set_abb(ABB_MODE_130V);
+ break;
+ }
+}
+
+static int exynos4x12_asv_store_result(struct samsung_asv *asv_info)
+{
+ unsigned int i;
+
+ if (soc_is_exynos4412()) {
+ for (i = 0; i < ARRAY_SIZE(exynos4x12_limit); i++) {
+ if ((asv_info->ids_result <= exynos4x12_limit[i].ids_limit) ||
+ (asv_info->hpm_result <= exynos4x12_limit[i].hpm_limit)) {
+ exynos_result_of_asv = i;
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(exynos4212_limit); i++) {
+ if ((asv_info->ids_result <= exynos4212_limit[i].ids_limit) ||
+ (asv_info->hpm_result <= exynos4212_limit[i].hpm_limit)) {
+ exynos_result_of_asv = i;
+ break;
+ }
+ }
+
+ }
+
+ /*
+ * If ASV result value is lower than default value
+ * Fix with default value.
+ */
+ if (exynos_result_of_asv < DEFAULT_ASV_GROUP)
+ exynos_result_of_asv = DEFAULT_ASV_GROUP;
+
+ pr_info("EXYNOS4X12(NO SG): IDS : %d HPM : %d RESULT : %d\n",
+ asv_info->ids_result, asv_info->hpm_result, exynos_result_of_asv);
+
+ exynos4x12_pre_set_abb();
+
+ return 0;
+}
+
+int exynos4x12_asv_init(struct samsung_asv *asv_info)
+{
+ unsigned int tmp;
+ unsigned int exynos_orig_sp;
+ unsigned int exynos_mod_sp;
+ int exynos_cal_asv;
+
+ exynos_result_of_asv = 0;
+
+ pr_info("EXYNOS4X12: Adaptive Support Voltage init\n");
+
+ tmp = __raw_readl(CHIP_ID_REG);
+
+ /* Store PKG_ID */
+ asv_info->pkg_id = tmp;
+
+ /* If Speed group is fused, get speed group from */
+ if ((tmp >> FUSED_SG_OFFSET) & 0x1) {
+ exynos_orig_sp = (tmp >> ORIG_SG_OFFSET) & ORIG_SG_MASK;
+ exynos_mod_sp = (tmp >> MOD_SG_OFFSET) & MOD_SG_MASK;
+
+ exynos_cal_asv = exynos_orig_sp - exynos_mod_sp;
+
+ /*
+ * If There is no origin speed group,
+ * store 1 asv group into exynos_result_of_asv.
+ */
+ if (!exynos_orig_sp) {
+ pr_info("EXYNOS4X12: No Origin speed Group\n");
+ exynos_result_of_asv = DEFAULT_ASV_GROUP;
+ } else {
+ if (exynos_cal_asv < DEFAULT_ASV_GROUP)
+ exynos_result_of_asv = DEFAULT_ASV_GROUP;
+ else
+ exynos_result_of_asv = exynos_cal_asv;
+ }
+
+ pr_info("EXYNOS4X12(SG): ORIG : %d MOD : %d RESULT : %d\n",
+ exynos_orig_sp, exynos_mod_sp, exynos_result_of_asv);
+
+ exynos4x12_pre_set_abb();
+
+ return -EEXIST;
+ }
+
+ asv_info->get_ids = exynos4x12_get_ids;
+ asv_info->get_hpm = exynos4x12_get_hpm;
+ asv_info->store_result = exynos4x12_asv_store_result;
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/asv-5250.c b/arch/arm/mach-exynos/asv-5250.c
new file mode 100644
index 0000000..867154f
--- /dev/null
+++ b/arch/arm/mach-exynos/asv-5250.c
@@ -0,0 +1,200 @@
+/* linux/arch/arm/mach-exynos/asv-4x12.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS5250 - ASV(Adaptive Supply Voltage) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/string.h>
+
+#include <mach/asv.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+
+/* ASV function for Fused Chip */
+#define IDS_ARM_OFFSET 24
+#define IDS_ARM_MASK 0xFF
+#define HPM_OFFSET 12
+#define HPM_MASK 0x1F
+
+#define FUSED_SG_OFFSET 3
+#define ORIG_SG_OFFSET 17
+#define ORIG_SG_MASK 0xF
+#define MOD_SG_OFFSET 21
+#define MOD_SG_MASK 0x7
+
+#define DEFAULT_ASV_GROUP 1
+
+#define CHIP_ID_REG (S5P_VA_CHIPID + 0x4)
+#define LOT_ID_REG (S5P_VA_CHIPID + 0x14)
+
+struct asv_judge_table exynos5250_limit[] = {
+ /* HPM, IDS */
+ { 0, 0}, /* Reserved Group */
+ { 9, 7},
+ { 10, 9},
+ { 12, 11},
+ { 14, 14},
+ { 15, 17},
+ { 16, 20},
+ { 17, 23},
+ { 18, 27},
+ { 19, 30},
+ {100, 100},
+ {999, 999}, /* Reserved Group */
+};
+
+static int exynos5250_get_hpm(struct samsung_asv *asv_info)
+{
+ asv_info->hpm_result = (asv_info->pkg_id >> HPM_OFFSET) & HPM_MASK;
+
+ return 0;
+}
+
+static int exynos5250_get_ids(struct samsung_asv *asv_info)
+{
+ asv_info->ids_result = (asv_info->pkg_id >> IDS_ARM_OFFSET) & IDS_ARM_MASK;
+
+ return 0;
+}
+
+/*
+ * If lot id is "NZVPU", it is need to modify for ARM_IDS value
+ */
+static int exynos5250_check_lot_id(void)
+{
+ unsigned int lid_reg = 0;
+ unsigned int rev_lid = 0;
+ unsigned int i;
+ unsigned int tmp;
+ char lot_id[5];
+
+ lid_reg = __raw_readl(LOT_ID_REG);
+
+ for (i = 0; i < 32; i++) {
+ tmp = (lid_reg >> i) & 0x1;
+ rev_lid += tmp << (31 - i);
+ }
+
+ lot_id[0] = 'N';
+ lid_reg = (rev_lid >> 11) & 0x1FFFFF;
+
+ for (i = 4; i >= 1; i--) {
+ tmp = lid_reg % 36;
+ lid_reg /= 36;
+ lot_id[i] = (tmp < 10) ? (tmp + '0') : ((tmp - 10) + 'A');
+ }
+
+ return strncmp(lot_id, "NZVPU", ARRAY_SIZE(lot_id));
+}
+
+static void exynos5250_pre_set_abb(void)
+{
+ switch (exynos_result_of_asv) {
+ case 0:
+ case 1:
+ case 2:
+ exynos4x12_set_abb(ABB_MODE_080V);
+ break;
+ case 3:
+ case 4:
+ exynos4x12_set_abb(ABB_MODE_BYPASS);
+ break;
+ default:
+ exynos4x12_set_abb(ABB_MODE_130V);
+ break;
+ }
+}
+
+static int exynos5250_asv_store_result(struct samsung_asv *asv_info)
+{
+ unsigned int i;
+
+ if (!exynos5250_check_lot_id())
+ asv_info->ids_result -= 15;
+
+ if (soc_is_exynos5250()) {
+ for (i = 0; i < ARRAY_SIZE(exynos5250_limit); i++) {
+ if ((asv_info->ids_result <= exynos5250_limit[i].ids_limit) ||
+ (asv_info->hpm_result <= exynos5250_limit[i].hpm_limit)) {
+ exynos_result_of_asv = i;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If ASV result value is lower than default value
+ * Fix with default value.
+ */
+ if (exynos_result_of_asv < DEFAULT_ASV_GROUP)
+ exynos_result_of_asv = DEFAULT_ASV_GROUP;
+
+ pr_info("EXYNOS5250(NO SG): IDS : %d HPM : %d RESULT : %d\n",
+ asv_info->ids_result, asv_info->hpm_result, exynos_result_of_asv);
+
+ exynos5250_pre_set_abb();
+
+ return 0;
+}
+
+int exynos5250_asv_init(struct samsung_asv *asv_info)
+{
+ unsigned int tmp;
+ unsigned int exynos_orig_sp;
+ unsigned int exynos_mod_sp;
+ int exynos_cal_asv;
+
+ exynos_result_of_asv = 0;
+
+ pr_info("EXYNOS5250: Adaptive Support Voltage init\n");
+
+ tmp = __raw_readl(CHIP_ID_REG);
+
+ /* Store PKG_ID */
+ asv_info->pkg_id = tmp;
+
+ /* If Speed group is fused, get speed group from */
+ if ((tmp >> FUSED_SG_OFFSET) & 0x1) {
+ exynos_orig_sp = (tmp >> ORIG_SG_OFFSET) & ORIG_SG_MASK;
+ exynos_mod_sp = (tmp >> MOD_SG_OFFSET) & MOD_SG_MASK;
+
+ exynos_cal_asv = exynos_orig_sp - exynos_mod_sp;
+ /*
+ * If There is no origin speed group,
+ * store 1 asv group into exynos_result_of_asv.
+ */
+ if (!exynos_orig_sp) {
+ pr_info("EXYNOS5250: No Origin speed Group\n");
+ exynos_result_of_asv = DEFAULT_ASV_GROUP;
+ } else {
+ if (exynos_cal_asv < DEFAULT_ASV_GROUP)
+ exynos_result_of_asv = DEFAULT_ASV_GROUP;
+ else
+ exynos_result_of_asv = exynos_cal_asv;
+ }
+
+ pr_info("EXYNOS5250(SG): ORIG : %d MOD : %d RESULT : %d\n",
+ exynos_orig_sp, exynos_mod_sp, exynos_result_of_asv);
+
+ return -EEXIST;
+ }
+
+ asv_info->get_ids = exynos5250_get_ids;
+ asv_info->get_hpm = exynos5250_get_hpm;
+ asv_info->store_result = exynos5250_asv_store_result;
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/asv.c b/arch/arm/mach-exynos/asv.c
new file mode 100644
index 0000000..4a58ad0
--- /dev/null
+++ b/arch/arm/mach-exynos/asv.c
@@ -0,0 +1,105 @@
+/* linux/arch/arm/mach-exynos/asv.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - ASV(Adaptive Supply Voltage) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <plat/cpu.h>
+
+#include <mach/map.h>
+#include <mach/regs-iem.h>
+#include <mach/asv.h>
+
+static struct samsung_asv *exynos_asv;
+unsigned int exynos_result_of_asv;
+
+static int __init exynos4_asv_init(void)
+{
+ int ret = -EINVAL;
+
+ exynos_asv = kzalloc(sizeof(struct samsung_asv), GFP_KERNEL);
+ if (!exynos_asv)
+ goto out1;
+
+ if (soc_is_exynos4210())
+ ret = exynos4210_asv_init(exynos_asv);
+ else if (soc_is_exynos4412() || soc_is_exynos4212()) {
+ ret = exynos4x12_asv_init(exynos_asv);
+
+ /*
+ * If return value is not zero,
+ * There is already value for asv group.
+ * So, It is not necessary to execute for getting asv group.
+ */
+ if (ret) {
+ kfree(exynos_asv);
+ return 0;
+ }
+ } else if (soc_is_exynos5250()) {
+ ret = exynos5250_asv_init(exynos_asv);
+ if (ret)
+ return 0;
+ } else {
+ pr_info("EXYNOS: There is no type for ASV\n");
+ goto out2;
+ }
+
+ if (exynos_asv->check_vdd_arm) {
+ if (exynos_asv->check_vdd_arm()) {
+ pr_info("EXYNOS: It is wrong vdd_arm\n");
+ goto out2;
+ }
+ }
+
+ /* Get HPM Delay value */
+ if (exynos_asv->get_hpm) {
+ if (exynos_asv->get_hpm(exynos_asv)) {
+ pr_info("EXYNOS: Fail to get HPM Value\n");
+ goto out2;
+ }
+ } else {
+ pr_info("EXYNOS: Fail to get HPM Value\n");
+ goto out2;
+ }
+
+ /* Get IDS ARM Value */
+ if (exynos_asv->get_ids) {
+ if (exynos_asv->get_ids(exynos_asv)) {
+ pr_info("EXYNOS: Fail to get IDS Value\n");
+ goto out2;
+ }
+ } else {
+ pr_info("EXYNOS: Fail to get IDS Value\n");
+ goto out2;
+ }
+
+ if (exynos_asv->store_result) {
+ if (exynos_asv->store_result(exynos_asv)) {
+ pr_info("EXYNOS: Can not success to store result\n");
+ goto out2;
+ }
+ } else {
+ pr_info("EXYNOS: No store_result function\n");
+ goto out2;
+ }
+
+ return 0;
+out2:
+ kfree(exynos_asv);
+out1:
+ return -EINVAL;
+}
+device_initcall_sync(exynos4_asv_init);
diff --git a/arch/arm/mach-exynos/bcm47511.c b/arch/arm/mach-exynos/bcm47511.c
new file mode 100644
index 0000000..1ae2c8b
--- /dev/null
+++ b/arch/arm/mach-exynos/bcm47511.c
@@ -0,0 +1,253 @@
+/*
+ * bcm47511.c: Machine specific driver for GPS module
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ * Minho Ban <mhban@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/rfkill.h>
+#include <linux/regulator/machine.h>
+
+#include <mach/gpio.h>
+#include <mach/bcm47511.h>
+
+#include <plat/gpio-cfg.h>
+
+struct bcm47511_data {
+ struct bcm47511_platform_data *pdata;
+ struct rfkill *rfk;
+ bool in_use;
+ bool regulator_state;
+ struct regulator *regulator;
+};
+
+static void bcm47511_enable(void *data)
+{
+ struct bcm47511_data *bd = data;
+ struct bcm47511_platform_data *pdata = bd->pdata;
+
+ if (bd->regulator && !bd->regulator_state) {
+ regulator_enable(bd->regulator);
+ bd->regulator_state = true;
+ }
+
+ gpio_set_value(pdata->regpu, 1);
+
+ if (gpio_is_valid(pdata->nrst))
+ gpio_set_value(pdata->nrst, 1);
+
+ if (gpio_is_valid(pdata->gps_cntl))
+ gpio_set_value(pdata->gps_cntl, 1);
+
+ bd->in_use = true;
+}
+
+static void bcm47511_disable(void *data)
+{
+ struct bcm47511_data *bd = data;
+ struct bcm47511_platform_data *pdata = bd->pdata;
+
+ gpio_set_value(pdata->regpu, 0);
+
+ if (gpio_is_valid(pdata->gps_cntl))
+ gpio_set_value(pdata->gps_cntl, 0);
+
+ if (bd->regulator && bd->regulator_state) {
+ regulator_disable(bd->regulator);
+ bd->regulator_state = false;
+ }
+
+ bd->in_use = false;
+}
+
+static int bcm47511_set_block(void *data, bool blocked)
+{
+ if (!blocked) {
+ printk(KERN_INFO "%s : Enable GPS chip\n", __func__);
+ bcm47511_enable(data);
+ } else {
+ printk(KERN_INFO "%s : Disable GPS chip\n", __func__);
+ bcm47511_disable(data);
+ }
+ return 0;
+}
+
+static const struct rfkill_ops bcm47511_rfkill_ops = {
+ .set_block = bcm47511_set_block,
+};
+
+static int __devinit bcm47511_probe(struct platform_device *dev)
+{
+ struct bcm47511_platform_data *pdata;
+ struct bcm47511_data *bd;
+ int gpio;
+ int ret = 0;
+
+ pdata = dev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&dev->dev, "No plat data.\n");
+ return -EINVAL;
+ }
+
+ if (!pdata->reg32khz) {
+ dev_err(&dev->dev, "No 32KHz clock id.\n");
+ return -EINVAL;
+ }
+
+ bd = kzalloc(sizeof(struct bcm47511_data), GFP_KERNEL);
+ if (!bd)
+ return -ENOMEM;
+
+ bd->pdata = pdata;
+
+ if (gpio_is_valid(pdata->regpu)) {
+ gpio = pdata->regpu;
+
+ /* GPS_EN is low */
+ gpio_request(gpio, "GPS_EN");
+ gpio_direction_output(gpio, 0);
+ }
+
+ if (gpio_is_valid(pdata->nrst)) {
+ gpio = pdata->nrst;
+ /* GPS_nRST is high */
+ gpio_request(gpio, "GPS_nRST");
+ gpio_direction_output(gpio, 1);
+ }
+
+ /* GPS_UART_RXD */
+ if (gpio_is_valid(pdata->uart_rxd))
+ s3c_gpio_setpull(pdata->uart_rxd, S3C_GPIO_PULL_UP);
+
+ if (gpio_is_valid(pdata->gps_cntl)) {
+ gpio = pdata->gps_cntl;
+ gpio_request(gpio, "GPS_CNTL");
+ gpio_direction_output(gpio, 0);
+ }
+
+ /* Register BCM47511 to RFKILL class */
+ bd->rfk = rfkill_alloc("bcm47511", &dev->dev, RFKILL_TYPE_GPS,
+ &bcm47511_rfkill_ops, bd);
+ if (!bd->rfk) {
+ ret = -ENOMEM;
+ goto err_rfk_alloc;
+ }
+
+ bd->regulator = regulator_get(&dev->dev, pdata->reg32khz);
+ if (IS_ERR_OR_NULL(bd->regulator)) {
+ dev_err(&dev->dev, "regulator_get error (%ld)\n",
+ PTR_ERR(bd->regulator));
+ goto err_regulator;
+ }
+
+ bd->regulator_state = false;
+
+ /*
+ * described by the comment in rfkill.h
+ * true : turn off
+ * false : turn on
+ */
+ rfkill_init_sw_state(bd->rfk, true);
+ bd->in_use = false;
+
+ ret = rfkill_register(bd->rfk);
+ if (ret)
+ goto err_rfkill;
+
+ platform_set_drvdata(dev, bd);
+
+ dev_info(&dev->dev, "ready\n");
+
+ return 0;
+
+err_rfkill:
+ rfkill_destroy(bd->rfk);
+err_regulator:
+err_rfk_alloc:
+ kfree(bd);
+ return ret;
+}
+
+static int __devexit bcm47511_remove(struct platform_device *dev)
+{
+ struct bcm47511_data *bd = platform_get_drvdata(dev);
+ struct bcm47511_platform_data *pdata = bd->pdata;
+
+ rfkill_unregister(bd->rfk);
+ rfkill_destroy(bd->rfk);
+ gpio_free(pdata->regpu);
+ gpio_free(pdata->nrst);
+ kfree(bd);
+ platform_set_drvdata(dev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int bcm47511_suspend(struct platform_device *dev, pm_message_t stata)
+{
+ struct bcm47511_data *bd = platform_get_drvdata(dev);
+ struct bcm47511_platform_data *pdata = bd->pdata;
+
+ if (bd->in_use) {
+ s5p_gpio_set_pd_cfg(pdata->regpu, S5P_GPIO_PD_OUTPUT1);
+ s5p_gpio_set_pd_cfg(pdata->nrst, S5P_GPIO_PD_OUTPUT1);
+ if (gpio_is_valid(pdata->gps_cntl))
+ s5p_gpio_set_pd_cfg(pdata->gps_cntl, S5P_GPIO_PD_OUTPUT1);
+ } else {
+ s5p_gpio_set_pd_cfg(pdata->regpu, S5P_GPIO_PD_OUTPUT0);
+ s5p_gpio_set_pd_cfg(pdata->nrst, S5P_GPIO_PD_OUTPUT0);
+ if (gpio_is_valid(pdata->gps_cntl))
+ s5p_gpio_set_pd_cfg(pdata->gps_cntl, S5P_GPIO_PD_OUTPUT0);
+ }
+
+ return 0;
+}
+
+static int bcm47511_resume(struct platform_device *dev)
+{
+ return 0;
+}
+#else
+#define bcm47511_suspend NULL
+#define bcm47511_resume NULL
+#endif
+
+static struct platform_driver bcm47511_driver = {
+ .probe = bcm47511_probe,
+ .remove = __devexit_p(bcm47511_remove),
+ .suspend = bcm47511_suspend,
+ .resume = bcm47511_resume,
+ .driver = {
+ .name = "bcm47511",
+ },
+};
+
+static int __init bcm47511_init(void)
+{
+ return platform_driver_register(&bcm47511_driver);
+}
+
+static void __exit bcm47511_exit(void)
+{
+ platform_driver_unregister(&bcm47511_driver);
+}
+
+module_init(bcm47511_init);
+module_exit(bcm47511_exit);
+
+MODULE_AUTHOR("Minho Ban <mhban@samsung.com>");
+MODULE_DESCRIPTION("BCM47511 GPS module driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/board-bluetooth-bcm43241.c b/arch/arm/mach-exynos/board-bluetooth-bcm43241.c
new file mode 100644
index 0000000..d508638
--- /dev/null
+++ b/arch/arm/mach-exynos/board-bluetooth-bcm43241.c
@@ -0,0 +1,383 @@
+/*
+ * Bluetooth Broadcom GPIO and Low Power Mode control
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill.h>
+#include <linux/wakelock.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define BT_UART_CFG
+#define BT_LPM_ENABLE
+
+static struct rfkill *bt_rfkill;
+
+struct bcm_bt_lpm {
+ int wake;
+ int host_wake;
+
+ struct hrtimer enter_lpm_timer;
+ ktime_t enter_lpm_delay;
+
+ struct hci_dev *hdev;
+
+ struct wake_lock wake_lock;
+ char wake_lock_name[100];
+} bt_lpm;
+
+#ifdef BT_UART_CFG
+int bt_is_running;
+EXPORT_SYMBOL(bt_is_running);
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+static unsigned int bt_uart_on_table[][4] = {
+ {EXYNOS5_GPA0(0), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS5_GPA0(1), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS5_GPA0(2), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS5_GPA0(3), 2, 2, S3C_GPIO_PULL_NONE},
+};
+
+void bt_config_gpio_table(int array_size, unsigned int (*gpio_table)[4])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != 2)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+void bt_uart_rts_ctrl(int flag)
+{
+ if (!gpio_get_value(GPIO_BTREG_ON))
+ return;
+ if (flag) {
+ /* BT RTS Set to HIGH */
+ s3c_gpio_cfgpin(EXYNOS5_GPA0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS5_GPA0(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(EXYNOS5_GPA0(3), 1);
+ s3c_gpio_slp_cfgpin(EXYNOS5_GPA0(3), S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(EXYNOS5_GPA0(3), S3C_GPIO_PULL_NONE);
+ } else {
+ /* BT RTS Set to LOW */
+ s3c_gpio_cfgpin(EXYNOS5_GPA0(3), S3C_GPIO_OUTPUT);
+ gpio_set_value(EXYNOS5_GPA0(3), 0);
+ s3c_gpio_cfgpin(EXYNOS5_GPA0(3), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPA0(3), S3C_GPIO_PULL_NONE);
+ }
+}
+EXPORT_SYMBOL(bt_uart_rts_ctrl);
+#endif
+
+static int bcm43241_bt_rfkill_set_power(void *data, bool blocked)
+{
+ /* rfkill_ops callback. Turn transmitter on when blocked is false */
+ if (!blocked) {
+ pr_info("[BT] Bluetooth Power On.\n");
+#ifdef BT_UART_CFG
+ bt_config_gpio_table(ARRAY_SIZE(bt_uart_on_table),
+ bt_uart_on_table);
+#endif
+ gpio_set_value(GPIO_BTREG_ON, 1);
+ msleep(50);
+ } else {
+ pr_info("[BT] Bluetooth Power Off.\n");
+ bt_is_running = 0;
+ gpio_set_value(GPIO_BTREG_ON, 0);
+ }
+ return 0;
+}
+
+static const struct rfkill_ops bcm43241_bt_rfkill_ops = {
+ .set_block = bcm43241_bt_rfkill_set_power,
+};
+
+#ifdef BT_LPM_ENABLE
+static void set_wake_locked(int wake)
+{
+ bt_lpm.wake = wake;
+
+ if (!wake)
+ wake_unlock(&bt_lpm.wake_lock);
+
+ gpio_set_value(GPIO_BT_WAKE, wake);
+}
+
+static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
+{
+ unsigned long flags;
+
+ if (bt_lpm.hdev != NULL) {
+ spin_lock_irqsave(&bt_lpm.hdev->lock, flags);
+ set_wake_locked(0);
+ spin_unlock_irqrestore(&bt_lpm.hdev->lock, flags);
+ }
+
+ bt_is_running = 0;
+
+ return HRTIMER_NORESTART;
+}
+
+static void bcm_bt_lpm_exit_lpm_locked(struct hci_dev *hdev)
+{
+ bt_lpm.hdev = hdev;
+
+ hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
+ bt_is_running = 1;
+ set_wake_locked(1);
+
+ pr_debug("[BT] bcm_bt_lpm_exit_lpm_locked\n");
+ hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
+ HRTIMER_MODE_REL);
+}
+
+static void update_host_wake_locked(int host_wake)
+{
+ if (host_wake == bt_lpm.host_wake)
+ return;
+
+ bt_lpm.host_wake = host_wake;
+
+ bt_is_running = 1;
+
+ if (host_wake) {
+ wake_lock(&bt_lpm.wake_lock);
+ } else {
+ /* Take a timed wakelock, so that upper layers can take it.
+ * The chipset deasserts the hostwake lock, when there is no
+ * more data to send.
+ */
+ wake_lock_timeout(&bt_lpm.wake_lock, HZ/2);
+ }
+}
+
+static irqreturn_t host_wake_isr(int irq, void *dev)
+{
+ int host_wake;
+ unsigned long flags;
+
+ host_wake = gpio_get_value(GPIO_BT_HOST_WAKE);
+ irq_set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
+
+ if (!bt_lpm.hdev) {
+ bt_lpm.host_wake = host_wake;
+ return IRQ_HANDLED;
+ }
+
+ spin_lock_irqsave(&bt_lpm.hdev->lock, flags);
+ update_host_wake_locked(host_wake);
+ spin_unlock_irqrestore(&bt_lpm.hdev->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int bcm_bt_lpm_init(struct platform_device *pdev)
+{
+ int irq;
+ int ret;
+
+ hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ bt_lpm.enter_lpm_delay = ktime_set(1, 0); /* 1 sec */
+ bt_lpm.enter_lpm_timer.function = enter_lpm;
+
+ bt_lpm.host_wake = 0;
+ bt_is_running = 0;
+
+ snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name),
+ "BTLowPower");
+ wake_lock_init(&bt_lpm.wake_lock, WAKE_LOCK_SUSPEND,
+ bt_lpm.wake_lock_name);
+
+ irq = IRQ_BT_HOST_WAKE;
+ ret = request_irq(irq, host_wake_isr, IRQF_TRIGGER_HIGH,
+ "bt host_wake", NULL);
+ if (ret) {
+ pr_err("[BT] Request_host wake irq failed.\n");
+ return ret;
+ }
+
+ ret = irq_set_irq_wake(irq, 1);
+ if (ret) {
+ pr_err("[BT] Set_irq_wake failed.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bcm_hci_wake_peer(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct hci_dev *hdev = (struct hci_dev *) ptr;
+
+ if (event == HCI_DEV_REG) {
+ if (hdev != NULL) {
+ hdev->wake_peer = bcm_bt_lpm_exit_lpm_locked;
+ pr_info("[BT] wake_peer is registered.\n");
+ }
+ } else if (event == HCI_DEV_UNREG) {
+ pr_info("[BT] %s: handle HCI_DEV_UNREG noti\n", __func__);
+ if (hdev != NULL && bt_lpm.hdev == hdev) {
+ bt_lpm.hdev = NULL;
+ pr_info("[BT] bt_lpm.hdev set to NULL\n");
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block bcm_bt_nblock = {
+ .notifier_call = bcm_hci_wake_peer
+};
+#endif
+
+static int bcm43241_bluetooth_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ int ret;
+
+ rc = gpio_request(GPIO_BTREG_ON, "bcm43241_bten_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BTREG_ON request failed.\n");
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_WAKE, "bcm43241_btwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_WAKE request failed.\n");
+ gpio_free(GPIO_BTREG_ON);
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_HOST_WAKE, "bcm43241_bthostwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_HOST_WAKE request failed.\n");
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BTREG_ON);
+ return rc;
+ }
+ gpio_direction_input(GPIO_BT_HOST_WAKE);
+ gpio_direction_output(GPIO_BT_WAKE, 0);
+ gpio_direction_output(GPIO_BTREG_ON, 0);
+
+ bt_rfkill = rfkill_alloc("bcm43241 Bluetooth", &pdev->dev,
+ RFKILL_TYPE_BLUETOOTH, &bcm43241_bt_rfkill_ops,
+ NULL);
+
+ if (unlikely(!bt_rfkill)) {
+ pr_err("[BT] bt_rfkill alloc failed.\n");
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BTREG_ON);
+ return -ENOMEM;
+ }
+
+ rfkill_init_sw_state(bt_rfkill, 0);
+
+ rc = rfkill_register(bt_rfkill);
+
+ if (unlikely(rc)) {
+ pr_err("[BT] bt_rfkill register failed.\n");
+ rfkill_destroy(bt_rfkill);
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BTREG_ON);
+ return -1;
+ }
+
+ rfkill_set_sw_state(bt_rfkill, true);
+
+#ifdef BT_LPM_ENABLE
+ ret = bcm_bt_lpm_init(pdev);
+ if (ret) {
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BTREG_ON);
+ }
+
+ hci_register_notifier(&bcm_bt_nblock);
+#endif
+ return rc;
+}
+
+static int bcm43241_bluetooth_remove(struct platform_device *pdev)
+{
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BTREG_ON);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_HOST_WAKE);
+
+ wake_lock_destroy(&bt_lpm.wake_lock);
+
+#ifdef BT_LPM_ENABLE
+ hci_unregister_notifier(&bcm_bt_nblock);
+#endif
+ return 0;
+}
+
+static struct platform_driver bcm43241_bluetooth_platform_driver = {
+ .probe = bcm43241_bluetooth_probe,
+ .remove = bcm43241_bluetooth_remove,
+ .driver = {
+ .name = "bcm43241_bluetooth",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bcm43241_bluetooth_init(void)
+{
+ return platform_driver_register(&bcm43241_bluetooth_platform_driver);
+}
+
+static void __exit bcm43241_bluetooth_exit(void)
+{
+ platform_driver_unregister(&bcm43241_bluetooth_platform_driver);
+}
+
+
+module_init(bcm43241_bluetooth_init);
+module_exit(bcm43241_bluetooth_exit);
+
+MODULE_ALIAS("platform:bcm43241");
+MODULE_DESCRIPTION("bcm43241_bluetooth");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/board-bluetooth-bcm4330.c b/arch/arm/mach-exynos/board-bluetooth-bcm4330.c
new file mode 100644
index 0000000..624d81a
--- /dev/null
+++ b/arch/arm/mach-exynos/board-bluetooth-bcm4330.c
@@ -0,0 +1,360 @@
+/*
+ * Bluetooth Broadcom GPIO and Low Power Mode control
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill.h>
+#include <linux/serial_core.h>
+#include <linux/wakelock.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define BT_UART_CFG
+#define BT_LPM_ENABLE
+
+static struct rfkill *bt_rfkill;
+
+struct bcm_bt_lpm {
+ int host_wake;
+
+ struct hrtimer enter_lpm_timer;
+ ktime_t enter_lpm_delay;
+
+ struct uart_port *uport;
+
+ struct wake_lock wake_lock;
+ char wake_lock_name[100];
+} bt_lpm;
+
+#ifdef BT_UART_CFG
+int bt_is_running;
+EXPORT_SYMBOL(bt_is_running);
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+static unsigned int bt_uart_on_table[][4] = {
+ {EXYNOS4_GPA0(0), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), 2, 2, S3C_GPIO_PULL_NONE},
+};
+
+void bt_config_gpio_table(int array_size, unsigned int (*gpio_table)[4])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != 2)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+void bt_uart_rts_ctrl(int flag)
+{
+ if (!gpio_get_value(GPIO_BT_EN))
+ return;
+ if (flag) {
+ /* BT RTS Set to HIGH */
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(EXYNOS4_GPA0(3), 1);
+ s3c_gpio_slp_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ } else {
+ /* BT RTS Set to LOW */
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_OUTPUT);
+ gpio_set_value(EXYNOS4_GPA0(3), 0);
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ }
+}
+EXPORT_SYMBOL(bt_uart_rts_ctrl);
+#endif
+
+static int bcm4330_bt_rfkill_set_power(void *data, bool blocked)
+{
+ /* rfkill_ops callback. Turn transmitter on when blocked is false */
+ if (!blocked) {
+ pr_info("[BT] Bluetooth Power On.\n");
+#ifdef BT_UART_CFG
+ bt_config_gpio_table(ARRAY_SIZE(bt_uart_on_table),
+ bt_uart_on_table);
+#endif
+ gpio_set_value(GPIO_BT_EN, 1);
+ msleep(20);
+ gpio_set_value(GPIO_BT_nRST, 1);
+ msleep(50);
+ } else {
+ pr_info("[BT] Bluetooth Power Off.\n");
+ bt_is_running = 0;
+ gpio_set_value(GPIO_BT_nRST, 0);
+ gpio_set_value(GPIO_BT_EN, 0);
+ }
+ return 0;
+}
+
+static const struct rfkill_ops bcm4330_bt_rfkill_ops = {
+ .set_block = bcm4330_bt_rfkill_set_power,
+};
+
+#ifdef BT_LPM_ENABLE
+static void set_wake_locked(int wake)
+{
+
+ if (!wake)
+ wake_unlock(&bt_lpm.wake_lock);
+
+ gpio_set_value(GPIO_BT_WAKE, wake);
+}
+
+static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&bt_lpm.uport->lock, flags);
+ bt_is_running = 0;
+ set_wake_locked(0);
+ spin_unlock_irqrestore(&bt_lpm.uport->lock, flags);
+
+ return HRTIMER_NORESTART;
+}
+
+void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport)
+{
+ bt_lpm.uport = uport;
+
+ hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
+ bt_is_running = 1;
+ set_wake_locked(1);
+
+ hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
+ HRTIMER_MODE_REL);
+}
+EXPORT_SYMBOL(bcm_bt_lpm_exit_lpm_locked);
+
+static void update_host_wake_locked(int host_wake)
+{
+ if (host_wake == bt_lpm.host_wake)
+ return;
+
+ bt_lpm.host_wake = host_wake;
+
+ bt_is_running = 1;
+ if (host_wake) {
+ wake_lock(&bt_lpm.wake_lock);
+ } else {
+ /* Take a timed wakelock, so that upper layers can take it.
+ * The chipset deasserts the hostwake lock, when there is no
+ * more data to send.
+ */
+ wake_lock_timeout(&bt_lpm.wake_lock, HZ/2);
+ }
+}
+
+static irqreturn_t host_wake_isr(int irq, void *dev)
+{
+ int host_wake;
+ unsigned long flags;
+
+ host_wake = gpio_get_value(GPIO_BT_HOST_WAKE);
+ irq_set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
+
+ if (!bt_lpm.uport) {
+ bt_lpm.host_wake = host_wake;
+ return IRQ_HANDLED;
+ }
+
+ spin_lock_irqsave(&bt_lpm.uport->lock, flags);
+ update_host_wake_locked(host_wake);
+ spin_unlock_irqrestore(&bt_lpm.uport->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int bcm_bt_lpm_init(struct platform_device *pdev)
+{
+ int irq;
+ int ret;
+
+ hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ bt_lpm.enter_lpm_delay = ktime_set(1, 0); /* 1 sec */
+ bt_lpm.enter_lpm_timer.function = enter_lpm;
+
+ bt_lpm.host_wake = 0;
+ bt_is_running = 0;
+
+ snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name),
+ "BTLowPower");
+ wake_lock_init(&bt_lpm.wake_lock, WAKE_LOCK_SUSPEND,
+ bt_lpm.wake_lock_name);
+
+ irq = IRQ_BT_HOST_WAKE;
+ ret = request_irq(irq, host_wake_isr, IRQF_TRIGGER_HIGH,
+ "bt host_wake", NULL);
+ if (ret) {
+ pr_err("[BT] Request_host wake irq failed.\n");
+ return ret;
+ }
+
+ ret = irq_set_irq_wake(irq, 1);
+ if (ret) {
+ pr_err("[BT] Set_irq_wake failed.\n");
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+static int bcm4330_bluetooth_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ int ret;
+
+ rc = gpio_request(GPIO_BT_EN, "bcm4330_bten_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_EN request failed.\n");
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_nRST, "bcm4330_btnrst_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_nRST request failed.\n");
+ gpio_free(GPIO_BT_EN);
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_WAKE, "bcm4330_btwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_WAKE request failed.\n");
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_EN);
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_HOST_WAKE, "bcm4330_bthostwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_HOST_WAKE request failed.\n");
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_EN);
+ return rc;
+ }
+ gpio_direction_input(GPIO_BT_HOST_WAKE);
+ gpio_direction_output(GPIO_BT_WAKE, 0);
+ gpio_direction_output(GPIO_BT_nRST, 0);
+ gpio_direction_output(GPIO_BT_EN, 0);
+
+ bt_rfkill = rfkill_alloc("bcm4330 Bluetooth", &pdev->dev,
+ RFKILL_TYPE_BLUETOOTH, &bcm4330_bt_rfkill_ops,
+ NULL);
+
+ if (unlikely(!bt_rfkill)) {
+ pr_err("[BT] bt_rfkill alloc failed.\n");
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_EN);
+ return -ENOMEM;
+ }
+
+ rfkill_init_sw_state(bt_rfkill, 0);
+
+ rc = rfkill_register(bt_rfkill);
+
+ if (unlikely(rc)) {
+ pr_err("[BT] bt_rfkill register failed.\n");
+ rfkill_destroy(bt_rfkill);
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_EN);
+ return -1;
+ }
+
+ rfkill_set_sw_state(bt_rfkill, true);
+
+#ifdef BT_LPM_ENABLE
+ ret = bcm_bt_lpm_init(pdev);
+ if (ret) {
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_EN);
+ }
+#endif
+ return rc;
+}
+
+static int bcm4330_bluetooth_remove(struct platform_device *pdev)
+{
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_EN);
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_HOST_WAKE);
+
+ wake_lock_destroy(&bt_lpm.wake_lock);
+ return 0;
+}
+
+static struct platform_driver bcm4330_bluetooth_platform_driver = {
+ .probe = bcm4330_bluetooth_probe,
+ .remove = bcm4330_bluetooth_remove,
+ .driver = {
+ .name = "bcm4330_bluetooth",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bcm4330_bluetooth_init(void)
+{
+ return platform_driver_register(&bcm4330_bluetooth_platform_driver);
+}
+
+static void __exit bcm4330_bluetooth_exit(void)
+{
+ platform_driver_unregister(&bcm4330_bluetooth_platform_driver);
+}
+
+
+module_init(bcm4330_bluetooth_init);
+module_exit(bcm4330_bluetooth_exit);
+
+MODULE_ALIAS("platform:bcm4330");
+MODULE_DESCRIPTION("bcm4330_bluetooth");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/board-bluetooth-bcm4334.c b/arch/arm/mach-exynos/board-bluetooth-bcm4334.c
new file mode 100644
index 0000000..7d7c00e
--- /dev/null
+++ b/arch/arm/mach-exynos/board-bluetooth-bcm4334.c
@@ -0,0 +1,380 @@
+/*
+ * Bluetooth Broadcom GPIO and Low Power Mode control
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill.h>
+#include <linux/wakelock.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define BT_UART_CFG
+#define BT_LPM_ENABLE
+
+static struct rfkill *bt_rfkill;
+
+struct bcm_bt_lpm {
+ int host_wake;
+
+ struct hrtimer enter_lpm_timer;
+ ktime_t enter_lpm_delay;
+
+ struct hci_dev *hdev;
+
+ struct wake_lock host_wake_lock;
+ struct wake_lock bt_wake_lock;
+ char wake_lock_name[100];
+} bt_lpm;
+
+#ifdef BT_UART_CFG
+int bt_is_running;
+EXPORT_SYMBOL(bt_is_running);
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+static unsigned int bt_uart_on_table[][4] = {
+ {EXYNOS4_GPA0(0), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), 2, 2, S3C_GPIO_PULL_NONE},
+};
+
+void bt_config_gpio_table(int array_size, unsigned int (*gpio_table)[4])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != 2)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+void bt_uart_rts_ctrl(int flag)
+{
+ if (!gpio_get_value(GPIO_BT_EN))
+ return;
+ if (flag) {
+ /* BT RTS Set to HIGH */
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(EXYNOS4_GPA0(3), 1);
+ s3c_gpio_slp_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ } else {
+ /* BT RTS Set to LOW */
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_OUTPUT);
+ gpio_set_value(EXYNOS4_GPA0(3), 0);
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ }
+}
+EXPORT_SYMBOL(bt_uart_rts_ctrl);
+#endif
+
+static int bcm4334_bt_rfkill_set_power(void *data, bool blocked)
+{
+ /* rfkill_ops callback. Turn transmitter on when blocked is false */
+ if (!blocked) {
+ pr_info("[BT] Bluetooth Power On.\n");
+#ifdef BT_UART_CFG
+ bt_config_gpio_table(ARRAY_SIZE(bt_uart_on_table),
+ bt_uart_on_table);
+#endif
+ gpio_set_value(GPIO_BT_EN, 1);
+ msleep(50);
+ } else {
+ pr_info("[BT] Bluetooth Power Off.\n");
+ bt_is_running = 0;
+ gpio_set_value(GPIO_BT_EN, 0);
+ }
+ return 0;
+}
+
+static const struct rfkill_ops bcm4334_bt_rfkill_ops = {
+ .set_block = bcm4334_bt_rfkill_set_power,
+};
+
+#ifdef BT_LPM_ENABLE
+static void set_wake_locked(int wake)
+{
+ if (wake)
+ wake_lock(&bt_lpm.bt_wake_lock);
+
+ gpio_set_value(GPIO_BT_WAKE, wake);
+}
+
+static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
+{
+ if (bt_lpm.hdev != NULL)
+ set_wake_locked(0);
+
+ bt_is_running = 0;
+ wake_lock_timeout(&bt_lpm.bt_wake_lock, HZ/2);
+
+ return HRTIMER_NORESTART;
+}
+
+static void bcm_bt_lpm_exit_lpm_locked(struct hci_dev *hdev)
+{
+ bt_lpm.hdev = hdev;
+
+ hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
+ bt_is_running = 1;
+ set_wake_locked(1);
+
+ pr_debug("[BT] bcm_bt_lpm_exit_lpm_locked\n");
+ hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
+ HRTIMER_MODE_REL);
+}
+
+static void update_host_wake_locked(int host_wake)
+{
+ if (host_wake == bt_lpm.host_wake)
+ return;
+
+ bt_lpm.host_wake = host_wake;
+
+ bt_is_running = 1;
+
+ if (host_wake) {
+ wake_lock(&bt_lpm.host_wake_lock);
+ } else {
+ /* Take a timed wakelock, so that upper layers can take it.
+ * The chipset deasserts the hostwake lock, when there is no
+ * more data to send.
+ */
+ wake_lock_timeout(&bt_lpm.host_wake_lock, HZ/2);
+ }
+}
+
+static irqreturn_t host_wake_isr(int irq, void *dev)
+{
+ int host_wake;
+
+ host_wake = gpio_get_value(GPIO_BT_HOST_WAKE);
+ irq_set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
+
+ if (!bt_lpm.hdev) {
+ bt_lpm.host_wake = host_wake;
+ return IRQ_HANDLED;
+ }
+
+ update_host_wake_locked(host_wake);
+
+ return IRQ_HANDLED;
+}
+
+static int bcm_bt_lpm_init(struct platform_device *pdev)
+{
+ int irq;
+ int ret;
+
+ hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ bt_lpm.enter_lpm_delay = ktime_set(4, 0); /* 1 sec */ /*1->3*//*3->4*/
+ bt_lpm.enter_lpm_timer.function = enter_lpm;
+
+ bt_lpm.host_wake = 0;
+ bt_is_running = 0;
+
+ snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name),
+ "BT_host_wake");
+ wake_lock_init(&bt_lpm.host_wake_lock, WAKE_LOCK_SUSPEND,
+ bt_lpm.wake_lock_name);
+
+ snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name),
+ "BT_bt_wake");
+ wake_lock_init(&bt_lpm.bt_wake_lock, WAKE_LOCK_SUSPEND,
+ bt_lpm.wake_lock_name);
+
+ irq = IRQ_BT_HOST_WAKE;
+ ret = request_irq(irq, host_wake_isr, IRQF_TRIGGER_HIGH,
+ "bt host_wake", NULL);
+ if (ret) {
+ pr_err("[BT] Request_host wake irq failed.\n");
+ return ret;
+ }
+
+ ret = irq_set_irq_wake(irq, 1);
+ if (ret) {
+ pr_err("[BT] Set_irq_wake failed.\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bcm_hci_wake_peer(struct notifier_block *this, unsigned long event, void *ptr)
+{
+ struct hci_dev *hdev = (struct hci_dev *) ptr;
+
+ if (event == HCI_DEV_REG) {
+ if (hdev != NULL) {
+ hdev->wake_peer = bcm_bt_lpm_exit_lpm_locked;
+ pr_info("[BT] wake_peer is registered.\n");
+ }
+ } else if (event == HCI_DEV_UNREG) {
+ pr_info("[BT] %s: handle HCI_DEV_UNREG noti\n", __func__);
+ if (hdev != NULL && bt_lpm.hdev == hdev) {
+ bt_lpm.hdev = NULL;
+ pr_info("[BT] bt_lpm.hdev set to NULL\n");
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block bcm_bt_nblock = {
+ .notifier_call = bcm_hci_wake_peer
+};
+#endif
+
+static int bcm4334_bluetooth_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ int ret;
+
+ rc = gpio_request(GPIO_BT_EN, "bcm4334_bten_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_EN request failed.\n");
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_WAKE, "bcm4334_btwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_WAKE request failed.\n");
+ gpio_free(GPIO_BT_EN);
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_HOST_WAKE, "bcm4334_bthostwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_HOST_WAKE request failed.\n");
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_EN);
+ return rc;
+ }
+ gpio_direction_input(GPIO_BT_HOST_WAKE);
+ gpio_direction_output(GPIO_BT_WAKE, 0);
+ gpio_direction_output(GPIO_BT_EN, 0);
+
+ bt_rfkill = rfkill_alloc("bcm4334 Bluetooth", &pdev->dev,
+ RFKILL_TYPE_BLUETOOTH, &bcm4334_bt_rfkill_ops,
+ NULL);
+
+ if (unlikely(!bt_rfkill)) {
+ pr_err("[BT] bt_rfkill alloc failed.\n");
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_EN);
+ return -ENOMEM;
+ }
+
+ rfkill_init_sw_state(bt_rfkill, 0);
+
+ rc = rfkill_register(bt_rfkill);
+
+ if (unlikely(rc)) {
+ pr_err("[BT] bt_rfkill register failed.\n");
+ rfkill_destroy(bt_rfkill);
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_EN);
+ return -1;
+ }
+
+ rfkill_set_sw_state(bt_rfkill, true);
+
+#ifdef BT_LPM_ENABLE
+ ret = bcm_bt_lpm_init(pdev);
+ if (ret) {
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_EN);
+ }
+
+ hci_register_notifier(&bcm_bt_nblock);
+#endif
+ return rc;
+}
+
+static int bcm4334_bluetooth_remove(struct platform_device *pdev)
+{
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_EN);
+ gpio_free(GPIO_BT_WAKE);
+ gpio_free(GPIO_BT_HOST_WAKE);
+
+ wake_lock_destroy(&bt_lpm.host_wake_lock);
+ wake_lock_destroy(&bt_lpm.bt_wake_lock);
+
+#ifdef BT_LPM_ENABLE
+ hci_unregister_notifier(&bcm_bt_nblock);
+#endif
+ return 0;
+}
+
+static struct platform_driver bcm4334_bluetooth_platform_driver = {
+ .probe = bcm4334_bluetooth_probe,
+ .remove = bcm4334_bluetooth_remove,
+ .driver = {
+ .name = "bcm4334_bluetooth",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bcm4334_bluetooth_init(void)
+{
+ return platform_driver_register(&bcm4334_bluetooth_platform_driver);
+}
+
+static void __exit bcm4334_bluetooth_exit(void)
+{
+ platform_driver_unregister(&bcm4334_bluetooth_platform_driver);
+}
+
+
+module_init(bcm4334_bluetooth_init);
+module_exit(bcm4334_bluetooth_exit);
+
+MODULE_ALIAS("platform:bcm4334");
+MODULE_DESCRIPTION("bcm4334_bluetooth");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/board-bluetooth-csr8811.c b/arch/arm/mach-exynos/board-bluetooth-csr8811.c
new file mode 100644
index 0000000..c3f46bb
--- /dev/null
+++ b/arch/arm/mach-exynos/board-bluetooth-csr8811.c
@@ -0,0 +1,334 @@
+/*
+ * Bluetooth CSR GPIO
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill.h>
+#include <linux/serial_core.h>
+#include <linux/wakelock.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+#define BT_UART_CFG
+#define BT_LPM_ENABLE
+
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+static struct rfkill *bt_rfkill;
+
+struct csr_bt_lpm {
+ int wake;
+ int host_wake;
+
+ struct hrtimer enter_lpm_timer;
+ ktime_t enter_lpm_delay;
+
+ struct uart_port *uport;
+
+ struct wake_lock wake_lock;
+ char wake_lock_name[100];
+} bt_lpm;
+
+#ifdef BT_UART_CFG
+int bt_is_running;
+EXPORT_SYMBOL(bt_is_running);
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+static unsigned int bt_uart_on_table[][4] = {
+ {EXYNOS4_GPA0(0), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), 2, 2, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), 2, 2, S3C_GPIO_PULL_NONE},
+};
+
+void bt_config_gpio_table(int array_size, unsigned int (*gpio_table)[4])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != 2)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+void bt_uart_rts_ctrl(int flag)
+{
+ if (flag) {
+ /* BT RTS Set to HIGH */
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ gpio_set_value(EXYNOS4_GPA0(3), 1);
+ s3c_gpio_slp_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT0);
+ s3c_gpio_slp_setpull_updown(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ } else {
+ /* BT RTS Set to LOW */
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_OUTPUT);
+ gpio_set_value(EXYNOS4_GPA0(3), 0);
+ s3c_gpio_cfgpin(EXYNOS4_GPA0(3), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPA0(3), S3C_GPIO_PULL_NONE);
+ }
+}
+EXPORT_SYMBOL(bt_uart_rts_ctrl);
+#endif
+
+static int csr8811_bt_rfkill_set_power(void *data, bool blocked)
+{
+ /* rfkill_ops callback. Turn transmitter on when blocked is false */
+ if (!blocked) {
+ pr_info("[BT] Bluetooth Power On.\n");
+#ifdef BT_UART_CFG
+ bt_config_gpio_table(ARRAY_SIZE(bt_uart_on_table),
+ bt_uart_on_table);
+#endif
+ msleep(20);
+ gpio_set_value(GPIO_BT_nRST, 1);
+ msleep(50);
+ } else {
+ pr_info("[BT] Bluetooth Power Off.\n");
+ bt_is_running = 0;
+ gpio_set_value(GPIO_BT_nRST, 0);
+ }
+ return 0;
+}
+
+static const struct rfkill_ops csr8811_bt_rfkill_ops = {
+ .set_block = csr8811_bt_rfkill_set_power,
+};
+
+#ifdef BT_LPM_ENABLE
+static void set_wake_locked(int wake)
+{
+ bt_lpm.wake = wake;
+
+ if (!wake)
+ wake_unlock(&bt_lpm.wake_lock);
+}
+
+static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&bt_lpm.uport->lock, flags);
+ bt_is_running = 0;
+ set_wake_locked(0);
+ spin_unlock_irqrestore(&bt_lpm.uport->lock, flags);
+
+ return HRTIMER_NORESTART;
+}
+
+void csr_bt_lpm_exit_lpm_locked(struct uart_port *uport)
+{
+ bt_lpm.uport = uport;
+
+ hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
+ bt_is_running = 1;
+ set_wake_locked(1);
+
+ hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
+ HRTIMER_MODE_REL);
+}
+EXPORT_SYMBOL(csr_bt_lpm_exit_lpm_locked);
+
+static void update_host_wake_locked(int host_wake)
+{
+ if (host_wake == bt_lpm.host_wake)
+ return;
+
+ bt_lpm.host_wake = host_wake;
+
+ bt_is_running = 1;
+ if (host_wake) {
+ wake_lock(&bt_lpm.wake_lock);
+ } else {
+ /* Take a timed wakelock, so that upper layers can take it.
+ * The chipset deasserts the hostwake lock, when there is no
+ * more data to send.
+ */
+ wake_lock_timeout(&bt_lpm.wake_lock, 5*HZ);
+ }
+}
+
+static irqreturn_t host_wake_isr(int irq, void *dev)
+{
+ int host_wake;
+ unsigned long flags;
+
+ host_wake = gpio_get_value(GPIO_BT_HOST_WAKE);
+ irq_set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH);
+
+ if (!bt_lpm.uport) {
+ bt_lpm.host_wake = host_wake;
+ return IRQ_HANDLED;
+ }
+
+ spin_lock_irqsave(&bt_lpm.uport->lock, flags);
+ update_host_wake_locked(host_wake);
+ spin_unlock_irqrestore(&bt_lpm.uport->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static int csr_bt_lpm_init(struct platform_device *pdev)
+{
+ int irq;
+ int ret;
+
+ hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ bt_lpm.enter_lpm_delay = ktime_set(1, 0); /* 1 sec */
+ bt_lpm.enter_lpm_timer.function = enter_lpm;
+
+ bt_lpm.host_wake = 0;
+ bt_is_running = 0;
+
+ irq = IRQ_BT_HOST_WAKE;
+ ret = request_irq(irq, host_wake_isr, IRQF_TRIGGER_HIGH,
+ "bt host_wake", NULL);
+ if (ret) {
+ pr_err("[BT] Request_host wake irq failed.\n");
+ return ret;
+ }
+
+ ret = irq_set_irq_wake(irq, 1);
+ if (ret) {
+ pr_err("[BT] Set_irq_wake failed.\n");
+ return ret;
+ }
+
+ snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name),
+ "BTLowPower");
+ wake_lock_init(&bt_lpm.wake_lock, WAKE_LOCK_SUSPEND,
+ bt_lpm.wake_lock_name);
+ return 0;
+}
+#endif
+
+static int csr8811_bluetooth_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+ int ret;
+
+ printk("%s\n", __func__);
+
+ rc = gpio_request(GPIO_BT_nRST, "csr8811_btnrst_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_nRST request failed.\n");
+ return rc;
+ }
+ rc = gpio_request(GPIO_BT_HOST_WAKE, "csr8811_bthostwake_gpio");
+ if (unlikely(rc)) {
+ pr_err("[BT] GPIO_BT_HOST_WAKE request failed.\n");
+ gpio_free(GPIO_BT_nRST);
+ return rc;
+ }
+ gpio_direction_input(GPIO_BT_HOST_WAKE);
+ gpio_direction_output(GPIO_BT_nRST, 0);
+
+ bt_rfkill = rfkill_alloc("csr8811 Bluetooth", &pdev->dev,
+ RFKILL_TYPE_BLUETOOTH, &csr8811_bt_rfkill_ops,
+ NULL);
+
+ if (unlikely(!bt_rfkill)) {
+ pr_err("[BT] bt_rfkill alloc failed.\n");
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ return -ENOMEM;
+ }
+
+ rfkill_init_sw_state(bt_rfkill, 0);
+
+ rc = rfkill_register(bt_rfkill);
+
+ if (unlikely(rc)) {
+ pr_err("[BT] bt_rfkill register failed.\n");
+ rfkill_destroy(bt_rfkill);
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ return -1;
+ }
+
+ rfkill_set_sw_state(bt_rfkill, true);
+
+#ifdef BT_LPM_ENABLE
+ ret = csr_bt_lpm_init(pdev);
+ if (ret) {
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_HOST_WAKE);
+ gpio_free(GPIO_BT_nRST);
+ }
+#endif
+ return rc;
+}
+
+static int csr8811_bluetooth_remove(struct platform_device *pdev)
+{
+ rfkill_unregister(bt_rfkill);
+ rfkill_destroy(bt_rfkill);
+
+ gpio_free(GPIO_BT_nRST);
+ gpio_free(GPIO_BT_HOST_WAKE);
+
+ wake_lock_destroy(&bt_lpm.wake_lock);
+ return 0;
+}
+
+static struct platform_driver csr8811_bluetooth_platform_driver = {
+ .probe = csr8811_bluetooth_probe,
+ .remove = csr8811_bluetooth_remove,
+ .driver = {
+ .name = "csr8811_bluetooth",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init csr8811_bluetooth_init(void)
+{
+ return platform_driver_register(&csr8811_bluetooth_platform_driver);
+}
+
+static void __exit csr8811_bluetooth_exit(void)
+{
+ platform_driver_unregister(&csr8811_bluetooth_platform_driver);
+}
+
+
+module_init(csr8811_bluetooth_init);
+module_exit(csr8811_bluetooth_exit);
+
+MODULE_ALIAS("platform:csr8811");
+MODULE_DESCRIPTION("csr8811_bluetooth");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/board-c1-modems.c b/arch/arm/mach-exynos/board-c1-modems.c
new file mode 100644
index 0000000..9c33fda
--- /dev/null
+++ b/arch/arm/mach-exynos/board-c1-modems.c
@@ -0,0 +1,1302 @@
+/* linux/arch/arm/mach-xxxx/board-c1-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#ifdef CONFIG_USBHUB_USB3503
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/usb3503.h>
+#include <mach/cpufreq.h>
+#include <plat/usb-phy.h>
+#endif
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/* For "bus width and wait control (BW)" register */
+enum sromc_attr {
+ SROMC_DATA_16 = 0x1, /* 16-bit data bus */
+ SROMC_BYTE_ADDR = 0x2, /* Byte base address */
+ SROMC_WAIT_EN = 0x4, /* Wait enabled */
+ SROMC_BYTE_EN = 0x8, /* Byte access enabled */
+ SROMC_MASK = 0xF
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For CMC221 IDPRAM (Internal DPRAM) */
+#define CMC_IDPRAM_SIZE 0x4000 /* 16 KB */
+
+/* FOR CMC221 SFR for IDPRAM */
+#define CMC_INT2CP_REG 0x10 /* Interrupt to CP */
+#define CMC_INT2AP_REG 0x50
+#define CMC_CLR_INT_REG 0x28 /* Clear Interrupt to AP */
+#define CMC_RESET_REG 0x3C
+#define CMC_PUT_REG 0x40 /* AP->CP reg for hostbooting */
+#define CMC_GET_REG 0x50 /* CP->AP reg for hostbooting */
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+#ifdef CONFIG_USBHUB_USB3503
+static int host_port_enable(int port, int enable);
+#else
+static int host_port_enable(int port, int enable)
+{
+ return s5p_ehci_port_control(&s5p_device_ehci, port, enable);
+}
+#endif
+
+static struct sromc_cfg cmc_idpram_cfg = {
+ .attr = SROMC_DATA_16,
+ .size = CMC_IDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cmc_idpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ /* for 33 MHz clock, 64 cycles */
+ .tacs = 0x08 << 28,
+ .tcos = 0x08 << 24,
+ .tacc = 0x1F << 16,
+ .tcoh = 0x08 << 12,
+ .tcah = 0x08 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+ [DPRAM_SPEED_MID] = {
+ /* for 66 MHz clock, 32 cycles */
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x1B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+ [DPRAM_SPEED_HIGH] = {
+ /* for 133 MHz clock, 16 cycles */
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x0B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 4564 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 9124 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define DP_FMT_TX_BUFF_SZ 1336
+#define DP_RAW_TX_BUFF_SZ 4564
+#define DP_FMT_RX_BUFF_SZ 1336
+#define DP_RAW_RX_BUFF_SZ 9124
+
+#define MAX_CMC_IDPRAM_IPC_DEV (IPC_RAW + 1) /* FMT, RAW */
+
+struct dpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[DP_RAW_RX_BUFF_SZ];
+
+ u16 mbx_cp2ap;
+ u16 mbx_ap2cp;
+};
+
+struct cmc221_idpram_sfr {
+ u16 __iomem *int2cp;
+ u16 __iomem *int2ap;
+ u16 __iomem *clr_int2ap;
+ u16 __iomem *reset;
+ u16 __iomem *msg2cp;
+ u16 __iomem *msg2ap;
+};
+
+static struct dpram_ipc_map cmc_ipc_map;
+static u8 *cmc_sfr_base;
+static struct cmc221_idpram_sfr cmc_sfr;
+
+/* Function prototypes */
+static void cmc_idpram_reset(void);
+static void cmc_idpram_setup_speed(enum dpram_speed);
+static int cmc_idpram_wakeup(void);
+static void cmc_idpram_sleep(void);
+static void cmc_idpram_clr_intr(void);
+static u16 cmc_idpram_recv_intr(void);
+static void cmc_idpram_send_intr(u16 irq_mask);
+static u16 cmc_idpram_recv_msg(void);
+static void cmc_idpram_send_msg(u16 msg);
+
+static u16 cmc_idpram_get_magic(void);
+static void cmc_idpram_set_magic(u16 value);
+static u16 cmc_idpram_get_access(void);
+static void cmc_idpram_set_access(u16 value);
+
+static u32 cmc_idpram_get_tx_head(int dev_id);
+static u32 cmc_idpram_get_tx_tail(int dev_id);
+static void cmc_idpram_set_tx_head(int dev_id, u32 head);
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id);
+static u32 cmc_idpram_get_tx_buff_size(int dev_id);
+
+static u32 cmc_idpram_get_rx_head(int dev_id);
+static u32 cmc_idpram_get_rx_tail(int dev_id);
+static void cmc_idpram_set_rx_head(int dev_id, u32 head);
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id);
+static u32 cmc_idpram_get_rx_buff_size(int dev_id);
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id);
+static u16 cmc_idpram_get_mask_res_ack(int dev_id);
+static u16 cmc_idpram_get_mask_send(int dev_id);
+
+static struct modemlink_dpram_control cmc_idpram_ctrl = {
+ .reset = cmc_idpram_reset,
+
+ .setup_speed = cmc_idpram_setup_speed,
+
+ .wakeup = cmc_idpram_wakeup,
+ .sleep = cmc_idpram_sleep,
+
+ .clear_intr = cmc_idpram_clr_intr,
+ .recv_intr = cmc_idpram_recv_intr,
+ .send_intr = cmc_idpram_send_intr,
+ .recv_msg = cmc_idpram_recv_msg,
+ .send_msg = cmc_idpram_send_msg,
+
+ .get_magic = cmc_idpram_get_magic,
+ .set_magic = cmc_idpram_set_magic,
+ .get_access = cmc_idpram_get_access,
+ .set_access = cmc_idpram_set_access,
+
+ .get_tx_head = cmc_idpram_get_tx_head,
+ .get_tx_tail = cmc_idpram_get_tx_tail,
+ .set_tx_head = cmc_idpram_set_tx_head,
+ .set_tx_tail = cmc_idpram_set_tx_tail,
+ .get_tx_buff = cmc_idpram_get_tx_buff,
+ .get_tx_buff_size = cmc_idpram_get_tx_buff_size,
+
+ .get_rx_head = cmc_idpram_get_rx_head,
+ .get_rx_tail = cmc_idpram_get_rx_tail,
+ .set_rx_head = cmc_idpram_set_rx_head,
+ .set_rx_tail = cmc_idpram_set_rx_tail,
+ .get_rx_buff = cmc_idpram_get_rx_buff,
+ .get_rx_buff_size = cmc_idpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cmc_idpram_get_mask_req_ack,
+ .get_mask_res_ack = cmc_idpram_get_mask_res_ack,
+ .get_mask_send = cmc_idpram_get_mask_send,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = CP_IDPRAM,
+ .aligned = 1,
+
+ .dpram_irq = CMC_IDPRAM_INT_IRQ_00,
+ .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING),
+ .dpram_irq_name = "CMC221_IDPRAM_IRQ",
+ .dpram_wlock_name = "CMC221_IDPRAM_WLOCK",
+
+ .max_ipc_dev = MAX_CMC_IDPRAM_IPC_DEV,
+};
+
+/*
+** UMTS target platform data
+*/
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_boot0",
+ .id = 0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "umts_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "umts_rfs0",
+ .id = 245,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "umts_multipdp",
+ .id = 0,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [4] = {
+ .name = "rmnet0",
+ .id = 10,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [5] = {
+ .name = "rmnet1",
+ .id = 11,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [6] = {
+ .name = "rmnet2",
+ .id = 12,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [7] = {
+ .name = "rmnet3",
+ .id = 13,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [8] = {
+ .name = "umts_csd", /* CS Video Telephony */
+ .id = 1,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "umts_router", /* AT Iface & Dial-up */
+ .id = 25,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "umts_dm0", /* DM Port */
+ .id = 28,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "umts_loopback_ap2cp",
+ .id = 30,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "umts_loopback_cp2ap",
+ .id = 31,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "umts_ramdump0",
+ .id = 0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "lte_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_USB),
+ },
+};
+
+static int exynos_cpu_frequency_lock(void);
+static int exynos_cpu_frequency_unlock(void);
+
+static struct modemlink_pm_data umts_link_pm_data = {
+ .name = "umts_link_pm",
+
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+
+ .port_enable = host_port_enable,
+/*
+ .link_reconnect = umts_link_reconnect,
+*/
+ .freqlock = ATOMIC_INIT(0),
+ .cpufreq_lock = exynos_cpu_frequency_lock,
+ .cpufreq_unlock = exynos_cpu_frequency_unlock,
+
+ .autosuspend_delay_ms = 2000,
+
+ .has_usbhub = true,
+};
+
+static struct modem_data umts_modem_data = {
+ .name = "cmc221",
+
+ .gpio_cp_on = CP_CMC221_PMIC_PWRON,
+ .gpio_cp_reset = CP_CMC221_CPU_RST,
+ .gpio_phone_active = GPIO_LTE_ACTIVE,
+
+ .gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00,
+ .gpio_dpram_status = GPIO_CMC_IDPRAM_STATUS,
+ .gpio_dpram_wakeup = GPIO_CMC_IDPRAM_WAKEUP,
+
+ .gpio_slave_wakeup = GPIO_IPC_SLAVE_WAKEUP,
+ .gpio_host_active = GPIO_ACTIVE_STATE,
+ .gpio_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+ .gpio_dynamic_switching = GPIO_AP2CMC_INT2,
+
+ .modem_net = UMTS_NETWORK,
+ .modem_type = SEC_CMC221,
+ .link_types = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .link_name = "cmc221_idpram",
+ .dpram_ctl = &cmc_idpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &umts_link_pm_data,
+
+ .ipc_version = SIPC_VER_50,
+ .use_mif_log = true,
+};
+
+static struct resource umts_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = LTE_ACTIVE_IRQ,
+ .end = LTE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device umts_modem = {
+ .name = "mif_sipc5",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+#define HUB_STATE_OFF 0
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val && states == STATE_HSIC_LPA_ENTER) {
+ mif_info("usb3503: hub off - lpa\n");
+ host_port_enable(2, 0);
+ *(umts_link_pm_data.p_hub_status) = HUB_STATE_OFF;
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static void cmc_idpram_reset(void)
+{
+ iowrite16(1, cmc_sfr.reset);
+}
+
+static void cmc_idpram_setup_speed(enum dpram_speed speed)
+{
+ setup_dpram_speed(cmc_idpram_cfg.csn, &cmc_idpram_access_cfg[speed]);
+}
+
+static int cmc_idpram_wakeup(void)
+{
+ int cnt = 0;
+
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 1);
+
+ while (!gpio_get_value(umts_modem_data.gpio_dpram_status)) {
+ if (cnt++ > 10) {
+ mif_err("ERR: gpio_dpram_status == 0\n");
+ return -EAGAIN;
+ }
+
+ if (in_interrupt())
+ mdelay(1);
+ else
+ msleep_interruptible(1);
+ }
+
+ return 0;
+}
+
+static void cmc_idpram_sleep(void)
+{
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 0);
+}
+
+static void cmc_idpram_clr_intr(void)
+{
+ iowrite16(0xFFFF, cmc_sfr.clr_int2ap);
+ iowrite16(0, cmc_sfr.int2ap);
+}
+
+static u16 cmc_idpram_recv_intr(void)
+{
+ return ioread16(cmc_sfr.int2ap);
+}
+
+static void cmc_idpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cmc_sfr.int2cp);
+}
+
+static u16 cmc_idpram_recv_msg(void)
+{
+ return ioread16(cmc_sfr.msg2ap);
+}
+
+static void cmc_idpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cmc_sfr.msg2cp);
+}
+
+static u16 cmc_idpram_get_magic(void)
+{
+ return ioread16(cmc_ipc_map.magic);
+}
+
+static void cmc_idpram_set_magic(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.magic);
+}
+
+static u16 cmc_idpram_get_access(void)
+{
+ return ioread16(cmc_ipc_map.access);
+}
+
+static void cmc_idpram_set_access(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.access);
+}
+
+static u32 cmc_idpram_get_tx_head(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cmc_idpram_get_tx_tail(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cmc_idpram_set_tx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].txq.head);
+ if (val == head)
+ break;
+
+ mif_err("ERR: txq.head(%d) != head(%d)\n", val, head);
+
+ /* Write head value again */
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].txq.tail);
+ if (val == tail)
+ break;
+
+ mif_err("ERR: txq.tail(%d) != tail(%d)\n", val, tail);
+
+ /* Write tail value again */
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cmc_idpram_get_tx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cmc_idpram_get_rx_head(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cmc_idpram_get_rx_tail(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cmc_idpram_set_rx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].rxq.head);
+ if (val == head)
+ break;
+
+ mif_err("ERR: rxq.head(%d) != head(%d)\n", val, head);
+
+ /* Write head value again */
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].rxq.tail);
+ if (val == tail)
+ break;
+
+ mif_err("ERR: rxq.tail(%d) != tail(%d)\n", val, tail);
+
+ /* Write tail value again */
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cmc_idpram_get_rx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cmc_idpram_get_mask_res_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cmc_idpram_get_mask_send(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_send;
+}
+
+/* Set dynamic environment for a modem */
+static void setup_umts_modem_env(void)
+{
+ /* Config DPRAM control structure */
+ cmc_idpram_cfg.csn = 0;
+ cmc_idpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cmc_idpram_cfg.csn);
+ cmc_idpram_cfg.end = cmc_idpram_cfg.addr + cmc_idpram_cfg.size - 1;
+
+ umts_modem_data.gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00;
+}
+
+static void config_umts_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_active_state = umts_modem_data.gpio_host_active;
+ unsigned gpio_host_wakeup = umts_modem_data.gpio_host_wakeup;
+ unsigned gpio_slave_wakeup = umts_modem_data.gpio_slave_wakeup;
+ unsigned gpio_dpram_int = umts_modem_data.gpio_dpram_int;
+ unsigned gpio_dpram_status = umts_modem_data.gpio_dpram_status;
+ unsigned gpio_dpram_wakeup = umts_modem_data.gpio_dpram_wakeup;
+ unsigned gpio_dynamic_switching =
+ umts_modem_data.gpio_dynamic_switching;
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CMC_ON");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 0);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CMC_RST");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "CMC_ACTIVE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_ACTIVE");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_active_state) {
+ err = gpio_request(gpio_active_state, "CMC_ACTIVE_STATE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_ACTIVE_STATE");
+ } else {
+ gpio_direction_output(gpio_active_state, 0);
+ s3c_gpio_setpull(gpio_active_state, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_slave_wakeup) {
+ err = gpio_request(gpio_slave_wakeup, "CMC_SLAVE_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_SLAVE_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_slave_wakeup, 0);
+ s3c_gpio_setpull(gpio_slave_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_host_wakeup) {
+ err = gpio_request(gpio_host_wakeup, "CMC_HOST_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_HOST_WAKEUP");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_host_wakeup);
+ s3c_gpio_setpull(gpio_host_wakeup, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(gpio_host_wakeup, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "CMC_DPRAM_INT");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_dpram_int);
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_status) {
+ err = gpio_request(gpio_dpram_status, "CMC_DPRAM_STATUS");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_STATUS");
+ } else {
+ gpio_direction_input(gpio_dpram_status);
+ s3c_gpio_setpull(gpio_dpram_status, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_dpram_wakeup) {
+ err = gpio_request(gpio_dpram_wakeup, "CMC_DPRAM_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_dpram_wakeup, 1);
+ s3c_gpio_setpull(gpio_dpram_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_dynamic_switching) {
+ err = gpio_request(gpio_dynamic_switching, "DYNAMIC_SWITCHING");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "DYNAMIC_SWITCHING\n");
+ } else {
+ gpio_direction_input(gpio_dynamic_switching);
+ s3c_gpio_setpull(gpio_dynamic_switching,
+ S3C_GPIO_PULL_NONE);
+ }
+ }
+}
+
+static u8 *cmc_idpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = cfg->addr;
+ int dp_size = cfg->size;
+ u8 __iomem *dp_base;
+ struct dpram_ipc_cfg *ipc_map;
+ struct dpram_ipc_device *dev;
+
+ /* Remap DPRAM memory region */
+ dp_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ mif_err("ERR: ioremap_nocache for dp_base fail\n");
+ return NULL;
+ }
+ mif_err("DPRAM VA=0x%08X\n", (int)dp_base);
+
+ /* Remap DPRAM SFR region */
+ dp_addr += dp_size;
+ cmc_sfr_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size);
+ if (cmc_sfr_base == NULL) {
+ iounmap(dp_base);
+ mif_err("ERR: ioremap_nocache for cmc_sfr_base fail\n");
+ return NULL;
+ }
+
+ cmc_sfr.int2cp = (u16 __iomem *)(cmc_sfr_base + CMC_INT2CP_REG);
+ cmc_sfr.int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_INT2AP_REG);
+ cmc_sfr.clr_int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_CLR_INT_REG);
+ cmc_sfr.reset = (u16 __iomem *)(cmc_sfr_base + CMC_RESET_REG);
+ cmc_sfr.msg2cp = (u16 __iomem *)(cmc_sfr_base + CMC_PUT_REG);
+ cmc_sfr.msg2ap = (u16 __iomem *)(cmc_sfr_base + CMC_GET_REG);
+
+ cmc_idpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cmc_idpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct dpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cmc_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cmc_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cmc_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cmc_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+ return dp_base;
+}
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ mif_info("address line = %d bits\n", addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for address bus (13 ~ 14 bits) */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_LOW,
+ EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_HIGH,
+ (addr_bits - EXYNOS4_GPIO_Y3_NR), S3C_GPIO_SFN(2));
+ break;
+
+ default:
+ mif_err("ERR: invalid addr_bits!!!\n");
+ return;
+ }
+
+ /* Set GPIO for data bus (16 bits) */
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_LOW, 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_HIGH, 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgpin(GPIO_DPRAM_REN, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(GPIO_DPRAM_WEN, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ mif_err("ERR: SROMC clock gate fail\n");
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(
+ unsigned csn,
+ struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg
+)
+{
+ unsigned bw = 0; /* Bus width and wait control */
+ unsigned bc = 0; /* Vank control */
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ mif_err("SROMC settings for CS%d...\n", csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ mif_err("Old SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn << 2));
+ bw |= (cfg->attr << (csn << 2));
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ mif_err("New SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc);
+}
+
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg)
+{
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+ unsigned bc = 0;
+
+ bc = __raw_readl(bank_sfr);
+ mif_info("Old CS%d setting = 0x%08X\n", csn, bc);
+
+ /* SROMC memory access timing setting */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+ writel(bc, bank_sfr);
+
+ bc = __raw_readl(bank_sfr);
+ mif_info("New CS%d setting = 0x%08X\n", csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ mif_err("System Revision = %d\n", system_rev);
+
+ setup_umts_modem_env();
+
+ config_dpram_port_gpio();
+
+ config_umts_modem_gpio();
+
+ init_sromc();
+
+ cfg = &cmc_idpram_cfg;
+ acc_cfg = &cmc_idpram_access_cfg[DPRAM_SPEED_LOW];
+
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!cmc_idpram_remap_mem_region(&cmc_idpram_cfg))
+ return -1;
+
+ platform_device_register(&umts_modem);
+
+ return 0;
+}
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
+
+#ifdef CONFIG_USBHUB_USB3503
+static int (*usbhub_set_mode)(struct usb3503_hubctl *, int);
+static struct usb3503_hubctl *usbhub_ctl;
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+static int exynos_cpu_frequency_lock(void)
+{
+ unsigned int level, freq = 700;
+
+ if (atomic_read(&umts_link_pm_data.freqlock) == 0) {
+ if (exynos_cpufreq_get_level(freq * 1000, &level)) {
+ mif_err("ERR: exynos_cpufreq_get_level fail\n");
+ return -EINVAL;
+ }
+
+ if (exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level)) {
+ mif_err("ERR: exynos_cpufreq_lock fail\n");
+ return -EINVAL;
+ }
+
+ atomic_set(&umts_link_pm_data.freqlock, 1);
+ mif_debug("<%d> %d MHz\n", level, freq);
+ }
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ if (atomic_read(&umts_link_pm_data.freqlock) == 1) {
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF);
+ atomic_set(&umts_link_pm_data.freqlock, 0);
+ mif_debug("\n");
+ }
+ return 0;
+}
+#else
+static int exynos_cpu_frequency_lock(void)
+{
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ return 0;
+}
+#endif
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+}
+
+static int usb3503_hub_handler(void (*set_mode)(void), void *ctl)
+{
+ if (!set_mode || !ctl)
+ return -EINVAL;
+
+ usbhub_set_mode = (int (*)(struct usb3503_hubctl *, int))set_mode;
+ usbhub_ctl = (struct usb3503_hubctl *)ctl;
+
+ mif_info("set_mode(%pF)\n", set_mode);
+
+ return 0;
+}
+
+static int usb3503_hw_config(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_USB_HUB_RST, "HUB_RST");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "HUB_RST");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_RST, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_RST, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_RST, S5P_GPIO_DRVSTR_LV1);
+ /* need to check drvstr 1 or 2 */
+
+ /* for USB3503 26Mhz Reference clock setting */
+ err = gpio_request(GPIO_USB_HUB_INT, "HUB_INT");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "HUB_INT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_INT, 1);
+ s3c_gpio_setpull(GPIO_USB_HUB_INT, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static int usb3503_reset_n(int val)
+{
+ gpio_set_value(GPIO_USB_HUB_RST, 0);
+
+ /* hub off from cpuidle(LPA), skip the msleep schedule*/
+ if (val) {
+ msleep(20);
+ mif_info("val = %d\n", gpio_get_value(GPIO_USB_HUB_RST));
+
+ gpio_set_value(GPIO_USB_HUB_RST, !!val);
+
+ mif_info("val = %d\n", gpio_get_value(GPIO_USB_HUB_RST));
+ udelay(5); /* need it ?*/
+ }
+ return 0;
+}
+
+static struct usb3503_platform_data usb3503_pdata = {
+ .initial_mode = USB3503_MODE_STANDBY,
+ .reset_n = usb3503_reset_n,
+ .register_hub_handler = usb3503_hub_handler,
+ .port_enable = host_port_enable,
+};
+
+static struct i2c_board_info i2c_devs20_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO(USB3503_I2C_NAME, 0x08),
+ .platform_data = &usb3503_pdata,
+ },
+};
+
+/* I2C20_EMUL */
+static struct i2c_gpio_platform_data i2c20_platdata = {
+ .sda_pin = GPIO_USB_HUB_SDA,
+ .scl_pin = GPIO_USB_HUB_SCL,
+ /*FIXME: need to timming tunning... */
+ .udelay = 20,
+};
+
+static struct platform_device s3c_device_i2c20 = {
+ .name = "i2c-gpio",
+ .id = 20,
+ .dev.platform_data = &i2c20_platdata,
+};
+
+static int __init init_usbhub(void)
+{
+ usb3503_hw_config();
+ i2c_register_board_info(20, i2c_devs20_emul,
+ ARRAY_SIZE(i2c_devs20_emul));
+
+ platform_device_register(&s3c_device_i2c20);
+ return 0;
+}
+
+device_initcall(init_usbhub);
+
+static int host_port_enable(int port, int enable)
+{
+ int err;
+
+ mif_info("port(%d) control(%d)\n", port, enable);
+
+ if (enable) {
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB);
+ if (err < 0) {
+ mif_err("ERR: hub on fail\n");
+ goto exit;
+ }
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 1);
+ if (err < 0) {
+ mif_err("ERR: port(%d) enable fail\n", port);
+ goto exit;
+ }
+ } else {
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 0);
+ if (err < 0) {
+ mif_err("ERR: port(%d) enable fail\n", port);
+ goto exit;
+ }
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY);
+ if (err < 0) {
+ mif_err("ERR: hub off fail\n");
+ goto exit;
+ }
+ }
+
+ err = gpio_direction_output(umts_modem_data.gpio_host_active, enable);
+ mif_info("active state err(%d), en(%d), level(%d)\n",
+ err, enable, gpio_get_value(umts_modem_data.gpio_host_active));
+
+exit:
+ return err;
+}
+#else
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ mif_err("<%s> Active States =%d, %s\n", pdev->name, type);
+ gpio_direction_output(umts_link_pm_data.gpio_link_active, type);
+ } else {
+ active_ctl.gpio_request_host_active = 1;
+ }
+}
+#endif
+
diff --git a/arch/arm/mach-exynos/board-c1ctc-modems.c b/arch/arm/mach-exynos/board-c1ctc-modems.c
new file mode 100644
index 0000000..85e35f5
--- /dev/null
+++ b/arch/arm/mach-exynos/board-c1ctc-modems.c
@@ -0,0 +1,1712 @@
+/* linux/arch/arm/mach-xxxx/board-c1ctc-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/if_arp.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#ifdef CONFIG_USBHUB_USB3503
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/usb3503.h>
+#endif
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/*
+ * For SROMC Configuration:
+ * SROMC_ADDR_BYTE enable for byte access
+ */
+#define SROMC_DATA_16 0x1
+#define SROMC_ADDR_BYTE 0x2
+#define SROMC_WAIT_EN 0x4
+#define SROMC_BYTE_EN 0x8
+#define SROMC_MASK 0xF
+
+/* Memory attributes */
+enum sromc_attr {
+ MEM_DATA_BUS_16BIT = 0x00000001,
+ MEM_BYTE_ADDRESSABLE = 0x00000002,
+ MEM_WAIT_EN = 0x00000004,
+ MEM_BYTE_EN = 0x00000008,
+
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For MDM6600 EDPRAM (External DPRAM) */
+#define MSM_EDPRAM_SIZE 0x4000 /* 16 KB */
+
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+#ifdef CONFIG_USBHUB_USB3503
+static int host_port_enable(int port, int enable);
+#else
+static int host_port_enable(int port, int enable)
+{
+ return s5p_ehci_port_control(&s5p_device_ehci, port, enable);
+}
+#endif
+
+static struct sromc_cfg msm_edpram_cfg = {
+ .attr = (MEM_DATA_BUS_16BIT | MEM_WAIT_EN | MEM_BYTE_EN),
+ .size = MSM_EDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg msm_edpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ .tacs = 0x2 << 28,
+ .tcos = 0x2 << 24,
+ .tacc = 0x3 << 16,
+ .tcoh = 0x2 << 12,
+ .tcah = 0x2 << 8,
+ .tacp = 0x2 << 4,
+ .pmc = 0x0 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ padding +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 2044 +
+ 2 + 2 + 6128 +
+ 2 + 2 + 2044 +
+ 2 + 2 + 6128 +
+ 16 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define MSM_DP_FMT_TX_BUFF_SZ 2044
+#define MSM_DP_RAW_TX_BUFF_SZ 6128
+#define MSM_DP_FMT_RX_BUFF_SZ 2044
+#define MSM_DP_RAW_RX_BUFF_SZ 6128
+
+#define MAX_MSM_EDPRAM_IPC_DEV 2 /* FMT, RAW */
+
+struct msm_edpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[MSM_DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[MSM_DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[MSM_DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[MSM_DP_RAW_RX_BUFF_SZ];
+
+ u8 padding[16];
+ u16 mbx_ap2cp;
+ u16 mbx_cp2ap;
+};
+
+struct msm_edpram_circ {
+ u16 __iomem *head;
+ u16 __iomem *tail;
+ u8 __iomem *buff;
+ u32 size;
+};
+
+struct msm_edpram_ipc_device {
+ char name[16];
+ int id;
+
+ struct msm_edpram_circ txq;
+ struct msm_edpram_circ rxq;
+
+ u16 mask_req_ack;
+ u16 mask_res_ack;
+ u16 mask_send;
+};
+
+struct msm_edpram_ipc_map {
+ u16 __iomem *magic;
+ u16 __iomem *access;
+
+ struct msm_edpram_ipc_device dev[MAX_MSM_EDPRAM_IPC_DEV];
+
+ u16 __iomem *mbx_ap2cp;
+ u16 __iomem *mbx_cp2ap;
+};
+
+
+struct msm_edpram_boot_map {
+ u8 __iomem *buff;
+ u16 __iomem *frame_size;
+ u16 __iomem *tag;
+ u16 __iomem *count;
+};
+
+static struct msm_edpram_ipc_map msm_ipc_map;
+
+struct _param_nv {
+ unsigned char *addr;
+ unsigned int size;
+ unsigned int count;
+ unsigned int tag;
+};
+
+
+#if (MSM_EDPRAM_SIZE == 0x4000)
+/*
+------------------
+Buffer : 15KByte
+------------------
+Reserved: 1014Byte
+------------------
+SIZE: 2Byte
+------------------
+TAG: 2Byte
+------------------
+COUNT: 2Byte
+------------------
+AP -> CP Intr : 2Byte
+------------------
+CP -> AP Intr : 2Byte
+------------------
+*/
+#define DP_BOOT_CLEAR_OFFSET 4
+#define DP_BOOT_RSRVD_OFFSET 0x3C00
+#define DP_BOOT_SIZE_OFFSET 0x3FF6
+#define DP_BOOT_TAG_OFFSET 0x3FF8
+#define DP_BOOT_COUNT_OFFSET 0x3FFA
+
+
+#define DP_BOOT_FRAME_SIZE_LIMIT 0x3C00 /* 15KB = 15360byte = 0x3C00 */
+#else
+/*
+------------------
+Buffer : 31KByte
+------------------
+Reserved: 1014Byte
+------------------
+SIZE: 2Byte
+------------------
+TAG: 2Byte
+------------------
+COUNT: 2Byte
+------------------
+AP -> CP Intr : 2Byte
+------------------
+CP -> AP Intr : 2Byte
+------------------
+*/
+#define DP_BOOT_CLEAR_OFFSET 4
+#define DP_BOOT_RSRVD_OFFSET 0x7C00
+#define DP_BOOT_SIZE_OFFSET 0x7FF6
+#define DP_BOOT_TAG_OFFSET 0x7FF8
+#define DP_BOOT_COUNT_OFFSET 0x7FFA
+
+
+#define DP_BOOT_FRAME_SIZE_LIMIT 0x7C00 /* 31KB = 31744byte = 0x7C00 */
+#endif
+
+struct _param_check {
+ unsigned int total_size;
+ unsigned int rest_size;
+ unsigned int send_size;
+ unsigned int copy_start;
+ unsigned int copy_complete;
+ unsigned int boot_complete;
+};
+
+static struct _param_nv *data_param;
+static struct _param_check check_param;
+
+static unsigned int boot_start_complete;
+static struct msm_edpram_boot_map msm_edpram_bt_map;
+static struct msm_edpram_ipc_map msm_ipc_map;
+
+static void msm_edpram_reset(void);
+static void msm_edpram_clr_intr(void);
+static u16 msm_edpram_recv_intr(void);
+static void msm_edpram_send_intr(u16 irq_mask);
+static u16 msm_edpram_recv_msg(void);
+static void msm_edpram_send_msg(u16 msg);
+
+static u16 msm_edpram_get_magic(void);
+static void msm_edpram_set_magic(u16 value);
+static u16 msm_edpram_get_access(void);
+static void msm_edpram_set_access(u16 value);
+
+static u32 msm_edpram_get_tx_head(int dev_id);
+static u32 msm_edpram_get_tx_tail(int dev_id);
+static void msm_edpram_set_tx_head(int dev_id, u32 head);
+static void msm_edpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *msm_edpram_get_tx_buff(int dev_id);
+static u32 msm_edpram_get_tx_buff_size(int dev_id);
+
+static u32 msm_edpram_get_rx_head(int dev_id);
+static u32 msm_edpram_get_rx_tail(int dev_id);
+static void msm_edpram_set_rx_head(int dev_id, u32 head);
+static void msm_edpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *msm_edpram_get_rx_buff(int dev_id);
+static u32 msm_edpram_get_rx_buff_size(int dev_id);
+
+static u16 msm_edpram_get_mask_req_ack(int dev_id);
+static u16 msm_edpram_get_mask_res_ack(int dev_id);
+static u16 msm_edpram_get_mask_send(int dev_id);
+
+static void msm_log_disp(struct modemlink_dpram_control *dpctl);
+static int msm_uload_step1(struct modemlink_dpram_control *dpctl);
+static int msm_uload_step2(void *arg, struct modemlink_dpram_control *dpctl);
+static int msm_dload_prep(struct modemlink_dpram_control *dpctl);
+static int msm_dload(void *arg, struct modemlink_dpram_control *dpctl);
+static int msm_nv_load(void *arg, struct modemlink_dpram_control *dpctl);
+static int msm_boot_start(struct modemlink_dpram_control *dpctl);
+static int msm_boot_start_post_proc(void);
+static void msm_boot_start_handler(struct modemlink_dpram_control *dpctl);
+static void msm_dload_handler(struct modemlink_dpram_control *dpctl, u16 cmd);
+static void msm_bt_map_init(struct modemlink_dpram_control *dpctl);
+static void msm_load_init(struct modemlink_dpram_control *dpctl);
+
+static struct modemlink_dpram_control msm_edpram_ctrl = {
+ .reset = msm_edpram_reset,
+
+ .clear_intr = msm_edpram_clr_intr,
+ .recv_intr = msm_edpram_recv_intr,
+ .send_intr = msm_edpram_send_intr,
+ .recv_msg = msm_edpram_recv_msg,
+ .send_msg = msm_edpram_send_msg,
+
+ .get_magic = msm_edpram_get_magic,
+ .set_magic = msm_edpram_set_magic,
+ .get_access = msm_edpram_get_access,
+ .set_access = msm_edpram_set_access,
+
+ .get_tx_head = msm_edpram_get_tx_head,
+ .get_tx_tail = msm_edpram_get_tx_tail,
+ .set_tx_head = msm_edpram_set_tx_head,
+ .set_tx_tail = msm_edpram_set_tx_tail,
+ .get_tx_buff = msm_edpram_get_tx_buff,
+ .get_tx_buff_size = msm_edpram_get_tx_buff_size,
+
+ .get_rx_head = msm_edpram_get_rx_head,
+ .get_rx_tail = msm_edpram_get_rx_tail,
+ .set_rx_head = msm_edpram_set_rx_head,
+ .set_rx_tail = msm_edpram_set_rx_tail,
+ .get_rx_buff = msm_edpram_get_rx_buff,
+ .get_rx_buff_size = msm_edpram_get_rx_buff_size,
+
+ .get_mask_req_ack = msm_edpram_get_mask_req_ack,
+ .get_mask_res_ack = msm_edpram_get_mask_res_ack,
+ .get_mask_send = msm_edpram_get_mask_send,
+
+ .log_disp = msm_log_disp,
+ .cpupload_step1 = msm_uload_step1,
+ .cpupload_step2 = msm_uload_step2,
+ .cpimage_load = msm_dload,
+ .nvdata_load = msm_nv_load,
+ .phone_boot_start = msm_boot_start,
+ .dload_cmd_hdlr = msm_dload_handler,
+ .bt_map_init = msm_bt_map_init,
+ .load_init = msm_load_init,
+ .cpimage_load_prepare = msm_dload_prep,
+ .phone_boot_start_post_process = msm_boot_start_post_proc,
+ .phone_boot_start_handler = msm_boot_start_handler,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = EXT_DPRAM,
+
+ .dpram_irq = MSM_DPRAM_INT_IRQ,
+ .dpram_irq_flags = IRQF_TRIGGER_FALLING,
+ .dpram_irq_name = "MDM6600_EDPRAM_IRQ",
+ .dpram_wlock_name = "MDM6600_EDPRAM_WLOCK",
+
+ .max_ipc_dev = IPC_RFS,
+};
+
+/*
+** CDMA target platform data
+*/
+static struct modem_io_t cdma_io_devices[] = {
+ [0] = {
+ .name = "cdma_boot0",
+ .id = 0x1,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "cdma_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "cdma_multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "cdma_CSD",
+ .id = (1|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [4] = {
+ .name = "cdma_FOTA",
+ .id = (2|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [5] = {
+ .name = "cdma_GPS",
+ .id = (5|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [6] = {
+ .name = "cdma_XTRA",
+ .id = (6|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [7] = {
+ .name = "cdma_CDMA",
+ .id = (7|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [8] = {
+ .name = "cdma_EFS",
+ .id = (8|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "cdma_TRFB",
+ .id = (9|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "rmnet3",
+ .id = 0x2D,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "cdma_SMD",
+ .id = (25|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [15] = {
+ .name = "cdma_VTVD",
+ .id = (26|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [16] = {
+ .name = "cdma_VTAD",
+ .id = (27|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [17] = {
+ .name = "cdma_VTCTRL",
+ .id = (28|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [18] = {
+ .name = "cdma_VTENT",
+ .id = (29|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [19] = {
+ .name = "cdma_ramdump0",
+ .id = 0x1,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+};
+
+static struct modem_data cdma_modem_data = {
+ .name = "mdm6600",
+
+ .gpio_cp_on = GPIO_CP_MSM_PWRON,
+ .gpio_cp_off = 0,
+ .gpio_reset_req_n = GPIO_CP_MSM_PMU_RST,
+ .gpio_cp_reset = GPIO_CP_MSM_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_MSM_PHONE_ACTIVE,
+ .gpio_flm_uart_sel = GPIO_BOOT_SW_SEL,
+
+ .gpio_cp_dump_int = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .use_handover = false,
+
+ .modem_net = CDMA_NETWORK,
+ .modem_type = QC_MDM6600,
+ .link_types = LINKTYPE(LINKDEV_DPRAM),
+ .link_name = "mdm6600_edpram",
+ .dpram_ctl = &msm_edpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(cdma_io_devices),
+ .iodevs = cdma_io_devices,
+};
+
+static struct resource cdma_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = MSM_PHONE_ACTIVE_IRQ,
+ .end = MSM_PHONE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cdma_modem = {
+ .name = "modem_if",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cdma_modem_res),
+ .resource = cdma_modem_res,
+ .dev = {
+ .platform_data = &cdma_modem_data,
+ },
+};
+
+static void msm_edpram_reset(void)
+{
+ return;
+}
+
+static void msm_edpram_clr_intr(void)
+{
+ ioread16(msm_ipc_map.mbx_cp2ap);
+}
+
+static u16 msm_edpram_recv_intr(void)
+{
+ return ioread16(msm_ipc_map.mbx_cp2ap);
+}
+
+static void msm_edpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, msm_ipc_map.mbx_ap2cp);
+}
+
+static u16 msm_edpram_recv_msg(void)
+{
+ return ioread16(msm_ipc_map.mbx_cp2ap);
+}
+
+static void msm_edpram_send_msg(u16 msg)
+{
+ iowrite16(msg, msm_ipc_map.mbx_ap2cp);
+}
+
+static u16 msm_edpram_get_magic(void)
+{
+ return ioread16(msm_ipc_map.magic);
+}
+
+static void msm_edpram_set_magic(u16 value)
+{
+ iowrite16(value, msm_ipc_map.magic);
+}
+
+static u16 msm_edpram_get_access(void)
+{
+ return ioread16(msm_ipc_map.access);
+}
+
+static void msm_edpram_set_access(u16 value)
+{
+ iowrite16(value, msm_ipc_map.access);
+}
+
+static u32 msm_edpram_get_tx_head(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 msm_edpram_get_tx_tail(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void msm_edpram_set_tx_head(int dev_id, u32 head)
+{
+ iowrite16((u16)head, msm_ipc_map.dev[dev_id].txq.head);
+}
+
+static void msm_edpram_set_tx_tail(int dev_id, u32 tail)
+{
+ iowrite16((u16)tail, msm_ipc_map.dev[dev_id].txq.tail);
+}
+
+static u8 __iomem *msm_edpram_get_tx_buff(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 msm_edpram_get_tx_buff_size(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 msm_edpram_get_rx_head(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 msm_edpram_get_rx_tail(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void msm_edpram_set_rx_head(int dev_id, u32 head)
+{
+ return iowrite16((u16)head, msm_ipc_map.dev[dev_id].rxq.head);
+}
+
+static void msm_edpram_set_rx_tail(int dev_id, u32 tail)
+{
+ return iowrite16((u16)tail, msm_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static u8 __iomem *msm_edpram_get_rx_buff(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 msm_edpram_get_rx_buff_size(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 msm_edpram_get_mask_req_ack(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 msm_edpram_get_mask_res_ack(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 msm_edpram_get_mask_send(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].mask_send;
+}
+
+static void msm_log_disp(struct modemlink_dpram_control *dpctl)
+{
+ static unsigned char buf[151];
+ u8 __iomem *tmp_buff = NULL;
+
+ tmp_buff = dpctl->get_rx_buff(IPC_FMT);
+ memcpy(buf, tmp_buff, (sizeof(buf)-1));
+
+ pr_info("[LNK] | PHONE ERR MSG\t| CDMA Crash\n");
+ pr_info("[LNK] | PHONE ERR MSG\t| %s\n", buf);
+}
+
+static int msm_data_upload(struct _param_nv *param,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ u16 in_interrupt = 0;
+ int count = 0;
+
+ while (1) {
+ if (!gpio_get_value(GPIO_MSM_DPRAM_INT)) {
+ in_interrupt = dpctl->recv_msg();
+ if (in_interrupt == 0xDBAB) {
+ break;
+ } else {
+ pr_err("[LNK][intr]:0x%08x\n", in_interrupt);
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+ msleep_interruptible(1);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ param->size = ioread16(msm_edpram_bt_map.frame_size);
+ memcpy(param->addr, msm_edpram_bt_map.buff, param->size);
+ param->tag = ioread16(msm_edpram_bt_map.tag);
+ param->count = ioread16(msm_edpram_bt_map.count);
+
+ dpctl->clear_intr();
+ dpctl->send_msg(0xDB12);
+
+ return retval;
+
+}
+
+static int msm_data_load(struct _param_nv *param,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+
+ if (param->size <= DP_BOOT_FRAME_SIZE_LIMIT) {
+ memcpy(msm_edpram_bt_map.buff, param->addr, param->size);
+ iowrite16(param->size, msm_edpram_bt_map.frame_size);
+ iowrite16(param->tag, msm_edpram_bt_map.tag);
+ iowrite16(param->count, msm_edpram_bt_map.count);
+
+ dpctl->clear_intr();
+ dpctl->send_msg(0xDB12);
+
+ } else {
+ pr_err("[LNK/E]<%s> size:0x%x\n", __func__, param->size);
+ }
+
+ return retval;
+}
+
+static int msm_uload_step1(struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ u16 in_interrupt = 0, out_interrupt = 0;
+
+ pr_info("[LNK] +---------------------------------------------+\n");
+ pr_info("[LNK] | UPLOAD PHONE SDRAM |\n");
+ pr_info("[LNK] +---------------------------------------------+\n");
+
+ while (1) {
+ if (!gpio_get_value(GPIO_MSM_DPRAM_INT)) {
+ in_interrupt = dpctl->recv_msg();
+ pr_info("[LNK] [in_interrupt] 0x%04x\n", in_interrupt);
+ if (in_interrupt == 0x1234) {
+ break;
+ } else {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+ msleep_interruptible(1);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ in_interrupt = dpctl->recv_msg();
+ if (in_interrupt == 0x1234) {
+ pr_info("[LNK] [in_interrupt]: 0x%04x\n",
+ in_interrupt);
+ break;
+ }
+ return -1;
+ }
+ }
+ out_interrupt = 0xDEAD;
+ dpctl->send_msg(out_interrupt);
+
+ return retval;
+}
+
+static int msm_uload_step2(void *arg,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ retval = msm_data_upload(&param, dpctl);
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ if (!(param.count % 500))
+ pr_info("[LNK] [param->count]:%d\n", param.count);
+
+ if (param.tag == 4) {
+ dpctl->clear_intr();
+ enable_irq(msm_edpram_ctrl.dpram_irq);
+ pr_info("[LNK] [param->tag]:%d\n", param.tag);
+ }
+
+ retval = copy_to_user((unsigned long *)arg, &param, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ return retval;
+}
+
+static int msm_dload_prep(struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+
+ while (1) {
+ if (check_param.copy_start) {
+ check_param.copy_start = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return retval;
+}
+
+static int msm_dload(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ unsigned char *img = NULL;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ img = vmalloc(param.size);
+ if (img == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ memset(img, 0, param.size);
+ memcpy(img, param.addr, param.size);
+
+ data_param = kzalloc(sizeof(struct _param_nv), GFP_KERNEL);
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ return -1;
+ }
+
+ check_param.total_size = param.size;
+ check_param.rest_size = param.size;
+ check_param.send_size = 0;
+ check_param.copy_complete = 0;
+
+ data_param->addr = img;
+ data_param->size = DP_BOOT_FRAME_SIZE_LIMIT;
+ data_param->count = param.count;
+
+ data_param->tag = 0x0001;
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ retval = msm_data_load(data_param, dpctl);
+
+ while (1) {
+ if (check_param.copy_complete) {
+ check_param.copy_complete = 0;
+
+ vfree(img);
+ kfree(data_param);
+
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 1000) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ kfree(data_param);
+ return -1;
+ }
+ }
+
+ return retval;
+
+}
+
+static int msm_nv_load(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ unsigned char *img = NULL;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ img = vmalloc(param.size);
+ if (img == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ memset(img, 0, param.size);
+ memcpy(img, param.addr, param.size);
+
+ data_param = kzalloc(sizeof(struct _param_nv), GFP_KERNEL);
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ return -1;
+ }
+
+ check_param.total_size = param.size;
+ check_param.rest_size = param.size;
+ check_param.send_size = 0;
+ check_param.copy_complete = 0;
+
+ data_param->addr = img;
+ data_param->size = DP_BOOT_FRAME_SIZE_LIMIT;
+ data_param->count = 1;
+ data_param->tag = 0x0002;
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ retval = msm_data_load(data_param, dpctl);
+
+ while (1) {
+ if (check_param.copy_complete) {
+ check_param.copy_complete = 0;
+
+ vfree(img);
+ kfree(data_param);
+
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ kfree(data_param);
+ return -1;
+ }
+ }
+
+ return retval;
+
+}
+
+static int msm_boot_start(struct modemlink_dpram_control *dpctl)
+{
+
+ u16 out_interrupt = 0;
+ int count = 0;
+
+ /* Send interrupt -> '0x4567' */
+ out_interrupt = 0x4567;
+ dpctl->send_msg(out_interrupt);
+
+ while (1) {
+ if (check_param.boot_complete) {
+ check_param.boot_complete = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static struct modemlink_dpram_control *tasklet_dpctl;
+
+static void interruptable_load_tasklet_handler(unsigned long data);
+
+static DECLARE_TASKLET(interruptable_load_tasklet,
+ interruptable_load_tasklet_handler, (unsigned long) &tasklet_dpctl);
+
+static void interruptable_load_tasklet_handler(unsigned long data)
+{
+ struct modemlink_dpram_control *dpctl =
+ (struct modemlink_dpram_control *)
+ (*((struct modemlink_dpram_control **) data));
+
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return;
+ }
+
+ check_param.send_size += data_param->size;
+ check_param.rest_size -= data_param->size;
+ data_param->addr += data_param->size;
+
+ if (check_param.send_size < check_param.total_size) {
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+
+ data_param->count += 1;
+
+ msm_data_load(data_param, dpctl);
+ } else {
+ data_param->tag = 0;
+ check_param.copy_complete = 1;
+ }
+
+}
+
+static int msm_boot_start_post_proc(void)
+{
+ int count = 0;
+
+ while (1) {
+ if (boot_start_complete) {
+ boot_start_complete = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void msm_boot_start_handler(struct modemlink_dpram_control *dpctl)
+{
+ boot_start_complete = 1;
+
+ /* Send INIT_END code to CP */
+ pr_info("[LNK] <%s> Send 0x11C2 (INIT_END)\n", __func__);
+
+ /*
+ * INT_MASK_VALID|INT_MASK_CMD|INT_MASK_CP_AIRPLANE_BOOT|
+ * INT_MASK_CP_AP_ANDROID|INT_MASK_CMD_INIT_END
+ */
+ dpctl->send_intr((0x0080|0x0040|0x1000|0x0100|0x0002));
+}
+
+static void msm_dload_handler(struct modemlink_dpram_control *dpctl, u16 cmd)
+{
+ switch (cmd) {
+ case 0x1234:
+ check_param.copy_start = 1;
+ break;
+
+ case 0xDBAB:
+ tasklet_schedule(&interruptable_load_tasklet);
+ break;
+
+ case 0xABCD:
+ check_param.boot_complete = 1;
+ break;
+
+ default:
+ pr_err("[LNK/Err] <%s> Unknown command.. %x\n", __func__, cmd);
+ }
+}
+
+static void msm_bt_map_init(struct modemlink_dpram_control *dpctl)
+{
+ msm_edpram_bt_map.buff = (u8 *)(dpctl->dp_base);
+ msm_edpram_bt_map.frame_size =
+ (u16 *)(dpctl->dp_base + DP_BOOT_SIZE_OFFSET);
+ msm_edpram_bt_map.tag =
+ (u16 *)(dpctl->dp_base + DP_BOOT_TAG_OFFSET);
+ msm_edpram_bt_map.count =
+ (u16 *)(dpctl->dp_base + DP_BOOT_COUNT_OFFSET);
+}
+
+
+static void msm_load_init(struct modemlink_dpram_control *dpctl)
+{
+ tasklet_dpctl = dpctl;
+ if (tasklet_dpctl == NULL)
+ pr_err("[LNK/Err] failed tasklet_dpctl remap\n");
+
+ check_param.total_size = 0;
+ check_param.rest_size = 0;
+ check_param.send_size = 0;
+ check_param.copy_start = 0;
+ check_param.copy_complete = 0;
+ check_param.boot_complete = 0;
+
+ dpctl->clear_intr();
+}
+
+static void config_cdma_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_cp_on = cdma_modem_data.gpio_cp_on;
+ unsigned gpio_cp_off = cdma_modem_data.gpio_cp_off;
+ unsigned gpio_rst_req_n = cdma_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_rst = cdma_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = cdma_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = cdma_modem_data.gpio_phone_active;
+ unsigned gpio_flm_uart_sel = cdma_modem_data.gpio_flm_uart_sel;
+
+ pr_info("[MODEMS] <%s>\n", __func__);
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 1);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_pda_active, 0);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "MSM_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_ACTIVE");
+ } else {
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_phone_active, IRQ_TYPE_EDGE_BOTH);
+ }
+ }
+
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "BOOT_SW_SEL");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "BOOT_SW_SEL");
+ } else {
+ gpio_direction_output(gpio_flm_uart_sel, 1);
+ s3c_gpio_setpull(gpio_flm_uart_sel, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_flm_uart_sel, 1);
+ }
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "MSM_ON");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 1);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_cp_on, 0);
+ }
+ }
+
+ if (gpio_cp_off) {
+ err = gpio_request(gpio_cp_off, "MSM_OFF");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_OFF");
+ } else {
+ gpio_direction_output(gpio_cp_off, 1);
+ s3c_gpio_setpull(gpio_cp_off, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_cp_off, 1);
+ }
+ }
+
+ if (gpio_rst_req_n) {
+ err = gpio_request(gpio_rst_req_n, "MSM_RST_REQ");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_RST_REQ");
+ } else {
+ gpio_direction_output(gpio_rst_req_n, 1);
+ s3c_gpio_setpull(gpio_rst_req_n, S3C_GPIO_PULL_NONE);
+ }
+ gpio_set_value(gpio_rst_req_n, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "MSM_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 1);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ gpio_set_value(gpio_cp_rst, 0);
+ }
+}
+
+static u8 *msm_edpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = 0;
+ int dp_size = 0;
+ u8 __iomem *dp_base = NULL;
+ struct msm_edpram_ipc_cfg *ipc_map = NULL;
+ struct msm_edpram_ipc_device *dev = NULL;
+
+ dp_addr = cfg->addr;
+ dp_size = cfg->size;
+ dp_base = (u8 *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ pr_err("[MDM] <%s> dpram base ioremap fail\n", __func__);
+ return NULL;
+ }
+ pr_info("[MDM] <%s> DPRAM VA=0x%08X\n", __func__, (int)dp_base);
+
+ msm_edpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ msm_edpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct msm_edpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ msm_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ msm_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &msm_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = MSM_DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = MSM_DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &msm_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = MSM_DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = MSM_DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+#if 0
+ /* RFS */
+ dev = &msm_ipc_map.dev[IPC_RFS];
+
+ strcpy(dev->name, "RFS");
+ dev->id = IPC_RFS;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->rfs_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->rfs_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->rfs_tx_buff[0];
+ dev->txq.size = MSM_DP_RFS_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->rfs_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->rfs_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->rfs_rx_buff[0];
+ dev->rxq.size = MSM_DP_RFS_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_RFS;
+ dev->mask_res_ack = INT_MASK_RES_ACK_RFS;
+ dev->mask_send = INT_MASK_SEND_RFS;
+#endif
+
+ /* Mailboxes */
+ msm_ipc_map.mbx_ap2cp = (u16 __iomem *)&ipc_map->mbx_ap2cp;
+ msm_ipc_map.mbx_cp2ap = (u16 __iomem *)&ipc_map->mbx_cp2ap;
+
+ return dp_base;
+}
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ pr_info("[MDM] <%s> address line = %d bits\n", __func__, addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for dpram address */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY3(0), EXYNOS4_GPIO_Y3_NR,
+ S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY4(0),
+ addr_bits - EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2));
+ pr_info("[MDM] <%s> last data gpio EXYNOS4_GPY4(0) ~ %d\n",
+ __func__, addr_bits - EXYNOS4_GPIO_Y3_NR);
+ break;
+
+ default:
+ pr_err("[MDM/E] <%s> Invalid addr_bits!!!\n", __func__);
+ return;
+ }
+
+ /* Set GPIO for dpram data - 16bit */
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY5(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY6(0), 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgrange_nopull(GPIO_DPRAM_REN, 2, S3C_GPIO_SFN(2));
+
+ /* Config LBn, UBn */
+ s3c_gpio_cfgrange_nopull(GPIO_DPRAM_LBN, 2, S3C_GPIO_SFN(2));
+
+ /* Config BUSY */
+ s3c_gpio_cfgpin(GPIO_DPRAM_BUSY, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ pr_err("[MDM/E] <%s> SROMC clock gate fail\n", __func__);
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(
+ unsigned csn,
+ struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg
+)
+{
+ unsigned bw = 0;
+ unsigned bc = 0;
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ pr_err("[MDM] <%s> SROMC settings for CS%d...\n", __func__, csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> Old SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn * 4));
+
+ if (cfg->attr | MEM_DATA_BUS_16BIT)
+ bw |= (SROMC_DATA_16 << (csn * 4));
+
+ if (cfg->attr | MEM_WAIT_EN)
+ bw |= (SROMC_WAIT_EN << (csn * 4));
+
+ if (cfg->attr | MEM_BYTE_EN)
+ bw |= (SROMC_BYTE_EN << (csn * 4));
+
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> New SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+}
+
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg)
+{
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+ unsigned bc = 0;
+
+ bc = __raw_readl(bank_sfr);
+ pr_info("[MDM] <%s> Old CS%d setting = 0x%08X\n", __func__, csn, bc);
+
+ /* SROMC memory access timing setting */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+ writel(bc, bank_sfr);
+
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> New CS%d setting = 0x%08X\n", __func__, csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ msm_edpram_cfg.csn = 0;
+ msm_edpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * msm_edpram_cfg.csn);
+ msm_edpram_cfg.end = msm_edpram_cfg.addr + msm_edpram_cfg.size - 1;
+
+ config_dpram_port_gpio();
+ config_cdma_modem_gpio();
+
+ init_sromc();
+ cfg = &msm_edpram_cfg;
+ acc_cfg = &msm_edpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!msm_edpram_remap_mem_region(&msm_edpram_cfg))
+ return -1;
+ platform_device_register(&cdma_modem);
+
+ return 0;
+}
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
+
+#ifdef CONFIG_USBHUB_USB3503
+static int (*usbhub_set_mode)(struct usb3503_hubctl *, int);
+static struct usb3503_hubctl *usbhub_ctl;
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+}
+
+static int usb3503_hub_handler(void (*set_mode)(void), void *ctl)
+{
+ if (!set_mode || !ctl)
+ return -EINVAL;
+
+ usbhub_set_mode = (int (*)(struct usb3503_hubctl *, int))set_mode;
+ usbhub_ctl = (struct usb3503_hubctl *)ctl;
+
+ pr_info("[MDM] <%s> set_mode(%pF)\n", __func__, set_mode);
+
+ return 0;
+}
+
+static int usb3503_hw_config(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_USB_HUB_CONNECT, "HUB_CONNECT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_CONNECT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_CONNECT, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_CONNECT, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_CONNECT, S5P_GPIO_DRVSTR_LV1);
+
+ err = gpio_request(GPIO_USB_BOOT_EN, "USB_BOOT_EN");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "USB_BOOT_EN");
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
+ }
+ msleep(100);
+
+ err = gpio_request(GPIO_USB_HUB_RST, "HUB_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_RST");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_RST, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_RST, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_RST, S5P_GPIO_DRVSTR_LV1);
+ /* need to check drvstr 1 or 2 */
+
+ /* for USB3503 26Mhz Reference clock setting */
+ err = gpio_request(GPIO_USB_HUB_INT, "HUB_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_INT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_INT, 1);
+ s3c_gpio_setpull(GPIO_USB_HUB_INT, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static int usb3503_reset_n(int val)
+{
+ gpio_set_value(GPIO_USB_HUB_RST, 0);
+ msleep(20);
+ pr_info("[MDM] <%s> val = %d\n", __func__,
+ gpio_get_value(GPIO_USB_HUB_RST));
+ gpio_set_value(GPIO_USB_HUB_RST, !!val);
+
+ pr_info("[MDM] <%s> val = %d\n", __func__,
+ gpio_get_value(GPIO_USB_HUB_RST));
+
+ udelay(5); /* need it ?*/
+ return 0;
+}
+
+static struct usb3503_platform_data usb3503_pdata = {
+ .initial_mode = USB3503_MODE_STANDBY,
+ .reset_n = usb3503_reset_n,
+ .register_hub_handler = usb3503_hub_handler,
+ .port_enable = host_port_enable,
+};
+
+static struct i2c_board_info i2c_devs20_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO(USB3503_I2C_NAME, 0x08),
+ .platform_data = &usb3503_pdata,
+ },
+};
+
+/* I2C20_EMUL */
+static struct i2c_gpio_platform_data i2c20_platdata = {
+ .sda_pin = GPIO_USB_HUB_SDA,
+ .scl_pin = GPIO_USB_HUB_SCL,
+ /*FIXME: need to timming tunning... */
+ .udelay = 20,
+};
+
+static struct platform_device s3c_device_i2c20 = {
+ .name = "i2c-gpio",
+ .id = 20,
+ .dev.platform_data = &i2c20_platdata,
+};
+
+static int __init init_usbhub(void)
+{
+ usb3503_hw_config();
+ i2c_register_board_info(20, i2c_devs20_emul,
+ ARRAY_SIZE(i2c_devs20_emul));
+
+ platform_device_register(&s3c_device_i2c20);
+ return 0;
+}
+
+device_initcall(init_usbhub);
+
+static int host_port_enable(int port, int enable)
+{
+ int err, retry = 30;
+
+ pr_info("[MDM] <%s> port(%d) control(%d)\n", __func__, port, enable);
+
+ if (enable) {
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB);
+ if (err < 0) {
+ pr_err("[MDM] <%s> hub on fail\n", __func__);
+ goto exit;
+ }
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 1);
+ if (err < 0) {
+ pr_err("[MDM] <%s> port(%d) enable fail\n", __func__,
+ port);
+ goto exit;
+ }
+#ifdef CONFIG_LTE_MODEM_CMC221
+ msleep(20);
+ err = gpio_direction_output(umts_modem_data.gpio_slave_wakeup,
+ 1);
+ pr_err("[MDM] <%s> slave wakeup err(%d), en(%d), level(%d)\n",
+ __func__, err, 1,
+ gpio_get_value(umts_modem_data.gpio_slave_wakeup));
+
+ while (!gpio_get_value(umts_modem_data.gpio_slave_wakeup)
+ && retry--)
+ msleep(20);
+ pr_err("[MDM] <%s> Host wakeup (%d) retry(%d)\n", __func__,
+ gpio_get_value(umts_modem_data.gpio_host_wakeup),
+ retry);
+ err = gpio_direction_output(umts_modem_data.gpio_slave_wakeup,
+ 0);
+ pr_err("[MDM] <%s> slave wakeup err(%d), en(%d), level(%d)\n",
+ __func__, err, 0,
+ gpio_get_value(umts_modem_data.gpio_slave_wakeup));
+#endif
+ } else {
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 0);
+ if (err < 0) {
+ pr_err("[MDM] <%s> port(%d) enable fail\n", __func__,
+ port);
+ goto exit;
+ }
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY);
+ if (err < 0) {
+ pr_err("[MDM] <%s> hub off fail\n", __func__);
+ goto exit;
+ }
+ }
+
+#ifdef CONFIG_LTE_MODEM_CMC221
+ err = gpio_direction_output(umts_modem_data.gpio_host_active, enable);
+ pr_info("[MDM] <%s> active state err(%d), en(%d), level(%d)\n",
+ __func__, err, enable,
+ gpio_get_value(umts_modem_data.gpio_host_active));
+#endif
+
+exit:
+ return err;
+}
+#else
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ pr_err(" [MODEM_IF] Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+#endif
+
diff --git a/arch/arm/mach-exynos/board-c1lgt-modems.c b/arch/arm/mach-exynos/board-c1lgt-modems.c
new file mode 100644
index 0000000..aa218db
--- /dev/null
+++ b/arch/arm/mach-exynos/board-c1lgt-modems.c
@@ -0,0 +1,1937 @@
+/* linux/arch/arm/mach-xxxx/board-c1lgt-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#ifdef CONFIG_USBHUB_USB3503
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/usb3503.h>
+#include <mach/cpufreq.h>
+#include <plat/usb-phy.h>
+#endif
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/* For "bus width and wait control (BW)" register */
+enum sromc_attr {
+ SROMC_DATA_16 = 0x1, /* 16-bit data bus */
+ SROMC_BYTE_ADDR = 0x2, /* Byte base address */
+ SROMC_WAIT_EN = 0x4, /* Wait enabled */
+ SROMC_BYTE_EN = 0x8, /* Byte access enabled */
+ SROMC_MASK = 0xF
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For CMC221 IDPRAM (Internal DPRAM) */
+#define CMC_IDPRAM_SIZE 0x4000 /* 16 KB */
+
+/* FOR CMC221 SFR for IDPRAM */
+#define CMC_INT2CP_REG 0x10 /* Interrupt to CP */
+#define CMC_INT2AP_REG 0x50
+#define CMC_CLR_INT_REG 0x28 /* Clear Interrupt to AP */
+#define CMC_RESET_REG 0x3C
+#define CMC_PUT_REG 0x40 /* AP->CP reg for hostbooting */
+#define CMC_GET_REG 0x50 /* CP->AP reg for hostbooting */
+
+/* For CBP7.2 EDPRAM (External DPRAM) */
+#define CBP_EDPRAM_SIZE 0x4000 /* 16 KB */
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+#ifdef CONFIG_USBHUB_USB3503
+static int host_port_enable(int port, int enable);
+#else
+static int host_port_enable(int port, int enable)
+{
+ return s5p_ehci_port_control(&s5p_device_ehci, port, enable);
+}
+#endif
+
+#ifdef CONFIG_LTE_MODEM_CMC221
+static struct sromc_cfg cmc_idpram_cfg = {
+ .attr = SROMC_DATA_16,
+ .size = CMC_IDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cmc_idpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ /* for 33 MHz clock, 64 cycles */
+ .tacs = 0x08 << 28,
+ .tcos = 0x08 << 24,
+ .tacc = 0x1F << 16,
+ .tcoh = 0x08 << 12,
+ .tcah = 0x08 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+ [DPRAM_SPEED_MID] = {
+ /* for 66 MHz clock, 32 cycles */
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x1B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+ [DPRAM_SPEED_HIGH] = {
+ /* for 133 MHz clock, 16 cycles */
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x0B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 4564 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 9124 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define DP_FMT_TX_BUFF_SZ 1336
+#define DP_RAW_TX_BUFF_SZ 4564
+#define DP_FMT_RX_BUFF_SZ 1336
+#define DP_RAW_RX_BUFF_SZ 9124
+
+#define MAX_CMC_IDPRAM_IPC_DEV (IPC_RAW + 1) /* FMT, RAW */
+
+struct dpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[DP_RAW_RX_BUFF_SZ];
+
+ u16 mbx_cp2ap;
+ u16 mbx_ap2cp;
+};
+
+struct cmc221_idpram_sfr {
+ u16 __iomem *int2cp;
+ u16 __iomem *int2ap;
+ u16 __iomem *clr_int2ap;
+ u16 __iomem *reset;
+ u16 __iomem *msg2cp;
+ u16 __iomem *msg2ap;
+};
+
+static struct dpram_ipc_map cmc_ipc_map;
+static u8 *cmc_sfr_base;
+static struct cmc221_idpram_sfr cmc_sfr;
+
+/* Function prototypes */
+static void cmc_idpram_reset(void);
+static void cmc_idpram_setup_speed(enum dpram_speed);
+static int cmc_idpram_wakeup(void);
+static void cmc_idpram_sleep(void);
+static void cmc_idpram_clr_intr(void);
+static u16 cmc_idpram_recv_intr(void);
+static void cmc_idpram_send_intr(u16 irq_mask);
+static u16 cmc_idpram_recv_msg(void);
+static void cmc_idpram_send_msg(u16 msg);
+
+static u16 cmc_idpram_get_magic(void);
+static void cmc_idpram_set_magic(u16 value);
+static u16 cmc_idpram_get_access(void);
+static void cmc_idpram_set_access(u16 value);
+
+static u32 cmc_idpram_get_tx_head(int dev_id);
+static u32 cmc_idpram_get_tx_tail(int dev_id);
+static void cmc_idpram_set_tx_head(int dev_id, u32 head);
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id);
+static u32 cmc_idpram_get_tx_buff_size(int dev_id);
+
+static u32 cmc_idpram_get_rx_head(int dev_id);
+static u32 cmc_idpram_get_rx_tail(int dev_id);
+static void cmc_idpram_set_rx_head(int dev_id, u32 head);
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id);
+static u32 cmc_idpram_get_rx_buff_size(int dev_id);
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id);
+static u16 cmc_idpram_get_mask_res_ack(int dev_id);
+static u16 cmc_idpram_get_mask_send(int dev_id);
+
+static struct modemlink_dpram_control cmc_idpram_ctrl = {
+ .reset = cmc_idpram_reset,
+
+ .setup_speed = cmc_idpram_setup_speed,
+
+ .wakeup = cmc_idpram_wakeup,
+ .sleep = cmc_idpram_sleep,
+
+ .clear_intr = cmc_idpram_clr_intr,
+ .recv_intr = cmc_idpram_recv_intr,
+ .send_intr = cmc_idpram_send_intr,
+ .recv_msg = cmc_idpram_recv_msg,
+ .send_msg = cmc_idpram_send_msg,
+
+ .get_magic = cmc_idpram_get_magic,
+ .set_magic = cmc_idpram_set_magic,
+ .get_access = cmc_idpram_get_access,
+ .set_access = cmc_idpram_set_access,
+
+ .get_tx_head = cmc_idpram_get_tx_head,
+ .get_tx_tail = cmc_idpram_get_tx_tail,
+ .set_tx_head = cmc_idpram_set_tx_head,
+ .set_tx_tail = cmc_idpram_set_tx_tail,
+ .get_tx_buff = cmc_idpram_get_tx_buff,
+ .get_tx_buff_size = cmc_idpram_get_tx_buff_size,
+
+ .get_rx_head = cmc_idpram_get_rx_head,
+ .get_rx_tail = cmc_idpram_get_rx_tail,
+ .set_rx_head = cmc_idpram_set_rx_head,
+ .set_rx_tail = cmc_idpram_set_rx_tail,
+ .get_rx_buff = cmc_idpram_get_rx_buff,
+ .get_rx_buff_size = cmc_idpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cmc_idpram_get_mask_req_ack,
+ .get_mask_res_ack = cmc_idpram_get_mask_res_ack,
+ .get_mask_send = cmc_idpram_get_mask_send,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = CP_IDPRAM,
+ .aligned = 1,
+
+ .dpram_irq = CMC_IDPRAM_INT_IRQ_00,
+ .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING),
+ .dpram_irq_name = "CMC221_IDPRAM_IRQ",
+ .dpram_wlock_name = "CMC221_IDPRAM_WLOCK",
+
+ .max_ipc_dev = MAX_CMC_IDPRAM_IPC_DEV,
+};
+
+/*
+** UMTS target platform data
+*/
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_boot0",
+ .id = 0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "umts_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "umts_rfs0",
+ .id = 245,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "lte_multipdp",
+ .id = 0,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [4] = {
+ .name = "lte_rmnet0",
+ .id = 10,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [5] = {
+ .name = "lte_rmnet1",
+ .id = 11,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [6] = {
+ .name = "lte_rmnet2",
+ .id = 12,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [7] = {
+ .name = "lte_rmnet3",
+ .id = 13,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [8] = {
+ .name = "umts_csd", /* CS Video Telephony */
+ .id = 1,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "umts_router", /* AT Iface & Dial-up */
+ .id = 25,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "umts_dm0", /* DM Port */
+ .id = 28,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "umts_loopback_ap2cp",
+ .id = 30,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "umts_loopback_cp2ap",
+ .id = 31,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "umts_ramdump0",
+ .id = 0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "lte_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_USB),
+ },
+};
+
+static int exynos_cpu_frequency_lock(void);
+static int exynos_cpu_frequency_unlock(void);
+
+static struct modemlink_pm_data umts_link_pm_data = {
+ .name = "umts_link_pm",
+
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+
+ .port_enable = host_port_enable,
+/*
+ .link_reconnect = umts_link_reconnect,
+*/
+ .freqlock = ATOMIC_INIT(0),
+ .cpufreq_lock = exynos_cpu_frequency_lock,
+ .cpufreq_unlock = exynos_cpu_frequency_unlock,
+
+ .autosuspend_delay_ms = 2000,
+
+ .has_usbhub = true,
+};
+
+static struct modem_data umts_modem_data = {
+ .name = "cmc221",
+
+ .gpio_cp_on = CP_CMC221_PMIC_PWRON,
+ .gpio_cp_reset = CP_CMC221_CPU_RST,
+ .gpio_phone_active = GPIO_LTE_ACTIVE,
+
+ .gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00,
+ .gpio_dpram_status = GPIO_CMC_IDPRAM_STATUS,
+ .gpio_dpram_wakeup = GPIO_CMC_IDPRAM_WAKEUP,
+
+ .gpio_slave_wakeup = GPIO_IPC_SLAVE_WAKEUP,
+ .gpio_host_active = GPIO_ACTIVE_STATE,
+ .gpio_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+
+ .modem_net = UMTS_NETWORK,
+ .modem_type = SEC_CMC221,
+ .link_types = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .link_name = "cmc221_idpram",
+ .dpram_ctl = &cmc_idpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &umts_link_pm_data,
+
+ .use_handover = true,
+
+ .ipc_version = SIPC_VER_50,
+ .use_mif_log = true,
+};
+
+static struct resource umts_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = LTE_ACTIVE_IRQ,
+ .end = LTE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device umts_modem = {
+ .name = "mif_sipc5",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+#define HUB_STATE_OFF 0
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val && states == STATE_HSIC_LPA_ENTER) {
+ mif_info("usb3503: hub off - lpa\n");
+ host_port_enable(2, 0);
+ *(umts_link_pm_data.p_hub_status) = HUB_STATE_OFF;
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static void cmc_idpram_reset(void)
+{
+ iowrite16(1, cmc_sfr.reset);
+}
+
+static void cmc_idpram_setup_speed(enum dpram_speed speed)
+{
+ setup_dpram_speed(cmc_idpram_cfg.csn, &cmc_idpram_access_cfg[speed]);
+}
+
+static int cmc_idpram_wakeup(void)
+{
+ int cnt = 0;
+
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 1);
+
+ while (!gpio_get_value(umts_modem_data.gpio_dpram_status)) {
+ if (cnt++ > 10) {
+ mif_err("ERR: gpio_dpram_status == 0\n");
+ return -EAGAIN;
+ }
+
+ if (in_interrupt())
+ mdelay(1);
+ else
+ msleep_interruptible(1);
+ }
+
+ return 0;
+}
+
+static void cmc_idpram_sleep(void)
+{
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 0);
+}
+
+static void cmc_idpram_clr_intr(void)
+{
+ iowrite16(0xFFFF, cmc_sfr.clr_int2ap);
+ iowrite16(0, cmc_sfr.int2ap);
+}
+
+static u16 cmc_idpram_recv_intr(void)
+{
+ return ioread16(cmc_sfr.int2ap);
+}
+
+static void cmc_idpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cmc_sfr.int2cp);
+}
+
+static u16 cmc_idpram_recv_msg(void)
+{
+ return ioread16(cmc_sfr.msg2ap);
+}
+
+static void cmc_idpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cmc_sfr.msg2cp);
+}
+
+static u16 cmc_idpram_get_magic(void)
+{
+ return ioread16(cmc_ipc_map.magic);
+}
+
+static void cmc_idpram_set_magic(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.magic);
+}
+
+static u16 cmc_idpram_get_access(void)
+{
+ return ioread16(cmc_ipc_map.access);
+}
+
+static void cmc_idpram_set_access(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.access);
+}
+
+static u32 cmc_idpram_get_tx_head(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cmc_idpram_get_tx_tail(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cmc_idpram_set_tx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].txq.head);
+ if (val == head)
+ break;
+
+ mif_err("ERR: txq.head(%d) != head(%d)\n", val, head);
+
+ /* Write head value again */
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].txq.tail);
+ if (val == tail)
+ break;
+
+ mif_err("ERR: txq.tail(%d) != tail(%d)\n", val, tail);
+
+ /* Write tail value again */
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cmc_idpram_get_tx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cmc_idpram_get_rx_head(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cmc_idpram_get_rx_tail(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cmc_idpram_set_rx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].rxq.head);
+ if (val == head)
+ break;
+
+ mif_err("ERR: rxq.head(%d) != head(%d)\n", val, head);
+
+ /* Write head value again */
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].rxq.tail);
+ if (val == tail)
+ break;
+
+ mif_err("ERR: rxq.tail(%d) != tail(%d)\n", val, tail);
+
+ /* Write tail value again */
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cmc_idpram_get_rx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cmc_idpram_get_mask_res_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cmc_idpram_get_mask_send(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_send;
+}
+
+/* Set dynamic environment for a modem */
+static void setup_umts_modem_env(void)
+{
+ /*
+ ** Config DPRAM control structure
+ */
+ if (system_rev == 1 || system_rev >= 4)
+ cmc_idpram_cfg.csn = 0;
+ else
+ cmc_idpram_cfg.csn = 1;
+
+ cmc_idpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cmc_idpram_cfg.csn);
+ cmc_idpram_cfg.end = cmc_idpram_cfg.addr + cmc_idpram_cfg.size - 1;
+
+ if (system_rev == 1 || system_rev >= 4) {
+ umts_modem_data.gpio_dpram_int = GPIO_CMC_IDPRAM_INT_01;
+ cmc_idpram_ctrl.dpram_irq = CMC_IDPRAM_INT_IRQ_01;
+ }
+}
+
+static void config_umts_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_active_state = umts_modem_data.gpio_host_active;
+ unsigned gpio_host_wakeup = umts_modem_data.gpio_host_wakeup;
+ unsigned gpio_slave_wakeup = umts_modem_data.gpio_slave_wakeup;
+ unsigned gpio_dpram_int = umts_modem_data.gpio_dpram_int;
+ unsigned gpio_dpram_status = umts_modem_data.gpio_dpram_status;
+ unsigned gpio_dpram_wakeup = umts_modem_data.gpio_dpram_wakeup;
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CMC_ON");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 0);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CMC_RST");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "CMC_ACTIVE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_ACTIVE");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_active_state) {
+ err = gpio_request(gpio_active_state, "CMC_ACTIVE_STATE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_ACTIVE_STATE");
+ } else {
+ gpio_direction_output(gpio_active_state, 0);
+ s3c_gpio_setpull(gpio_active_state, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_slave_wakeup) {
+ err = gpio_request(gpio_slave_wakeup, "CMC_SLAVE_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_SLAVE_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_slave_wakeup, 0);
+ s3c_gpio_setpull(gpio_slave_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_host_wakeup) {
+ err = gpio_request(gpio_host_wakeup, "CMC_HOST_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_HOST_WAKEUP");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_host_wakeup);
+ s3c_gpio_setpull(gpio_host_wakeup, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(gpio_host_wakeup, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "CMC_DPRAM_INT");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_dpram_int);
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_status) {
+ err = gpio_request(gpio_dpram_status, "CMC_DPRAM_STATUS");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_STATUS");
+ } else {
+ gpio_direction_input(gpio_dpram_status);
+ s3c_gpio_setpull(gpio_dpram_status, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_dpram_wakeup) {
+ err = gpio_request(gpio_dpram_wakeup, "CMC_DPRAM_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_dpram_wakeup, 1);
+ s3c_gpio_setpull(gpio_dpram_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+}
+
+static u8 *cmc_idpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = cfg->addr;
+ int dp_size = cfg->size;
+ u8 __iomem *dp_base;
+ struct dpram_ipc_cfg *ipc_map;
+ struct dpram_ipc_device *dev;
+
+ /* Remap DPRAM memory region */
+ dp_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ mif_err("ERR: ioremap_nocache for dp_base fail\n");
+ return NULL;
+ }
+ mif_err("DPRAM VA=0x%08X\n", (int)dp_base);
+
+ /* Remap DPRAM SFR region */
+ dp_addr += dp_size;
+ cmc_sfr_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size);
+ if (cmc_sfr_base == NULL) {
+ iounmap(dp_base);
+ mif_err("ERR: ioremap_nocache for cmc_sfr_base fail\n");
+ return NULL;
+ }
+
+ cmc_sfr.int2cp = (u16 __iomem *)(cmc_sfr_base + CMC_INT2CP_REG);
+ cmc_sfr.int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_INT2AP_REG);
+ cmc_sfr.clr_int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_CLR_INT_REG);
+ cmc_sfr.reset = (u16 __iomem *)(cmc_sfr_base + CMC_RESET_REG);
+ cmc_sfr.msg2cp = (u16 __iomem *)(cmc_sfr_base + CMC_PUT_REG);
+ cmc_sfr.msg2ap = (u16 __iomem *)(cmc_sfr_base + CMC_GET_REG);
+
+ cmc_idpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cmc_idpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct dpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cmc_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cmc_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cmc_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cmc_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+ return dp_base;
+}
+#endif
+
+#ifdef CONFIG_CDMA_MODEM_CBP72
+static struct sromc_cfg cbp_edpram_cfg = {
+ .attr = SROMC_DATA_16 | SROMC_BYTE_EN,
+ .size = CBP_EDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cbp_edpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ .tacs = 0x00 << 28,
+ .tcos = 0x00 << 24,
+ .tacc = 0x0F << 16,
+ .tcoh = 0x00 << 12,
+ .tcah = 0x00 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 4564 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 9124 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define CBP_DP_FMT_TX_BUFF_SZ 1336
+#define CBP_DP_RAW_TX_BUFF_SZ 4564
+#define CBP_DP_FMT_RX_BUFF_SZ 1336
+#define CBP_DP_RAW_RX_BUFF_SZ 9124
+
+#define MAX_CBP_EDPRAM_IPC_DEV (IPC_RAW + 1) /* FMT, RAW */
+
+struct cbp_edpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[CBP_DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[CBP_DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[CBP_DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[CBP_DP_RAW_RX_BUFF_SZ];
+
+ u16 mbx_cp2ap;
+ u16 mbx_ap2cp;
+};
+
+static struct dpram_ipc_map cbp_ipc_map;
+
+static void cbp_edpram_reset(void);
+static void cbp_edpram_clr_intr(void);
+static u16 cbp_edpram_recv_intr(void);
+static void cbp_edpram_send_intr(u16 irq_mask);
+static u16 cbp_edpram_recv_msg(void);
+static void cbp_edpram_send_msg(u16 msg);
+
+static u16 cbp_edpram_get_magic(void);
+static void cbp_edpram_set_magic(u16 value);
+static u16 cbp_edpram_get_access(void);
+static void cbp_edpram_set_access(u16 value);
+
+static u32 cbp_edpram_get_tx_head(int dev_id);
+static u32 cbp_edpram_get_tx_tail(int dev_id);
+static void cbp_edpram_set_tx_head(int dev_id, u32 head);
+static void cbp_edpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cbp_edpram_get_tx_buff(int dev_id);
+static u32 cbp_edpram_get_tx_buff_size(int dev_id);
+
+static u32 cbp_edpram_get_rx_head(int dev_id);
+static u32 cbp_edpram_get_rx_tail(int dev_id);
+static void cbp_edpram_set_rx_head(int dev_id, u32 head);
+static void cbp_edpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cbp_edpram_get_rx_buff(int dev_id);
+static u32 cbp_edpram_get_rx_buff_size(int dev_id);
+
+static u16 cbp_edpram_get_mask_req_ack(int dev_id);
+static u16 cbp_edpram_get_mask_res_ack(int dev_id);
+static u16 cbp_edpram_get_mask_send(int dev_id);
+
+static struct modemlink_dpram_control cbp_edpram_ctrl = {
+ .reset = cbp_edpram_reset,
+
+ .clear_intr = cbp_edpram_clr_intr,
+ .recv_intr = cbp_edpram_recv_intr,
+ .send_intr = cbp_edpram_send_intr,
+ .recv_msg = cbp_edpram_recv_msg,
+ .send_msg = cbp_edpram_send_msg,
+
+ .get_magic = cbp_edpram_get_magic,
+ .set_magic = cbp_edpram_set_magic,
+ .get_access = cbp_edpram_get_access,
+ .set_access = cbp_edpram_set_access,
+
+ .get_tx_head = cbp_edpram_get_tx_head,
+ .get_tx_tail = cbp_edpram_get_tx_tail,
+ .set_tx_head = cbp_edpram_set_tx_head,
+ .set_tx_tail = cbp_edpram_set_tx_tail,
+ .get_tx_buff = cbp_edpram_get_tx_buff,
+ .get_tx_buff_size = cbp_edpram_get_tx_buff_size,
+
+ .get_rx_head = cbp_edpram_get_rx_head,
+ .get_rx_tail = cbp_edpram_get_rx_tail,
+ .set_rx_head = cbp_edpram_set_rx_head,
+ .set_rx_tail = cbp_edpram_set_rx_tail,
+ .get_rx_buff = cbp_edpram_get_rx_buff,
+ .get_rx_buff_size = cbp_edpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cbp_edpram_get_mask_req_ack,
+ .get_mask_res_ack = cbp_edpram_get_mask_res_ack,
+ .get_mask_send = cbp_edpram_get_mask_send,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = EXT_DPRAM,
+ .aligned = 1,
+
+ .dpram_irq = CBP_DPRAM_INT_IRQ_00,
+ .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_FALLING),
+ .dpram_irq_name = "CBP72_EDPRAM_IRQ",
+ .dpram_wlock_name = "CBP72_EDPRAM_WLOCK",
+
+ .max_ipc_dev = MAX_CBP_EDPRAM_IPC_DEV,
+};
+
+/*
+** CDMA target platform data
+*/
+static struct modem_io_t cdma_io_devices[] = {
+ [0] = {
+ .name = "cdma_boot0",
+ .id = 0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "cdma_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "cdma_rfs0",
+ .id = 245,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "cdma_multipdp",
+ .id = 0,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [4] = {
+ .name = "cdma_rmnet0",
+ .id = 10,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [5] = {
+ .name = "cdma_rmnet1",
+ .id = 11,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [6] = {
+ .name = "cdma_rmnet2",
+ .id = 12,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [7] = {
+ .name = "cdma_rmnet3",
+ .id = 13,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [8] = {
+ .name = "cdma_rmnet4",
+ .id = 7,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "cdma_rmnet5", /* DM Port IO device */
+ .id = 26,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "cdma_rmnet6", /* AT CMD IO device */
+ .id = 17,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "cdma_ramdump0",
+ .id = 0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "cdma_cplog",
+ .id = 29,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+};
+
+static struct modem_data cdma_modem_data = {
+ .name = "cbp7.2",
+
+ .gpio_cp_on = GPIO_CBP_PMIC_PWRON,
+ .gpio_cp_off = GPIO_CBP_PS_HOLD_OFF,
+ .gpio_cp_reset = GPIO_CBP_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_CBP_PHONE_ACTIVE,
+
+ .gpio_dpram_int = GPIO_CBP_DPRAM_INT_00,
+
+ .modem_net = CDMA_NETWORK,
+ .modem_type = VIA_CBP72,
+ .link_types = LINKTYPE(LINKDEV_DPRAM),
+ .link_name = "cbp72_edpram",
+ .dpram_ctl = &cbp_edpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(cdma_io_devices),
+ .iodevs = cdma_io_devices,
+
+ .use_handover = true,
+
+ .ipc_version = SIPC_VER_50,
+};
+
+static struct resource cdma_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = CBP_PHONE_ACTIVE_IRQ,
+ .end = CBP_PHONE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cdma_modem = {
+ .name = "mif_sipc5",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cdma_modem_res),
+ .resource = cdma_modem_res,
+ .dev = {
+ .platform_data = &cdma_modem_data,
+ },
+};
+
+static void cbp_edpram_reset(void)
+{
+ return;
+}
+
+static void cbp_edpram_clr_intr(void)
+{
+ ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static u16 cbp_edpram_recv_intr(void)
+{
+ return ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static void cbp_edpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cbp_ipc_map.mbx_ap2cp);
+}
+
+static u16 cbp_edpram_recv_msg(void)
+{
+ return ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static void cbp_edpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cbp_ipc_map.mbx_ap2cp);
+}
+
+static u16 cbp_edpram_get_magic(void)
+{
+ return ioread16(cbp_ipc_map.magic);
+}
+
+static void cbp_edpram_set_magic(u16 value)
+{
+ iowrite16(value, cbp_ipc_map.magic);
+}
+
+static u16 cbp_edpram_get_access(void)
+{
+ return ioread16(cbp_ipc_map.access);
+}
+
+static void cbp_edpram_set_access(u16 value)
+{
+ iowrite16(value, cbp_ipc_map.access);
+}
+
+static u32 cbp_edpram_get_tx_head(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cbp_edpram_get_tx_tail(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cbp_edpram_set_tx_head(int dev_id, u32 head)
+{
+ iowrite16((u16)head, cbp_ipc_map.dev[dev_id].txq.head);
+}
+
+static void cbp_edpram_set_tx_tail(int dev_id, u32 tail)
+{
+ iowrite16((u16)tail, cbp_ipc_map.dev[dev_id].txq.tail);
+}
+
+static u8 __iomem *cbp_edpram_get_tx_buff(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cbp_edpram_get_tx_buff_size(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cbp_edpram_get_rx_head(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cbp_edpram_get_rx_tail(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cbp_edpram_set_rx_head(int dev_id, u32 head)
+{
+ return iowrite16((u16)head, cbp_ipc_map.dev[dev_id].rxq.head);
+}
+
+static void cbp_edpram_set_rx_tail(int dev_id, u32 tail)
+{
+ return iowrite16((u16)tail, cbp_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static u8 __iomem *cbp_edpram_get_rx_buff(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cbp_edpram_get_rx_buff_size(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cbp_edpram_get_mask_req_ack(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cbp_edpram_get_mask_res_ack(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cbp_edpram_get_mask_send(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_send;
+}
+
+/* Set dynamic environment for a modem */
+static void setup_cdma_modem_env(void)
+{
+ /*
+ ** Config DPRAM control structure
+ */
+ if (system_rev == 1 || system_rev >= 4)
+ cbp_edpram_cfg.csn = 1;
+ else
+ cbp_edpram_cfg.csn = 0;
+
+ cbp_edpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cbp_edpram_cfg.csn);
+ cbp_edpram_cfg.end = cbp_edpram_cfg.addr + cbp_edpram_cfg.size - 1;
+
+ if (system_rev == 1 || system_rev >= 4) {
+ cdma_modem_data.gpio_dpram_int = GPIO_CBP_DPRAM_INT_01;
+ cbp_edpram_ctrl.dpram_irq = CBP_DPRAM_INT_IRQ_01;
+ }
+}
+
+static void config_cdma_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_boot_sel = GPIO_CBP_BOOT_SEL;
+ unsigned gpio_cp_on = cdma_modem_data.gpio_cp_on;
+ unsigned gpio_cp_off = cdma_modem_data.gpio_cp_off;
+ unsigned gpio_cp_rst = cdma_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = cdma_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = cdma_modem_data.gpio_phone_active;
+ unsigned gpio_dpram_int = cdma_modem_data.gpio_dpram_int;
+
+ pr_info("[MDM] <%s>\n", __func__);
+
+ if (gpio_boot_sel) {
+ err = gpio_request(gpio_boot_sel, "CBP_BOOT_SEL");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_BOOT_SEL");
+ } else {
+ gpio_direction_output(gpio_boot_sel, 0);
+ s3c_gpio_setpull(gpio_boot_sel, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CBP_ON");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 0);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_off) {
+ err = gpio_request(gpio_cp_off, "CBP_OFF");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_OFF");
+ } else {
+ gpio_direction_output(gpio_cp_off, 1);
+ s3c_gpio_setpull(gpio_cp_off, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CBP_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "CBP_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_ACTIVE");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "CBP_DPRAM_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_dpram_int);
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ /* set low unused gpios between AP and CP */
+ err = gpio_request(GPIO_FLM_RXD, "FLM_RXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_RXD",
+ err);
+ else {
+ gpio_direction_input(GPIO_FLM_RXD);
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_FLM_RXD, S3C_GPIO_SFN(2));
+ }
+
+ err = gpio_request(GPIO_FLM_TXD, "FLM_TXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_TXD",
+ err);
+ else {
+ gpio_direction_input(GPIO_FLM_TXD);
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_FLM_TXD, S3C_GPIO_SFN(2));
+ }
+}
+
+static u8 *cbp_edpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = 0;
+ int dp_size = 0;
+ u8 __iomem *dp_base = NULL;
+ struct cbp_edpram_ipc_cfg *ipc_map = NULL;
+ struct dpram_ipc_device *dev = NULL;
+
+ dp_addr = cfg->addr;
+ dp_size = cfg->size;
+ dp_base = (u8 *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ pr_err("[MDM] <%s> dpram base ioremap fail\n", __func__);
+ return NULL;
+ }
+ pr_info("[MDM] <%s> DPRAM VA=0x%08X\n", __func__, (int)dp_base);
+
+ cbp_edpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cbp_edpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct cbp_edpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cbp_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cbp_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cbp_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = CBP_DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = CBP_DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cbp_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = CBP_DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = CBP_DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+ /* Mailboxes */
+ cbp_ipc_map.mbx_ap2cp = (u16 __iomem *)&ipc_map->mbx_ap2cp;
+ cbp_ipc_map.mbx_cp2ap = (u16 __iomem *)&ipc_map->mbx_cp2ap;
+
+ return dp_base;
+}
+#endif
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ mif_info("address line = %d bits\n", addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for address bus (13 ~ 14 bits) */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_LOW,
+ EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_HIGH,
+ (addr_bits - EXYNOS4_GPIO_Y3_NR), S3C_GPIO_SFN(2));
+ break;
+
+ default:
+ mif_err("ERR: invalid addr_bits!!!\n");
+ return;
+ }
+
+ /* Set GPIO for data bus (16 bits) */
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_LOW, 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_HIGH, 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin((GPIO_DPRAM_CSN0 + 1), S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgpin(GPIO_DPRAM_REN, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(GPIO_DPRAM_WEN, S3C_GPIO_SFN(2));
+
+ /* Config LBn, UBn */
+ s3c_gpio_cfgpin(GPIO_DPRAM_LBN, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(GPIO_DPRAM_UBN, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ mif_err("ERR: SROMC clock gate fail\n");
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(
+ unsigned csn,
+ struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg
+)
+{
+ unsigned bw = 0; /* Bus width and wait control */
+ unsigned bc = 0; /* Vank control */
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ mif_err("SROMC settings for CS%d...\n", csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ mif_err("Old SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn << 2));
+ bw |= (cfg->attr << (csn << 2));
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ mif_err("New SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc);
+}
+
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg)
+{
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+ unsigned bc = 0;
+
+ bc = __raw_readl(bank_sfr);
+ mif_info("Old CS%d setting = 0x%08X\n", csn, bc);
+
+ /* SROMC memory access timing setting */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+ writel(bc, bank_sfr);
+
+ bc = __raw_readl(bank_sfr);
+ mif_info("New CS%d setting = 0x%08X\n", csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ mif_err("System Revision = %d\n", system_rev);
+
+ setup_umts_modem_env();
+ setup_cdma_modem_env();
+
+ config_dpram_port_gpio();
+
+ config_umts_modem_gpio();
+ config_cdma_modem_gpio();
+
+ init_sromc();
+
+ cfg = &cmc_idpram_cfg;
+ acc_cfg = &cmc_idpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ cfg = &cbp_edpram_cfg;
+ acc_cfg = &cbp_edpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!cmc_idpram_remap_mem_region(&cmc_idpram_cfg))
+ return -1;
+ platform_device_register(&umts_modem);
+
+ if (!cbp_edpram_remap_mem_region(&cbp_edpram_cfg))
+ return -1;
+ platform_device_register(&cdma_modem);
+
+ return 0;
+}
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
+
+#ifdef CONFIG_USBHUB_USB3503
+static int (*usbhub_set_mode)(struct usb3503_hubctl *, int);
+static struct usb3503_hubctl *usbhub_ctl;
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+static int exynos_cpu_frequency_lock(void)
+{
+ unsigned int level, freq = 700;
+
+ if (atomic_read(&umts_link_pm_data.freqlock) == 0) {
+ if (exynos_cpufreq_get_level(freq * 1000, &level)) {
+ mif_err("ERR: exynos_cpufreq_get_level fail\n");
+ return -EINVAL;
+ }
+
+ if (exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level)) {
+ mif_err("ERR: exynos_cpufreq_lock fail\n");
+ return -EINVAL;
+ }
+
+ atomic_set(&umts_link_pm_data.freqlock, 1);
+ mif_debug("<%d> %d MHz\n", level, freq);
+ }
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ if (atomic_read(&umts_link_pm_data.freqlock) == 1) {
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF);
+ atomic_set(&umts_link_pm_data.freqlock, 0);
+ mif_debug("\n");
+ }
+ return 0;
+}
+#else
+static int exynos_cpu_frequency_lock(void)
+{
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ return 0;
+}
+#endif
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+}
+
+static int usb3503_hub_handler(void (*set_mode)(void), void *ctl)
+{
+ if (!set_mode || !ctl)
+ return -EINVAL;
+
+ usbhub_set_mode = (int (*)(struct usb3503_hubctl *, int))set_mode;
+ usbhub_ctl = (struct usb3503_hubctl *)ctl;
+
+ mif_info("set_mode(%pF)\n", set_mode);
+
+ return 0;
+}
+
+static int usb3503_hw_config(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_USB_HUB_RST, "HUB_RST");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "HUB_RST");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_RST, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_RST, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_RST, S5P_GPIO_DRVSTR_LV1);
+ /* need to check drvstr 1 or 2 */
+
+ /* for USB3503 26Mhz Reference clock setting */
+ err = gpio_request(GPIO_USB_HUB_INT, "HUB_INT");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "HUB_INT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_INT, 1);
+ s3c_gpio_setpull(GPIO_USB_HUB_INT, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static int usb3503_reset_n(int val)
+{
+ gpio_set_value(GPIO_USB_HUB_RST, 0);
+
+ /* hub off from cpuidle(LPA), skip the msleep schedule*/
+ if (val) {
+ msleep(20);
+ mif_info("val = %d\n", gpio_get_value(GPIO_USB_HUB_RST));
+
+ gpio_set_value(GPIO_USB_HUB_RST, !!val);
+
+ mif_info("val = %d\n", gpio_get_value(GPIO_USB_HUB_RST));
+ udelay(5); /* need it ?*/
+ }
+ return 0;
+}
+
+static struct usb3503_platform_data usb3503_pdata = {
+ .initial_mode = USB3503_MODE_STANDBY,
+ .reset_n = usb3503_reset_n,
+ .register_hub_handler = usb3503_hub_handler,
+ .port_enable = host_port_enable,
+};
+
+static struct i2c_board_info i2c_devs20_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO(USB3503_I2C_NAME, 0x08),
+ .platform_data = &usb3503_pdata,
+ },
+};
+
+/* I2C20_EMUL */
+static struct i2c_gpio_platform_data i2c20_platdata = {
+ .sda_pin = GPIO_USB_HUB_SDA,
+ .scl_pin = GPIO_USB_HUB_SCL,
+ /*FIXME: need to timming tunning... */
+ .udelay = 20,
+};
+
+static struct platform_device s3c_device_i2c20 = {
+ .name = "i2c-gpio",
+ .id = 20,
+ .dev.platform_data = &i2c20_platdata,
+};
+
+static int __init init_usbhub(void)
+{
+ usb3503_hw_config();
+ i2c_register_board_info(20, i2c_devs20_emul,
+ ARRAY_SIZE(i2c_devs20_emul));
+
+ platform_device_register(&s3c_device_i2c20);
+ return 0;
+}
+
+device_initcall(init_usbhub);
+
+static int host_port_enable(int port, int enable)
+{
+ int err;
+
+ mif_info("port(%d) control(%d)\n", port, enable);
+
+ if (enable) {
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB);
+ if (err < 0) {
+ mif_err("ERR: hub on fail\n");
+ goto exit;
+ }
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 1);
+ if (err < 0) {
+ mif_err("ERR: port(%d) enable fail\n", port);
+ goto exit;
+ }
+ } else {
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 0);
+ if (err < 0) {
+ mif_err("ERR: port(%d) enable fail\n", port);
+ goto exit;
+ }
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY);
+ if (err < 0) {
+ mif_err("ERR: hub off fail\n");
+ goto exit;
+ }
+ }
+
+ err = gpio_direction_output(umts_modem_data.gpio_host_active, enable);
+ mif_info("active state err(%d), en(%d), level(%d)\n",
+ err, enable, gpio_get_value(umts_modem_data.gpio_host_active));
+
+exit:
+ return err;
+}
+#else
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ mif_err("<%s> Active States =%d, %s\n", pdev->name, type);
+ gpio_direction_output(umts_link_pm_data.gpio_link_active, type);
+ } else {
+ active_ctl.gpio_request_host_active = 1;
+ }
+}
+#endif
+
diff --git a/arch/arm/mach-exynos/board-c1vzw-modems.c b/arch/arm/mach-exynos/board-c1vzw-modems.c
new file mode 100644
index 0000000..6eb0509
--- /dev/null
+++ b/arch/arm/mach-exynos/board-c1vzw-modems.c
@@ -0,0 +1,1930 @@
+/* linux/arch/arm/mach-xxxx/board-c1vzw-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#ifdef CONFIG_USBHUB_USB3503
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/usb3503.h>
+#include <mach/cpufreq.h>
+#include <plat/usb-phy.h>
+#endif
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/* For "bus width and wait control (BW)" register */
+enum sromc_attr {
+ SROMC_DATA_16 = 0x1, /* 16-bit data bus */
+ SROMC_BYTE_ADDR = 0x2, /* Byte base address */
+ SROMC_WAIT_EN = 0x4, /* Wait enabled */
+ SROMC_BYTE_EN = 0x8, /* Byte access enabled */
+ SROMC_MASK = 0xF
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For CMC221 IDPRAM (Internal DPRAM) */
+#define CMC_IDPRAM_SIZE 0x4000 /* 16 KB */
+
+/* FOR CMC221 SFR for IDPRAM */
+#define CMC_INT2CP_REG 0x10 /* Interrupt to CP */
+#define CMC_INT2AP_REG 0x50
+#define CMC_CLR_INT_REG 0x28 /* Clear Interrupt to AP */
+#define CMC_RESET_REG 0x3C
+#define CMC_PUT_REG 0x40 /* AP->CP reg for hostbooting */
+#define CMC_GET_REG 0x50 /* CP->AP reg for hostbooting */
+
+/* For CBP7.2 EDPRAM (External DPRAM) */
+#define CBP_EDPRAM_SIZE 0x4000 /* 16 KB */
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+#ifdef CONFIG_USBHUB_USB3503
+static int host_port_enable(int port, int enable);
+#else
+static int host_port_enable(int port, int enable)
+{
+ return s5p_ehci_port_control(&s5p_device_ehci, port, enable);
+}
+#endif
+
+#ifdef CONFIG_LTE_MODEM_CMC221
+static struct sromc_cfg cmc_idpram_cfg = {
+ .attr = SROMC_DATA_16,
+ .size = CMC_IDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cmc_idpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ /* for 33 MHz clock, 64 cycles */
+ .tacs = 0x08 << 28,
+ .tcos = 0x08 << 24,
+ .tacc = 0x1F << 16,
+ .tcoh = 0x08 << 12,
+ .tcah = 0x08 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+ [DPRAM_SPEED_MID] = {
+ /* for 66 MHz clock, 32 cycles */
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x1B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+ [DPRAM_SPEED_HIGH] = {
+ /* for 133 MHz clock, 16 cycles */
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x0B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 4564 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 9124 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define DP_FMT_TX_BUFF_SZ 1336
+#define DP_RAW_TX_BUFF_SZ 4564
+#define DP_FMT_RX_BUFF_SZ 1336
+#define DP_RAW_RX_BUFF_SZ 9124
+
+#define MAX_CMC_IDPRAM_IPC_DEV (IPC_RAW + 1) /* FMT, RAW */
+
+struct dpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[DP_RAW_RX_BUFF_SZ];
+
+ u16 mbx_cp2ap;
+ u16 mbx_ap2cp;
+};
+
+struct cmc221_idpram_sfr {
+ u16 __iomem *int2cp;
+ u16 __iomem *int2ap;
+ u16 __iomem *clr_int2ap;
+ u16 __iomem *reset;
+ u16 __iomem *msg2cp;
+ u16 __iomem *msg2ap;
+};
+
+static struct dpram_ipc_map cmc_ipc_map;
+static u8 *cmc_sfr_base;
+static struct cmc221_idpram_sfr cmc_sfr;
+
+/* Function prototypes */
+static void cmc_idpram_reset(void);
+static void cmc_idpram_setup_speed(enum dpram_speed);
+static int cmc_idpram_wakeup(void);
+static void cmc_idpram_sleep(void);
+static void cmc_idpram_clr_intr(void);
+static u16 cmc_idpram_recv_intr(void);
+static void cmc_idpram_send_intr(u16 irq_mask);
+static u16 cmc_idpram_recv_msg(void);
+static void cmc_idpram_send_msg(u16 msg);
+
+static u16 cmc_idpram_get_magic(void);
+static void cmc_idpram_set_magic(u16 value);
+static u16 cmc_idpram_get_access(void);
+static void cmc_idpram_set_access(u16 value);
+
+static u32 cmc_idpram_get_tx_head(int dev_id);
+static u32 cmc_idpram_get_tx_tail(int dev_id);
+static void cmc_idpram_set_tx_head(int dev_id, u32 head);
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id);
+static u32 cmc_idpram_get_tx_buff_size(int dev_id);
+
+static u32 cmc_idpram_get_rx_head(int dev_id);
+static u32 cmc_idpram_get_rx_tail(int dev_id);
+static void cmc_idpram_set_rx_head(int dev_id, u32 head);
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id);
+static u32 cmc_idpram_get_rx_buff_size(int dev_id);
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id);
+static u16 cmc_idpram_get_mask_res_ack(int dev_id);
+static u16 cmc_idpram_get_mask_send(int dev_id);
+
+static struct modemlink_dpram_control cmc_idpram_ctrl = {
+ .reset = cmc_idpram_reset,
+
+ .setup_speed = cmc_idpram_setup_speed,
+
+ .wakeup = cmc_idpram_wakeup,
+ .sleep = cmc_idpram_sleep,
+
+ .clear_intr = cmc_idpram_clr_intr,
+ .recv_intr = cmc_idpram_recv_intr,
+ .send_intr = cmc_idpram_send_intr,
+ .recv_msg = cmc_idpram_recv_msg,
+ .send_msg = cmc_idpram_send_msg,
+
+ .get_magic = cmc_idpram_get_magic,
+ .set_magic = cmc_idpram_set_magic,
+ .get_access = cmc_idpram_get_access,
+ .set_access = cmc_idpram_set_access,
+
+ .get_tx_head = cmc_idpram_get_tx_head,
+ .get_tx_tail = cmc_idpram_get_tx_tail,
+ .set_tx_head = cmc_idpram_set_tx_head,
+ .set_tx_tail = cmc_idpram_set_tx_tail,
+ .get_tx_buff = cmc_idpram_get_tx_buff,
+ .get_tx_buff_size = cmc_idpram_get_tx_buff_size,
+
+ .get_rx_head = cmc_idpram_get_rx_head,
+ .get_rx_tail = cmc_idpram_get_rx_tail,
+ .set_rx_head = cmc_idpram_set_rx_head,
+ .set_rx_tail = cmc_idpram_set_rx_tail,
+ .get_rx_buff = cmc_idpram_get_rx_buff,
+ .get_rx_buff_size = cmc_idpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cmc_idpram_get_mask_req_ack,
+ .get_mask_res_ack = cmc_idpram_get_mask_res_ack,
+ .get_mask_send = cmc_idpram_get_mask_send,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = CP_IDPRAM,
+ .aligned = 1,
+
+ .dpram_irq = CMC_IDPRAM_INT_IRQ_00,
+ .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING),
+ .dpram_irq_name = "CMC221_IDPRAM_IRQ",
+ .dpram_wlock_name = "CMC221_IDPRAM_WLOCK",
+
+ .max_ipc_dev = MAX_CMC_IDPRAM_IPC_DEV,
+};
+
+/*
+** UMTS target platform data
+*/
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_boot0",
+ .id = 0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "umts_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "umts_rfs0",
+ .id = 245,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "lte_multipdp",
+ .id = 0,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [4] = {
+ .name = "lte_rmnet0",
+ .id = 10,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [5] = {
+ .name = "lte_rmnet1",
+ .id = 11,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [6] = {
+ .name = "lte_rmnet2",
+ .id = 12,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [7] = {
+ .name = "lte_rmnet3",
+ .id = 13,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [8] = {
+ .name = "umts_csd", /* CS Video Telephony */
+ .id = 1,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "umts_router", /* AT Iface & Dial-up */
+ .id = 25,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "umts_dm0", /* DM Port */
+ .id = 28,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "umts_loopback_ap2cp",
+ .id = 30,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "umts_loopback_cp2ap",
+ .id = 31,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "umts_ramdump0",
+ .id = 0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "lte_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_USB),
+ },
+};
+
+static int exynos_cpu_frequency_lock(void);
+static int exynos_cpu_frequency_unlock(void);
+
+static struct modemlink_pm_data umts_link_pm_data = {
+ .name = "umts_link_pm",
+
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+
+ .port_enable = host_port_enable,
+/*
+ .link_reconnect = umts_link_reconnect,
+*/
+ .freqlock = ATOMIC_INIT(0),
+ .cpufreq_lock = exynos_cpu_frequency_lock,
+ .cpufreq_unlock = exynos_cpu_frequency_unlock,
+
+ .autosuspend_delay_ms = 2000,
+
+ .has_usbhub = true,
+};
+
+static struct modem_data umts_modem_data = {
+ .name = "cmc221",
+
+ .gpio_cp_on = CP_CMC221_PMIC_PWRON,
+ .gpio_cp_reset = CP_CMC221_CPU_RST,
+ .gpio_phone_active = GPIO_LTE_ACTIVE,
+
+ .gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00,
+ .gpio_dpram_status = GPIO_CMC_IDPRAM_STATUS,
+ .gpio_dpram_wakeup = GPIO_CMC_IDPRAM_WAKEUP,
+
+ .gpio_slave_wakeup = GPIO_IPC_SLAVE_WAKEUP,
+ .gpio_host_active = GPIO_ACTIVE_STATE,
+ .gpio_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+
+ .modem_net = UMTS_NETWORK,
+ .modem_type = SEC_CMC221,
+ .link_types = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB),
+ .link_name = "cmc221_idpram",
+ .dpram_ctl = &cmc_idpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &umts_link_pm_data,
+
+ .use_handover = true,
+
+ .ipc_version = SIPC_VER_50,
+ .use_mif_log = true,
+};
+
+static struct resource umts_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = LTE_ACTIVE_IRQ,
+ .end = LTE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device umts_modem = {
+ .name = "mif_sipc5",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+#define HUB_STATE_OFF 0
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val && states == STATE_HSIC_LPA_ENTER) {
+ mif_info("usb3503: hub off - lpa\n");
+ host_port_enable(2, 0);
+ *(umts_link_pm_data.p_hub_status) = HUB_STATE_OFF;
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static void cmc_idpram_reset(void)
+{
+ iowrite16(1, cmc_sfr.reset);
+}
+
+static void cmc_idpram_setup_speed(enum dpram_speed speed)
+{
+ setup_dpram_speed(cmc_idpram_cfg.csn, &cmc_idpram_access_cfg[speed]);
+}
+
+static int cmc_idpram_wakeup(void)
+{
+ int cnt = 0;
+
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 1);
+
+ while (!gpio_get_value(umts_modem_data.gpio_dpram_status)) {
+ if (cnt++ > 10) {
+ mif_err("ERR: gpio_dpram_status == 0\n");
+ return -EAGAIN;
+ }
+
+ if (in_interrupt())
+ mdelay(1);
+ else
+ msleep_interruptible(1);
+ }
+
+ return 0;
+}
+
+static void cmc_idpram_sleep(void)
+{
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 0);
+}
+
+static void cmc_idpram_clr_intr(void)
+{
+ iowrite16(0xFFFF, cmc_sfr.clr_int2ap);
+ iowrite16(0, cmc_sfr.int2ap);
+}
+
+static u16 cmc_idpram_recv_intr(void)
+{
+ return ioread16(cmc_sfr.int2ap);
+}
+
+static void cmc_idpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cmc_sfr.int2cp);
+}
+
+static u16 cmc_idpram_recv_msg(void)
+{
+ return ioread16(cmc_sfr.msg2ap);
+}
+
+static void cmc_idpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cmc_sfr.msg2cp);
+}
+
+static u16 cmc_idpram_get_magic(void)
+{
+ return ioread16(cmc_ipc_map.magic);
+}
+
+static void cmc_idpram_set_magic(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.magic);
+}
+
+static u16 cmc_idpram_get_access(void)
+{
+ return ioread16(cmc_ipc_map.access);
+}
+
+static void cmc_idpram_set_access(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.access);
+}
+
+static u32 cmc_idpram_get_tx_head(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cmc_idpram_get_tx_tail(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cmc_idpram_set_tx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].txq.head);
+ if (val == head)
+ break;
+
+ mif_err("ERR: txq.head(%d) != head(%d)\n", val, head);
+
+ /* Write head value again */
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].txq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].txq.tail);
+ if (val == tail)
+ break;
+
+ mif_err("ERR: txq.tail(%d) != tail(%d)\n", val, tail);
+
+ /* Write tail value again */
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].txq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cmc_idpram_get_tx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cmc_idpram_get_rx_head(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cmc_idpram_get_rx_tail(int dev_id)
+{
+ return ioread16(cmc_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cmc_idpram_set_rx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].rxq.head);
+ if (val == head)
+ break;
+
+ mif_err("ERR: rxq.head(%d) != head(%d)\n", val, head);
+
+ /* Write head value again */
+ iowrite16((u16)head, cmc_ipc_map.dev[dev_id].rxq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread16(cmc_ipc_map.dev[dev_id].rxq.tail);
+ if (val == tail)
+ break;
+
+ mif_err("ERR: rxq.tail(%d) != tail(%d)\n", val, tail);
+
+ /* Write tail value again */
+ iowrite16((u16)tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cmc_idpram_get_rx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cmc_idpram_get_mask_res_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cmc_idpram_get_mask_send(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_send;
+}
+
+/* Set dynamic environment for a modem */
+static void setup_umts_modem_env(void)
+{
+ /*
+ ** Config DPRAM control structure
+ */
+ if (system_rev == 1 || system_rev >= 4)
+ cmc_idpram_cfg.csn = 0;
+ else
+ cmc_idpram_cfg.csn = 1;
+
+ cmc_idpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cmc_idpram_cfg.csn);
+ cmc_idpram_cfg.end = cmc_idpram_cfg.addr + cmc_idpram_cfg.size - 1;
+
+ if (system_rev == 1 || system_rev >= 4) {
+ umts_modem_data.gpio_dpram_int = GPIO_CMC_IDPRAM_INT_01;
+ cmc_idpram_ctrl.dpram_irq = CMC_IDPRAM_INT_IRQ_01;
+ }
+}
+
+static void config_umts_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_active_state = umts_modem_data.gpio_host_active;
+ unsigned gpio_host_wakeup = umts_modem_data.gpio_host_wakeup;
+ unsigned gpio_slave_wakeup = umts_modem_data.gpio_slave_wakeup;
+ unsigned gpio_dpram_int = umts_modem_data.gpio_dpram_int;
+ unsigned gpio_dpram_status = umts_modem_data.gpio_dpram_status;
+ unsigned gpio_dpram_wakeup = umts_modem_data.gpio_dpram_wakeup;
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CMC_ON");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 0);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CMC_RST");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "CMC_ACTIVE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "CMC_ACTIVE");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_active_state) {
+ err = gpio_request(gpio_active_state, "CMC_ACTIVE_STATE");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_ACTIVE_STATE");
+ } else {
+ gpio_direction_output(gpio_active_state, 0);
+ s3c_gpio_setpull(gpio_active_state, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_slave_wakeup) {
+ err = gpio_request(gpio_slave_wakeup, "CMC_SLAVE_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_SLAVE_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_slave_wakeup, 0);
+ s3c_gpio_setpull(gpio_slave_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_host_wakeup) {
+ err = gpio_request(gpio_host_wakeup, "CMC_HOST_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_HOST_WAKEUP");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_host_wakeup);
+ s3c_gpio_setpull(gpio_host_wakeup, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(gpio_host_wakeup, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "CMC_DPRAM_INT");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_dpram_int);
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_status) {
+ err = gpio_request(gpio_dpram_status, "CMC_DPRAM_STATUS");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_STATUS");
+ } else {
+ gpio_direction_input(gpio_dpram_status);
+ s3c_gpio_setpull(gpio_dpram_status, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_dpram_wakeup) {
+ err = gpio_request(gpio_dpram_wakeup, "CMC_DPRAM_WAKEUP");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n",
+ "CMC_DPRAM_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_dpram_wakeup, 1);
+ s3c_gpio_setpull(gpio_dpram_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+}
+
+static u8 *cmc_idpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = cfg->addr;
+ int dp_size = cfg->size;
+ u8 __iomem *dp_base;
+ struct dpram_ipc_cfg *ipc_map;
+ struct dpram_ipc_device *dev;
+
+ /* Remap DPRAM memory region */
+ dp_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ mif_err("ERR: ioremap_nocache for dp_base fail\n");
+ return NULL;
+ }
+ mif_err("DPRAM VA=0x%08X\n", (int)dp_base);
+
+ /* Remap DPRAM SFR region */
+ dp_addr += dp_size;
+ cmc_sfr_base = (u8 __iomem *)ioremap_nocache(dp_addr, dp_size);
+ if (cmc_sfr_base == NULL) {
+ iounmap(dp_base);
+ mif_err("ERR: ioremap_nocache for cmc_sfr_base fail\n");
+ return NULL;
+ }
+
+ cmc_sfr.int2cp = (u16 __iomem *)(cmc_sfr_base + CMC_INT2CP_REG);
+ cmc_sfr.int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_INT2AP_REG);
+ cmc_sfr.clr_int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_CLR_INT_REG);
+ cmc_sfr.reset = (u16 __iomem *)(cmc_sfr_base + CMC_RESET_REG);
+ cmc_sfr.msg2cp = (u16 __iomem *)(cmc_sfr_base + CMC_PUT_REG);
+ cmc_sfr.msg2ap = (u16 __iomem *)(cmc_sfr_base + CMC_GET_REG);
+
+ cmc_idpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cmc_idpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct dpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cmc_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cmc_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cmc_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cmc_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+ return dp_base;
+}
+#endif
+
+#ifdef CONFIG_CDMA_MODEM_CBP72
+static struct sromc_cfg cbp_edpram_cfg = {
+ .attr = SROMC_DATA_16 | SROMC_BYTE_EN,
+ .size = CBP_EDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cbp_edpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ .tacs = 0x00 << 28,
+ .tcos = 0x00 << 24,
+ .tacc = 0x0F << 16,
+ .tcoh = 0x00 << 12,
+ .tcah = 0x00 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 4564 +
+ 2 + 2 + 1336 +
+ 2 + 2 + 9124 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define CBP_DP_FMT_TX_BUFF_SZ 1336
+#define CBP_DP_RAW_TX_BUFF_SZ 4564
+#define CBP_DP_FMT_RX_BUFF_SZ 1336
+#define CBP_DP_RAW_RX_BUFF_SZ 9124
+
+#define MAX_CBP_EDPRAM_IPC_DEV (IPC_RAW + 1) /* FMT, RAW */
+
+struct cbp_edpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[CBP_DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[CBP_DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[CBP_DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[CBP_DP_RAW_RX_BUFF_SZ];
+
+ u16 mbx_cp2ap;
+ u16 mbx_ap2cp;
+};
+
+static struct dpram_ipc_map cbp_ipc_map;
+
+static void cbp_edpram_reset(void);
+static void cbp_edpram_clr_intr(void);
+static u16 cbp_edpram_recv_intr(void);
+static void cbp_edpram_send_intr(u16 irq_mask);
+static u16 cbp_edpram_recv_msg(void);
+static void cbp_edpram_send_msg(u16 msg);
+
+static u16 cbp_edpram_get_magic(void);
+static void cbp_edpram_set_magic(u16 value);
+static u16 cbp_edpram_get_access(void);
+static void cbp_edpram_set_access(u16 value);
+
+static u32 cbp_edpram_get_tx_head(int dev_id);
+static u32 cbp_edpram_get_tx_tail(int dev_id);
+static void cbp_edpram_set_tx_head(int dev_id, u32 head);
+static void cbp_edpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cbp_edpram_get_tx_buff(int dev_id);
+static u32 cbp_edpram_get_tx_buff_size(int dev_id);
+
+static u32 cbp_edpram_get_rx_head(int dev_id);
+static u32 cbp_edpram_get_rx_tail(int dev_id);
+static void cbp_edpram_set_rx_head(int dev_id, u32 head);
+static void cbp_edpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cbp_edpram_get_rx_buff(int dev_id);
+static u32 cbp_edpram_get_rx_buff_size(int dev_id);
+
+static u16 cbp_edpram_get_mask_req_ack(int dev_id);
+static u16 cbp_edpram_get_mask_res_ack(int dev_id);
+static u16 cbp_edpram_get_mask_send(int dev_id);
+
+static struct modemlink_dpram_control cbp_edpram_ctrl = {
+ .reset = cbp_edpram_reset,
+
+ .clear_intr = cbp_edpram_clr_intr,
+ .recv_intr = cbp_edpram_recv_intr,
+ .send_intr = cbp_edpram_send_intr,
+ .recv_msg = cbp_edpram_recv_msg,
+ .send_msg = cbp_edpram_send_msg,
+
+ .get_magic = cbp_edpram_get_magic,
+ .set_magic = cbp_edpram_set_magic,
+ .get_access = cbp_edpram_get_access,
+ .set_access = cbp_edpram_set_access,
+
+ .get_tx_head = cbp_edpram_get_tx_head,
+ .get_tx_tail = cbp_edpram_get_tx_tail,
+ .set_tx_head = cbp_edpram_set_tx_head,
+ .set_tx_tail = cbp_edpram_set_tx_tail,
+ .get_tx_buff = cbp_edpram_get_tx_buff,
+ .get_tx_buff_size = cbp_edpram_get_tx_buff_size,
+
+ .get_rx_head = cbp_edpram_get_rx_head,
+ .get_rx_tail = cbp_edpram_get_rx_tail,
+ .set_rx_head = cbp_edpram_set_rx_head,
+ .set_rx_tail = cbp_edpram_set_rx_tail,
+ .get_rx_buff = cbp_edpram_get_rx_buff,
+ .get_rx_buff_size = cbp_edpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cbp_edpram_get_mask_req_ack,
+ .get_mask_res_ack = cbp_edpram_get_mask_res_ack,
+ .get_mask_send = cbp_edpram_get_mask_send,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = EXT_DPRAM,
+ .aligned = 1,
+
+ .dpram_irq = CBP_DPRAM_INT_IRQ_00,
+ .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_FALLING),
+ .dpram_irq_name = "CBP72_EDPRAM_IRQ",
+ .dpram_wlock_name = "CBP72_EDPRAM_WLOCK",
+
+ .max_ipc_dev = MAX_CBP_EDPRAM_IPC_DEV,
+};
+
+/*
+** CDMA target platform data
+*/
+static struct modem_io_t cdma_io_devices[] = {
+ [0] = {
+ .name = "cdma_boot0",
+ .id = 0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "cdma_ipc0",
+ .id = 235,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "cdma_rfs0",
+ .id = 245,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "cdma_multipdp",
+ .id = 0,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [4] = {
+ .name = "cdma_rmnet0",
+ .id = 10,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [5] = {
+ .name = "cdma_rmnet1",
+ .id = 11,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [6] = {
+ .name = "cdma_rmnet2",
+ .id = 12,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [7] = {
+ .name = "cdma_rmnet3",
+ .id = 13,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [8] = {
+ .name = "cdma_rmnet4",
+ .id = 7,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "cdma_rmnet5", /* DM Port IO device */
+ .id = 26,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "cdma_rmnet6", /* AT CMD IO device */
+ .id = 17,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "cdma_ramdump0",
+ .id = 0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+};
+
+static struct modem_data cdma_modem_data = {
+ .name = "cbp7.2",
+
+ .gpio_cp_on = GPIO_CBP_PMIC_PWRON,
+ .gpio_cp_off = GPIO_CBP_PS_HOLD_OFF,
+ .gpio_cp_reset = GPIO_CBP_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_CBP_PHONE_ACTIVE,
+
+ .gpio_dpram_int = GPIO_CBP_DPRAM_INT_00,
+
+ .modem_net = CDMA_NETWORK,
+ .modem_type = VIA_CBP72,
+ .link_types = LINKTYPE(LINKDEV_DPRAM),
+ .link_name = "cbp72_edpram",
+ .dpram_ctl = &cbp_edpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(cdma_io_devices),
+ .iodevs = cdma_io_devices,
+
+ .use_handover = true,
+
+ .ipc_version = SIPC_VER_50,
+};
+
+static struct resource cdma_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = CBP_PHONE_ACTIVE_IRQ,
+ .end = CBP_PHONE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cdma_modem = {
+ .name = "mif_sipc5",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cdma_modem_res),
+ .resource = cdma_modem_res,
+ .dev = {
+ .platform_data = &cdma_modem_data,
+ },
+};
+
+static void cbp_edpram_reset(void)
+{
+ return;
+}
+
+static void cbp_edpram_clr_intr(void)
+{
+ ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static u16 cbp_edpram_recv_intr(void)
+{
+ return ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static void cbp_edpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cbp_ipc_map.mbx_ap2cp);
+}
+
+static u16 cbp_edpram_recv_msg(void)
+{
+ return ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static void cbp_edpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cbp_ipc_map.mbx_ap2cp);
+}
+
+static u16 cbp_edpram_get_magic(void)
+{
+ return ioread16(cbp_ipc_map.magic);
+}
+
+static void cbp_edpram_set_magic(u16 value)
+{
+ iowrite16(value, cbp_ipc_map.magic);
+}
+
+static u16 cbp_edpram_get_access(void)
+{
+ return ioread16(cbp_ipc_map.access);
+}
+
+static void cbp_edpram_set_access(u16 value)
+{
+ iowrite16(value, cbp_ipc_map.access);
+}
+
+static u32 cbp_edpram_get_tx_head(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cbp_edpram_get_tx_tail(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cbp_edpram_set_tx_head(int dev_id, u32 head)
+{
+ iowrite16((u16)head, cbp_ipc_map.dev[dev_id].txq.head);
+}
+
+static void cbp_edpram_set_tx_tail(int dev_id, u32 tail)
+{
+ iowrite16((u16)tail, cbp_ipc_map.dev[dev_id].txq.tail);
+}
+
+static u8 __iomem *cbp_edpram_get_tx_buff(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cbp_edpram_get_tx_buff_size(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cbp_edpram_get_rx_head(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cbp_edpram_get_rx_tail(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cbp_edpram_set_rx_head(int dev_id, u32 head)
+{
+ return iowrite16((u16)head, cbp_ipc_map.dev[dev_id].rxq.head);
+}
+
+static void cbp_edpram_set_rx_tail(int dev_id, u32 tail)
+{
+ return iowrite16((u16)tail, cbp_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static u8 __iomem *cbp_edpram_get_rx_buff(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cbp_edpram_get_rx_buff_size(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cbp_edpram_get_mask_req_ack(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cbp_edpram_get_mask_res_ack(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cbp_edpram_get_mask_send(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_send;
+}
+
+/* Set dynamic environment for a modem */
+static void setup_cdma_modem_env(void)
+{
+ /*
+ ** Config DPRAM control structure
+ */
+ if (system_rev == 1 || system_rev >= 4)
+ cbp_edpram_cfg.csn = 1;
+ else
+ cbp_edpram_cfg.csn = 0;
+
+ cbp_edpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cbp_edpram_cfg.csn);
+ cbp_edpram_cfg.end = cbp_edpram_cfg.addr + cbp_edpram_cfg.size - 1;
+
+ if (system_rev == 1 || system_rev >= 4) {
+ cdma_modem_data.gpio_dpram_int = GPIO_CBP_DPRAM_INT_01;
+ cbp_edpram_ctrl.dpram_irq = CBP_DPRAM_INT_IRQ_01;
+ }
+}
+
+static void config_cdma_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_boot_sel = GPIO_CBP_BOOT_SEL;
+ unsigned gpio_cp_on = cdma_modem_data.gpio_cp_on;
+ unsigned gpio_cp_off = cdma_modem_data.gpio_cp_off;
+ unsigned gpio_cp_rst = cdma_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = cdma_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = cdma_modem_data.gpio_phone_active;
+ unsigned gpio_dpram_int = cdma_modem_data.gpio_dpram_int;
+
+ pr_info("[MDM] <%s>\n", __func__);
+
+ if (gpio_boot_sel) {
+ err = gpio_request(gpio_boot_sel, "CBP_BOOT_SEL");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_BOOT_SEL");
+ } else {
+ gpio_direction_output(gpio_boot_sel, 0);
+ s3c_gpio_setpull(gpio_boot_sel, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CBP_ON");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 0);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_off) {
+ err = gpio_request(gpio_cp_off, "CBP_OFF");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_OFF");
+ } else {
+ gpio_direction_output(gpio_cp_off, 1);
+ s3c_gpio_setpull(gpio_cp_off, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CBP_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "CBP_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_ACTIVE");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "CBP_DPRAM_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CBP_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ gpio_direction_input(gpio_dpram_int);
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ }
+ }
+
+ /* set low unused gpios between AP and CP */
+ err = gpio_request(GPIO_FLM_RXD, "FLM_RXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_RXD",
+ err);
+ else {
+ gpio_direction_input(GPIO_FLM_RXD);
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_FLM_RXD, S3C_GPIO_SFN(2));
+ }
+
+ err = gpio_request(GPIO_FLM_TXD, "FLM_TXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_TXD",
+ err);
+ else {
+ gpio_direction_input(GPIO_FLM_TXD);
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_FLM_TXD, S3C_GPIO_SFN(2));
+ }
+}
+
+static u8 *cbp_edpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = 0;
+ int dp_size = 0;
+ u8 __iomem *dp_base = NULL;
+ struct cbp_edpram_ipc_cfg *ipc_map = NULL;
+ struct dpram_ipc_device *dev = NULL;
+
+ dp_addr = cfg->addr;
+ dp_size = cfg->size;
+ dp_base = (u8 *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ pr_err("[MDM] <%s> dpram base ioremap fail\n", __func__);
+ return NULL;
+ }
+ pr_info("[MDM] <%s> DPRAM VA=0x%08X\n", __func__, (int)dp_base);
+
+ cbp_edpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cbp_edpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct cbp_edpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cbp_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cbp_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cbp_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = CBP_DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = CBP_DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cbp_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = CBP_DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = CBP_DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+ /* Mailboxes */
+ cbp_ipc_map.mbx_ap2cp = (u16 __iomem *)&ipc_map->mbx_ap2cp;
+ cbp_ipc_map.mbx_cp2ap = (u16 __iomem *)&ipc_map->mbx_cp2ap;
+
+ return dp_base;
+}
+#endif
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ mif_info("address line = %d bits\n", addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for address bus (13 ~ 14 bits) */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_LOW,
+ EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_HIGH,
+ (addr_bits - EXYNOS4_GPIO_Y3_NR), S3C_GPIO_SFN(2));
+ break;
+
+ default:
+ mif_err("ERR: invalid addr_bits!!!\n");
+ return;
+ }
+
+ /* Set GPIO for data bus (16 bits) */
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_LOW, 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_HIGH, 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin((GPIO_DPRAM_CSN0 + 1), S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgpin(GPIO_DPRAM_REN, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(GPIO_DPRAM_WEN, S3C_GPIO_SFN(2));
+
+ /* Config LBn, UBn */
+ s3c_gpio_cfgpin(GPIO_DPRAM_LBN, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(GPIO_DPRAM_UBN, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ mif_err("ERR: SROMC clock gate fail\n");
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(
+ unsigned csn,
+ struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg
+)
+{
+ unsigned bw = 0; /* Bus width and wait control */
+ unsigned bc = 0; /* Vank control */
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ mif_err("SROMC settings for CS%d...\n", csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ mif_err("Old SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn << 2));
+ bw |= (cfg->attr << (csn << 2));
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ mif_err("New SROMC settings = BW(0x%08X) BC%d(0x%08X)\n", bw, csn, bc);
+}
+
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg)
+{
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+ unsigned bc = 0;
+
+ bc = __raw_readl(bank_sfr);
+ mif_info("Old CS%d setting = 0x%08X\n", csn, bc);
+
+ /* SROMC memory access timing setting */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+ writel(bc, bank_sfr);
+
+ bc = __raw_readl(bank_sfr);
+ mif_info("New CS%d setting = 0x%08X\n", csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ mif_err("System Revision = %d\n", system_rev);
+
+ setup_umts_modem_env();
+ setup_cdma_modem_env();
+
+ config_dpram_port_gpio();
+
+ config_umts_modem_gpio();
+ config_cdma_modem_gpio();
+
+ init_sromc();
+
+ cfg = &cmc_idpram_cfg;
+ acc_cfg = &cmc_idpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ cfg = &cbp_edpram_cfg;
+ acc_cfg = &cbp_edpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!cmc_idpram_remap_mem_region(&cmc_idpram_cfg))
+ return -1;
+ platform_device_register(&umts_modem);
+
+ if (!cbp_edpram_remap_mem_region(&cbp_edpram_cfg))
+ return -1;
+ platform_device_register(&cdma_modem);
+
+ return 0;
+}
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
+
+#ifdef CONFIG_USBHUB_USB3503
+static int (*usbhub_set_mode)(struct usb3503_hubctl *, int);
+static struct usb3503_hubctl *usbhub_ctl;
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+static int exynos_cpu_frequency_lock(void)
+{
+ unsigned int level, freq = 700;
+
+ if (atomic_read(&umts_link_pm_data.freqlock) == 0) {
+ if (exynos_cpufreq_get_level(freq * 1000, &level)) {
+ mif_err("ERR: exynos_cpufreq_get_level fail\n");
+ return -EINVAL;
+ }
+
+ if (exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level)) {
+ mif_err("ERR: exynos_cpufreq_lock fail\n");
+ return -EINVAL;
+ }
+
+ atomic_set(&umts_link_pm_data.freqlock, 1);
+ mif_debug("<%d> %d MHz\n", level, freq);
+ }
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ if (atomic_read(&umts_link_pm_data.freqlock) == 1) {
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF);
+ atomic_set(&umts_link_pm_data.freqlock, 0);
+ mif_debug("\n");
+ }
+ return 0;
+}
+#else
+static int exynos_cpu_frequency_lock(void)
+{
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ return 0;
+}
+#endif
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+}
+
+static int usb3503_hub_handler(void (*set_mode)(void), void *ctl)
+{
+ if (!set_mode || !ctl)
+ return -EINVAL;
+
+ usbhub_set_mode = (int (*)(struct usb3503_hubctl *, int))set_mode;
+ usbhub_ctl = (struct usb3503_hubctl *)ctl;
+
+ mif_info("set_mode(%pF)\n", set_mode);
+
+ return 0;
+}
+
+static int usb3503_hw_config(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_USB_HUB_RST, "HUB_RST");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "HUB_RST");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_RST, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_RST, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_RST, S5P_GPIO_DRVSTR_LV1);
+ /* need to check drvstr 1 or 2 */
+
+ /* for USB3503 26Mhz Reference clock setting */
+ err = gpio_request(GPIO_USB_HUB_INT, "HUB_INT");
+ if (err) {
+ mif_err("ERR: fail to request gpio %s\n", "HUB_INT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_INT, 1);
+ s3c_gpio_setpull(GPIO_USB_HUB_INT, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static int usb3503_reset_n(int val)
+{
+ gpio_set_value(GPIO_USB_HUB_RST, 0);
+
+ /* hub off from cpuidle(LPA), skip the msleep schedule*/
+ if (val) {
+ msleep(20);
+ mif_info("val = %d\n", gpio_get_value(GPIO_USB_HUB_RST));
+
+ gpio_set_value(GPIO_USB_HUB_RST, !!val);
+
+ mif_info("val = %d\n", gpio_get_value(GPIO_USB_HUB_RST));
+ udelay(5); /* need it ?*/
+ }
+ return 0;
+}
+
+static struct usb3503_platform_data usb3503_pdata = {
+ .initial_mode = USB3503_MODE_STANDBY,
+ .reset_n = usb3503_reset_n,
+ .register_hub_handler = usb3503_hub_handler,
+ .port_enable = host_port_enable,
+};
+
+static struct i2c_board_info i2c_devs20_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO(USB3503_I2C_NAME, 0x08),
+ .platform_data = &usb3503_pdata,
+ },
+};
+
+/* I2C20_EMUL */
+static struct i2c_gpio_platform_data i2c20_platdata = {
+ .sda_pin = GPIO_USB_HUB_SDA,
+ .scl_pin = GPIO_USB_HUB_SCL,
+ /*FIXME: need to timming tunning... */
+ .udelay = 20,
+};
+
+static struct platform_device s3c_device_i2c20 = {
+ .name = "i2c-gpio",
+ .id = 20,
+ .dev.platform_data = &i2c20_platdata,
+};
+
+static int __init init_usbhub(void)
+{
+ usb3503_hw_config();
+ i2c_register_board_info(20, i2c_devs20_emul,
+ ARRAY_SIZE(i2c_devs20_emul));
+
+ platform_device_register(&s3c_device_i2c20);
+ return 0;
+}
+
+device_initcall(init_usbhub);
+
+static int host_port_enable(int port, int enable)
+{
+ int err;
+
+ mif_info("port(%d) control(%d)\n", port, enable);
+
+ if (enable) {
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB);
+ if (err < 0) {
+ mif_err("ERR: hub on fail\n");
+ goto exit;
+ }
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 1);
+ if (err < 0) {
+ mif_err("ERR: port(%d) enable fail\n", port);
+ goto exit;
+ }
+ } else {
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 0);
+ if (err < 0) {
+ mif_err("ERR: port(%d) enable fail\n", port);
+ goto exit;
+ }
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY);
+ if (err < 0) {
+ mif_err("ERR: hub off fail\n");
+ goto exit;
+ }
+ }
+
+ err = gpio_direction_output(umts_modem_data.gpio_host_active, enable);
+ mif_info("active state err(%d), en(%d), level(%d)\n",
+ err, enable, gpio_get_value(umts_modem_data.gpio_host_active));
+
+exit:
+ return err;
+}
+#else
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ mif_err("<%s> Active States =%d, %s\n", pdev->name, type);
+ gpio_direction_output(umts_link_pm_data.gpio_link_active, type);
+ } else {
+ active_ctl.gpio_request_host_active = 1;
+ }
+}
+#endif
+
diff --git a/arch/arm/mach-exynos/board-gaia-modems.c b/arch/arm/mach-exynos/board-gaia-modems.c
new file mode 100644
index 0000000..e453d6e
--- /dev/null
+++ b/arch/arm/mach-exynos/board-gaia-modems.c
@@ -0,0 +1,1369 @@
+/* linux/arch/arm/mach-xxxx/board-c1via-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos5.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#ifdef CONFIG_USBHUB_USB3503
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/usb3503.h>
+#include <mach/cpufreq.h>
+#include <plat/usb-phy.h>
+#endif
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/* For "bus width and wait control (BW)" register */
+enum sromc_attr {
+ SROMC_DATA_16 = 0x1, /* 16-bit data bus */
+ SROMC_BYTE_ADDR = 0x2, /* Byte base address */
+ SROMC_WAIT_EN = 0x4, /* Wait enabled */
+ SROMC_BYTE_EN = 0x8, /* Byte access enabled */
+ SROMC_MASK = 0xF
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For CMC221 IDPRAM (Internal DPRAM) */
+#define CMC_IDPRAM_SIZE 0x4000 /* 16 KB */
+
+/* FOR CMC221 SFR for IDPRAM */
+#define CMC_INT2CP_REG 0x10 /* Interrupt to CP */
+#define CMC_INT2AP_REG 0x50
+#define CMC_CLR_INT_REG 0x28 /* Clear Interrupt to AP */
+#define CMC_RESET_REG 0x3C
+#define CMC_PUT_REG 0x40 /* AP->CP reg for hostbooting */
+#define CMC_GET_REG 0x50 /* CP->AP reg for hostbooting */
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+
+#ifdef CONFIG_USBHUB_USB3503
+static int host_port_enable(int port, int enable);
+#else
+/*
+static int host_port_enable(int port, int enable)
+{
+ return s5p_ehci_port_control(&s5p_device_ehci, port, enable);
+}
+*/
+#endif
+
+static struct sromc_cfg cmc_idpram_cfg = {
+ .attr = SROMC_DATA_16,
+ .size = CMC_IDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cmc_idpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ .tacs = 0x0F << 28,
+ .tcos = 0x0F << 24,
+ .tacc = 0x1F << 16,
+ .tcoh = 0x0F << 12,
+ .tcah = 0x0F << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+/* [DPRAM_SPEED_LOW] = {
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x1B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },*/
+ [DPRAM_SPEED_HIGH] = {
+ .tacs = 0x01 << 28,
+ .tcos = 0x01 << 24,
+ .tacc = 0x0B << 16,
+ .tcoh = 0x01 << 12,
+ .tcah = 0x01 << 8,
+ .tacp = 0x00 << 4,
+ .pmc = 0x00 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ rfs_tx_head + rfs_tx_tail + rfs_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ rfs_rx_head + rfs_rx_tail + rfs_rx_buff +
+ = 2 +
+ 2 +
+ 4 + 4 + 2040 +
+ 4 + 4 + 4088 +
+ 4 + 4 + 1016 +
+ 4 + 4 + 2040 +
+ 4 + 4 + 5112 +
+ 4 + 4 + 2036 +
+ = 16384
+*/
+#define DP_FMT_TX_BUFF_SZ 2040
+#define DP_RAW_TX_BUFF_SZ 4088
+#define DP_RFS_TX_BUFF_SZ 1016
+#define DP_FMT_RX_BUFF_SZ 2040
+#define DP_RAW_RX_BUFF_SZ 5112
+#define DP_RFS_RX_BUFF_SZ 2036
+
+#define MAX_CMC_IDPRAM_IPC_DEV (IPC_RFS + 1) /* FMT, RAW, RFS */
+
+struct dpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u32 fmt_tx_head;
+ u32 fmt_tx_tail;
+ u8 fmt_tx_buff[DP_FMT_TX_BUFF_SZ];
+
+ u32 raw_tx_head;
+ u32 raw_tx_tail;
+ u8 raw_tx_buff[DP_RAW_TX_BUFF_SZ];
+
+ u32 rfs_tx_head;
+ u32 rfs_tx_tail;
+ u8 rfs_tx_buff[DP_RFS_TX_BUFF_SZ];
+
+ u32 fmt_rx_head;
+ u32 fmt_rx_tail;
+ u8 fmt_rx_buff[DP_FMT_RX_BUFF_SZ];
+
+ u32 raw_rx_head;
+ u32 raw_rx_tail;
+ u8 raw_rx_buff[DP_RAW_RX_BUFF_SZ];
+
+ u32 rfs_rx_head;
+ u32 rfs_rx_tail;
+ u8 rfs_rx_buff[DP_RFS_RX_BUFF_SZ];
+};
+
+struct cmc_dpram_circ {
+ u32 __iomem *head;
+ u32 __iomem *tail;
+ u8 __iomem *buff;
+ u32 size;
+};
+
+struct cmc_dpram_ipc_device {
+ char name[16];
+ int id;
+
+ struct cmc_dpram_circ txq;
+ struct cmc_dpram_circ rxq;
+
+ u16 mask_req_ack;
+ u16 mask_res_ack;
+ u16 mask_send;
+};
+
+struct cmc_dpram_ipc_map {
+ u16 __iomem *magic;
+ u16 __iomem *access;
+
+ struct cmc_dpram_ipc_device dev[MAX_CMC_IDPRAM_IPC_DEV];
+};
+
+struct cmc221_idpram_sfr {
+ u16 __iomem *int2cp;
+ u16 __iomem *int2ap;
+ u16 __iomem *clr_int2ap;
+ u16 __iomem *reset;
+ u16 __iomem *msg2cp;
+ u16 __iomem *msg2ap;
+};
+
+static struct cmc_dpram_ipc_map cmc_ipc_map;
+static u8 *cmc_sfr_base;
+static struct cmc221_idpram_sfr cmc_sfr;
+
+/* Function prototypes */
+static void cmc_idpram_reset(void);
+static void cmc_idpram_setup_speed(enum dpram_speed);
+static int cmc_idpram_wakeup(void);
+static void cmc_idpram_sleep(void);
+static void cmc_idpram_clr_intr(void);
+static u16 cmc_idpram_recv_intr(void);
+static void cmc_idpram_send_intr(u16 irq_mask);
+static u16 cmc_idpram_recv_msg(void);
+static void cmc_idpram_send_msg(u16 msg);
+
+static u16 cmc_idpram_get_magic(void);
+static void cmc_idpram_set_magic(u16 value);
+static u16 cmc_idpram_get_access(void);
+static void cmc_idpram_set_access(u16 value);
+
+static u32 cmc_idpram_get_tx_head(int dev_id);
+static u32 cmc_idpram_get_tx_tail(int dev_id);
+static void cmc_idpram_set_tx_head(int dev_id, u32 head);
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id);
+static u32 cmc_idpram_get_tx_buff_size(int dev_id);
+
+static u32 cmc_idpram_get_rx_head(int dev_id);
+static u32 cmc_idpram_get_rx_tail(int dev_id);
+static void cmc_idpram_set_rx_head(int dev_id, u32 head);
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id);
+static u32 cmc_idpram_get_rx_buff_size(int dev_id);
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id);
+static u16 cmc_idpram_get_mask_res_ack(int dev_id);
+static u16 cmc_idpram_get_mask_send(int dev_id);
+
+static struct modemlink_dpram_control cmc_idpram_ctrl = {
+ .reset = cmc_idpram_reset,
+
+ .setup_speed = cmc_idpram_setup_speed,
+
+ .wakeup = cmc_idpram_wakeup,
+ .sleep = cmc_idpram_sleep,
+
+ .clear_intr = cmc_idpram_clr_intr,
+ .recv_intr = cmc_idpram_recv_intr,
+ .send_intr = cmc_idpram_send_intr,
+ .recv_msg = cmc_idpram_recv_msg,
+ .send_msg = cmc_idpram_send_msg,
+
+ .get_magic = cmc_idpram_get_magic,
+ .set_magic = cmc_idpram_set_magic,
+ .get_access = cmc_idpram_get_access,
+ .set_access = cmc_idpram_set_access,
+
+ .get_tx_head = cmc_idpram_get_tx_head,
+ .get_tx_tail = cmc_idpram_get_tx_tail,
+ .set_tx_head = cmc_idpram_set_tx_head,
+ .set_tx_tail = cmc_idpram_set_tx_tail,
+ .get_tx_buff = cmc_idpram_get_tx_buff,
+ .get_tx_buff_size = cmc_idpram_get_tx_buff_size,
+
+ .get_rx_head = cmc_idpram_get_rx_head,
+ .get_rx_tail = cmc_idpram_get_rx_tail,
+ .set_rx_head = cmc_idpram_set_rx_head,
+ .set_rx_tail = cmc_idpram_set_rx_tail,
+ .get_rx_buff = cmc_idpram_get_rx_buff,
+ .get_rx_buff_size = cmc_idpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cmc_idpram_get_mask_req_ack,
+ .get_mask_res_ack = cmc_idpram_get_mask_res_ack,
+ .get_mask_send = cmc_idpram_get_mask_send,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = CP_IDPRAM,
+ .aligned = 1,
+
+ .dpram_irq = CMC_IDPRAM_INT_IRQ_00,
+ .dpram_irq_flags = (IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING),
+ .dpram_irq_name = "CMC221_IDPRAM_IRQ",
+ .dpram_wlock_name = "CMC221_IDPRAM_WLOCK",
+
+ .max_ipc_dev = MAX_CMC_IDPRAM_IPC_DEV,
+};
+
+/*
+** UMTS target platform data
+*/
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "umts_ipc0",
+ .id = 0x0,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "umts_rfs0",
+ .id = 0x0,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "umts_multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ /* .links = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB), */
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ .tx_link = LINKDEV_DPRAM,
+ },
+ [4] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [5] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [6] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [7] = {
+ .name = "rmnet3",
+ .id = 0x2D,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [8] = {
+ .name = "umts_rmnet4",
+ .id = 0x27,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "umts_rmnet5",
+ .id = 0x3A,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "umts_router", /* AT Iface & Dial-up */
+ .id = 0x3E, /* Channel 30 (0x3E & 0x1F) */
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "umts_ramdump0",
+ .id = 0x0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "umts_loopback0",
+ .id = 0x0,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "umts_dm0", /* DM Port */
+ .id = 0x3F, /* Channel 31 (0x3F & 0x1F) */
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+/*
+ [15] = {
+ .name = "lte_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_USB),
+ },
+*/
+};
+
+/*
+static int exynos_cpu_frequency_lock(void);
+static int exynos_cpu_frequency_unlock(void);
+*/
+
+static struct modemlink_pm_data umts_link_pm_data = {
+ .name = "umts_link_pm",
+
+ .gpio_link_enable = 0,
+ /*
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+
+ .port_enable = host_port_enable,
+
+ .link_reconnect = umts_link_reconnect,
+ */
+ .freqlock = ATOMIC_INIT(0),
+ /*
+ .cpufreq_lock = exynos_cpu_frequency_lock,
+ .cpufreq_unlock = exynos_cpu_frequency_unlock,
+ */
+};
+
+static struct modem_data umts_modem_data = {
+ .name = "cmc221",
+
+ .gpio_cp_on = CP_CMC221_PMIC_PWRON,
+ .gpio_cp_reset = CP_CMC221_CPU_RST,
+ .gpio_phone_active = GPIO_LTE_ACTIVE,
+
+ .gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00,
+ .gpio_dpram_status = GPIO_CMC_IDPRAM_STATUS,
+ .gpio_dpram_wakeup = GPIO_CMC_IDPRAM_WAKEUP,
+ /*
+ .gpio_slave_wakeup = GPIO_IPC_SLAVE_WAKEUP,
+ .gpio_host_active = GPIO_ACTIVE_STATE,
+ .gpio_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+ */
+ .modem_net = UMTS_NETWORK,
+ .modem_type = SEC_CMC221,
+ /* .link_types = LINKTYPE(LINKDEV_DPRAM) | LINKTYPE(LINKDEV_USB), */
+ .link_types = LINKTYPE(LINKDEV_DPRAM),
+ .link_name = "cmc221_idpram",
+ .dpram_ctl = &cmc_idpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &umts_link_pm_data,
+
+ .ipc_version = SIPC_VER_41,
+};
+
+static struct resource umts_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = LTE_ACTIVE_IRQ,
+ .end = LTE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+#define HUB_STATE_OFF 0
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val && states == STATE_HSIC_LPA_ENTER) {
+ pr_info("mif: usb3503: %s: hub off - lpa\n", __func__);
+ host_port_enable(2, 0);
+ *(umts_link_pm_data.p_hub_status) = HUB_STATE_OFF;
+ }
+}
+#endif
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static void cmc_idpram_reset(void)
+{
+ iowrite16(1, cmc_sfr.reset);
+}
+
+static void cmc_idpram_setup_speed(enum dpram_speed speed)
+{
+ setup_dpram_speed(cmc_idpram_cfg.csn, &cmc_idpram_access_cfg[speed]);
+}
+
+static int cmc_idpram_wakeup(void)
+{
+ int cnt = 0;
+ u16 magic = 0;
+ u16 access = 0;
+
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 1);
+
+ cnt = 0;
+ while (!gpio_get_value(umts_modem_data.gpio_dpram_status)) {
+ if (cnt++ > 10) {
+ pr_err("[MDM/E] <%s> gpio_dpram_status == 0\n",
+ __func__);
+ break; /* return -EAGAIN; */
+ }
+
+ if (in_interrupt())
+ mdelay(1);
+ else
+ msleep_interruptible(1);
+ }
+
+ return 0;
+}
+
+static void cmc_idpram_sleep(void)
+{
+ gpio_set_value(umts_modem_data.gpio_dpram_wakeup, 0);
+}
+
+static void cmc_idpram_clr_intr(void)
+{
+ iowrite16(0xFFFF, cmc_sfr.clr_int2ap);
+ iowrite16(0, cmc_sfr.int2ap);
+}
+
+static u16 cmc_idpram_recv_intr(void)
+{
+ return ioread16(cmc_sfr.int2ap);
+}
+
+static void cmc_idpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cmc_sfr.int2cp);
+}
+
+static u16 cmc_idpram_recv_msg(void)
+{
+ return ioread16(cmc_sfr.msg2ap);
+}
+
+static void cmc_idpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cmc_sfr.msg2cp);
+}
+
+static u16 cmc_idpram_get_magic(void)
+{
+ return ioread16(cmc_ipc_map.magic);
+}
+
+static void cmc_idpram_set_magic(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.magic);
+}
+
+static u16 cmc_idpram_get_access(void)
+{
+ return ioread16(cmc_ipc_map.access);
+}
+
+static void cmc_idpram_set_access(u16 value)
+{
+ iowrite16(value, cmc_ipc_map.access);
+}
+
+static u32 cmc_idpram_get_tx_head(int dev_id)
+{
+ return ioread32(cmc_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cmc_idpram_get_tx_tail(int dev_id)
+{
+ return ioread32(cmc_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cmc_idpram_set_tx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite32(head, cmc_ipc_map.dev[dev_id].txq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread32(cmc_ipc_map.dev[dev_id].txq.head);
+ if (val == head)
+ break;
+
+ pr_err("[MDM/E] <%s> txq.head(%d) != head(%d)\n",
+ __func__, val, head);
+
+ /* Write head value again */
+ iowrite32(head, cmc_ipc_map.dev[dev_id].txq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_tx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite32(tail, cmc_ipc_map.dev[dev_id].txq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread32(cmc_ipc_map.dev[dev_id].txq.tail);
+ if (val == tail)
+ break;
+
+ pr_err("[MDM/E] <%s> txq.tail(%d) != tail(%d)\n",
+ __func__, val, tail);
+
+ /* Write tail value again */
+ iowrite32(tail, cmc_ipc_map.dev[dev_id].txq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_tx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cmc_idpram_get_tx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cmc_idpram_get_rx_head(int dev_id)
+{
+ return ioread32(cmc_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cmc_idpram_get_rx_tail(int dev_id)
+{
+ return ioread32(cmc_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cmc_idpram_set_rx_head(int dev_id, u32 head)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite32(head, cmc_ipc_map.dev[dev_id].rxq.head);
+
+ do {
+ /* Check head value written */
+ val = ioread32(cmc_ipc_map.dev[dev_id].rxq.head);
+ if (val == head)
+ break;
+
+ pr_err("[MDM/E] <%s> rxq.head(%d) != head(%d)\n",
+ __func__, val, head);
+
+ /* Write head value again */
+ iowrite32(head, cmc_ipc_map.dev[dev_id].rxq.head);
+ } while (cnt--);
+}
+
+static void cmc_idpram_set_rx_tail(int dev_id, u32 tail)
+{
+ int cnt = 100;
+ u32 val = 0;
+
+ iowrite32(tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+
+ do {
+ /* Check tail value written */
+ val = ioread32(cmc_ipc_map.dev[dev_id].rxq.tail);
+ if (val == tail)
+ break;
+
+ pr_err("[MDM/E] <%s> rxq.tail(%d) != tail(%d)\n",
+ __func__, val, tail);
+
+ /* Write tail value again */
+ iowrite32(tail, cmc_ipc_map.dev[dev_id].rxq.tail);
+ } while (cnt--);
+}
+
+static u8 __iomem *cmc_idpram_get_rx_buff(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cmc_idpram_get_rx_buff_size(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cmc_idpram_get_mask_req_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cmc_idpram_get_mask_res_ack(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cmc_idpram_get_mask_send(int dev_id)
+{
+ return cmc_ipc_map.dev[dev_id].mask_send;
+}
+
+/* Set dynamic environment for a modem */
+static void setup_umts_modem_env(void)
+{
+ /* Config DPRAM control structure */
+ cmc_idpram_cfg.csn = 0;
+ cmc_idpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cmc_idpram_cfg.csn);
+ cmc_idpram_cfg.end = cmc_idpram_cfg.addr + cmc_idpram_cfg.size - 1;
+
+ umts_modem_data.gpio_dpram_int = GPIO_CMC_IDPRAM_INT_00;
+}
+
+static void config_umts_modem_gpio(void)
+{
+ int err = 0;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_active_state = umts_modem_data.gpio_host_active;
+ unsigned gpio_host_wakeup = umts_modem_data.gpio_host_wakeup;
+ unsigned gpio_slave_wakeup = umts_modem_data.gpio_slave_wakeup;
+ unsigned gpio_dpram_int = umts_modem_data.gpio_dpram_int;
+ unsigned gpio_dpram_status = umts_modem_data.gpio_dpram_status;
+ unsigned gpio_dpram_wakeup = umts_modem_data.gpio_dpram_wakeup;
+
+ pr_info("[MDM] <%s>\n", __func__);
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CMC_ON");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 0);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CMC_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "CMC_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_ACTIVE");
+ } else {
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_active_state) {
+ err = gpio_request(gpio_active_state, "CMC_ACTIVE_STATE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_ACTIVE_STATE");
+ } else {
+ gpio_direction_output(gpio_active_state, 0);
+ s3c_gpio_setpull(gpio_active_state, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_slave_wakeup) {
+ err = gpio_request(gpio_slave_wakeup, "CMC_SLAVE_WAKEUP");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_SLAVE_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_slave_wakeup, 0);
+ s3c_gpio_setpull(gpio_slave_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_host_wakeup) {
+ err = gpio_request(gpio_host_wakeup, "CMC_HOST_WAKEUP");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_HOST_WAKEUP");
+ } else {
+ s3c_gpio_cfgpin(gpio_host_wakeup, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_host_wakeup, S3C_GPIO_PULL_DOWN);
+ }
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "CMC_DPRAM_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_dpram_status) {
+ err = gpio_request(gpio_dpram_status, "CMC_DPRAM_STATUS");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_DPRAM_STATUS");
+ } else {
+ /* Configure as a wake-up source */
+ s3c_gpio_cfgpin(gpio_dpram_status, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_dpram_status, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_dpram_wakeup) {
+ err = gpio_request(gpio_dpram_wakeup, "CMC_DPRAM_WAKEUP");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "CMC_DPRAM_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_dpram_wakeup, 1);
+ s3c_gpio_setpull(gpio_dpram_wakeup, S3C_GPIO_PULL_NONE);
+ }
+ }
+}
+
+static u8 *cmc_idpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = 0;
+ int dp_size = 0;
+ u8 __iomem *dp_base = NULL;
+ struct dpram_ipc_cfg *ipc_map = NULL;
+ struct cmc_dpram_ipc_device *dev = NULL;
+
+ dp_addr = cfg->addr;
+ dp_size = cfg->size;
+
+ dp_base = (u8 *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ pr_err("[MDM] <%s> dpram base ioremap fail\n", __func__);
+ return NULL;
+ }
+ pr_info("[MDM] <%s> DPRAM VA=0x%08X\n", __func__, (int)dp_base);
+
+ cmc_sfr_base = (u8 *)ioremap_nocache((dp_addr + dp_size), dp_size);
+ if (cmc_sfr_base == NULL) {
+ pr_err("[MDM] <%s> Failed in ioremap_nocache()\n", __func__);
+ return NULL;
+ }
+
+ cmc_sfr.int2cp = (u16 __iomem *)(cmc_sfr_base + CMC_INT2CP_REG);
+ cmc_sfr.int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_INT2AP_REG);
+ cmc_sfr.clr_int2ap = (u16 __iomem *)(cmc_sfr_base + CMC_CLR_INT_REG);
+ cmc_sfr.reset = (u16 __iomem *)(cmc_sfr_base + CMC_RESET_REG);
+ cmc_sfr.msg2cp = (u16 __iomem *)(cmc_sfr_base + CMC_PUT_REG);
+ cmc_sfr.msg2ap = (u16 __iomem *)(cmc_sfr_base + CMC_GET_REG);
+
+
+ cmc_idpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cmc_idpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct dpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cmc_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cmc_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cmc_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u32 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u32 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u32 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u32 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cmc_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u32 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u32 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u32 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u32 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+ /* RFS */
+ dev = &cmc_ipc_map.dev[IPC_RFS];
+
+ strcpy(dev->name, "RFS");
+ dev->id = IPC_RFS;
+
+ dev->txq.head = (u32 __iomem *)&ipc_map->rfs_tx_head;
+ dev->txq.tail = (u32 __iomem *)&ipc_map->rfs_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->rfs_tx_buff[0];
+ dev->txq.size = DP_RFS_TX_BUFF_SZ;
+
+ dev->rxq.head = (u32 __iomem *)&ipc_map->rfs_rx_head;
+ dev->rxq.tail = (u32 __iomem *)&ipc_map->rfs_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->rfs_rx_buff[0];
+ dev->rxq.size = DP_RFS_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_RFS;
+ dev->mask_res_ack = INT_MASK_RES_ACK_RFS;
+ dev->mask_send = INT_MASK_SEND_RFS;
+
+ return dp_base;
+}
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ pr_info("[MDM] <%s> address line = %d bits\n", __func__, addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for address bus (13 ~ 14 bits) */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_LOW,
+ EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_ADDR_BUS_HIGH,
+ (addr_bits - EXYNOS4_GPIO_Y3_NR), S3C_GPIO_SFN(2));
+ break;
+
+ default:
+ pr_err("[MDM/E] <%s> Invalid addr_bits!!!\n", __func__);
+ return;
+ }
+
+ /* Set GPIO for data bus (16 bits) */
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_LOW, 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(GPIO_SROM_DATA_BUS_HIGH, 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgpin(GPIO_DPRAM_REN, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(GPIO_DPRAM_WEN, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ pr_err("[MDM/E] <%s> SROMC clock gate fail\n", __func__);
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(
+ unsigned csn,
+ struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg
+)
+{
+ unsigned bw = 0; /* Bus width and wait control */
+ unsigned bc = 0; /* Vank control */
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ pr_err("[MDM] <%s> SROMC settings for CS%d...\n", __func__, csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> Old SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn << 2));
+ bw |= (cfg->attr << (csn << 2));
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> New SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+}
+
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg)
+{
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+ unsigned bc = 0;
+
+ bc = __raw_readl(bank_sfr);
+ pr_info("[MDM] <%s> Old CS%d setting = 0x%08X\n", __func__, csn, bc);
+
+ /* SROMC memory access timing setting */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+ writel(bc, bank_sfr);
+
+ bc = __raw_readl(bank_sfr);
+ pr_info("[MDM] <%s> New CS%d setting = 0x%08X\n", __func__, csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ pr_err("[MODEM_IF] <%s> System Revision = %d\n", __func__, system_rev);
+
+ setup_umts_modem_env();
+
+ config_dpram_port_gpio();
+
+ config_umts_modem_gpio();
+
+ init_sromc();
+
+ cfg = &cmc_idpram_cfg;
+ acc_cfg = &cmc_idpram_access_cfg[DPRAM_SPEED_LOW];
+
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!cmc_idpram_remap_mem_region(&cmc_idpram_cfg))
+ return -1;
+
+ platform_device_register(&umts_modem);
+
+ pr_err("[MODEM_IF] %s: DONE!!\n", __func__);
+ return 0;
+}
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
+
+
+
+
+
+
+#ifdef CONFIG_USBHUB_USB3503
+static int (*usbhub_set_mode)(struct usb3503_hubctl *, int);
+static struct usb3503_hubctl *usbhub_ctl;
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+static int exynos_cpu_frequency_lock(void)
+{
+ unsigned int level, freq = 700;
+
+ if (atomic_read(&umts_link_pm_data.freqlock) == 0) {
+ if (exynos_cpufreq_get_level(freq * 1000, &level)) {
+ pr_err("[MIF] exynos_cpufreq_get_level is fail\n");
+ return -EINVAL;
+ }
+
+ if (exynos_cpufreq_lock(DVFS_LOCK_ID_USB_IF, level)) {
+ pr_err("[MIF] exynos_cpufreq_lock is fail\n");
+ return -EINVAL;
+ }
+
+ atomic_set(&umts_link_pm_data.freqlock, 1);
+ pr_debug("[MIF] %s: <%d>%dMHz\n", __func__, level, freq);
+ }
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ if (atomic_read(&umts_link_pm_data.freqlock) == 1) {
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_USB_IF);
+ atomic_set(&umts_link_pm_data.freqlock, 0);
+ pr_debug("[MIF] %s\n", __func__);
+ }
+ return 0;
+}
+#else /* for CONFIG_EXYNOS4_CPUFREQ */
+static int exynos_cpu_frequency_lock(void)
+{
+ return 0;
+}
+
+static int exynos_cpu_frequency_unlock(void)
+{
+ return 0;
+}
+#endif /* for CONFIG_EXYNOS4_CPUFREQ */
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+}
+
+static int usb3503_hub_handler(void (*set_mode)(void), void *ctl)
+{
+ if (!set_mode || !ctl)
+ return -EINVAL;
+
+ usbhub_set_mode = (int (*)(struct usb3503_hubctl *, int))set_mode;
+ usbhub_ctl = (struct usb3503_hubctl *)ctl;
+
+ pr_info("[MDM] <%s> set_mode(%pF)\n", __func__, set_mode);
+
+ return 0;
+}
+
+static int usb3503_hw_config(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_USB_HUB_RST, "HUB_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_RST");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_RST, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_RST, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_RST, S5P_GPIO_DRVSTR_LV1);
+ /* need to check drvstr 1 or 2 */
+
+ /* for USB3503 26Mhz Reference clock setting */
+ err = gpio_request(GPIO_USB_HUB_INT, "HUB_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_INT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_INT, 1);
+ s3c_gpio_setpull(GPIO_USB_HUB_INT, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static int usb3503_reset_n(int val)
+{
+ gpio_set_value(GPIO_USB_HUB_RST, 0);
+
+ /* hub off from cpuidle(LPA), skip the msleep schedule*/
+ if (val) {
+ msleep(20);
+ pr_info("[MDM] <%s> val = %d\n", __func__,
+ gpio_get_value(GPIO_USB_HUB_RST));
+ gpio_set_value(GPIO_USB_HUB_RST, !!val);
+
+ pr_info("[MDM] <%s> val = %d\n", __func__,
+ gpio_get_value(GPIO_USB_HUB_RST));
+
+ udelay(5); /* need it ?*/
+ }
+ return 0;
+}
+
+static struct usb3503_platform_data usb3503_pdata = {
+ .initial_mode = USB3503_MODE_STANDBY,
+ .reset_n = usb3503_reset_n,
+ .register_hub_handler = usb3503_hub_handler,
+ .port_enable = host_port_enable,
+};
+
+static struct i2c_board_info i2c_devs20_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO(USB3503_I2C_NAME, 0x08),
+ .platform_data = &usb3503_pdata,
+ },
+};
+
+/* I2C20_EMUL */
+static struct i2c_gpio_platform_data i2c20_platdata = {
+ .sda_pin = GPIO_USB_HUB_SDA,
+ .scl_pin = GPIO_USB_HUB_SCL,
+ /*FIXME: need to timming tunning... */
+ .udelay = 20,
+};
+
+static struct platform_device s3c_device_i2c20 = {
+ .name = "i2c-gpio",
+ .id = 20,
+ .dev.platform_data = &i2c20_platdata,
+};
+
+static int __init init_usbhub(void)
+{
+ usb3503_hw_config();
+ i2c_register_board_info(20, i2c_devs20_emul,
+ ARRAY_SIZE(i2c_devs20_emul));
+
+ platform_device_register(&s3c_device_i2c20);
+ return 0;
+}
+
+device_initcall(init_usbhub);
+
+static int host_port_enable(int port, int enable)
+{
+ int err;
+
+ pr_info("[MDM] <%s> port(%d) control(%d)\n", __func__, port, enable);
+
+ if (enable) {
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB);
+ if (err < 0) {
+ pr_err("[MDM] <%s> hub on fail\n", __func__);
+ goto exit;
+ }
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 1);
+ if (err < 0) {
+ pr_err("[MDM] <%s> port(%d) enable fail\n", __func__,
+ port);
+ goto exit;
+ }
+ } else {
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 0);
+ if (err < 0) {
+ pr_err("[MDM] <%s> port(%d) enable fail\n", __func__,
+ port);
+ goto exit;
+ }
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY);
+ if (err < 0) {
+ pr_err("[MDM] <%s> hub off fail\n", __func__);
+ goto exit;
+ }
+ }
+
+ err = gpio_direction_output(umts_modem_data.gpio_host_active, enable);
+ pr_info("[MDM] <%s> active state err(%d), en(%d), level(%d)\n",
+ __func__, err, enable,
+ gpio_get_value(umts_modem_data.gpio_host_active));
+
+exit:
+ return err;
+}
+#else /* for CONFIG_USBHUB_USB3503 */
+void set_host_states(struct platform_device *pdev, int type)
+{
+ /*
+ if (active_ctl.gpio_initialized) {
+ pr_err(" [MODEM_IF] Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(umts_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+ */
+ return;
+}
+#endif /* for CONFIG_USBHUB_USB3503 */
+
diff --git a/arch/arm/mach-exynos/board-gps-bcm475x.c b/arch/arm/mach-exynos/board-gps-bcm475x.c
new file mode 100644
index 0000000..7b9a1c7
--- /dev/null
+++ b/arch/arm/mach-exynos/board-gps-bcm475x.c
@@ -0,0 +1,69 @@
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <mach/board-gps.h>
+
+#if !defined(CONFIG_MACH_M0_GRANDECTC)
+
+static struct device *gps_dev;
+
+static int __init gps_bcm475x_init(void)
+{
+ int n_rst_pin = 0;
+ int n_rst_nc_pin = 0;
+ BUG_ON(!sec_class);
+ gps_dev = device_create(sec_class, NULL, 0, NULL, "gps");
+ BUG_ON(!gps_dev);
+
+ s3c_gpio_cfgpin(GPIO_GPS_RXD, S3C_GPIO_SFN(GPIO_GPS_RXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_RXD, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_TXD, S3C_GPIO_SFN(GPIO_GPS_TXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_CTS, S3C_GPIO_SFN(GPIO_GPS_CTS_AF));
+ s3c_gpio_setpull(GPIO_GPS_CTS, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_RTS, S3C_GPIO_SFN(GPIO_GPS_RTS_AF));
+ s3c_gpio_setpull(GPIO_GPS_RTS, S3C_GPIO_PULL_NONE);
+
+#ifdef CONFIG_MACH_P2
+ n_rst_pin = GPIO_GPS_nRST_28V;
+ n_rst_nc_pin = GPIO_GPS_nRST;
+#else
+ n_rst_pin = GPIO_GPS_nRST;
+ n_rst_nc_pin = 0;
+#endif
+
+ if (gpio_request(n_rst_pin, "GPS_nRST"))
+ WARN(1, "fail to request gpio (GPS_nRST)\n");
+
+ s3c_gpio_setpull(n_rst_pin, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(n_rst_pin, S3C_GPIO_OUTPUT);
+ gpio_direction_output(n_rst_pin, 1);
+
+ if (gpio_request(GPIO_GPS_PWR_EN, "GPS_PWR_EN"))
+ WARN(1, "fail to request gpio (GPS_PWR_EN)\n");
+
+#ifdef CONFIG_MACH_P2
+ gpio_set_value(n_rst_nc_pin, 0);
+ s3c_gpio_cfgpin(n_rst_nc_pin, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(n_rst_nc_pin, S3C_GPIO_PULL_NONE);
+#endif
+
+ s3c_gpio_setpull(GPIO_GPS_PWR_EN, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_PWR_EN, 0);
+
+ gpio_export(n_rst_pin, 1);
+ gpio_export(GPIO_GPS_PWR_EN, 1);
+
+ gpio_export_link(gps_dev, "GPS_nRST", n_rst_pin);
+ gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN);
+
+ return 0;
+}
+
+device_initcall(gps_bcm475x_init);
+
+#endif
diff --git a/arch/arm/mach-exynos/board-gps-gsd4t.c b/arch/arm/mach-exynos/board-gps-gsd4t.c
new file mode 100644
index 0000000..cabb9a7
--- /dev/null
+++ b/arch/arm/mach-exynos/board-gps-gsd4t.c
@@ -0,0 +1,90 @@
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <mach/board-gps.h>
+
+static struct device *gps_dev;
+
+static int __init gps_gsd4t_init(void)
+{
+ BUG_ON(!sec_class);
+ gps_dev = device_create(sec_class, NULL, 0, NULL, "gps");
+ BUG_ON(!gps_dev);
+
+ s3c_gpio_cfgpin(GPIO_GPS_RXD, S3C_GPIO_SFN(GPIO_GPS_RXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_RXD, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_TXD, S3C_GPIO_SFN(GPIO_GPS_TXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_TXD, S3C_GPIO_PULL_NONE);
+
+ if (gpio_request(GPIO_GPS_nRST, "GPS_nRST"))
+ WARN(1, "fail to request gpio (GPS_nRST)\n");
+
+ s3c_gpio_setpull(GPIO_GPS_nRST, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_nRST, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_nRST, 1);
+
+#ifdef CONFIG_TARGET_LOCALE_NTT
+ if (system_rev >= 11) {
+ if (gpio_request(GPIO_GPS_PWR_EN, "GPS_PWR_EN"))
+ WARN(1, "fail to request gpio (GPS_PWR_EN)\n");
+ s3c_gpio_setpull(GPIO_GPS_PWR_EN, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_PWR_EN, 0);
+
+ gpio_export(GPIO_GPS_nRST, 1);
+ gpio_export(GPIO_GPS_PWR_EN, 1);
+ } else {
+ if (gpio_request(GPIO_GPS_PWR_EN_SPI, "GPS_PWR_EN"))
+ WARN(1, "fail to request gpio (GPS_PWR_EN)\n");
+ s3c_gpio_setpull(GPIO_GPS_PWR_EN_SPI, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_PWR_EN_SPI, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_PWR_EN_SPI, 0);
+
+ gpio_export(GPIO_GPS_nRST, 1);
+ gpio_export(GPIO_GPS_PWR_EN_SPI, 1);
+ }
+#else
+ if (gpio_request(GPIO_GPS_PWR_EN, "GPS_PWR_EN"))
+ WARN(1, "fail to request gpio (GPS_PWR_EN)\n");
+
+ s3c_gpio_setpull(GPIO_GPS_PWR_EN, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_PWR_EN, 0);
+
+ gpio_export(GPIO_GPS_nRST, 1);
+ gpio_export(GPIO_GPS_PWR_EN, 1);
+#endif
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ if (system_rev >= 7) {
+ if (gpio_request(GPIO_GPS_RTS, "GPS_RTS"))
+ WARN(1, "fail to request gpio (GPS_RTS)\n");
+ s3c_gpio_setpull(GPIO_GPS_RTS, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_RTS, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_RTS, 1);
+
+ if (gpio_request(GPIO_GPS_CTS, "GPS_CTS"))
+ WARN(1, "fail to request gpio (GPS_RTS)\n");
+ s3c_gpio_setpull(GPIO_GPS_CTS, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_CTS, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_CTS, 1);
+ }
+#endif
+
+ gpio_export_link(gps_dev, "GPS_nRST", GPIO_GPS_nRST);
+#ifdef CONFIG_TARGET_LOCALE_NTT
+ if (system_rev >= 11)
+ gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN);
+ else
+ gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN_SPI);
+#else
+ gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN);
+#endif
+
+ return 0;
+}
+
+device_initcall(gps_gsd4t_init);
diff --git a/arch/arm/mach-exynos/board-jenga-modems.c b/arch/arm/mach-exynos/board-jenga-modems.c
new file mode 100644
index 0000000..8071df1
--- /dev/null
+++ b/arch/arm/mach-exynos/board-jenga-modems.c
@@ -0,0 +1,429 @@
+/* linux/arch/arm/mach-xxxx/board-m0-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Modem configuraiton for M0 (P-Q + XMM6262)*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/platform_data/modem.h>
+
+/* umts target platform data */
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [1] = {
+ .name = "umts_rfs0",
+ .id = 0x41,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [2] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [3] = {
+ .name = "multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [4] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [5] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [6] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [7] = {
+ .name = "umts_router",
+ .id = 0x39,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [8] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [9] = {
+ .name = "umts_ramdump0",
+ .id = 0x0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [10] = {
+ .name = "umts_loopback0",
+ .id = 0x3f,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+};
+
+/* To get modem state, register phone active irq using resource */
+static struct resource umts_modem_res[] = {
+};
+
+static int umts_link_ldo_enble(bool enable)
+{
+ /* Exynos HSIC V1.2 LDO was controlled by kernel */
+ return 0;
+}
+
+static int umts_link_reconnect(void);
+static struct modemlink_pm_data modem_link_pm_data = {
+ .name = "link_pm",
+ .link_ldo_enable = umts_link_ldo_enble,
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+ .link_reconnect = umts_link_reconnect,
+};
+
+static struct modemlink_pm_link_activectl active_ctl;
+
+static void xmm_gpio_revers_bias_clear(void);
+static void xmm_gpio_revers_bias_restore(void);
+static struct modem_data umts_modem_data = {
+ .name = "xmm6262",
+
+ .gpio_cp_on = GPIO_PHONE_ON,
+ .gpio_reset_req_n = GPIO_CP_REQ_RESET,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+ .gpio_flm_uart_sel = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .modem_type = IMC_XMM6262,
+ .link_types = LINKTYPE(LINKDEV_HSIC),
+ .modem_net = UMTS_NETWORK,
+ .use_handover = false,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &modem_link_pm_data,
+ .gpio_revers_bias_clear = xmm_gpio_revers_bias_clear,
+ .gpio_revers_bias_restore = xmm_gpio_revers_bias_restore,
+};
+
+/* HSIC specific function */
+void set_slave_wake(void)
+{
+ int spin = 20;
+ if (gpio_get_value(modem_link_pm_data.gpio_link_hostwake)) {
+ pr_err(LOG_TAG "Send Slave Wake\n");
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 1);
+ mdelay(5);
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 0);
+ while (spin--) {
+ if (!gpio_get_value(
+ modem_link_pm_data.gpio_link_hostwake))
+ break;
+ mdelay(5);
+ }
+ }
+}
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ if (type)
+ set_slave_wake();
+ pr_err(LOG_TAG "Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+
+static int umts_link_reconnect(void)
+{
+ if (gpio_get_value(umts_modem_data.gpio_phone_active) &&
+ gpio_get_value(umts_modem_data.gpio_cp_reset)) {
+ pr_info("[MODEM_IF] trying reconnect link\n");
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ mdelay(10);
+ set_slave_wake();
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 1);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+/* if use more than one modem device, then set id num */
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+static void umts_modem_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_reset_req_n = umts_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_cp_dump_int = umts_modem_data.gpio_cp_dump_int;
+ unsigned gpio_flm_uart_sel = umts_modem_data.gpio_flm_uart_sel;
+ unsigned irq_phone_active = umts_modem_res[0].start;
+
+ if (gpio_reset_req_n) {
+ err = gpio_request(gpio_reset_req_n, "RESET_REQ_N");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "RESET_REQ_N", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CP_ON");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_ON", err);
+ }
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_RST", err);
+ }
+ gpio_direction_output(gpio_cp_rst, 0);
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PDA_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PHONE_ACTIVE", err);
+ }
+ gpio_direction_input(gpio_phone_active);
+ pr_err(LOG_TAG "check phone active = %d\n", irq_phone_active);
+ }
+
+ if (gpio_cp_dump_int) {
+ err = gpio_request(gpio_cp_dump_int, "CP_DUMP_INT");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_DUMP_INT", err);
+ }
+ gpio_direction_input(gpio_cp_dump_int);
+ }
+
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "GPS_UART_SEL");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "GPS_UART_SEL", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_phone_active)
+ irq_set_irq_type(gpio_to_irq(gpio_phone_active),
+ IRQ_TYPE_LEVEL_HIGH);
+ /* set low unused gpios between AP and CP */
+ err = gpio_request(GPIO_FLM_RXD, "FLM_RXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_RXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_RXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_FLM_TXD, "FLM_TXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_TXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_TXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_SUSPEND_REQUEST, "SUS_REQ");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "SUS_REQ",
+ err);
+ else {
+ gpio_direction_output(GPIO_SUSPEND_REQUEST, 0);
+ s3c_gpio_setpull(GPIO_SUSPEND_REQUEST, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_GPS_CNTL, "GPS_CNTL");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "GPS_CNTL",
+ err);
+ else {
+ gpio_direction_output(GPIO_GPS_CNTL, 0);
+ s3c_gpio_setpull(GPIO_GPS_CNTL, S3C_GPIO_PULL_NONE);
+ }
+
+ pr_info(LOG_TAG "umts_modem_cfg_gpio done\n");
+}
+
+static void xmm_gpio_revers_bias_clear(void)
+{
+ gpio_direction_output(umts_modem_data.gpio_pda_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_phone_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_cp_dump_int, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_hostwake, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_slavewake, 0);
+
+ msleep(20);
+}
+
+static void xmm_gpio_revers_bias_restore(void)
+{
+ s3c_gpio_cfgpin(umts_modem_data.gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_cfgpin(modem_link_pm_data.gpio_link_hostwake,
+ S3C_GPIO_SFN(0xF));
+ gpio_direction_input(umts_modem_data.gpio_cp_dump_int);
+}
+
+static void modem_link_pm_config_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_link_enable = modem_link_pm_data.gpio_link_enable;
+ unsigned gpio_link_active = modem_link_pm_data.gpio_link_active;
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+ unsigned gpio_link_slavewake = modem_link_pm_data.gpio_link_slavewake;
+ /* unsigned irq_link_hostwake = umts_modem_res[1].start; */
+
+ if (gpio_link_enable) {
+ err = gpio_request(gpio_link_enable, "LINK_EN");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_EN", err);
+ }
+ gpio_direction_output(gpio_link_enable, 0);
+ }
+
+ if (gpio_link_active) {
+ err = gpio_request(gpio_link_active, "LINK_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_link_active, 0);
+ }
+
+ if (gpio_link_hostwake) {
+ err = gpio_request(gpio_link_hostwake, "HOSTWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "HOSTWAKE", err);
+ }
+ gpio_direction_input(gpio_link_hostwake);
+ }
+
+ if (gpio_link_slavewake) {
+ err = gpio_request(gpio_link_slavewake, "SLAVEWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "SLAVEWAKE", err);
+ }
+ gpio_direction_output(gpio_link_slavewake, 0);
+ }
+
+ if (gpio_link_hostwake)
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQ_TYPE_EDGE_BOTH);
+
+ active_ctl.gpio_initialized = 1;
+ if (active_ctl.gpio_request_host_active) {
+ pr_err(LOG_TAG "Active States = 1, %s\n", __func__);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 1);
+ }
+
+
+ pr_info(LOG_TAG "modem_link_pm_config_gpio done\n");
+}
+
+static int __init init_modem(void)
+{
+ int ret;
+ pr_info(LOG_TAG "init_modem\n");
+
+ /* umts gpios configuration */
+ umts_modem_cfg_gpio();
+ modem_link_pm_config_gpio();
+ ret = platform_device_register(&umts_modem);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+late_initcall(init_modem);
diff --git a/arch/arm/mach-exynos/board-m0-modems.c b/arch/arm/mach-exynos/board-m0-modems.c
new file mode 100644
index 0000000..9362e24
--- /dev/null
+++ b/arch/arm/mach-exynos/board-m0-modems.c
@@ -0,0 +1,498 @@
+/* linux/arch/arm/mach-xxxx/board-m0-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Modem configuraiton for M0 (P-Q + XMM6262)*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+/* umts target platform data */
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [1] = {
+ .name = "umts_rfs0",
+ .id = 0x41,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [2] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [3] = {
+ .name = "multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [4] = {
+#ifdef CONFIG_SLP
+ .name = "pdp0",
+#else
+ .name = "rmnet0",
+#endif
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [5] = {
+#ifdef CONFIG_SLP
+ .name = "pdp1",
+#else
+ .name = "rmnet1",
+#endif
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [6] = {
+#ifdef CONFIG_SLP
+ .name = "pdp2",
+#else
+ .name = "rmnet2",
+#endif
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [7] = {
+ .name = "umts_router",
+ .id = 0x39,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [8] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [9] = {
+ .name = "umts_ramdump0",
+ .id = 0x0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [10] = {
+ .name = "umts_loopback0",
+ .id = 0x3f,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+};
+
+/* To get modem state, register phone active irq using resource */
+static struct resource umts_modem_res[] = {
+};
+
+static int umts_link_ldo_enble(bool enable)
+{
+ /* Exynos HSIC V1.2 LDO was controlled by kernel */
+ return 0;
+}
+
+static int umts_link_reconnect(void);
+static struct modemlink_pm_data modem_link_pm_data = {
+ .name = "link_pm",
+ .link_ldo_enable = umts_link_ldo_enble,
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+ .link_reconnect = umts_link_reconnect,
+};
+
+static struct modemlink_pm_link_activectl active_ctl;
+
+static void xmm_gpio_revers_bias_clear(void);
+static void xmm_gpio_revers_bias_restore(void);
+
+#ifndef GPIO_AP_DUMP_INT
+#define GPIO_AP_DUMP_INT 0
+#endif
+static struct modem_data umts_modem_data = {
+ .name = "xmm6262",
+
+ .gpio_cp_on = GPIO_PHONE_ON,
+ .gpio_reset_req_n = GPIO_CP_REQ_RESET,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+ .gpio_ap_dump_int = GPIO_AP_DUMP_INT,
+ .gpio_flm_uart_sel = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .modem_type = IMC_XMM6262,
+ .link_types = LINKTYPE(LINKDEV_HSIC),
+ .modem_net = UMTS_NETWORK,
+ .use_handover = false,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &modem_link_pm_data,
+ .gpio_revers_bias_clear = xmm_gpio_revers_bias_clear,
+ .gpio_revers_bias_restore = xmm_gpio_revers_bias_restore,
+};
+
+/* HSIC specific function */
+void set_slave_wake(void)
+{
+ if (gpio_get_value(modem_link_pm_data.gpio_link_hostwake)) {
+ pr_info("[MODEM_IF]Slave Wake\n");
+ if (gpio_get_value(modem_link_pm_data.gpio_link_slavewake)) {
+ pr_info("[MODEM_IF]Slave Wake set _-\n");
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 0);
+ mdelay(10);
+ }
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 1);
+ }
+}
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ if (!val) {
+ pr_info("CP not ready, Active State low\n");
+ return;
+ }
+
+ if (active_ctl.gpio_initialized) {
+ pr_err(LOG_TAG "Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ }
+}
+
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val) {
+ switch (states) {
+ case STATE_HSIC_LPA_ENTER:
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ gpio_set_value(umts_modem_data.gpio_pda_active, 0);
+ pr_info(LOG_TAG "set hsic lpa enter: "
+ "active state (%d)" ", pda active (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_active),
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_WAKE:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ pr_info(LOG_TAG "set hsic lpa wake: "
+ "pda active (%d)\n",
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_PHY_INIT:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ set_slave_wake();
+ pr_info(LOG_TAG "set hsic lpa phy init: "
+ "slave wake-up (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_slavewake)
+ );
+ break;
+ }
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static int umts_link_reconnect(void)
+{
+ if (gpio_get_value(umts_modem_data.gpio_phone_active) &&
+ gpio_get_value(umts_modem_data.gpio_cp_reset)) {
+ pr_info("[MODEM_IF] trying reconnect link\n");
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ mdelay(10);
+ set_slave_wake();
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 1);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+/* if use more than one modem device, then set id num */
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+static void umts_modem_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_reset_req_n = umts_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_cp_dump_int = umts_modem_data.gpio_cp_dump_int;
+ unsigned gpio_ap_dump_int = umts_modem_data.gpio_ap_dump_int;
+ unsigned gpio_flm_uart_sel = umts_modem_data.gpio_flm_uart_sel;
+ unsigned irq_phone_active = umts_modem_res[0].start;
+
+ if (gpio_reset_req_n) {
+ err = gpio_request(gpio_reset_req_n, "RESET_REQ_N");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "RESET_REQ_N", err);
+ }
+ s3c_gpio_slp_cfgpin(gpio_reset_req_n, S3C_GPIO_SLP_OUT1);
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CP_ON");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_ON", err);
+ }
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_RST", err);
+ }
+ s3c_gpio_slp_cfgpin(gpio_cp_rst, S3C_GPIO_SLP_OUT1);
+ gpio_direction_output(gpio_cp_rst, 0);
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PDA_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PHONE_ACTIVE", err);
+ }
+ gpio_direction_input(gpio_phone_active);
+ pr_err(LOG_TAG "check phone active = %d\n", irq_phone_active);
+ }
+
+ if (gpio_cp_dump_int) {
+ err = gpio_request(gpio_cp_dump_int, "CP_DUMP_INT");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_DUMP_INT", err);
+ }
+ gpio_direction_input(gpio_cp_dump_int);
+ }
+
+ if (gpio_ap_dump_int /*&& system_rev >= 11*/) { /* MO rev1.0*/
+ err = gpio_request(gpio_ap_dump_int, "AP_DUMP_INT");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "AP_DUMP_INT", err);
+ }
+ gpio_direction_output(gpio_ap_dump_int, 0);
+ }
+
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "GPS_UART_SEL");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "GPS_UART_SEL", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_phone_active)
+ irq_set_irq_type(gpio_to_irq(gpio_phone_active),
+ IRQ_TYPE_LEVEL_HIGH);
+ /* set low unused gpios between AP and CP */
+ err = gpio_request(GPIO_FLM_RXD, "FLM_RXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_RXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_RXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_FLM_TXD, "FLM_TXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_TXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_TXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_SUSPEND_REQUEST, "SUS_REQ");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "SUS_REQ",
+ err);
+ else {
+ gpio_direction_output(GPIO_SUSPEND_REQUEST, 0);
+ s3c_gpio_setpull(GPIO_SUSPEND_REQUEST, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_GPS_CNTL, "GPS_CNTL");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "GPS_CNTL",
+ err);
+ else {
+ gpio_direction_output(GPIO_GPS_CNTL, 0);
+ s3c_gpio_setpull(GPIO_GPS_CNTL, S3C_GPIO_PULL_NONE);
+ }
+
+ pr_info(LOG_TAG "umts_modem_cfg_gpio done\n");
+}
+
+static void xmm_gpio_revers_bias_clear(void)
+{
+ gpio_direction_output(umts_modem_data.gpio_pda_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_phone_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_cp_dump_int, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_hostwake, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_slavewake, 0);
+
+ msleep(20);
+}
+
+static void xmm_gpio_revers_bias_restore(void)
+{
+ s3c_gpio_cfgpin(umts_modem_data.gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_cfgpin(modem_link_pm_data.gpio_link_hostwake,
+ S3C_GPIO_SFN(0xF));
+ gpio_direction_input(umts_modem_data.gpio_cp_dump_int);
+}
+
+static void modem_link_pm_config_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_link_enable = modem_link_pm_data.gpio_link_enable;
+ unsigned gpio_link_active = modem_link_pm_data.gpio_link_active;
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+ unsigned gpio_link_slavewake = modem_link_pm_data.gpio_link_slavewake;
+ /* unsigned irq_link_hostwake = umts_modem_res[1].start; */
+
+ if (gpio_link_enable) {
+ err = gpio_request(gpio_link_enable, "LINK_EN");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_EN", err);
+ }
+ gpio_direction_output(gpio_link_enable, 0);
+ }
+
+ if (gpio_link_active) {
+ err = gpio_request(gpio_link_active, "LINK_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_link_active, 0);
+ }
+
+ if (gpio_link_hostwake) {
+ err = gpio_request(gpio_link_hostwake, "HOSTWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "HOSTWAKE", err);
+ }
+ gpio_direction_input(gpio_link_hostwake);
+ }
+
+ if (gpio_link_slavewake) {
+ err = gpio_request(gpio_link_slavewake, "SLAVEWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "SLAVEWAKE", err);
+ }
+ gpio_direction_output(gpio_link_slavewake, 0);
+ }
+
+ if (gpio_link_hostwake)
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQ_TYPE_EDGE_BOTH);
+
+ active_ctl.gpio_initialized = 1;
+
+ pr_info(LOG_TAG "modem_link_pm_config_gpio done\n");
+}
+
+static int __init init_modem(void)
+{
+ int ret;
+ pr_info(LOG_TAG "init_modem, system_rev = %d\n", system_rev);
+
+ /* umts gpios configuration */
+ umts_modem_cfg_gpio();
+ modem_link_pm_config_gpio();
+ ret = platform_device_register(&umts_modem);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+late_initcall(init_modem);
diff --git a/arch/arm/mach-exynos/board-m0-td-modems.c b/arch/arm/mach-exynos/board-m0-td-modems.c
new file mode 100644
index 0000000..f98a66b
--- /dev/null
+++ b/arch/arm/mach-exynos/board-m0-td-modems.c
@@ -0,0 +1,292 @@
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/regulator/consumer.h>
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+#include <linux/phone_svn/modemctl.h>
+
+#define DEBUG
+
+static struct modemctl_platform_data mdmctl_data;
+void modemctl_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_phone_on = mdmctl_data.gpio_phone_on;
+ unsigned gpio_phone_active = mdmctl_data.gpio_phone_active;
+ unsigned gpio_cp_rst = mdmctl_data.gpio_cp_reset;
+ unsigned gpio_pda_active = mdmctl_data.gpio_pda_active;
+ unsigned gpio_cp_req_reset = mdmctl_data.gpio_cp_req_reset;
+ unsigned gpio_ipc_slave_wakeup = mdmctl_data.gpio_ipc_slave_wakeup;
+ unsigned gpio_ipc_host_wakeup = mdmctl_data.gpio_ipc_host_wakeup;
+ unsigned gpio_suspend_request = mdmctl_data.gpio_suspend_request;
+ unsigned gpio_active_state = mdmctl_data.gpio_active_state;
+ unsigned gpio_cp_dump_int = mdmctl_data.gpio_cp_dump_int;
+
+ /*TODO: check uart init func AP FLM BOOT RX -- */
+ s3c_gpio_setpull(EXYNOS4_GPA1(4), S3C_GPIO_PULL_UP);
+
+ err = gpio_request(gpio_phone_on, "PHONE_ON");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "PHONE_ON");
+ } else {
+ gpio_direction_output(gpio_phone_on, 0);
+ s3c_gpio_setpull(gpio_phone_on, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 0);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ }
+#if !defined(CONFIG_CHN_CMCC_SPI_SPRD)
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "CP_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(gpio_cp_req_reset, "CP_REQ_RESET");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "CP_REQ_RESET");
+ } else {
+ gpio_direction_output(gpio_cp_req_reset, 0);
+ s3c_gpio_setpull(gpio_cp_req_reset, S3C_GPIO_PULL_NONE);
+ }
+
+ err = gpio_request(gpio_ipc_slave_wakeup, "IPC_SLAVE_WAKEUP");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n",
+ "IPC_SLAVE_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_ipc_slave_wakeup, 0);
+ s3c_gpio_setpull(gpio_ipc_slave_wakeup, S3C_GPIO_PULL_NONE);
+ }
+
+ err = gpio_request(gpio_ipc_host_wakeup, "IPC_HOST_WAKEUP");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "IPC_HOST_WAKEUP");
+ } else {
+ gpio_direction_output(gpio_ipc_host_wakeup, 0);
+ s3c_gpio_cfgpin(gpio_ipc_host_wakeup, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_host_wakeup, S3C_GPIO_PULL_NONE);
+ }
+
+ err = gpio_request(gpio_suspend_request, "SUSPEND_REQUEST");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "SUSPEND_REQUEST");
+ } else {
+ gpio_direction_input(gpio_suspend_request);
+ s3c_gpio_setpull(gpio_suspend_request, S3C_GPIO_PULL_NONE);
+ }
+
+ err = gpio_request(gpio_active_state, "ACTIVE_STATE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "ACTIVE_STATE");
+ } else {
+ gpio_direction_output(gpio_active_state, 0);
+ s3c_gpio_setpull(gpio_active_state, S3C_GPIO_PULL_NONE);
+ }
+#endif
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "PHONE_ACTIVE");
+ } else {
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_DOWN);
+ }
+
+ err = gpio_request(gpio_cp_dump_int, "CP_DUMP_INT");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s\n", "CP_DUMP_INT");
+ } else {
+ gpio_direction_input(gpio_cp_dump_int);
+ s3c_gpio_cfgpin(gpio_cp_dump_int, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_cp_dump_int, S3C_GPIO_PULL_DOWN);
+ }
+}
+
+static void xmm6260_vcc_init(struct modemctl *mc)
+{
+ int err;
+
+ if (!mc->vcc) {
+ mc->vcc = regulator_get(NULL, "vhsic");
+ if (IS_ERR(mc->vcc)) {
+ err = PTR_ERR(mc->vcc);
+ dev_dbg(mc->dev, "No VHSIC_1.2V regualtor: %d\n", err);
+ mc->vcc = NULL;
+ }
+ }
+
+ if (mc->vcc)
+ regulator_enable(mc->vcc);
+}
+
+static void xmm6260_vcc_off(struct modemctl *mc)
+{
+ if (mc->vcc)
+ regulator_disable(mc->vcc);
+}
+
+static void xmm6260_on(struct modemctl *mc)
+{
+ dev_dbg(mc->dev, "%s\n", __func__);
+ if (!mc->gpio_cp_reset || !mc->gpio_phone_on || !mc->gpio_cp_req_reset)
+ return;
+#if defined(CONFIG_CHN_CMCC_SPI_SPRD)
+ gpio_set_value(mc->gpio_cp_req_reset, 0);
+ gpio_set_value(mc->gpio_pda_active, 0);
+ gpio_set_value(mc->gpio_phone_on, 0);
+ msleep(100);
+ gpio_set_value(mc->gpio_phone_on, 1);
+ gpio_set_value(mc->gpio_pda_active, 1);
+#else
+ xmm6260_vcc_init(mc);
+
+ gpio_set_value(mc->gpio_phone_on, 0);
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ udelay(160);
+
+ gpio_set_value(mc->gpio_pda_active, 0);
+ gpio_set_value(mc->gpio_active_state, 0);
+ msleep(100);
+
+ gpio_set_value(mc->gpio_cp_reset, 1);
+ udelay(160);
+ gpio_set_value(mc->gpio_cp_req_reset, 1);
+ udelay(160);
+
+ gpio_set_value(mc->gpio_phone_on, 1);
+
+ msleep(20);
+ gpio_set_value(mc->gpio_active_state, 1);
+ gpio_set_value(mc->gpio_pda_active, 1);
+#endif
+}
+
+static void xmm6260_off(struct modemctl *mc)
+{
+ dev_dbg(mc->dev, "%s\n", __func__);
+ if (!mc->gpio_cp_reset || !mc->gpio_phone_on)
+ return;
+
+ gpio_set_value(mc->gpio_phone_on, 0);
+ gpio_set_value(mc->gpio_cp_reset, 0);
+
+ xmm6260_vcc_off(mc);
+}
+
+static void xmm6260_reset(struct modemctl *mc)
+{
+ dev_dbg(mc->dev, "%s\n", __func__);
+ if (!mc->gpio_cp_reset || !mc->gpio_cp_req_reset)
+ return;
+
+#if defined(CONFIG_CHN_CMCC_SPI_SPRD)
+ gpio_set_value(mc->gpio_cp_req_reset, 0);
+ msleep(100);
+ gpio_set_value(mc->gpio_cp_req_reset, 1);
+#else
+/* gpio_set_value(mc->gpio_pda_active, 0);
+ gpio_set_value(mc->gpio_active_state, 0);*/
+ gpio_set_value(mc->gpio_cp_reset, 0);
+ gpio_set_value(mc->gpio_cp_req_reset, 0);
+
+ msleep(100);
+
+ gpio_set_value(mc->gpio_cp_reset, 1);
+ udelay(160);
+ gpio_set_value(mc->gpio_cp_req_reset, 1);
+#endif
+}
+
+/* move the PDA_ACTIVE Pin control to sleep_gpio_table */
+static void xmm6260_suspend(struct modemctl *mc)
+{
+ xmm6260_vcc_off(mc);
+}
+
+static void xmm6260_resume(struct modemctl *mc)
+{
+ xmm6260_vcc_init(mc);
+}
+
+#if defined(CONFIG_CHN_CMCC_SPI_SPRD)
+static struct modemctl_platform_data mdmctl_data = {
+ .name = "xmm6260",
+
+ .gpio_phone_on = GPIO_PHONE_ON,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_cp_req_reset = GPIO_AP_CP_INT2,
+ .gpio_ipc_slave_wakeup = GPIO_IPC_SLAVE_WAKEUP,
+ .gpio_ipc_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+ .gpio_suspend_request = GPIO_SUSPEND_REQUEST,
+ .gpio_active_state = GPIO_ACTIVE_STATE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+
+ .ops = {
+ .modem_on = xmm6260_on,
+ .modem_off = xmm6260_off,
+ .modem_reset = xmm6260_reset,
+ .modem_suspend = xmm6260_suspend,
+ .modem_resume = xmm6260_resume,
+ .modem_cfg_gpio = modemctl_cfg_gpio,
+ }
+};
+#else
+static struct modemctl_platform_data mdmctl_data = {
+ .name = "xmm6260",
+ .gpio_phone_on = GPIO_PHONE_ON,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_cp_req_reset = GPIO_CP_REQ_RESET,
+ .gpio_ipc_slave_wakeup = GPIO_IPC_SLAVE_WAKEUP,
+ .gpio_ipc_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+ .gpio_suspend_request = GPIO_SUSPEND_REQUEST,
+ .gpio_active_state = GPIO_ACTIVE_STATE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+ .ops = {
+ .modem_on = xmm6260_on,
+ .modem_off = xmm6260_off,
+ .modem_reset = xmm6260_reset,
+ .modem_suspend = xmm6260_suspend,
+ .modem_resume = xmm6260_resume,
+ .modem_cfg_gpio = modemctl_cfg_gpio,
+ }
+};
+#endif
+
+/* TODO: check the IRQs..... */
+static struct resource mdmctl_res[] = {
+ [0] = {
+ .start = IRQ_PHONE_ACTIVE,
+ .end = IRQ_PHONE_ACTIVE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device modemctl = {
+ .name = "modemctl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mdmctl_res),
+ .resource = mdmctl_res,
+
+ .dev = {
+ .platform_data = &mdmctl_data,
+ },
+};
diff --git a/arch/arm/mach-exynos/board-m0ctc-modems.c b/arch/arm/mach-exynos/board-m0ctc-modems.c
new file mode 100644
index 0000000..3f69c69
--- /dev/null
+++ b/arch/arm/mach-exynos/board-m0ctc-modems.c
@@ -0,0 +1,1877 @@
+/* linux/arch/arm/mach-xxxx/board-c1ctc-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/if_arp.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#ifdef CONFIG_USBHUB_USB3503
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/platform_data/usb3503.h>
+#endif
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/*
+ * For SROMC Configuration:
+ * SROMC_ADDR_BYTE enable for byte access
+ */
+#define SROMC_DATA_16 0x1
+#define SROMC_ADDR_BYTE 0x2
+#define SROMC_WAIT_EN 0x4
+#define SROMC_BYTE_EN 0x8
+#define SROMC_MASK 0xF
+
+/* Memory attributes */
+enum sromc_attr {
+ MEM_DATA_BUS_16BIT = 0x00000001,
+ MEM_BYTE_ADDRESSABLE = 0x00000002,
+ MEM_WAIT_EN = 0x00000004,
+ MEM_BYTE_EN = 0x00000008,
+
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For MDM6600 EDPRAM (External DPRAM) */
+#define MSM_EDPRAM_SIZE 0x4000 /* 16 KB */
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+#ifdef CONFIG_USBHUB_USB3503
+static int host_port_enable(int port, int enable);
+#else
+static int host_port_enable(int port, int enable)
+{
+ return s5p_ehci_port_control(&s5p_device_ehci, port, enable);
+}
+#endif
+
+static struct sromc_cfg msm_edpram_cfg = {
+ .attr = (MEM_DATA_BUS_16BIT | MEM_WAIT_EN | MEM_BYTE_EN),
+ .size = MSM_EDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg msm_edpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ .tacs = 0x2 << 28,
+ .tcos = 0x2 << 24,
+ .tacc = 0x3 << 16,
+ .tcoh = 0x2 << 12,
+ .tcah = 0x2 << 8,
+ .tacp = 0x2 << 4,
+ .pmc = 0x0 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ padding +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 2044 +
+ 2 + 2 + 6128 +
+ 2 + 2 + 2044 +
+ 2 + 2 + 6128 +
+ 16 +
+ 2 +
+ 2
+ = 16384
+*/
+
+#define MSM_DP_FMT_TX_BUFF_SZ 2044
+#define MSM_DP_RAW_TX_BUFF_SZ 6128
+#define MSM_DP_FMT_RX_BUFF_SZ 2044
+#define MSM_DP_RAW_RX_BUFF_SZ 6128
+
+#define MAX_MSM_EDPRAM_IPC_DEV 2 /* FMT, RAW */
+
+struct msm_edpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[MSM_DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[MSM_DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[MSM_DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[MSM_DP_RAW_RX_BUFF_SZ];
+
+ u8 padding[16];
+ u16 mbx_ap2cp;
+ u16 mbx_cp2ap;
+};
+
+struct msm_edpram_boot_map {
+ u8 __iomem *buff;
+ u16 __iomem *frame_size;
+ u16 __iomem *tag;
+ u16 __iomem *count;
+};
+
+static struct dpram_ipc_map msm_ipc_map;
+
+struct _param_nv {
+ unsigned char *addr;
+ unsigned int size;
+ unsigned int count;
+ unsigned int tag;
+};
+
+#if (MSM_EDPRAM_SIZE == 0x4000)
+/*
+------------------
+Buffer : 15KByte
+------------------
+Reserved: 1014Byte
+------------------
+SIZE: 2Byte
+------------------
+TAG: 2Byte
+------------------
+COUNT: 2Byte
+------------------
+AP -> CP Intr : 2Byte
+------------------
+CP -> AP Intr : 2Byte
+------------------
+*/
+#define DP_BOOT_CLEAR_OFFSET 4
+#define DP_BOOT_RSRVD_OFFSET 0x3C00
+#define DP_BOOT_SIZE_OFFSET 0x3FF6
+#define DP_BOOT_TAG_OFFSET 0x3FF8
+#define DP_BOOT_COUNT_OFFSET 0x3FFA
+
+#define DP_BOOT_FRAME_SIZE_LIMIT 0x3C00 /* 15KB = 15360byte = 0x3C00 */
+#else
+/*
+------------------
+Buffer : 31KByte
+------------------
+Reserved: 1014Byte
+------------------
+SIZE: 2Byte
+------------------
+TAG: 2Byte
+------------------
+COUNT: 2Byte
+------------------
+AP -> CP Intr : 2Byte
+------------------
+CP -> AP Intr : 2Byte
+------------------
+*/
+#define DP_BOOT_CLEAR_OFFSET 4
+#define DP_BOOT_RSRVD_OFFSET 0x7C00
+#define DP_BOOT_SIZE_OFFSET 0x7FF6
+#define DP_BOOT_TAG_OFFSET 0x7FF8
+#define DP_BOOT_COUNT_OFFSET 0x7FFA
+
+#define DP_BOOT_FRAME_SIZE_LIMIT 0x7C00 /* 31KB = 31744byte = 0x7C00 */
+#endif
+
+struct _param_check {
+ unsigned int total_size;
+ unsigned int rest_size;
+ unsigned int send_size;
+ unsigned int copy_start;
+ unsigned int copy_complete;
+ unsigned int boot_complete;
+};
+
+static struct _param_nv *data_param;
+static struct _param_check check_param;
+
+static unsigned int boot_start_complete;
+static struct msm_edpram_boot_map msm_edpram_bt_map;
+static struct dpram_ipc_map msm_ipc_map;
+
+static unsigned char *img;
+static unsigned char *nv_img;
+
+static void msm_edpram_reset(void);
+static void msm_edpram_clr_intr(void);
+static u16 msm_edpram_recv_intr(void);
+static void msm_edpram_send_intr(u16 irq_mask);
+static u16 msm_edpram_recv_msg(void);
+static void msm_edpram_send_msg(u16 msg);
+
+static u16 msm_edpram_get_magic(void);
+static void msm_edpram_set_magic(u16 value);
+static u16 msm_edpram_get_access(void);
+static void msm_edpram_set_access(u16 value);
+
+static u32 msm_edpram_get_tx_head(int dev_id);
+static u32 msm_edpram_get_tx_tail(int dev_id);
+static void msm_edpram_set_tx_head(int dev_id, u32 head);
+static void msm_edpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *msm_edpram_get_tx_buff(int dev_id);
+static u32 msm_edpram_get_tx_buff_size(int dev_id);
+
+static u32 msm_edpram_get_rx_head(int dev_id);
+static u32 msm_edpram_get_rx_tail(int dev_id);
+static void msm_edpram_set_rx_head(int dev_id, u32 head);
+static void msm_edpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *msm_edpram_get_rx_buff(int dev_id);
+static u32 msm_edpram_get_rx_buff_size(int dev_id);
+
+static u16 msm_edpram_get_mask_req_ack(int dev_id);
+static u16 msm_edpram_get_mask_res_ack(int dev_id);
+static u16 msm_edpram_get_mask_send(int dev_id);
+
+static void msm_log_disp(struct modemlink_dpram_control *dpctl);
+static int msm_uload_step1(struct modemlink_dpram_control *dpctl);
+static int msm_uload_step2(void *arg, struct modemlink_dpram_control *dpctl);
+static int msm_dload_prep(struct modemlink_dpram_control *dpctl);
+static int msm_dload(void *arg, struct modemlink_dpram_control *dpctl);
+static int msm_nv_load(void *arg, struct modemlink_dpram_control *dpctl);
+static int msm_boot_start(struct modemlink_dpram_control *dpctl);
+static int msm_boot_start_post_proc(void);
+static void msm_boot_start_handler(struct modemlink_dpram_control *dpctl);
+static void msm_dload_handler(struct modemlink_dpram_control *dpctl, u16 cmd);
+static void msm_bt_map_init(struct modemlink_dpram_control *dpctl);
+static void msm_load_init(struct modemlink_dpram_control *dpctl);
+static void msm_terminate_link(struct modemlink_dpram_control *dpctl);
+
+static struct modemlink_dpram_control msm_edpram_ctrl = {
+ .reset = msm_edpram_reset,
+
+ .clear_intr = msm_edpram_clr_intr,
+ .recv_intr = msm_edpram_recv_intr,
+ .send_intr = msm_edpram_send_intr,
+ .recv_msg = msm_edpram_recv_msg,
+ .send_msg = msm_edpram_send_msg,
+
+ .get_magic = msm_edpram_get_magic,
+ .set_magic = msm_edpram_set_magic,
+ .get_access = msm_edpram_get_access,
+ .set_access = msm_edpram_set_access,
+
+ .get_tx_head = msm_edpram_get_tx_head,
+ .get_tx_tail = msm_edpram_get_tx_tail,
+ .set_tx_head = msm_edpram_set_tx_head,
+ .set_tx_tail = msm_edpram_set_tx_tail,
+ .get_tx_buff = msm_edpram_get_tx_buff,
+ .get_tx_buff_size = msm_edpram_get_tx_buff_size,
+
+ .get_rx_head = msm_edpram_get_rx_head,
+ .get_rx_tail = msm_edpram_get_rx_tail,
+ .set_rx_head = msm_edpram_set_rx_head,
+ .set_rx_tail = msm_edpram_set_rx_tail,
+ .get_rx_buff = msm_edpram_get_rx_buff,
+ .get_rx_buff_size = msm_edpram_get_rx_buff_size,
+
+ .get_mask_req_ack = msm_edpram_get_mask_req_ack,
+ .get_mask_res_ack = msm_edpram_get_mask_res_ack,
+ .get_mask_send = msm_edpram_get_mask_send,
+
+ .log_disp = msm_log_disp,
+ .cpupload_step1 = msm_uload_step1,
+ .cpupload_step2 = msm_uload_step2,
+ .cpimage_load = msm_dload,
+ .nvdata_load = msm_nv_load,
+ .phone_boot_start = msm_boot_start,
+ .dload_cmd_hdlr = msm_dload_handler,
+ .bt_map_init = msm_bt_map_init,
+ .load_init = msm_load_init,
+ .cpimage_load_prepare = msm_dload_prep,
+ .phone_boot_start_post_process = msm_boot_start_post_proc,
+ .phone_boot_start_handler = msm_boot_start_handler,
+ .terminate_link = msm_terminate_link,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = EXT_DPRAM,
+
+ .dpram_irq = MSM_DPRAM_INT_IRQ,
+ .dpram_irq_flags = IRQF_TRIGGER_FALLING,
+ .dpram_irq_name = "MDM6600_EDPRAM_IRQ",
+ .dpram_wlock_name = "MDM6600_EDPRAM_WLOCK",
+
+ .max_ipc_dev = IPC_RFS,
+};
+
+/*
+** CDMA target platform data
+*/
+static struct modem_io_t cdma_io_devices[] = {
+ [0] = {
+ .name = "cdma_boot0",
+ .id = 0x1,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "cdma_ramdump0",
+ .id = 0x1,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "umts_ipc0",
+ .id = 0x01,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "cdma_ipc0",
+ .id = 0x00,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [4] = {
+ .name = "multi_pdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [5] = {
+ .name = "cdma_CSD",
+ .id = (1 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [6] = {
+ .name = "cdma_FOTA",
+ .id = (2 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [7] = {
+ .name = "cdma_GPS",
+ .id = (5 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [8] = {
+ .name = "cdma_XTRA",
+ .id = (6 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "cdma_CDMA",
+ .id = (7 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "cdma_EFS",
+ .id = (8 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "cdma_TRFB",
+ .id = (9 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [15] = {
+ .name = "rmnet3",
+ .id = 0x2D,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [16] = {
+ .name = "cdma_SMD",
+ .id = (25 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [17] = {
+ .name = "cdma_VTVD",
+ .id = (26 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [18] = {
+ .name = "cdma_VTAD",
+ .id = (27 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [19] = {
+ .name = "cdma_VTCTRL",
+ .id = (28 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [20] = {
+ .name = "cdma_VTENT",
+ .id = (29 | 0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+};
+
+static struct modem_data cdma_modem_data = {
+ .name = "mdm6600",
+
+ .gpio_cp_on = GPIO_CP_MSM_PWRON,
+ .gpio_cp_off = 0,
+ .gpio_reset_req_n = GPIO_CP_MSM_PMU_RST,
+ .gpio_cp_reset = GPIO_CP_MSM_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_MSM_PHONE_ACTIVE,
+ .gpio_flm_uart_sel = GPIO_BOOT_SW_SEL,
+#if 1
+ .gpio_flm_uart_sel_rev06 = GPIO_BOOT_SW_SEL_REV06,
+#endif
+
+ .gpio_dpram_int = GPIO_MSM_DPRAM_INT,
+ .gpio_host_wakeup = GPIO_IPC_HOST_WAKEUP,
+
+ .gpio_cp_dump_int = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .use_handover = false,
+
+ .modem_net = CDMA_NETWORK,
+ .modem_type = QC_MDM6600,
+ .link_types = LINKTYPE(LINKDEV_DPRAM),
+ .link_name = "mdm6600_edpram",
+ .dpram_ctl = &msm_edpram_ctrl,
+
+ .ipc_version = SIPC_VER_42,
+
+ .num_iodevs = ARRAY_SIZE(cdma_io_devices),
+ .iodevs = cdma_io_devices,
+};
+
+static struct resource cdma_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = MSM_PHONE_ACTIVE_IRQ,
+ .end = MSM_PHONE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cdma_modem = {
+ .name = "modem_if",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cdma_modem_res),
+ .resource = cdma_modem_res,
+ .dev = {
+ .platform_data = &cdma_modem_data,
+ },
+};
+
+static void msm_edpram_reset(void)
+{
+ return;
+}
+
+static void msm_edpram_clr_intr(void)
+{
+ ioread16(msm_ipc_map.mbx_cp2ap);
+}
+
+static u16 msm_edpram_recv_intr(void)
+{
+ return ioread16(msm_ipc_map.mbx_cp2ap);
+}
+
+static void msm_edpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, msm_ipc_map.mbx_ap2cp);
+}
+
+static u16 msm_edpram_recv_msg(void)
+{
+ return ioread16(msm_ipc_map.mbx_cp2ap);
+}
+
+static void msm_edpram_send_msg(u16 msg)
+{
+ iowrite16(msg, msm_ipc_map.mbx_ap2cp);
+}
+
+static u16 msm_edpram_get_magic(void)
+{
+ return ioread16(msm_ipc_map.magic);
+}
+
+static void msm_edpram_set_magic(u16 value)
+{
+ iowrite16(value, msm_ipc_map.magic);
+}
+
+static u16 msm_edpram_get_access(void)
+{
+ return ioread16(msm_ipc_map.access);
+}
+
+static void msm_edpram_set_access(u16 value)
+{
+ iowrite16(value, msm_ipc_map.access);
+}
+
+static u32 msm_edpram_get_tx_head(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 msm_edpram_get_tx_tail(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void msm_edpram_set_tx_head(int dev_id, u32 head)
+{
+ iowrite16((u16) head, msm_ipc_map.dev[dev_id].txq.head);
+}
+
+static void msm_edpram_set_tx_tail(int dev_id, u32 tail)
+{
+ iowrite16((u16) tail, msm_ipc_map.dev[dev_id].txq.tail);
+}
+
+static u8 __iomem *msm_edpram_get_tx_buff(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 msm_edpram_get_tx_buff_size(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 msm_edpram_get_rx_head(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 msm_edpram_get_rx_tail(int dev_id)
+{
+ return ioread16(msm_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void msm_edpram_set_rx_head(int dev_id, u32 head)
+{
+ return iowrite16((u16) head, msm_ipc_map.dev[dev_id].rxq.head);
+}
+
+static void msm_edpram_set_rx_tail(int dev_id, u32 tail)
+{
+ return iowrite16((u16) tail, msm_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static u8 __iomem *msm_edpram_get_rx_buff(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 msm_edpram_get_rx_buff_size(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 msm_edpram_get_mask_req_ack(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 msm_edpram_get_mask_res_ack(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 msm_edpram_get_mask_send(int dev_id)
+{
+ return msm_ipc_map.dev[dev_id].mask_send;
+}
+
+static void msm_log_disp(struct modemlink_dpram_control *dpctl)
+{
+ static unsigned char buf[151];
+ u8 __iomem *tmp_buff = NULL;
+
+ tmp_buff = dpctl->get_rx_buff(IPC_FMT);
+ memcpy(buf, tmp_buff, (sizeof(buf) - 1));
+
+ pr_info("[LNK] | PHONE ERR MSG\t| CDMA Crash\n");
+ pr_info("[LNK] | PHONE ERR MSG\t| %s\n", buf);
+}
+
+static int msm_data_upload(struct _param_nv *param,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ u16 in_interrupt = 0;
+ int count = 0;
+
+ while (1) {
+ if (!gpio_get_value(GPIO_MSM_DPRAM_INT)) {
+ in_interrupt = dpctl->recv_msg();
+ if (in_interrupt == 0xDBAB) {
+ break;
+ } else {
+ pr_err("[LNK][intr]:0x%08x\n", in_interrupt);
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+ msleep_interruptible(1);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ param->size = ioread16(msm_edpram_bt_map.frame_size);
+ memcpy(param->addr, msm_edpram_bt_map.buff, param->size);
+ param->tag = ioread16(msm_edpram_bt_map.tag);
+ param->count = ioread16(msm_edpram_bt_map.count);
+
+ dpctl->clear_intr();
+ dpctl->send_msg(0xDB12);
+
+ return retval;
+
+}
+
+static int msm_data_load(struct _param_nv *param,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+
+ if (param->size <= DP_BOOT_FRAME_SIZE_LIMIT) {
+ memcpy(msm_edpram_bt_map.buff, param->addr, param->size);
+ iowrite16(param->size, msm_edpram_bt_map.frame_size);
+ iowrite16(param->tag, msm_edpram_bt_map.tag);
+ iowrite16(param->count, msm_edpram_bt_map.count);
+
+ dpctl->clear_intr();
+ dpctl->send_msg(0xDB12);
+
+ } else {
+ pr_err("[LNK/E]<%s> size:0x%x\n", __func__, param->size);
+ }
+
+ return retval;
+}
+
+static int msm_uload_step1(struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ u16 in_interrupt = 0, out_interrupt = 0;
+
+ pr_info("[LNK] +---------------------------------------------+\n");
+ pr_info("[LNK] | UPLOAD PHONE SDRAM |\n");
+ pr_info("[LNK] +---------------------------------------------+\n");
+
+ while (1) {
+ if (!gpio_get_value(GPIO_MSM_DPRAM_INT)) {
+ in_interrupt = dpctl->recv_msg();
+ pr_info("[LNK] [in_interrupt] 0x%04x\n", in_interrupt);
+ if (in_interrupt == 0x1234) {
+ break;
+ } else {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+ msleep_interruptible(1);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ in_interrupt = dpctl->recv_msg();
+ if (in_interrupt == 0x1234) {
+ pr_info("[LNK] [in_interrupt]: 0x%04x\n",
+ in_interrupt);
+ break;
+ }
+ return -1;
+ }
+ }
+ out_interrupt = 0xDEAD;
+ dpctl->send_msg(out_interrupt);
+
+ return retval;
+}
+
+static int msm_uload_step2(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ retval = msm_data_upload(&param, dpctl);
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ if (!(param.count % 500))
+ pr_info("[LNK] [param->count]:%d\n", param.count);
+
+ if (param.tag == 4) {
+ dpctl->clear_intr();
+ enable_irq(msm_edpram_ctrl.dpram_irq);
+ pr_info("[LNK] [param->tag]:%d\n", param.tag);
+ }
+
+ retval = copy_to_user((unsigned long *)arg, &param, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ return retval;
+}
+
+static int msm_dload_prep(struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+
+ while (1) {
+ if (check_param.copy_start) {
+ check_param.copy_start = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return retval;
+}
+
+static int msm_dload(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ img = vmalloc(param.size);
+ if (img == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ memset(img, 0, param.size);
+ memcpy(img, param.addr, param.size);
+
+ data_param = kzalloc(sizeof(struct _param_nv), GFP_KERNEL);
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ img = NULL;
+ return -1;
+ }
+
+ check_param.total_size = param.size;
+ check_param.rest_size = param.size;
+ check_param.send_size = 0;
+ check_param.copy_complete = 0;
+
+ data_param->addr = img;
+ data_param->size = DP_BOOT_FRAME_SIZE_LIMIT;
+ data_param->count = param.count;
+
+ data_param->tag = 0x0001;
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ retval = msm_data_load(data_param, dpctl);
+
+ while (1) {
+ if (check_param.copy_complete) {
+ check_param.copy_complete = 0;
+
+ vfree(img);
+ img = NULL;
+ kfree(data_param);
+ data_param = NULL;
+
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 1000) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ img = NULL;
+ kfree(data_param);
+ data_param = NULL;
+ return -1;
+ }
+ }
+
+ return retval;
+
+}
+
+static int msm_nv_load(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ nv_img = vmalloc(param.size);
+ if (nv_img == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ memset(nv_img, 0, param.size);
+ memcpy(nv_img, param.addr, param.size);
+
+ data_param = kzalloc(sizeof(struct _param_nv), GFP_KERNEL);
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(nv_img);
+ nv_img = NULL;
+ return -1;
+ }
+
+ check_param.total_size = param.size;
+ check_param.rest_size = param.size;
+ check_param.send_size = 0;
+ check_param.copy_complete = 0;
+
+ data_param->addr = nv_img;
+ data_param->size = DP_BOOT_FRAME_SIZE_LIMIT;
+ data_param->count = 1;
+ data_param->tag = 0x0002;
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ retval = msm_data_load(data_param, dpctl);
+
+ while (1) {
+ if (check_param.copy_complete) {
+ check_param.copy_complete = 0;
+
+ vfree(nv_img);
+ nv_img = NULL;
+ kfree(data_param);
+ data_param = NULL;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(nv_img);
+ nv_img = NULL;
+ kfree(data_param);
+ data_param = NULL;
+ return -1;
+ }
+ }
+
+ return retval;
+
+}
+
+static int msm_boot_start(struct modemlink_dpram_control *dpctl)
+{
+
+ u16 out_interrupt = 0;
+ int count = 0;
+
+ /* Send interrupt -> '0x4567' */
+ out_interrupt = 0x4567;
+ dpctl->send_msg(out_interrupt);
+
+ while (1) {
+ if (check_param.boot_complete) {
+ check_param.boot_complete = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static void msm_terminate_link(struct modemlink_dpram_control *dpctl)
+{
+ pr_info("[LNK] +--------------msm_terminate_link------------+\n");
+ if (img != NULL) {
+ pr_info("[LNK] +--------------img free----------------+\n");
+ vfree(img);
+ img = NULL;
+ }
+ if (nv_img != NULL) {
+ pr_info("[LNK] +--------------nv_img free----------------+\n");
+ vfree(nv_img);
+ nv_img = NULL;
+ }
+ if (data_param != NULL) {
+ pr_info("[LNK] +--------------data_param free----------------+\n");
+ kfree(data_param);
+ data_param = NULL;
+ }
+
+}
+
+static struct modemlink_dpram_control *tasklet_dpctl;
+
+static void interruptable_load_tasklet_handler(unsigned long data);
+
+static DECLARE_TASKLET(interruptable_load_tasklet,
+ interruptable_load_tasklet_handler,
+ (unsigned long)&tasklet_dpctl);
+
+static void interruptable_load_tasklet_handler(unsigned long data)
+{
+ struct modemlink_dpram_control *dpctl =
+ (struct modemlink_dpram_control *)
+ (*((struct modemlink_dpram_control **)data));
+
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return;
+ }
+
+ check_param.send_size += data_param->size;
+ check_param.rest_size -= data_param->size;
+ data_param->addr += data_param->size;
+
+ if (check_param.send_size < check_param.total_size) {
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ data_param->count += 1;
+
+ msm_data_load(data_param, dpctl);
+ } else {
+ data_param->tag = 0;
+ check_param.copy_complete = 1;
+ }
+
+}
+
+static int msm_boot_start_post_proc(void)
+{
+ int count = 0;
+
+ while (1) {
+ if (boot_start_complete) {
+ boot_start_complete = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void msm_boot_start_handler(struct modemlink_dpram_control *dpctl)
+{
+ boot_start_complete = 1;
+
+ /* Send INIT_END code to CP */
+ pr_info("[LNK] <%s> Send 0x11C2 (INIT_END)\n", __func__);
+
+ /*
+ * INT_MASK_VALID|INT_MASK_CMD|INT_MASK_CP_AIRPLANE_BOOT|
+ * INT_MASK_CP_AP_ANDROID|INT_MASK_CMD_INIT_END
+ */
+ dpctl->send_intr((0x0080 | 0x0040 | 0x1000 | 0x0100 | 0x0002));
+}
+
+static void msm_dload_handler(struct modemlink_dpram_control *dpctl, u16 cmd)
+{
+ switch (cmd) {
+ case 0x1234:
+ check_param.copy_start = 1;
+ break;
+
+ case 0xDBAB:
+ tasklet_schedule(&interruptable_load_tasklet);
+ break;
+
+ case 0xABCD:
+ check_param.boot_complete = 1;
+ break;
+
+ default:
+ pr_err("[LNK/Err] <%s> Unknown command.. %x\n", __func__, cmd);
+ }
+}
+
+static void msm_bt_map_init(struct modemlink_dpram_control *dpctl)
+{
+ msm_edpram_bt_map.buff = (u8 *) (dpctl->dp_base);
+ msm_edpram_bt_map.frame_size =
+ (u16 *) (dpctl->dp_base + DP_BOOT_SIZE_OFFSET);
+ msm_edpram_bt_map.tag = (u16 *) (dpctl->dp_base + DP_BOOT_TAG_OFFSET);
+ msm_edpram_bt_map.count =
+ (u16 *) (dpctl->dp_base + DP_BOOT_COUNT_OFFSET);
+}
+
+static void msm_load_init(struct modemlink_dpram_control *dpctl)
+{
+ tasklet_dpctl = dpctl;
+ if (tasklet_dpctl == NULL)
+ pr_err("[LNK/Err] failed tasklet_dpctl remap\n");
+
+ check_param.total_size = 0;
+ check_param.rest_size = 0;
+ check_param.send_size = 0;
+ check_param.copy_start = 0;
+ check_param.copy_complete = 0;
+ check_param.boot_complete = 0;
+
+ dpctl->clear_intr();
+}
+
+static irqreturn_t host_wakeup_isr(int irq, void *dev)
+{
+ pr_err("[MODEMS] <%s>\n", __func__);
+
+ return IRQ_HANDLED;
+}
+
+static void config_cdma_modem_gpio(void)
+{
+ int err;
+ unsigned gpio_cp_on = cdma_modem_data.gpio_cp_on;
+ unsigned gpio_cp_off = cdma_modem_data.gpio_cp_off;
+ unsigned gpio_rst_req_n = cdma_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_rst = cdma_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = cdma_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = cdma_modem_data.gpio_phone_active;
+ unsigned gpio_flm_uart_sel = cdma_modem_data.gpio_flm_uart_sel;
+#if 1
+ unsigned gpio_flm_uart_sel_rev06 =
+ cdma_modem_data.gpio_flm_uart_sel_rev06;
+#endif
+ unsigned gpio_dpram_int = cdma_modem_data.gpio_dpram_int;
+ unsigned gpio_host_wakeup = cdma_modem_data.gpio_host_wakeup;
+
+ pr_info("[MODEMS] <%s>\n", __func__);
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "PDA_ACTIVE");
+ } else {
+ gpio_direction_output(gpio_pda_active, 1);
+ s3c_gpio_setpull(gpio_pda_active, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_pda_active, 0);
+ }
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "MSM_ACTIVE");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_ACTIVE");
+ } else {
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_phone_active, IRQ_TYPE_EDGE_BOTH);
+ }
+ }
+
+ if (system_rev < 11) {
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "BOOT_SW_SEL");
+ if (err) {
+ pr_err("fail request gpio %s\n", "BOOT_SW_SEL");
+ } else {
+ gpio_direction_output(gpio_flm_uart_sel, 1);
+ s3c_gpio_setpull(gpio_flm_uart_sel,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_flm_uart_sel, 1);
+ }
+ }
+ } else if (system_rev == 11) {
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "BOOT_SW_SEL");
+ if (err) {
+ pr_err("fail request gpio %s\n", "BOOT_SW_SEL");
+ } else {
+ gpio_direction_output(gpio_flm_uart_sel, 1);
+ s3c_gpio_setpull(gpio_flm_uart_sel,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_flm_uart_sel, 1);
+ }
+ }
+ if (gpio_flm_uart_sel_rev06) {
+ err = gpio_request(gpio_flm_uart_sel_rev06,
+ "BOOT_SW_SEL_REV06");
+ if (err) {
+ pr_err("fail request gpio %s\n",
+ "BOOT_SW_SEL_REV06");
+ } else {
+ gpio_direction_output(gpio_flm_uart_sel_rev06,
+ 1);
+ s3c_gpio_setpull(gpio_flm_uart_sel_rev06,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_flm_uart_sel_rev06, 1);
+ }
+ }
+ } else {
+ err =
+ gpio_request(gpio_flm_uart_sel_rev06, "BOOT_SW_SEL_REV06");
+ if (err) {
+ pr_err("fail request gpio %s\n", "BOOT_SW_SEL_REV06");
+ } else {
+ gpio_direction_output(gpio_flm_uart_sel_rev06, 1);
+ s3c_gpio_setpull(gpio_flm_uart_sel_rev06,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_flm_uart_sel_rev06, 1);
+ }
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "MSM_ON");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_ON");
+ } else {
+ gpio_direction_output(gpio_cp_on, 1);
+ s3c_gpio_setpull(gpio_cp_on, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_cp_on, 0);
+ }
+ }
+
+ if (gpio_cp_off) {
+ err = gpio_request(gpio_cp_off, "MSM_OFF");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_OFF");
+ } else {
+ gpio_direction_output(gpio_cp_off, 1);
+ s3c_gpio_setpull(gpio_cp_off, S3C_GPIO_PULL_NONE);
+ gpio_set_value(gpio_cp_off, 1);
+ }
+ }
+
+ if (gpio_rst_req_n) {
+ err = gpio_request(gpio_rst_req_n, "MSM_RST_REQ");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_RST_REQ");
+ } else {
+ gpio_direction_output(gpio_rst_req_n, 1);
+ s3c_gpio_setpull(gpio_rst_req_n, S3C_GPIO_PULL_NONE);
+ }
+ gpio_set_value(gpio_rst_req_n, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "MSM_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_RST");
+ } else {
+ gpio_direction_output(gpio_cp_rst, 1);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+ gpio_set_value(gpio_cp_rst, 0);
+ }
+
+ if (gpio_dpram_int) {
+ err = gpio_request(gpio_dpram_int, "MSM_DPRAM_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_DPRAM_INT");
+ } else {
+ /* Configure as a wake-up source */
+ s3c_gpio_cfgpin(gpio_dpram_int, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_dpram_int, S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ if (gpio_host_wakeup) {
+ err = gpio_request(gpio_host_wakeup, "MSM_HOST_WAKEUP");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "MSM_HOST_WAKEUP");
+ } else {
+ /* Configure as a wake-up source */
+ s3c_gpio_cfgpin(gpio_host_wakeup, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_host_wakeup, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_to_irq(gpio_host_wakeup),
+ IRQ_TYPE_LEVEL_HIGH);
+ }
+ }
+}
+
+static u8 *msm_edpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = 0;
+ int dp_size = 0;
+ u8 __iomem *dp_base = NULL;
+ struct msm_edpram_ipc_cfg *ipc_map = NULL;
+ struct dpram_ipc_device *dev = NULL;
+
+ dp_addr = cfg->addr;
+ dp_size = cfg->size;
+ dp_base = (u8 *) ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ pr_err("[MDM] <%s> dpram base ioremap fail\n", __func__);
+ return NULL;
+ }
+ pr_info("[MDM] <%s> DPRAM VA=0x%08X\n", __func__, (int)dp_base);
+
+ msm_edpram_ctrl.dp_base = (u8 __iomem *) dp_base;
+ msm_edpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct msm_edpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ msm_ipc_map.magic = (u16 __iomem *) &ipc_map->magic;
+ msm_ipc_map.access = (u16 __iomem *) &ipc_map->access;
+
+ /* FMT */
+ dev = &msm_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *) &ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *) &ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *) &ipc_map->fmt_tx_buff[0];
+ dev->txq.size = MSM_DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *) &ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *) &ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *) &ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = MSM_DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &msm_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *) &ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *) &ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *) &ipc_map->raw_tx_buff[0];
+ dev->txq.size = MSM_DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *) &ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *) &ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *) &ipc_map->raw_rx_buff[0];
+ dev->rxq.size = MSM_DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+#if 0
+ /* RFS */
+ dev = &msm_ipc_map.dev[IPC_RFS];
+
+ strcpy(dev->name, "RFS");
+ dev->id = IPC_RFS;
+
+ dev->txq.head = (u16 __iomem *) &ipc_map->rfs_tx_head;
+ dev->txq.tail = (u16 __iomem *) &ipc_map->rfs_tx_tail;
+ dev->txq.buff = (u8 __iomem *) &ipc_map->rfs_tx_buff[0];
+ dev->txq.size = MSM_DP_RFS_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *) &ipc_map->rfs_rx_head;
+ dev->rxq.tail = (u16 __iomem *) &ipc_map->rfs_rx_tail;
+ dev->rxq.buff = (u8 __iomem *) &ipc_map->rfs_rx_buff[0];
+ dev->rxq.size = MSM_DP_RFS_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_RFS;
+ dev->mask_res_ack = INT_MASK_RES_ACK_RFS;
+ dev->mask_send = INT_MASK_SEND_RFS;
+#endif
+
+ /* Mailboxes */
+ msm_ipc_map.mbx_ap2cp = (u16 __iomem *) &ipc_map->mbx_ap2cp;
+ msm_ipc_map.mbx_cp2ap = (u16 __iomem *) &ipc_map->mbx_cp2ap;
+
+ return dp_base;
+}
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ pr_info("[MDM] <%s> address line = %d bits\n", __func__, addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for dpram address */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY3(0), EXYNOS4_GPIO_Y3_NR,
+ S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY4(0),
+ addr_bits - EXYNOS4_GPIO_Y3_NR,
+ S3C_GPIO_SFN(2));
+ pr_info("[MDM] <%s> last data gpio EXYNOS4_GPY4(0) ~ %d\n",
+ __func__, addr_bits - EXYNOS4_GPIO_Y3_NR);
+ break;
+
+ default:
+ pr_err("[MDM/E] <%s> Invalid addr_bits!!!\n", __func__);
+ return;
+ }
+
+ /* Set GPIO for dpram data - 16bit */
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY5(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY6(0), 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgrange_nopull(GPIO_DPRAM_REN, 2, S3C_GPIO_SFN(2));
+
+ /* Config LBn, UBn */
+ s3c_gpio_cfgrange_nopull(GPIO_DPRAM_LBN, 2, S3C_GPIO_SFN(2));
+
+ /* Config BUSY */
+ s3c_gpio_cfgpin(GPIO_DPRAM_BUSY, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ pr_err("[MDM/E] <%s> SROMC clock gate fail\n", __func__);
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(unsigned csn, struct sromc_cfg *cfg, struct sromc_access_cfg *acc_cfg) {
+ unsigned bw = 0;
+ unsigned bc = 0;
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ pr_err("[MDM] <%s> SROMC settings for CS%d...\n", __func__, csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> Old SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn * 4));
+
+ if (cfg->attr | MEM_DATA_BUS_16BIT)
+ bw |= (SROMC_DATA_16 << (csn * 4));
+
+ if (cfg->attr | MEM_WAIT_EN)
+ bw |= (SROMC_WAIT_EN << (csn * 4));
+
+ if (cfg->attr | MEM_BYTE_EN)
+ bw |= (SROMC_BYTE_EN << (csn * 4));
+
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> New SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+}
+
+static void setup_dpram_speed(unsigned csn, struct sromc_access_cfg *acc_cfg)
+{
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+ unsigned bc = 0;
+
+ bc = __raw_readl(bank_sfr);
+ pr_info("[MDM] <%s> Old CS%d setting = 0x%08X\n", __func__, csn, bc);
+
+ /* SROMC memory access timing setting */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+ writel(bc, bank_sfr);
+
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> New CS%d setting = 0x%08X\n", __func__, csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ msm_edpram_cfg.csn = 0;
+ msm_edpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * msm_edpram_cfg.csn);
+ msm_edpram_cfg.end = msm_edpram_cfg.addr + msm_edpram_cfg.size - 1;
+
+ config_dpram_port_gpio();
+ config_cdma_modem_gpio();
+
+ init_sromc();
+ cfg = &msm_edpram_cfg;
+ acc_cfg = &msm_edpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!msm_edpram_remap_mem_region(&msm_edpram_cfg))
+ return -1;
+ platform_device_register(&cdma_modem);
+
+ return 0;
+}
+
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
+
+#ifdef CONFIG_USBHUB_USB3503
+static int (*usbhub_set_mode) (struct usb3503_hubctl *, int);
+static struct usb3503_hubctl *usbhub_ctl;
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+}
+
+static int usb3503_hub_handler(void (*set_mode) (void), void *ctl)
+{
+ if (!set_mode || !ctl)
+ return -EINVAL;
+
+ usbhub_set_mode = (int (*)(struct usb3503_hubctl *, int))set_mode;
+ usbhub_ctl = (struct usb3503_hubctl *)ctl;
+
+ pr_info("[MDM] <%s> set_mode(%pF)\n", __func__, set_mode);
+
+ return 0;
+}
+
+static int usb3503_hw_config(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_USB_HUB_CONNECT, "HUB_CONNECT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_CONNECT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_CONNECT, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_CONNECT, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_CONNECT, S5P_GPIO_DRVSTR_LV1);
+
+ if (system_rev < 11) {
+ err = gpio_request(GPIO_USB_BOOT_EN, "USB_BOOT_EN");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "USB_BOOT_EN");
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
+ }
+ } else if (system_rev == 11) {
+ err = gpio_request(GPIO_USB_BOOT_EN, "USB_BOOT_EN");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "USB_BOOT_EN");
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_USB_BOOT_EN_REV06, "USB_BOOT_EN_REV06");
+ if (err) {
+ pr_err("fail to request gpio %s\n",
+ "USB_BOOT_EN_REV06");
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06,
+ S3C_GPIO_PULL_NONE);
+ }
+ } else {
+ err = gpio_request(GPIO_USB_BOOT_EN_REV06, "USB_BOOT_EN_REV06");
+ if (err) {
+ pr_err("fail to request gpio %s\n",
+ "USB_BOOT_EN_REV06");
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06,
+ S3C_GPIO_PULL_NONE);
+ }
+ }
+
+ msleep(100);
+
+ err = gpio_request(GPIO_USB_HUB_RST, "HUB_RST");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_RST");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_RST, 0);
+ s3c_gpio_setpull(GPIO_USB_HUB_RST, S3C_GPIO_PULL_NONE);
+ }
+ s5p_gpio_set_drvstr(GPIO_USB_HUB_RST, S5P_GPIO_DRVSTR_LV1);
+ /* need to check drvstr 1 or 2 */
+
+ /* for USB3503 26Mhz Reference clock setting */
+ err = gpio_request(GPIO_USB_HUB_INT, "HUB_INT");
+ if (err) {
+ pr_err("fail to request gpio %s\n", "HUB_INT");
+ } else {
+ gpio_direction_output(GPIO_USB_HUB_INT, 1);
+ s3c_gpio_setpull(GPIO_USB_HUB_INT, S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static int usb3503_reset_n(int val)
+{
+ gpio_set_value(GPIO_USB_HUB_RST, 0);
+ msleep(20);
+ pr_info("[MDM] <%s> val = %d\n", __func__,
+ gpio_get_value(GPIO_USB_HUB_RST));
+ gpio_set_value(GPIO_USB_HUB_RST, !!val);
+
+ pr_info("[MDM] <%s> val = %d\n", __func__,
+ gpio_get_value(GPIO_USB_HUB_RST));
+
+ udelay(5); /* need it ? */
+ return 0;
+}
+
+static struct usb3503_platform_data usb3503_pdata = {
+ .initial_mode = USB3503_MODE_STANDBY,
+ .reset_n = usb3503_reset_n,
+ .register_hub_handler = usb3503_hub_handler,
+ .port_enable = host_port_enable,
+};
+
+static struct i2c_board_info i2c_devs20_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO(USB3503_I2C_NAME, 0x08),
+ .platform_data = &usb3503_pdata,
+ },
+};
+
+/* I2C20_EMUL */
+static struct i2c_gpio_platform_data i2c20_platdata = {
+ .sda_pin = GPIO_USB_HUB_SDA,
+ .scl_pin = GPIO_USB_HUB_SCL,
+ /*FIXME: need to timming tunning... */
+ .udelay = 20,
+};
+
+static struct platform_device s3c_device_i2c20 = {
+ .name = "i2c-gpio",
+ .id = 20,
+ .dev.platform_data = &i2c20_platdata,
+};
+
+static int __init init_usbhub(void)
+{
+ usb3503_hw_config();
+ i2c_register_board_info(20, i2c_devs20_emul,
+ ARRAY_SIZE(i2c_devs20_emul));
+
+ platform_device_register(&s3c_device_i2c20);
+ return 0;
+}
+
+device_initcall(init_usbhub);
+
+static int host_port_enable(int port, int enable)
+{
+ int err, retry = 30;
+
+ pr_info("[MDM] <%s> port(%d) control(%d)\n", __func__, port, enable);
+
+ if (enable) {
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_HUB);
+ if (err < 0) {
+ pr_err("[MDM] <%s> hub on fail\n", __func__);
+ goto exit;
+ }
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 1);
+ if (err < 0) {
+ pr_err("[MDM] <%s> port(%d) enable fail\n", __func__,
+ port);
+ goto exit;
+ }
+ } else {
+ err = s5p_ehci_port_control(&s5p_device_ehci, port, 0);
+ if (err < 0) {
+ pr_err("[MDM] <%s> port(%d) enable fail\n", __func__,
+ port);
+ goto exit;
+ }
+ err = usbhub_set_mode(usbhub_ctl, USB3503_MODE_STANDBY);
+ if (err < 0) {
+ pr_err("[MDM] <%s> hub off fail\n", __func__);
+ goto exit;
+ }
+
+ gpio_direction_output(GPIO_USB_BOOT_EN, 0);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_BOOT_EN, 0);
+
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ gpio_set_value(GPIO_USB_BOOT_EN, 1);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
+ s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BOOT_SW_SEL, 0);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
+ gpio_set_value(GPIO_BOOT_SW_SEL, 1);
+
+ if (system_rev < 11) {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 0);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_BOOT_EN, 0);
+
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ gpio_set_value(GPIO_USB_BOOT_EN, 1);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
+ s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BOOT_SW_SEL, 0);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
+ gpio_set_value(GPIO_BOOT_SW_SEL, 1);
+ } else if (system_rev == 11) {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 0);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_BOOT_EN, 0);
+
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ gpio_set_value(GPIO_USB_BOOT_EN, 1);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL, 0);
+ s3c_gpio_setpull(GPIO_BOOT_SW_SEL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BOOT_SW_SEL, 0);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL, 1);
+ gpio_set_value(GPIO_BOOT_SW_SEL, 1);
+
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);
+
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
+ gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
+ s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 1);
+ gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 1);
+
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 0);
+ s3c_gpio_setpull(GPIO_USB_BOOT_EN_REV06,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_BOOT_EN_REV06, 0);
+
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
+ gpio_set_value(GPIO_USB_BOOT_EN_REV06, 1);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 0);
+ s3c_gpio_setpull(GPIO_BOOT_SW_SEL_REV06,
+ S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 0);
+
+ gpio_direction_output(GPIO_BOOT_SW_SEL_REV06, 1);
+ gpio_set_value(GPIO_BOOT_SW_SEL_REV06, 1);
+
+ }
+
+ }
+
+ exit:
+ return err;
+}
+#else
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ pr_err(" [MODEM_IF] Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+#endif
diff --git a/arch/arm/mach-exynos/board-midas-modems.c b/arch/arm/mach-exynos/board-midas-modems.c
new file mode 100644
index 0000000..635fbbd
--- /dev/null
+++ b/arch/arm/mach-exynos/board-midas-modems.c
@@ -0,0 +1,250 @@
+/* linux/arch/arm/mach-xxxx/board-midas-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/platform_data/modem.h>
+
+/* umts target platform data */
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_C2C),
+ },
+ [1] = {
+ .name = "umts_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [2] = {
+ .name = "umts_rfs0",
+ .id = 0x41,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [3] = {
+ .name = "multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [4] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [5] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [6] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [7] = {
+ .name = "umts_router",
+ .id = 0x39,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [8] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+};
+
+/* To get modem state, register phone active irq using resource */
+static struct resource umts_modem_res[] = {
+ [0] = {
+ .name = "umts_phone_active",
+ .start = PHONE_ACTIVE_IRQ,
+ .end = PHONE_ACTIVE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int umts_link_ldo_enble(bool enable)
+{
+ /* Exynos HSIC V1.2 LDO was controlled by kernel */
+ return 0;
+}
+
+static struct modemlink_pm_data modem_link_pm_data = {
+ .name = "link_pm",
+ .link_ldo_enable = umts_link_ldo_enble,
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+};
+static struct modemlink_pm_link_activectl active_ctl;
+
+static struct modem_data umts_modem_data = {
+ .name = "xmm6262",
+
+ .gpio_cp_on = CP_ON,
+ .gpio_reset_req_n = CP_RESET_REQ_N,
+ .gpio_cp_reset = CP_PMU_RST_N,
+ .gpio_pda_active = PDA_ACTIVE,
+ .gpio_phone_active = PHONE_ACTIVE,
+ .gpio_cp_dump_int = CP_DUMP_INT,
+ .gpio_flm_uart_sel = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .modem_type = IMC_XMM6262,
+ .link_types = LINKTYPE(LINKDEV_HSIC) | LINKTYPE(LINKDEV_C2C),
+ .modem_net = UMTS_NETWORK,
+ .use_handover = false,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &modem_link_pm_data,
+};
+
+/* HSIC specific function */
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ pr_err(" [MODEM_IF] Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+struct io_list {
+ unsigned num;
+ char *name;
+ unsigned val;
+};
+
+static void umts_modem_cfg_gpio(void)
+{
+ unsigned gpio_reset_req_n = umts_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+
+ if (gpio_reset_req_n) {
+ gpio_request(gpio_reset_req_n, "CP_RST_REQ");
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_cp_on) {
+ gpio_request(gpio_cp_on, "CP_ON");
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ gpio_request(gpio_cp_rst, "CP_RST");
+ gpio_direction_output(gpio_cp_rst, 0);
+ }
+
+ if (gpio_pda_active) {
+ gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ gpio_direction_input(gpio_phone_active);
+ }
+}
+
+static void modem_link_pm_config_gpio(void)
+{
+ int i, err;
+ unsigned gpio_num;
+ struct io_list gpio_list[] = {
+ {modem_link_pm_data.gpio_link_enable, "hsic_en", 1},
+ {modem_link_pm_data.gpio_link_active, "host_active", 0},
+ {modem_link_pm_data.gpio_link_hostwake, "host_wakeup", 0},
+ {modem_link_pm_data.gpio_link_slavewake, "slave_wakeup", 0},
+ };
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+
+ for (i = 0; i < ARRAY_SIZE(gpio_list); i++) {
+ gpio_num = gpio_list[i].num;
+ if (gpio_num) {
+ err = gpio_request(gpio_num, gpio_list[i].name);
+ if (err) {
+ pr_err("request gpio fail %s: %d\n",
+ gpio_list[i].name, err);
+ continue;
+ }
+ gpio_direction_output(gpio_num, gpio_list[i].val);
+ pr_debug("%s gpio cfg done\n", gpio_list[i].name);
+ }
+ }
+
+ if (gpio_link_hostwake)
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQ_TYPE_EDGE_BOTH);
+
+ active_ctl.gpio_initialized = 1;
+ if (active_ctl.gpio_request_host_active) {
+ pr_err(" [MODEM_IF] Active States = 1, %s\n", __func__);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 1);
+ }
+
+ printk(KERN_INFO "modem_link_pm_config_gpio done\n");
+}
+
+static int __init init_modem(void)
+{
+ pr_debug("[BOARD] <%s> Invoked!!!\n", __func__);
+
+ umts_modem_cfg_gpio();
+ modem_link_pm_config_gpio();
+ platform_device_register(&umts_modem);
+
+ return 0;
+}
+late_initcall(init_modem);
diff --git a/arch/arm/mach-exynos/board-midas-wlan.c b/arch/arm/mach-exynos/board-midas-wlan.c
new file mode 100755
index 0000000..5d9a584
--- /dev/null
+++ b/arch/arm/mach-exynos/board-midas-wlan.c
@@ -0,0 +1,326 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/skbuff.h>
+#include <linux/wlan_plat.h>
+
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+
+#define WLAN_STATIC_SCAN_BUF0 5
+#define WLAN_STATIC_SCAN_BUF1 6
+#define PREALLOC_WLAN_SEC_NUM 4
+#define PREALLOC_WLAN_BUF_NUM 160
+#define PREALLOC_WLAN_SECTION_HEADER 24
+
+#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512)
+#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
+
+#define DHD_SKB_HDRSIZE 336
+#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
+
+#define WLAN_SKB_BUF_NUM 17
+
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
+
+struct wlan_mem_prealloc {
+ void *mem_ptr;
+ unsigned long size;
+};
+
+static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
+ {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
+};
+
+void *wlan_static_scan_buf0;
+void *wlan_static_scan_buf1;
+static void *brcm_wlan_mem_prealloc(int section, unsigned long size)
+{
+ if (section == PREALLOC_WLAN_SEC_NUM)
+ return wlan_static_skb;
+ if (section == WLAN_STATIC_SCAN_BUF0)
+ return wlan_static_scan_buf0;
+ if (section == WLAN_STATIC_SCAN_BUF1)
+ return wlan_static_scan_buf1;
+ if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
+ return NULL;
+
+ if (wlan_mem_array[section].size < size)
+ return NULL;
+
+ return wlan_mem_array[section].mem_ptr;
+}
+
+static int brcm_init_wlan_mem(void)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 8; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ for (; i < 16; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+
+ for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) {
+ wlan_mem_array[i].mem_ptr =
+ kmalloc(wlan_mem_array[i].size, GFP_KERNEL);
+
+ if (!wlan_mem_array[i].mem_ptr)
+ goto err_mem_alloc;
+ }
+ wlan_static_scan_buf0 = kmalloc (65536, GFP_KERNEL);
+ if(!wlan_static_scan_buf0)
+ goto err_mem_alloc;
+ wlan_static_scan_buf1 = kmalloc (65536, GFP_KERNEL);
+ if(!wlan_static_scan_buf1)
+ goto err_mem_alloc;
+
+ printk("%s: WIFI MEM Allocated\n", __FUNCTION__);
+ return 0;
+
+ err_mem_alloc:
+ pr_err("Failed to mem_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ kfree(wlan_mem_array[j].mem_ptr);
+
+ i = WLAN_SKB_BUF_NUM;
+
+ err_skb_alloc:
+ pr_err("Failed to skb_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ dev_kfree_skb(wlan_static_skb[j]);
+
+ return -ENOMEM;
+}
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+
+static unsigned int wlan_on_gpio_table[][4] = {
+ {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_HIGH, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_HOST_WAKE, GPIO_WLAN_HOST_WAKE_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int wlan_off_gpio_table[][4] = {
+ {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_HOST_WAKE, 0 , GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int wlan_sdio_on_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, GPIO_WLAN_SDIO_CLK_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, GPIO_WLAN_SDIO_CMD_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, GPIO_WLAN_SDIO_D0_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, GPIO_WLAN_SDIO_D1_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, GPIO_WLAN_SDIO_D2_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, GPIO_WLAN_SDIO_D3_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static unsigned int wlan_sdio_off_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, 1, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static void s3c_config_gpio_alive_table(int array_size, unsigned int (*gpio_table)[4])
+{
+ u32 i, gpio;
+ printk("gpio_table = [%d] \r\n" , array_size);
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+static int brcm_wlan_power(int onoff)
+{
+ printk("------------------------------------------------");
+ printk("------------------------------------------------\n");
+ printk("%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off");
+ pr_info("111%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off");
+ if (onoff) {
+ s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_on_gpio_table), wlan_on_gpio_table);
+ udelay(200);
+ gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_HIGH);
+ printk(KERN_DEBUG "WLAN: GPIO_WLAN_EN = %d \n", gpio_get_value(GPIO_WLAN_EN));
+ } else {
+ gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_LOW);
+ s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_off_gpio_table), wlan_off_gpio_table);
+ printk(KERN_DEBUG "WLAN: GPIO_WLAN_EN = %d \n", gpio_get_value(GPIO_WLAN_EN));
+ }
+
+ return 0;
+}
+
+static int brcm_wlan_reset(int onoff)
+{
+ gpio_set_value(GPIO_WLAN_EN,
+ onoff ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
+ return 0;
+}
+
+static int brcm_wlan_set_carddetect(int onoff)
+{
+ if (onoff)
+ s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_sdio_on_table), wlan_sdio_on_table);
+ else
+ s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_sdio_off_table), wlan_sdio_off_table);
+
+ udelay(200);
+
+ mmc_force_presence_change(&s3c_device_hsmmc3);
+ /* msleep(500); wait for carddetect */
+ return 0;
+}
+
+/* Customized Locale table : OPTIONAL feature */
+#define WLC_CNTRY_BUF_SZ 4
+typedef struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ];
+ char custom_locale[WLC_CNTRY_BUF_SZ];
+ int custom_locale_rev;
+} cntry_locales_custom_t;
+
+static cntry_locales_custom_t brcm_wlan_translate_custom_table[] = {
+ /* Table should be filled out based on custom platform regulatory requirement */
+ {"", "XZ", 11}, /* Universal if Country code is unknown or empty */
+ {"AE", "AE", 1},
+ {"AR", "AR", 1},
+ {"AT", "AT", 1},
+ {"AU", "AU", 2},
+ {"BE", "BE", 1},
+ {"BG", "BG", 1},
+ {"BN", "BN", 1},
+ {"CA", "CA", 2},
+ {"CH", "CH", 1},
+ {"CY", "CY", 1},
+ {"CZ", "CZ", 1},
+ {"DE", "DE", 3},
+ {"DK", "DK", 1},
+ {"EE", "EE", 1},
+ {"ES", "ES", 1},
+ {"FI", "FI", 1},
+ {"FR", "FR", 1},
+ {"GB", "GB", 1},
+ {"GR", "GR", 1},
+ {"HR", "HR", 1},
+ {"HU", "HU", 1},
+ {"IE", "IE", 1},
+ {"IS", "IS", 1},
+ {"IT", "IT", 1},
+ {"JP", "JP", 3},
+ {"KR", "KR", 24},
+ {"KW", "KW", 1},
+ {"LI", "LI", 1},
+ {"LT", "LT", 1},
+ {"LU", "LU", 1},
+ {"LV", "LV", 1},
+ {"MA", "MA", 1},
+ {"MT", "MT", 1},
+ {"MX", "MX", 1},
+ {"NL", "NL", 1},
+ {"NO", "NO", 1},
+ {"PL", "PL", 1},
+ {"PT", "PT", 1},
+ {"PY", "PY", 1},
+ {"RO", "RO", 1},
+ {"RU", "RU", 5},
+ {"SE", "SE", 1},
+ {"SG", "SG", 4},
+ {"SI", "SI", 1},
+ {"SK", "SK", 1},
+ {"TR", "TR", 7},
+ {"TW", "TW", 2},
+ {"US", "US", 46}
+};
+
+static void *brcm_wlan_get_country_code(char *ccode)
+{
+ int size = ARRAY_SIZE(brcm_wlan_translate_custom_table);
+ int i;
+
+ if (!ccode)
+ return NULL;
+
+ for (i = 0; i < size; i++)
+ if (strcmp(ccode, brcm_wlan_translate_custom_table[i].iso_abbrev) == 0)
+ return &brcm_wlan_translate_custom_table[i];
+ return &brcm_wlan_translate_custom_table[0];
+}
+
+static struct resource brcm_wlan_resources[] = {
+ [0] = {
+ .name = "bcmdhd_wlan_irq",
+ .start = IRQ_EINT(21),
+ .end = IRQ_EINT(21),
+//chanyun 12.21 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
+ },
+};
+
+static struct wifi_platform_data brcm_wlan_control = {
+ .set_power = brcm_wlan_power,
+ .set_reset = brcm_wlan_reset,
+ .set_carddetect = brcm_wlan_set_carddetect,
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+ .mem_prealloc = brcm_wlan_mem_prealloc,
+#endif
+ .get_country_code = brcm_wlan_get_country_code,
+};
+
+static struct platform_device brcm_device_wlan = {
+ .name = "bcmdhd_wlan",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(brcm_wlan_resources),
+ .resource = brcm_wlan_resources,
+ .dev = {
+ .platform_data = &brcm_wlan_control,
+ },
+};
+
+int __init brcm_wlan_init(void)
+{
+ int ret;
+ printk("%s: start\n", __FUNCTION__);
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+ brcm_init_wlan_mem();
+#endif
+
+ ret = platform_device_register(&brcm_device_wlan);
+ printk("-----------------------------------------------------\n");
+ printk("-----------------------------------------------------\n");
+ printk("-----------------------------------------------------\n");
+ printk("regist ret:%d\n", ret);
+ return ret;
+
+// return platform_device_register(&brcm_device_wlan);
+}
diff --git a/arch/arm/mach-exynos/board-mobile.h b/arch/arm/mach-exynos/board-mobile.h
new file mode 100644
index 0000000..54384d0
--- /dev/null
+++ b/arch/arm/mach-exynos/board-mobile.h
@@ -0,0 +1,39 @@
+#ifndef __SAMSUNG_MOBILE_BOARD_COMMON_H
+#define __SAMSUNG_MOBILE_BOARD_COMMON_H
+
+/*
+ * Please add the common mobile external declarations
+ */
+extern void midas_camera_init(void);
+
+/* charger-manager */
+extern struct charger_global_desc midas_charger_g_desc;
+extern struct platform_device midas_charger_manager;
+
+/* MAX77693 */
+extern struct max77693_muic_data max77693_muic;
+extern struct max77693_regulator_data max77693_regulators;
+
+/* i2c-gpio(sw) pin configuration */
+#define GPIO_I2C_PIN_SETUP(_bus) { \
+ s3c_gpio_cfgpin(gpio_i2c_##_bus.sda_pin, S3C_GPIO_INPUT); \
+ s3c_gpio_setpull(gpio_i2c_##_bus.sda_pin, S3C_GPIO_PULL_NONE); \
+ s3c_gpio_cfgpin(gpio_i2c_##_bus.scl_pin, S3C_GPIO_INPUT); \
+ s3c_gpio_setpull(gpio_i2c_##_bus.scl_pin, S3C_GPIO_PULL_NONE); \
+}
+
+#ifdef CONFIG_SLP
+extern int __init midas_nfc_init(int i2c_bus);
+
+/* NTC thermistor */
+extern struct platform_device midas_ncp15wb473_thermistor;
+extern int __init adc_ntc_init(int port);
+#endif
+
+/* wifi */
+extern int brcm_wlan_init(void);
+
+/* gps */
+extern void set_gps_uart_op(int onoff);
+
+#endif
diff --git a/arch/arm/mach-exynos/board-p10-wlan.c b/arch/arm/mach-exynos/board-p10-wlan.c
new file mode 100644
index 0000000..de4b352
--- /dev/null
+++ b/arch/arm/mach-exynos/board-p10-wlan.c
@@ -0,0 +1,333 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/skbuff.h>
+#include <linux/wlan_plat.h>
+
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+
+#define WLAN_STATIC_SCAN_BUF0 5
+#define WLAN_STATIC_SCAN_BUF1 6
+#define WLAN_SCAN_BUF_SIZE (64 * 1024)
+#define PREALLOC_WLAN_SEC_NUM 4
+#define PREALLOC_WLAN_BUF_NUM 160
+#define PREALLOC_WLAN_SECTION_HEADER 24
+
+#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512)
+#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
+
+#define DHD_SKB_HDRSIZE 336
+#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
+
+#define WLAN_SKB_BUF_NUM 17
+
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
+
+struct wlan_mem_prealloc {
+ void *mem_ptr;
+ unsigned long size;
+};
+
+static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
+ {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
+};
+
+void *wlan_static_scan_buf0;
+void *wlan_static_scan_buf1;
+
+static void *brcm_wlan_mem_prealloc(int section, unsigned long size)
+{
+ if (section == PREALLOC_WLAN_SEC_NUM)
+ return wlan_static_skb;
+
+ if (section == WLAN_STATIC_SCAN_BUF0)
+ return wlan_static_scan_buf0;
+
+ if (section == WLAN_STATIC_SCAN_BUF1)
+ return wlan_static_scan_buf1;
+
+ if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
+ return NULL;
+
+ if (wlan_mem_array[section].size < size)
+ return NULL;
+
+ return wlan_mem_array[section].mem_ptr;
+}
+
+static int brcm_init_wlan_mem(void)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 8; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ for (; i < 16; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+
+ for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) {
+ wlan_mem_array[i].mem_ptr =
+ kmalloc(wlan_mem_array[i].size, GFP_KERNEL);
+
+ if (!wlan_mem_array[i].mem_ptr)
+ goto err_mem_alloc;
+ }
+
+ wlan_static_scan_buf0 = kmalloc (WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+ if (!wlan_static_scan_buf0)
+ goto err_mem_alloc;
+
+ wlan_static_scan_buf1 = kmalloc (WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+ if (!wlan_static_scan_buf1)
+ goto err_mem_alloc;
+
+ printk(KERN_INFO"%s: WIFI MEM Allocated\n", __func__);
+ return 0;
+
+ err_mem_alloc:
+ pr_err("Failed to mem_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ kfree(wlan_mem_array[j].mem_ptr);
+
+ i = WLAN_SKB_BUF_NUM;
+
+ err_skb_alloc:
+ pr_err("Failed to skb_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ dev_kfree_skb(wlan_static_skb[j]);
+
+ return -ENOMEM;
+}
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+
+static unsigned int wlan_on_gpio_table[][4] = {
+ {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_HIGH, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_HOST_WAKE, GPIO_WLAN_HOST_WAKE_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int wlan_off_gpio_table[][4] = {
+ {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_HOST_WAKE, 0 , GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int wlan_sdio_on_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, GPIO_WLAN_SDIO_CLK_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, GPIO_WLAN_SDIO_CMD_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, GPIO_WLAN_SDIO_D0_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, GPIO_WLAN_SDIO_D1_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, GPIO_WLAN_SDIO_D2_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, GPIO_WLAN_SDIO_D3_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static unsigned int wlan_sdio_off_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, 1, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static void s3c_config_gpio_alive_table
+(int array_size, unsigned int
+(*gpio_table)[4])
+{
+ u32 i, gpio;
+ printk(KERN_INFO"gpio_table = [%d] \r\n" , array_size);
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+static int brcm_wlan_power(int onoff)
+{
+ printk(KERN_INFO"------------------------------------------------");
+ printk(KERN_INFO"------------------------------------------------\n");
+ printk(KERN_INFO"%s Enter: power %s\n", __func__, onoff ? "on" : "off");
+ if (onoff) {
+ s3c_config_gpio_alive_table
+ (ARRAY_SIZE(wlan_on_gpio_table), wlan_on_gpio_table);
+ udelay(200);
+ gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_HIGH);
+ printk(KERN_DEBUG"WLAN: GPIO_WLAN_EN = %d\n",
+ gpio_get_value(GPIO_WLAN_EN));
+ } else {
+ gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_LOW);
+ s3c_config_gpio_alive_table
+ (ARRAY_SIZE(wlan_off_gpio_table), wlan_off_gpio_table);
+ printk(KERN_DEBUG"WLAN: GPIO_WLAN_EN = %d\n",
+ gpio_get_value(GPIO_WLAN_EN));
+ }
+
+ return 0;
+}
+
+static int brcm_wlan_reset(int onoff)
+{
+ gpio_set_value(GPIO_WLAN_EN,
+ onoff ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
+ return 0;
+}
+
+static int brcm_wlan_set_carddetect(int onoff)
+{
+ if (onoff) {
+ s3c_config_gpio_alive_table(
+ARRAY_SIZE(wlan_sdio_on_table), wlan_sdio_on_table);
+ } else {
+ s3c_config_gpio_alive_table(
+ARRAY_SIZE(wlan_sdio_off_table), wlan_sdio_off_table); }
+
+ udelay(200);
+
+ mmc_force_presence_change(&s3c_device_hsmmc3);
+ msleep(500); /* wait for carddetect */
+ return 0;
+}
+
+/* Customized Locale table : OPTIONAL feature */
+#define WLC_CNTRY_BUF_SZ 4
+struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ];
+ char custom_locale[WLC_CNTRY_BUF_SZ];
+ int custom_locale_rev;
+};
+
+static struct cntry_locales_custom brcm_wlan_translate_custom_table[] = {
+ /* Table should be filled out based
+ on custom platform regulatory requirement */
+ {"", "XY", 4}, /* universal */
+ {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
+ {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
+ {"EU", "EU", 5}, /* European union countries */
+ {"AT", "EU", 5},
+ {"BE", "EU", 5},
+ {"BG", "EU", 5},
+ {"CY", "EU", 5},
+ {"CZ", "EU", 5},
+ {"DK", "EU", 5},
+ {"EE", "EU", 5},
+ {"FI", "EU", 5},
+ {"FR", "EU", 5},
+ {"DE", "EU", 5},
+ {"GR", "EU", 5},
+ {"HU", "EU", 5},
+ {"IE", "EU", 5},
+ {"IT", "EU", 5},
+ {"LV", "EU", 5},
+ {"LI", "EU", 5},
+ {"LT", "EU", 5},
+ {"LU", "EU", 5},
+ {"MT", "EU", 5},
+ {"NL", "EU", 5},
+ {"PL", "EU", 5},
+ {"PT", "EU", 5},
+ {"RO", "EU", 5},
+ {"SK", "EU", 5},
+ {"SI", "EU", 5},
+ {"ES", "EU", 5},
+ {"SE", "EU", 5},
+ {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */
+ {"IL", "IL", 0},
+ {"CH", "CH", 0},
+ {"TR", "TR", 0},
+ {"NO", "NO", 0},
+ {"KR", "XY", 3},
+ {"AU", "XY", 3},
+ {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
+ {"TW", "XY", 3},
+ {"AR", "XY", 3},
+ {"MX", "XY", 3}
+};
+
+static void *brcm_wlan_get_country_code(char *ccode)
+{
+ int size = ARRAY_SIZE(brcm_wlan_translate_custom_table);
+ int i;
+
+ if (!ccode)
+ return NULL;
+
+ for (i = 0; i < size; i++)
+ if (strcmp(ccode,
+ brcm_wlan_translate_custom_table[i].iso_abbrev) == 0)
+ return &brcm_wlan_translate_custom_table[i];
+ return &brcm_wlan_translate_custom_table[0];
+}
+
+static struct resource brcm_wlan_resources[] = {
+ [0] = {
+ .name = "bcmdhd_wlan_irq",
+ .start = IRQ_EINT(21),
+ .end = IRQ_EINT(21),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
+ },
+};
+
+static struct wifi_platform_data brcm_wlan_control = {
+ .set_power = brcm_wlan_power,
+ .set_reset = brcm_wlan_reset,
+ .set_carddetect = brcm_wlan_set_carddetect,
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+ .mem_prealloc = brcm_wlan_mem_prealloc,
+#endif
+ .get_country_code = brcm_wlan_get_country_code,
+};
+
+static struct platform_device brcm_device_wlan = {
+ .name = "bcmdhd_wlan",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(brcm_wlan_resources),
+ .resource = brcm_wlan_resources,
+ .dev = {
+ .platform_data = &brcm_wlan_control,
+ },
+};
+
+int __init brcm_wlan_init(void)
+{
+ printk(KERN_INFO"%s: start\n", __func__);
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+ brcm_init_wlan_mem();
+#endif
+
+ return platform_device_register(&brcm_device_wlan);
+}
diff --git a/arch/arm/mach-exynos/board-p4notepq-modems.c b/arch/arm/mach-exynos/board-p4notepq-modems.c
new file mode 100644
index 0000000..3ab6fbe
--- /dev/null
+++ b/arch/arm/mach-exynos/board-p4notepq-modems.c
@@ -0,0 +1,535 @@
+/* linux/arch/arm/mach-xxxx/board-m0-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Modem configuraiton for M0 (P-Q + XMM6262)*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+/* umts target platform data */
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [1] = {
+ .name = "umts_rfs0",
+ .id = 0x41,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [2] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [3] = {
+ .name = "multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [4] = {
+#ifdef CONFIG_SLP
+ .name = "pdp0",
+#else
+ .name = "rmnet0",
+#endif
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [5] = {
+#ifdef CONFIG_SLP
+ .name = "pdp1",
+#else
+ .name = "rmnet1",
+#endif
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [6] = {
+#ifdef CONFIG_SLP
+ .name = "pdp2",
+#else
+ .name = "rmnet2",
+#endif
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [7] = {
+ .name = "umts_router",
+ .id = 0x39,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [8] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [9] = {
+ .name = "umts_ramdump0",
+ .id = 0x0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [10] = {
+ .name = "umts_loopback0",
+ .id = 0x3f,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+};
+
+/* To get modem state, register phone active irq using resource */
+static struct resource umts_modem_res[] = {
+};
+
+static int umts_link_ldo_enble(bool enable)
+{
+ /* Exynos HSIC V1.2 LDO was controlled by kernel */
+ return 0;
+}
+
+static int umts_link_reconnect(void);
+static struct modemlink_pm_data modem_link_pm_data = {
+ .name = "link_pm",
+ .link_ldo_enable = umts_link_ldo_enble,
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+ .link_reconnect = umts_link_reconnect,
+};
+
+static struct modemlink_pm_link_activectl active_ctl;
+
+static void xmm_gpio_revers_bias_clear(void);
+static void xmm_gpio_revers_bias_restore(void);
+
+#ifndef GPIO_AP_DUMP_INT
+#define GPIO_AP_DUMP_INT 0
+#endif
+static struct modem_data umts_modem_data = {
+ .name = "xmm6262",
+
+ .gpio_cp_on = GPIO_PHONE_ON,
+ .gpio_reset_req_n = GPIO_CP_REQ_RESET,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+ .gpio_ap_dump_int = GPIO_AP_DUMP_INT,
+ .gpio_flm_uart_sel = 0,
+ .gpio_cp_warm_reset = 0,
+#if defined(CONFIG_SIM_DETECT)
+ .gpio_sim_detect = GPIO_SIM_DETECT,
+#endif
+
+ .modem_type = IMC_XMM6262,
+ .link_types = LINKTYPE(LINKDEV_HSIC),
+ .modem_net = UMTS_NETWORK,
+ .use_handover = false,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &modem_link_pm_data,
+ .gpio_revers_bias_clear = xmm_gpio_revers_bias_clear,
+ .gpio_revers_bias_restore = xmm_gpio_revers_bias_restore,
+};
+
+/* HSIC specific function */
+void set_slave_wake(void)
+{
+ if (gpio_get_value(modem_link_pm_data.gpio_link_hostwake)) {
+ pr_info("[MODEM_IF]Slave Wake\n");
+ if (gpio_get_value(modem_link_pm_data.gpio_link_slavewake)) {
+ pr_info("[MODEM_IF]Slave Wake set _-\n");
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 0);
+ mdelay(10);
+ }
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 1);
+ }
+}
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ if (!val) {
+ pr_info("CP not ready, Active State low\n");
+ return;
+ }
+
+ if (active_ctl.gpio_initialized) {
+ pr_err(LOG_TAG "Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val) {
+ switch (states) {
+ case STATE_HSIC_LPA_ENTER:
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ gpio_set_value(umts_modem_data.gpio_pda_active, 0);
+ pr_info(LOG_TAG "set hsic lpa enter: "
+ "active state (%d)" ", pda active (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_active),
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_WAKE:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ pr_info(LOG_TAG "set hsic lpa wake: "
+ "pda active (%d)\n",
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_PHY_INIT:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ set_slave_wake();
+ pr_info(LOG_TAG "set hsic lpa phy init: "
+ "slave wake-up (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_slavewake)
+ );
+ break;
+ }
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static int umts_link_reconnect(void)
+{
+ if (gpio_get_value(umts_modem_data.gpio_phone_active) &&
+ gpio_get_value(umts_modem_data.gpio_cp_reset)) {
+ pr_info("[MODEM_IF] trying reconnect link\n");
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ mdelay(10);
+ set_slave_wake();
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 1);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+/* if use more than one modem device, then set id num */
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+static void umts_modem_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_reset_req_n = umts_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_cp_dump_int = umts_modem_data.gpio_cp_dump_int;
+ unsigned gpio_ap_dump_int = umts_modem_data.gpio_ap_dump_int;
+ unsigned gpio_flm_uart_sel = umts_modem_data.gpio_flm_uart_sel;
+ unsigned gpio_sim_detect = umts_modem_data.gpio_sim_detect;
+ unsigned irq_phone_active = umts_modem_res[0].start;
+
+ if (gpio_reset_req_n) {
+ err = gpio_request(gpio_reset_req_n, "RESET_REQ_N");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "RESET_REQ_N", err);
+ }
+ s3c_gpio_slp_cfgpin(gpio_reset_req_n, S3C_GPIO_SLP_OUT1);
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CP_ON");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_ON", err);
+ }
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_RST", err);
+ }
+ s3c_gpio_slp_cfgpin(gpio_cp_rst, S3C_GPIO_SLP_OUT1);
+ gpio_direction_output(gpio_cp_rst, 0);
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PDA_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PHONE_ACTIVE", err);
+ }
+ gpio_direction_input(gpio_phone_active);
+ pr_err(LOG_TAG "check phone active = %d\n", irq_phone_active);
+ }
+
+ if (gpio_sim_detect) {
+ err = gpio_request(gpio_sim_detect, "SIM_DETECT");
+ if (err)
+ printk(KERN_ERR "fail to request gpio %s: %d\n",
+ "SIM_DETECT", err);
+
+ /* gpio_direction_input(gpio_sim_detect); */
+ s3c_gpio_cfgpin(gpio_sim_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_sim_detect, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_to_irq(gpio_sim_detect),
+ IRQ_TYPE_EDGE_BOTH);
+ }
+
+ if (gpio_cp_dump_int) {
+ err = gpio_request(gpio_cp_dump_int, "CP_DUMP_INT");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_DUMP_INT", err);
+ }
+ gpio_direction_input(gpio_cp_dump_int);
+ }
+
+ if (gpio_ap_dump_int) {
+ err = gpio_request(gpio_ap_dump_int, "AP_DUMP_INT");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "AP_DUMP_INT", err);
+ }
+ gpio_direction_output(gpio_ap_dump_int, 0);
+ }
+
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "GPS_UART_SEL");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "GPS_UART_SEL", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_phone_active)
+ irq_set_irq_type(gpio_to_irq(gpio_phone_active),
+ IRQ_TYPE_LEVEL_HIGH);
+ /* set low unused gpios between AP and CP */
+ err = gpio_request(GPIO_FLM_RXD, "FLM_RXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_RXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_RXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_FLM_TXD, "FLM_TXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_TXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_TXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_SUSPEND_REQUEST, "SUS_REQ");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "SUS_REQ",
+ err);
+ else {
+ gpio_direction_output(GPIO_SUSPEND_REQUEST, 0);
+ s3c_gpio_setpull(GPIO_SUSPEND_REQUEST, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_GPS_CNTL, "GPS_CNTL");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "GPS_CNTL",
+ err);
+ else {
+ gpio_direction_output(GPIO_GPS_CNTL, 0);
+ s3c_gpio_setpull(GPIO_GPS_CNTL, S3C_GPIO_PULL_NONE);
+ }
+
+ pr_info(LOG_TAG "umts_modem_cfg_gpio done\n");
+}
+
+static void xmm_gpio_revers_bias_clear(void)
+{
+ gpio_direction_output(umts_modem_data.gpio_pda_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_phone_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_cp_dump_int, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_hostwake, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_slavewake, 0);
+
+ if (umts_modem_data.gpio_sim_detect)
+ gpio_direction_output(umts_modem_data.gpio_sim_detect, 0);
+
+ msleep(20);
+}
+
+static void xmm_gpio_revers_bias_restore(void)
+{
+ unsigned gpio_sim_detect = umts_modem_data.gpio_sim_detect;
+
+ s3c_gpio_cfgpin(umts_modem_data.gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_cfgpin(modem_link_pm_data.gpio_link_hostwake,
+ S3C_GPIO_SFN(0xF));
+ gpio_direction_input(umts_modem_data.gpio_cp_dump_int);
+
+ if (umts_modem_data.gpio_sim_detect) {
+ gpio_direction_input(gpio_sim_detect);
+ s3c_gpio_cfgpin(gpio_sim_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_sim_detect, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_to_irq(gpio_sim_detect),
+ IRQ_TYPE_EDGE_BOTH);
+ enable_irq_wake(gpio_to_irq(gpio_sim_detect));
+ }
+}
+
+static void modem_link_pm_config_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_link_enable = modem_link_pm_data.gpio_link_enable;
+ unsigned gpio_link_active = modem_link_pm_data.gpio_link_active;
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+ unsigned gpio_link_slavewake = modem_link_pm_data.gpio_link_slavewake;
+ /* unsigned irq_link_hostwake = umts_modem_res[1].start; */
+
+ if (gpio_link_enable) {
+ err = gpio_request(gpio_link_enable, "LINK_EN");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_EN", err);
+ }
+ gpio_direction_output(gpio_link_enable, 0);
+ }
+
+ if (gpio_link_active) {
+ err = gpio_request(gpio_link_active, "LINK_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_link_active, 0);
+ }
+
+ if (gpio_link_hostwake) {
+ err = gpio_request(gpio_link_hostwake, "HOSTWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "HOSTWAKE", err);
+ }
+ gpio_direction_input(gpio_link_hostwake);
+ }
+
+ if (gpio_link_slavewake) {
+ err = gpio_request(gpio_link_slavewake, "SLAVEWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "SLAVEWAKE", err);
+ }
+ gpio_direction_output(gpio_link_slavewake, 0);
+ }
+
+ if (gpio_link_hostwake)
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQ_TYPE_EDGE_BOTH);
+
+ active_ctl.gpio_initialized = 1;
+ if (active_ctl.gpio_request_host_active) {
+ pr_err(LOG_TAG "Active States = 1, %s\n", __func__);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 1);
+ }
+
+ pr_info(LOG_TAG "modem_link_pm_config_gpio done\n");
+}
+
+static int __init init_modem(void)
+{
+ int ret;
+ pr_info(LOG_TAG "init_modem, system_rev = %d\n", system_rev);
+
+ /* umts gpios configuration */
+ umts_modem_cfg_gpio();
+ modem_link_pm_config_gpio();
+ ret = platform_device_register(&umts_modem);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+late_initcall(init_modem);
diff --git a/arch/arm/mach-exynos/board-s2plus-modems.c b/arch/arm/mach-exynos/board-s2plus-modems.c
new file mode 100644
index 0000000..38ee0b2
--- /dev/null
+++ b/arch/arm/mach-exynos/board-s2plus-modems.c
@@ -0,0 +1,479 @@
+/* linux/arch/arm/mach-xxxx/board-m0-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Modem configuraiton for M0 (P-Q + XMM6262)*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+/* umts target platform data */
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [1] = {
+ .name = "umts_rfs0",
+ .id = 0x41,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [2] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [3] = {
+ .name = "multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [4] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [5] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [6] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [7] = {
+ .name = "umts_router",
+ .id = 0x39,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [8] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [9] = {
+ .name = "umts_ramdump0",
+ .id = 0x0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [10] = {
+ .name = "umts_loopback0",
+ .id = 0x3f,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+};
+
+/* To get modem state, register phone active irq using resource */
+static struct resource umts_modem_res[] = {
+};
+
+static int umts_link_ldo_enble(bool enable)
+{
+ /* Exynos HSIC V1.2 LDO was controlled by kernel */
+ return 0;
+}
+
+static int umts_link_reconnect(void);
+static struct modemlink_pm_data modem_link_pm_data = {
+ .name = "link_pm",
+ .link_ldo_enable = umts_link_ldo_enble,
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+ .link_reconnect = umts_link_reconnect,
+};
+
+static struct modemlink_pm_link_activectl active_ctl;
+
+static void xmm_gpio_revers_bias_clear(void);
+static void xmm_gpio_revers_bias_restore(void);
+static struct modem_data umts_modem_data = {
+ .name = "xmm6262",
+
+ .gpio_cp_on = GPIO_PHONE_ON,
+ .gpio_reset_req_n = GPIO_CP_REQ_RESET,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+ .gpio_flm_uart_sel = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .modem_type = IMC_XMM6262,
+ .link_types = LINKTYPE(LINKDEV_HSIC),
+ .modem_net = UMTS_NETWORK,
+ .use_handover = false,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &modem_link_pm_data,
+ .gpio_revers_bias_clear = xmm_gpio_revers_bias_clear,
+ .gpio_revers_bias_restore = xmm_gpio_revers_bias_restore,
+};
+
+/* HSIC specific function */
+void set_slave_wake(void)
+{
+ int spin = 20;
+ if (gpio_get_value(modem_link_pm_data.gpio_link_hostwake)) {
+ pr_info("[MODEM_IF]Slave Wake\n");
+ if (gpio_get_value(modem_link_pm_data.gpio_link_slavewake)) {
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 0);
+ mdelay(10);
+ }
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 1);
+ mdelay(10);
+ while (spin--) {
+ if (!gpio_get_value(
+ modem_link_pm_data.gpio_link_hostwake))
+ break;
+ mdelay(10);
+ }
+ }
+}
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+ if (active_ctl.gpio_initialized) {
+ if (type)
+ set_slave_wake();
+ pr_err(LOG_TAG "Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val) {
+ switch (states) {
+ case STATE_HSIC_LPA_ENTER:
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ gpio_set_value(umts_modem_data.gpio_pda_active, 0);
+ pr_info(LOG_TAG "set hsic lpa enter: "
+ "active state (%d)" ", pda active (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_active),
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_WAKE:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ pr_info(LOG_TAG "set hsic lpa wake: "
+ "pda active (%d)\n",
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_PHY_INIT:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ gpio_set_value(modem_link_pm_data.gpio_link_slavewake,
+ 1);
+ pr_info(LOG_TAG "set hsic lpa phy init: "
+ "slave wake-up (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_slavewake)
+ );
+ break;
+ }
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static int umts_link_reconnect(void)
+{
+ if (gpio_get_value(umts_modem_data.gpio_phone_active) &&
+ gpio_get_value(umts_modem_data.gpio_cp_reset)) {
+ pr_info("[MODEM_IF] trying reconnect link\n");
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ mdelay(10);
+ set_slave_wake();
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 1);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+/* if use more than one modem device, then set id num */
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+static void umts_modem_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_reset_req_n = umts_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_cp_dump_int = umts_modem_data.gpio_cp_dump_int;
+ unsigned gpio_flm_uart_sel = umts_modem_data.gpio_flm_uart_sel;
+ unsigned irq_phone_active = umts_modem_res[0].start;
+
+ if (gpio_reset_req_n) {
+ err = gpio_request(gpio_reset_req_n, "RESET_REQ_N");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "RESET_REQ_N", err);
+ }
+ s3c_gpio_slp_cfgpin(gpio_reset_req_n, S3C_GPIO_SLP_OUT1);
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CP_ON");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_ON", err);
+ }
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_RST", err);
+ }
+ s3c_gpio_slp_cfgpin(gpio_cp_rst, S3C_GPIO_SLP_OUT1);
+ gpio_direction_output(gpio_cp_rst, 0);
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PDA_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "PHONE_ACTIVE", err);
+ }
+ gpio_direction_input(gpio_phone_active);
+ pr_err(LOG_TAG "check phone active = %d\n", irq_phone_active);
+ }
+
+ if (gpio_cp_dump_int) {
+ err = gpio_request(gpio_cp_dump_int, "CP_DUMP_INT");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "CP_DUMP_INT", err);
+ }
+ gpio_direction_input(gpio_cp_dump_int);
+ }
+
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "GPS_UART_SEL");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "GPS_UART_SEL", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_phone_active)
+ irq_set_irq_type(gpio_to_irq(gpio_phone_active),
+ IRQ_TYPE_LEVEL_HIGH);
+ /* set low unused gpios between AP and CP */
+ err = gpio_request(GPIO_FLM_RXD, "FLM_RXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_RXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_RXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_RXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_FLM_TXD, "FLM_TXD");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "FLM_TXD",
+ err);
+ else {
+ gpio_direction_output(GPIO_FLM_TXD, 0);
+ s3c_gpio_setpull(GPIO_FLM_TXD, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_SUSPEND_REQUEST, "SUS_REQ");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "SUS_REQ",
+ err);
+ else {
+ gpio_direction_output(GPIO_SUSPEND_REQUEST, 0);
+ s3c_gpio_setpull(GPIO_SUSPEND_REQUEST, S3C_GPIO_PULL_NONE);
+ }
+ err = gpio_request(GPIO_GPS_CNTL, "GPS_CNTL");
+ if (err)
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n", "GPS_CNTL",
+ err);
+ else {
+ gpio_direction_output(GPIO_GPS_CNTL, 0);
+ s3c_gpio_setpull(GPIO_GPS_CNTL, S3C_GPIO_PULL_NONE);
+ }
+
+ pr_info(LOG_TAG "umts_modem_cfg_gpio done\n");
+}
+
+static void xmm_gpio_revers_bias_clear(void)
+{
+ gpio_direction_output(umts_modem_data.gpio_pda_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_phone_active, 0);
+ gpio_direction_output(umts_modem_data.gpio_cp_dump_int, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_hostwake, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_slavewake, 0);
+
+ msleep(20);
+}
+
+static void xmm_gpio_revers_bias_restore(void)
+{
+ s3c_gpio_cfgpin(umts_modem_data.gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_cfgpin(modem_link_pm_data.gpio_link_hostwake,
+ S3C_GPIO_SFN(0xF));
+ gpio_direction_input(umts_modem_data.gpio_cp_dump_int);
+}
+
+static void modem_link_pm_config_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_link_enable = modem_link_pm_data.gpio_link_enable;
+ unsigned gpio_link_active = modem_link_pm_data.gpio_link_active;
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+ unsigned gpio_link_slavewake = modem_link_pm_data.gpio_link_slavewake;
+ /* unsigned irq_link_hostwake = umts_modem_res[1].start; */
+
+ if (gpio_link_enable) {
+ err = gpio_request(gpio_link_enable, "LINK_EN");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_EN", err);
+ }
+ gpio_direction_output(gpio_link_enable, 0);
+ }
+
+ if (gpio_link_active) {
+ err = gpio_request(gpio_link_active, "LINK_ACTIVE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "LINK_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_link_active, 0);
+ }
+
+ if (gpio_link_hostwake) {
+ err = gpio_request(gpio_link_hostwake, "HOSTWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "HOSTWAKE", err);
+ }
+ gpio_direction_input(gpio_link_hostwake);
+ }
+
+ if (gpio_link_slavewake) {
+ err = gpio_request(gpio_link_slavewake, "SLAVEWAKE");
+ if (err) {
+ pr_err(LOG_TAG "fail to request gpio %s : %d\n",
+ "SLAVEWAKE", err);
+ }
+ gpio_direction_output(gpio_link_slavewake, 0);
+ }
+
+ if (gpio_link_hostwake)
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQ_TYPE_EDGE_BOTH);
+
+ active_ctl.gpio_initialized = 1;
+ if (active_ctl.gpio_request_host_active) {
+ pr_err(LOG_TAG "Active States = 1, %s\n", __func__);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 1);
+ }
+
+ pr_info(LOG_TAG "modem_link_pm_config_gpio done\n");
+}
+
+static int __init init_modem(void)
+{
+ int ret;
+ pr_info(LOG_TAG "init_modem\n");
+
+ /* umts gpios configuration */
+ umts_modem_cfg_gpio();
+ modem_link_pm_config_gpio();
+ ret = platform_device_register(&umts_modem);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+late_initcall(init_modem);
diff --git a/arch/arm/mach-exynos/board-smdk5250-audio.c b/arch/arm/mach-exynos/board-smdk5250-audio.c
new file mode 100644
index 0000000..6cd1405
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-audio.c
@@ -0,0 +1,177 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-audio.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/iic.h>
+
+#include "board-smdk5250.h"
+
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ REGULATOR_SUPPLY("AVDD2", "1-001a"),
+ REGULATOR_SUPPLY("CPVDD", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage2_supplies =
+ REGULATOR_SUPPLY("DBVDD", "1-001a");
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+ .consumer_supplies = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+ .consumer_supplies = wm8994_fixed_voltage1_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage2_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_fixed_voltage2_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VDD_1.8V",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage2_config = {
+ .supply_name = "VDD_3.3V",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage2_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage2 = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage2_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+ REGULATOR_SUPPLY("AVDD1", "1-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+ REGULATOR_SUPPLY("DCVDD", "1-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* If the i2s0 and i2s2 is enabled simultaneously */
+ .gpio_defaults[7] = 0x8100, /* GPIO8 DACDAT3 in */
+ .gpio_defaults[8] = 0x0100, /* GPIO9 ADCDAT3 out */
+ .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3 out */
+ .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3 out */
+ .ldo[0] = { 0, NULL, &wm8994_ldo1_data },
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
+static struct platform_device *smdk5250_audio_devices[] __initdata = {
+ &s3c_device_i2c1,
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
+ &wm8994_fixed_voltage2,
+ &samsung_asoc_dma,
+ &samsung_asoc_idma,
+};
+
+void __init exynos5_smdk5250_audio_init(void)
+{
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ platform_add_devices(smdk5250_audio_devices,
+ ARRAY_SIZE(smdk5250_audio_devices));
+}
diff --git a/arch/arm/mach-exynos/board-smdk5250-display.c b/arch/arm/mach-exynos/board-smdk5250-display.c
new file mode 100644
index 0000000..d247805
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-display.c
@@ -0,0 +1,695 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-display.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+#include <video/s5p-dp.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/fb-s5p.h>
+#include <plat/fb-core.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/dp.h>
+#include <plat/pd.h>
+#include <plat/backlight.h>
+
+#include <mach/map.h>
+#include <mach/dev.h>
+
+#ifdef CONFIG_FB_MIPI_DSIM
+#include <plat/dsim.h>
+#include <plat/mipi_dsi.h>
+#endif
+
+#if defined(CONFIG_LCD_MIPI_S6E8AB0)
+static void mipi_lcd_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ if (!gpio_request(EXYNOS5_GPD1(5), "GPD1")) {
+ s3c_gpio_cfgpin(EXYNOS5_GPD1(5), S3C_GPIO_SFN(1));
+ gpio_direction_output(EXYNOS5_GPD1(5), 0);
+ gpio_direction_output(EXYNOS5_GPD1(5), 1);
+ gpio_free(EXYNOS5_GPD1(5));
+ }
+ }
+ /* reset */
+ gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
+
+ msleep(20);
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS5_GPX1(5), 0);
+ msleep(20);
+ gpio_set_value(EXYNOS5_GPX1(5), 1);
+ msleep(20);
+ gpio_free(EXYNOS5_GPX1(5));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS5_GPX1(5), 0);
+ msleep(20);
+ gpio_set_value(EXYNOS5_GPX1(5), 1);
+ msleep(20);
+ gpio_free(EXYNOS5_GPX1(5));
+ }
+ msleep(20);
+ /* power */
+ gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_LOW, "GPX3");
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS5_GPX3(0), 1);
+ gpio_free(EXYNOS5_GPX3(0));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS5_GPX3(0), 0);
+ gpio_free(EXYNOS5_GPX3(0));
+ }
+
+#ifndef CONFIG_BACKLIGHT_PWM
+ /* backlight */
+ gpio_request_one(EXYNOS5_GPB2(0), GPIOF_OUT_INIT_LOW, "GPB2");
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS5_GPB2(0), 1);
+ gpio_free(EXYNOS5_GPB2(0));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS5_GPB2(0), 0);
+ gpio_free(EXYNOS5_GPB2(0));
+ }
+#endif /* CONFIG_BACKLIGHT_PWM */
+}
+
+static struct plat_lcd_data smdk5250_mipi_lcd_data = {
+ .set_power = mipi_lcd_set_power,
+};
+
+static struct platform_device smdk5250_mipi_lcd = {
+ .name = "platform-lcd",
+ .dev.platform_data = &smdk5250_mipi_lcd_data,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win0 = {
+ .win_mode = {
+ .left_margin = 0x4,
+ .right_margin = 0x4,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .xres = 1280,
+ .yres = 800,
+ },
+ .virtual_x = 1280,
+ .virtual_y = 840 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win1 = {
+ .win_mode = {
+ .left_margin = 0x2,
+ .right_margin = 0x4,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .xres = 1280,
+ .yres = 800,
+ },
+ .virtual_x = 1280,
+ .virtual_y = 840 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win2 = {
+ .win_mode = {
+ .left_margin = 0x4,
+ .right_margin = 0x4,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .xres = 1280,
+ .yres = 800,
+ },
+ .virtual_x = 1280,
+ .virtual_y = 800 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#elif defined(CONFIG_LCD_MIPI_TC358764)
+static void mipi_lcd_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ /* reset */
+ gpio_request_one(EXYNOS5_GPX1(5), GPIOF_OUT_INIT_HIGH, "GPX1");
+
+ msleep(20);
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS5_GPX1(5), 0);
+ msleep(20);
+ gpio_set_value(EXYNOS5_GPX1(5), 1);
+ msleep(20);
+ gpio_free(EXYNOS5_GPX1(5));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS5_GPX1(5), 0);
+ msleep(20);
+ gpio_set_value(EXYNOS5_GPX1(5), 1);
+ msleep(20);
+ gpio_free(EXYNOS5_GPX1(5));
+ }
+ msleep(20);
+ /* power */
+ gpio_request_one(EXYNOS5_GPX3(0), GPIOF_OUT_INIT_LOW, "GPX3");
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS5_GPX3(0), 1);
+ gpio_free(EXYNOS5_GPX3(0));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS5_GPX3(0), 0);
+ gpio_free(EXYNOS5_GPX3(0));
+ }
+
+#ifndef CONFIG_BACKLIGHT_PWM
+ /* backlight */
+ gpio_request_one(EXYNOS5_GPB2(0), GPIOF_OUT_INIT_LOW, "GPB2");
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS5_GPB2(0), 1);
+ gpio_free(EXYNOS5_GPB2(0));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS5_GPB2(0), 0);
+ gpio_free(EXYNOS5_GPB2(0));
+ }
+#endif
+}
+
+static struct plat_lcd_data smdk5250_mipi_lcd_data = {
+ .set_power = mipi_lcd_set_power,
+};
+
+static struct platform_device smdk5250_mipi_lcd = {
+ .name = "platform-lcd",
+ .dev.platform_data = &smdk5250_mipi_lcd_data,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win0 = {
+ .win_mode = {
+ .left_margin = 4,
+ .right_margin = 4,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .xres = 1280,
+ .yres = 800,
+ },
+ .virtual_x = 1280,
+ .virtual_y = 840 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win1 = {
+ .win_mode = {
+ .left_margin = 4,
+ .right_margin = 4,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .xres = 1280,
+ .yres = 800,
+ },
+ .virtual_x = 1280,
+ .virtual_y = 840 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win2 = {
+ .win_mode = {
+ .left_margin = 4,
+ .right_margin = 4,
+ .upper_margin = 4,
+ .lower_margin = 4,
+ .hsync_len = 4,
+ .vsync_len = 4,
+ .xres = 1280,
+ .yres = 800,
+ },
+ .virtual_x = 1280,
+ .virtual_y = 800 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#elif defined(CONFIG_S5P_DP)
+static void dp_lcd_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+#ifndef CONFIG_BACKLIGHT_PWM
+ /* LCD_PWM_IN_2.8V: LCD_B_PWM, GPB2_0 */
+ gpio_request(EXYNOS5_GPB2(0), "GPB2");
+#endif
+ /* LCD_APS_EN_2.8V: GPD0_6 */
+ gpio_request(EXYNOS5_GPD0(6), "GPD0");
+
+ /* LCD_EN: GPD0_5 */
+ gpio_request(EXYNOS5_GPD0(5), "GPD0");
+
+ /* LCD_EN: GPD0_5 */
+ gpio_direction_output(EXYNOS5_GPD0(5), power);
+ msleep(20);
+
+ /* LCD_APS_EN_2.8V: GPD0_6 */
+ gpio_direction_output(EXYNOS5_GPD0(6), power);
+ msleep(20);
+#ifndef CONFIG_BACKLIGHT_PWM
+ /* LCD_PWM_IN_2.8V: LCD_B_PWM, GPB2_0 */
+ gpio_direction_output(EXYNOS5_GPB2(0), power);
+
+ gpio_free(EXYNOS5_GPB2(0));
+#endif
+ gpio_free(EXYNOS5_GPD0(6));
+ gpio_free(EXYNOS5_GPD0(5));
+}
+
+static struct plat_lcd_data smdk5250_dp_lcd_data = {
+ .set_power = dp_lcd_set_power,
+};
+
+static struct platform_device smdk5250_dp_lcd = {
+ .name = "platform-lcd",
+ .dev = {
+ .parent = &s5p_device_fimd1.dev,
+ .platform_data = &smdk5250_dp_lcd_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5250_fb_win2 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1600 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static void exynos_fimd_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+
+#if defined(CONFIG_S5P_DP)
+ /* Set Hotplug detect for DP */
+ gpio_request(EXYNOS5_GPX0(7), "GPX0");
+ s3c_gpio_cfgpin(EXYNOS5_GPX0(7), S3C_GPIO_SFN(3));
+#endif
+
+ /*
+ * Set DISP1BLK_CFG register for Display path selection
+ *
+ * FIMD of DISP1_BLK Bypass selection : DISP1BLK_CFG[15]
+ * ---------------------
+ * 0 | MIE/MDNIE
+ * 1 | FIMD : selected
+ */
+ reg = __raw_readl(S3C_VA_SYS + 0x0214);
+ reg &= ~(1 << 15); /* To save other reset values */
+ reg |= (1 << 15);
+ __raw_writel(reg, S3C_VA_SYS + 0x0214);
+
+#if defined(CONFIG_S5P_DP)
+ /* Reference clcok selection for DPTX_PHY: PAD_OSC_IN */
+ reg = __raw_readl(S3C_VA_SYS + 0x04d4);
+ reg &= ~(1 << 0);
+ __raw_writel(reg, S3C_VA_SYS + 0x04d4);
+
+ /* DPTX_PHY: XXTI */
+ reg = __raw_readl(S3C_VA_SYS + 0x04d8);
+ reg &= ~(1 << 3);
+ __raw_writel(reg, S3C_VA_SYS + 0x04d8);
+#endif
+}
+
+static struct s3c_fb_platdata smdk5250_lcd1_pdata __initdata = {
+#if defined(CONFIG_LCD_MIPI_S6E8AB0) || defined(CONFIG_LCD_MIPI_TC358764) || \
+ defined(CONFIG_S5P_DP)
+ .win[0] = &smdk5250_fb_win0,
+ .win[1] = &smdk5250_fb_win1,
+ .win[2] = &smdk5250_fb_win2,
+#endif
+ .default_win = 2,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_MIPI_S6E8AB0) || defined(CONFIG_LCD_MIPI_TC358764)
+ .vidcon1 = VIDCON1_INV_VCLK,
+#elif defined(CONFIG_S5P_DP)
+ .vidcon1 = 0,
+#endif
+ .setup_gpio = exynos_fimd_gpio_setup_24bpp,
+};
+
+#ifdef CONFIG_FB_MIPI_DSIM
+#if defined(CONFIG_LCD_MIPI_S6E8AB0)
+static struct mipi_dsim_config dsim_info = {
+ .e_interface = DSIM_VIDEO,
+ .e_pixel_format = DSIM_24BPP_888,
+ /* main frame fifo auto flush at VSYNC pulse */
+ .auto_flush = false,
+ .eot_disable = false,
+ .auto_vertical_cnt = true,
+ .hse = false,
+ .hfp = false,
+ .hbp = false,
+ .hsa = false,
+
+ .e_no_data_lane = DSIM_DATA_LANE_4,
+ .e_byte_clk = DSIM_PLL_OUT_DIV8,
+ .e_burst_mode = DSIM_BURST,
+
+ .p = 2,
+ .m = 57,
+ .s = 1,
+
+ /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
+ .pll_stable_time = 500,
+
+ .esc_clk = 20 * 1000000, /* escape clk : 10MHz */
+
+ /* stop state holding counter after bta change count 0 ~ 0xfff */
+ .stop_holding_cnt = 0x0fff,
+ .bta_timeout = 0xff, /* bta timeout 0 ~ 0xff */
+ .rx_timeout = 0xffff, /* lp rx timeout 0 ~ 0xffff */
+
+ .dsim_ddi_pd = &s6e8ab0_mipi_lcd_driver,
+};
+
+static struct mipi_dsim_lcd_config dsim_lcd_info = {
+ .rgb_timing.left_margin = 0xa,
+ .rgb_timing.right_margin = 0xa,
+ .rgb_timing.upper_margin = 80,
+ .rgb_timing.lower_margin = 48,
+ .rgb_timing.hsync_len = 5,
+ .rgb_timing.vsync_len = 32,
+ .cpu_timing.cs_setup = 0,
+ .cpu_timing.wr_setup = 1,
+ .cpu_timing.wr_act = 0,
+ .cpu_timing.wr_hold = 0,
+ .lcd_size.width = 1280,
+ .lcd_size.height = 800,
+};
+#elif defined(CONFIG_LCD_MIPI_S6E63M0)
+static struct mipi_dsim_config dsim_info = {
+ .e_interface = DSIM_VIDEO,
+ .e_pixel_format = DSIM_24BPP_888,
+ /* main frame fifo auto flush at VSYNC pulse */
+ .auto_flush = false,
+ .eot_disable = false,
+ .auto_vertical_cnt = true,
+ .hse = false,
+ .hfp = false,
+ .hbp = false,
+ .hsa = false,
+
+ .e_no_data_lane = DSIM_DATA_LANE_2,
+ .e_byte_clk = DSIM_PLL_OUT_DIV8,
+ .e_burst_mode = DSIM_NON_BURST_SYNC_PULSE,
+
+ .p = 3,
+ .m = 90,
+ .s = 1,
+
+ /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
+ .pll_stable_time = 500,
+
+ .esc_clk = 10 * 1000000, /* escape clk : 10MHz */
+
+ /* stop state holding counter after bta change count 0 ~ 0xfff */
+ .stop_holding_cnt = 0x0fff,
+ .bta_timeout = 0xff, /* bta timeout 0 ~ 0xff */
+ .rx_timeout = 0xffff, /* lp rx timeout 0 ~ 0xffff */
+
+ .dsim_ddi_pd = &s6e63m0_mipi_lcd_driver,
+};
+
+static struct mipi_dsim_lcd_config dsim_lcd_info = {
+ .rgb_timing.left_margin = 0x16,
+ .rgb_timing.right_margin = 0x16,
+ .rgb_timing.upper_margin = 0x28,
+ .rgb_timing.lower_margin = 0x1,
+ .rgb_timing.hsync_len = 0x2,
+ .rgb_timing.vsync_len = 0x3,
+ .cpu_timing.cs_setup = 0,
+ .cpu_timing.wr_setup = 1,
+ .cpu_timing.wr_act = 0,
+ .cpu_timing.wr_hold = 0,
+ .lcd_size.width = 480,
+ .lcd_size.height = 800,
+};
+#elif defined(CONFIG_LCD_MIPI_TC358764)
+static struct mipi_dsim_config dsim_info = {
+ .e_interface = DSIM_VIDEO,
+ .e_pixel_format = DSIM_24BPP_888,
+ /* main frame fifo auto flush at VSYNC pulse */
+ .auto_flush = false,
+ .eot_disable = false,
+ .auto_vertical_cnt = false,
+ .hse = false,
+ .hfp = false,
+ .hbp = false,
+ .hsa = false,
+
+ .e_no_data_lane = DSIM_DATA_LANE_4,
+ .e_byte_clk = DSIM_PLL_OUT_DIV8,
+ .e_burst_mode = DSIM_BURST,
+
+ .p = 3,
+ .m = 115,
+ .s = 1,
+
+ /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
+ .pll_stable_time = 500,
+
+ .esc_clk = 0.4 * 1000000, /* escape clk : 10MHz */
+
+ /* stop state holding counter after bta change count 0 ~ 0xfff */
+ .stop_holding_cnt = 0x0f,
+ .bta_timeout = 0xff, /* bta timeout 0 ~ 0xff */
+ .rx_timeout = 0xffff, /* lp rx timeout 0 ~ 0xffff */
+
+ .dsim_ddi_pd = &tc358764_mipi_lcd_driver,
+};
+
+static struct mipi_dsim_lcd_config dsim_lcd_info = {
+ .rgb_timing.left_margin = 0x4,
+ .rgb_timing.right_margin = 0x4,
+ .rgb_timing.upper_margin = 0x4,
+ .rgb_timing.lower_margin = 0x4,
+ .rgb_timing.hsync_len = 0x4,
+ .rgb_timing.vsync_len = 0x4,
+ .cpu_timing.cs_setup = 0,
+ .cpu_timing.wr_setup = 1,
+ .cpu_timing.wr_act = 0,
+ .cpu_timing.wr_hold = 0,
+ .lcd_size.width = 1280,
+ .lcd_size.height = 800,
+};
+#endif
+
+static struct s5p_platform_mipi_dsim dsim_platform_data = {
+ .clk_name = "dsim0",
+ .dsim_config = &dsim_info,
+ .dsim_lcd_config = &dsim_lcd_info,
+
+ .part_reset = s5p_dsim_part_reset,
+ .init_d_phy = s5p_dsim_init_d_phy,
+ .get_fb_frame_done = NULL,
+ .trigger = NULL,
+
+ /*
+ * the stable time of needing to write data on SFR
+ * when the mipi mode becomes LP mode.
+ */
+ .delay_for_stabilization = 600,
+};
+#endif
+
+#ifdef CONFIG_S5P_DP
+static struct video_info smdk5250_dp_config = {
+ .name = "WQXGA(2560x1600) LCD, for SMDK TEST",
+
+ .h_sync_polarity = 0,
+ .v_sync_polarity = 0,
+ .interlaced = 0,
+
+ .color_space = COLOR_RGB,
+ .dynamic_range = VESA,
+ .ycbcr_coeff = COLOR_YCBCR601,
+ .color_depth = COLOR_8,
+
+ .link_rate = LINK_RATE_2_70GBPS,
+ .lane_count = LANE_COUNT4,
+};
+
+static void s5p_dp_backlight_on(void)
+{
+ /* LED_BACKLIGHT_RESET: GPX1_5 */
+ gpio_request(EXYNOS5_GPX1(5), "GPX1");
+
+ gpio_direction_output(EXYNOS5_GPX1(5), 1);
+ msleep(20);
+
+ gpio_free(EXYNOS5_GPX1(5));
+}
+
+static void s5p_dp_backlight_off(void)
+{
+ /* LED_BACKLIGHT_RESET: GPX1_5 */
+ gpio_request(EXYNOS5_GPX1(5), "GPX1");
+
+ gpio_direction_output(EXYNOS5_GPX1(5), 0);
+ msleep(20);
+
+ gpio_free(EXYNOS5_GPX1(5));
+}
+
+static struct s5p_dp_platdata smdk5250_dp_data __initdata = {
+ .video_info = &smdk5250_dp_config,
+ .phy_init = s5p_dp_phy_init,
+ .phy_exit = s5p_dp_phy_exit,
+ .backlight_on = s5p_dp_backlight_on,
+ .backlight_off = s5p_dp_backlight_off,
+};
+#endif
+
+static struct platform_device *smdk5250_display_devices[] __initdata = {
+#ifdef CONFIG_FB_MIPI_DSIM
+ &smdk5250_mipi_lcd,
+ &s5p_device_mipi_dsim,
+#endif
+ &s5p_device_fimd1,
+#ifdef CONFIG_S5P_DP
+ &s5p_device_dp,
+ &smdk5250_dp_lcd,
+#endif
+};
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk5250_bl_gpio_info = {
+ .no = EXYNOS5_GPB2(0),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk5250_bl_data = {
+ .pwm_id = 0,
+ .pwm_period_ns = 30000,
+};
+
+void __init exynos5_smdk5250_display_init(void)
+{
+#ifdef CONFIG_FB_MIPI_DSIM
+ s5p_dsim_set_platdata(&dsim_platform_data);
+ s5p_device_mipi_dsim.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+#endif
+#ifdef CONFIG_S5P_DP
+ s5p_dp_set_platdata(&smdk5250_dp_data);
+ s5p_device_dp.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+#endif
+
+ s5p_device_fimd1.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+
+ dev_set_name(&s5p_device_fimd1.dev, "s3cfb.1");
+ clk_add_alias("lcd", "exynos5-fb.1", "lcd", &s5p_device_fimd1.dev);
+ clk_add_alias("sclk_fimd", "exynos5-fb.1", "sclk_fimd",
+ &s5p_device_fimd1.dev);
+ s5p_fb_setname(1, "exynos5-fb");
+
+ s5p_fimd1_set_platdata(&smdk5250_lcd1_pdata);
+
+ samsung_bl_set(&smdk5250_bl_gpio_info, &smdk5250_bl_data);
+
+ platform_add_devices(smdk5250_display_devices,
+ ARRAY_SIZE(smdk5250_display_devices));
+
+#ifdef CONFIG_S5P_DP
+ exynos4_fimd_setup_clock(&s5p_device_fimd1.dev,
+ "sclk_fimd", "mout_mpll_user", 267 * MHZ);
+#else
+ exynos4_fimd_setup_clock(&s5p_device_fimd1.dev,
+ "sclk_fimd", "mout_mpll_user", 800 * MHZ);
+#endif
+}
diff --git a/arch/arm/mach-exynos/board-smdk5250-input.c b/arch/arm/mach-exynos/board-smdk5250-input.c
new file mode 100644
index 0000000..f3ac26b
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-input.c
@@ -0,0 +1,117 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-input.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/iic.h>
+
+#include <mach/irqs.h>
+
+#include "board-smdk5250.h"
+
+static struct gpio_event_direct_entry smdk5250_keypad_key_map[] = {
+ {
+ .gpio = EXYNOS5_GPX0(0),
+ .code = KEY_POWER,
+ }
+};
+
+static struct gpio_event_input_info smdk5250_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdk5250_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdk5250_keypad_key_map)
+};
+
+static struct gpio_event_info *smdk5250_input_info[] = {
+ &smdk5250_keypad_key_info.info,
+};
+
+static struct gpio_event_platform_data smdk5250_input_data = {
+ .names = {
+ "smdk5250-keypad",
+ NULL,
+ },
+ .info = smdk5250_input_info,
+ .info_count = ARRAY_SIZE(smdk5250_input_info),
+};
+
+static struct platform_device smdk5250_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdk5250_input_data,
+ },
+};
+
+static void __init smdk5250_gpio_power_init(void)
+{
+ int err = 0;
+
+ err = gpio_request_one(EXYNOS5_GPX0(0), 0, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "suspend/resume control\n");
+ return;
+ }
+ s3c_gpio_setpull(EXYNOS5_GPX0(0), S3C_GPIO_PULL_NONE);
+
+ gpio_free(EXYNOS5_GPX0(0));
+}
+
+#ifdef CONFIG_WAKEUP_ASSIST
+static struct platform_device wakeup_assist_device = {
+ .name = "wakeup_assist",
+};
+#endif
+
+struct egalax_i2c_platform_data {
+ unsigned int gpio_int;
+ unsigned int gpio_en;
+ unsigned int gpio_rst;
+};
+
+static struct egalax_i2c_platform_data exynos5_egalax_data = {
+ .gpio_int = EXYNOS5_GPX3(1),
+};
+
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("egalax_i2c", 0x04),
+ .irq = IRQ_EINT(25),
+ .platform_data = &exynos5_egalax_data,
+ },
+};
+
+static struct platform_device *smdk5250_input_devices[] __initdata = {
+ &s3c_device_i2c7,
+ &smdk5250_input_device,
+#ifdef CONFIG_WAKEUP_ASSIST
+ &wakeup_assist_device,
+#endif
+};
+
+void __init exynos5_smdk5250_input_init(void)
+{
+ s3c_i2c7_set_platdata(NULL);
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+
+ smdk5250_gpio_power_init();
+
+ platform_add_devices(smdk5250_input_devices,
+ ARRAY_SIZE(smdk5250_input_devices));
+}
diff --git a/arch/arm/mach-exynos/board-smdk5250-mmc.c b/arch/arm/mach-exynos/board-smdk5250-mmc.c
new file mode 100644
index 0000000..f04a80a
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-mmc.c
@@ -0,0 +1,271 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-mmc.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/mmc/host.h>
+#include <linux/delay.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+
+#include <mach/dwmci.h>
+
+#include "board-smdk5250.h"
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+static void exynos_dwmci_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC0(0); gpio < EXYNOS5_GPC0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_8:
+ for (gpio = EXYNOS5_GPC1(3); gpio <= EXYNOS5_GPC1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC0(3); gpio <= EXYNOS5_GPC0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos_dwmci_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION |
+ DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 66 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci_cfg_gpio,
+};
+#endif
+
+static void exynos_dwmci0_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC0(0); gpio < EXYNOS5_GPC0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_8:
+ for (gpio = EXYNOS5_GPC1(0); gpio <= EXYNOS5_GPC1(3); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC0(3); gpio <= EXYNOS5_GPC0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board smdk5250_dwmci0_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION |
+ DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 100 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci0_cfg_gpio,
+};
+
+static int smdk5250_dwmci_get_ro(u32 slot_id)
+{
+ /* smdk5250 rev1.0 did not support SD/MMC card write pritect. */
+ return 0;
+}
+
+static void exynos_dwmci2_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC3(0); gpio < EXYNOS5_GPC3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC3(3); gpio <= EXYNOS5_GPC3(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC3(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+
+ gpio = EXYNOS5_GPC3(2);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+}
+
+static struct dw_mci_board smdk5250_dwmci2_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 100 * 1000 * 1000,
+ .caps = MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci2_cfg_gpio,
+ .get_ro = smdk5250_dwmci_get_ro,
+};
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdk5250_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdk5250_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdk5250_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdk5250_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+static struct platform_device *smdk5250_mmc_devices[] __initdata = {
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ &exynos_device_dwmci,
+ &exynos_device_dwmci0,
+ &exynos_device_dwmci2,
+#endif
+};
+
+void __init exynos5_smdk5250_mmc_init(void)
+{
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ exynos_dwmci_set_platdata(&smdk5250_dwmci0_pdata, 0);
+ dev_set_name(&exynos_device_dwmci0.dev, "s3c-sdhci.0");
+ clk_add_alias("dwmci", "dw_mmc.0", "hsmmc",
+ &exynos_device_dwmci0.dev);
+ clk_add_alias("sclk_dwmci", "dw_mmc.0", "sclk_mmc",
+ &exynos_device_dwmci0.dev);
+
+ exynos_dwmci_set_platdata(&smdk5250_dwmci2_pdata, 2);
+ dev_set_name(&exynos_device_dwmci2.dev, "s3c-sdhci.2");
+ clk_add_alias("dwmci", "dw_mmc.2", "hsmmc",
+ &exynos_device_dwmci2.dev);
+ clk_add_alias("sclk_dwmci", "dw_mmc.2", "sclk_mmc",
+ &exynos_device_dwmci2.dev);
+ } else
+#endif
+ {
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ exynos_dwmci_set_platdata(&exynos_dwmci_pdata, 0);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdk5250_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdk5250_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdk5250_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdk5250_hsmmc3_pdata);
+#endif
+ }
+
+ platform_add_devices(smdk5250_mmc_devices,
+ ARRAY_SIZE(smdk5250_mmc_devices));
+}
diff --git a/arch/arm/mach-exynos/board-smdk5250-power.c b/arch/arm/mach-exynos/board-smdk5250-power.c
new file mode 100644
index 0000000..c47fe4f
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-power.c
@@ -0,0 +1,808 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-power.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max77686.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/io.h>
+
+#include <plat/devs.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+
+#include <mach/ppmu.h>
+#include <mach/dev.h>
+#include <mach/regs-pmu.h>
+
+#ifdef CONFIG_REGULATOR_S5M8767
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#endif
+
+#if defined(CONFIG_EXYNOS_SETUP_THERMAL)
+#include <plat/s5p-tmu.h>
+#endif
+
+#include "board-smdk5250.h"
+
+#define REG_INFORM4 (S5P_INFORM4)
+
+/* max8997 */
+static struct regulator_consumer_supply max8997_buck1 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2 =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max8997_buck3 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max8997_buck4 =
+ REGULATOR_SUPPLY("vdd_mif", NULL);
+
+static struct regulator_consumer_supply __initdata ldo2_consumer =
+ REGULATOR_SUPPLY("vdd_ldo2", NULL);
+
+static struct regulator_consumer_supply __initdata ldo3_consumer =
+ REGULATOR_SUPPLY("vdd_ldo3", NULL);
+
+static struct regulator_consumer_supply __initdata ldo4_consumer =
+ REGULATOR_SUPPLY("vdd_ldo4", NULL);
+
+static struct regulator_consumer_supply __initdata ldo5_consumer =
+ REGULATOR_SUPPLY("vdd_ldo5", NULL);
+
+static struct regulator_consumer_supply __initdata ldo6_consumer =
+ REGULATOR_SUPPLY("vdd_ldo6", NULL);
+
+static struct regulator_consumer_supply __initdata ldo7_consumer =
+ REGULATOR_SUPPLY("vdd_ldo7", NULL);
+
+static struct regulator_consumer_supply __initdata ldo8_consumer =
+ REGULATOR_SUPPLY("vdd_ldo8", NULL);
+
+static struct regulator_consumer_supply __initdata ldo9_consumer =
+ REGULATOR_SUPPLY("vdd_ldo9", NULL);
+
+static struct regulator_consumer_supply __initdata ldo10_consumer =
+ REGULATOR_SUPPLY("vdd_ldo10", NULL);
+
+static struct regulator_consumer_supply __initdata ldo11_consumer =
+ REGULATOR_SUPPLY("vdd_ldo11", NULL);
+
+static struct regulator_consumer_supply __initdata ldo14_consumer =
+ REGULATOR_SUPPLY("vdd_ldo14", NULL);
+
+static struct regulator_consumer_supply __initdata ldo21_consumer =
+ REGULATOR_SUPPLY("vdd_ldo21", NULL);
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo2_data = {
+ .constraints = {
+ .name = "vdd_ldo2 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo2_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo3_data = {
+ .constraints = {
+ .name = "vdd_ldo3 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo3_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo4_data = {
+ .constraints = {
+ .name = "vdd_ldo4 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo4_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo5_data = {
+ .constraints = {
+ .name = "vdd_ldo5 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo5_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo6_data = {
+ .constraints = {
+ .name = "vdd_ldo6 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo6_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo7_data = {
+ .constraints = {
+ .name = "vdd_ldo7 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo7_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo8_data = {
+ .constraints = {
+ .name = "vdd_ldo8 range",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo8_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo9_data = {
+ .constraints = {
+ .name = "vdd_ldo9 range",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo9_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo10_data = {
+ .constraints = {
+ .name = "vdd_ldo10 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo10_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo11_data = {
+ .constraints = {
+ .name = "vdd_ldo11 range",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo11_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo14_data = {
+ .constraints = {
+ .name = "vdd_ldo14 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo14_consumer,
+};
+
+static struct regulator_init_data __initdata __maybe_unused max8997_ldo21_data = {
+ .constraints = {
+ .name = "vdd_ldo21 range",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo21_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_buck1_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1500000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck1,
+};
+
+static struct regulator_init_data __initdata max8997_buck2_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 950000,
+ .max_uV = 1150000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck2,
+};
+
+static struct regulator_init_data __initdata max8997_buck3_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck3,
+};
+
+static struct regulator_init_data __initdata max8997_buck4_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 950000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck4,
+};
+
+static struct max8997_regulator_data __initdata max8997_regulators[] = {
+ { MAX8997_LDO14, &max8997_ldo14_data, },
+ { MAX8997_BUCK1, &max8997_buck1_data, },
+ { MAX8997_BUCK2, &max8997_buck2_data, },
+ { MAX8997_BUCK3, &max8997_buck3_data, },
+ { MAX8997_BUCK4, &max8997_buck4_data, },
+};
+
+static struct max8997_platform_data __initdata smdk5250_max8997_info = {
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = max8997_regulators,
+
+ .buck1_voltage[0] = 1250000, /* 1.25V */
+ .buck1_voltage[1] = 1100000, /* 1.1V */
+ .buck1_voltage[2] = 1100000, /* 1.1V */
+ .buck1_voltage[3] = 1100000, /* 1.1V */
+ .buck1_voltage[4] = 1100000, /* 1.1V */
+ .buck1_voltage[5] = 1100000, /* 1.1V */
+ .buck1_voltage[6] = 1000000, /* 1.0V */
+ .buck1_voltage[7] = 950000, /* 0.95V */
+
+ .buck2_voltage[0] = 1150000, /* 1.15V */
+ .buck2_voltage[1] = 1000000, /* 1.0V */
+ .buck2_voltage[2] = 950000, /* 0.95V */
+ .buck2_voltage[3] = 900000, /* 0.9V */
+ .buck2_voltage[4] = 1000000, /* 1.0V */
+ .buck2_voltage[5] = 1000000, /* 1.0V */
+ .buck2_voltage[6] = 950000, /* 0.95V */
+ .buck2_voltage[7] = 900000, /* 0.9V */
+
+ .buck5_voltage[0] = 1100000, /* 1.2V */
+ .buck5_voltage[1] = 1100000, /* 1.1V */
+ .buck5_voltage[2] = 1100000, /* 1.1V */
+ .buck5_voltage[3] = 1100000, /* 1.1V */
+ .buck5_voltage[4] = 1100000, /* 1.1V */
+ .buck5_voltage[5] = 1100000, /* 1.1V */
+ .buck5_voltage[6] = 1100000, /* 1.1V */
+ .buck5_voltage[7] = 1100000, /* 1.1V */
+};
+
+/* max77686 */
+static struct regulator_consumer_supply max77686_buck1 =
+REGULATOR_SUPPLY("vdd_mif", NULL);
+
+static struct regulator_consumer_supply max77686_buck2 =
+REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3 =
+REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max77686_buck4 =
+REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max77686_ldo11_consumer =
+REGULATOR_SUPPLY("vdd_ldo11", NULL);
+
+static struct regulator_consumer_supply max77686_ldo14_consumer =
+REGULATOR_SUPPLY("vdd_ldo14", NULL);
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 950000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1350000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 900000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 700000,
+ .max_uV = 1300000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck4,
+};
+
+static struct regulator_init_data max77686_ldo11_data = {
+ .constraints = {
+ .name = "vdd_ldo11 range",
+ .min_uV = 1900000,
+ .max_uV = 1900000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_ldo11_consumer,
+};
+
+static struct regulator_init_data max77686_ldo14_data = {
+ .constraints = {
+ .name = "vdd_ldo14 range",
+ .min_uV = 1900000,
+ .max_uV = 1900000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_ldo14_consumer,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_LDO11, &max77686_ldo11_data,},
+ {MAX77686_LDO14, &max77686_ldo14_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+static struct max77686_platform_data smdk5250_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = 0,
+ .irq_base = 0,
+ .wakeup = 0,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+
+ .buck2_voltage[0] = 1300000, /* 1.3V */
+ .buck2_voltage[1] = 1000000, /* 1.0V */
+ .buck2_voltage[2] = 950000, /* 0.95V */
+ .buck2_voltage[3] = 900000, /* 0.9V */
+ .buck2_voltage[4] = 1000000, /* 1.0V */
+ .buck2_voltage[5] = 1000000, /* 1.0V */
+ .buck2_voltage[6] = 950000, /* 0.95V */
+ .buck2_voltage[7] = 900000, /* 0.9V */
+
+ .buck3_voltage[0] = 1037500, /* 1.0375V */
+ .buck3_voltage[1] = 1000000, /* 1.0V */
+ .buck3_voltage[2] = 950000, /* 0.95V */
+ .buck3_voltage[3] = 900000, /* 0.9V */
+ .buck3_voltage[4] = 1000000, /* 1.0V */
+ .buck3_voltage[5] = 1000000, /* 1.0V */
+ .buck3_voltage[6] = 950000, /* 0.95V */
+ .buck3_voltage[7] = 900000, /* 0.9V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1000000, /* 1.0V */
+ .buck4_voltage[2] = 950000, /* 0.95V */
+ .buck4_voltage[3] = 900000, /* 0.9V */
+ .buck4_voltage[4] = 1000000, /* 1.0V */
+ .buck4_voltage[5] = 1000000, /* 1.0V */
+ .buck4_voltage[6] = 950000, /* 0.95V */
+ .buck4_voltage[7] = 900000, /* 0.9V */
+};
+
+#ifdef CONFIG_REGULATOR_S5M8767
+/* S5M8767 Regulator */
+static int s5m_cfg_irq(void)
+{
+ /* AP_PMIC_IRQ: EINT26 */
+ s3c_gpio_cfgpin(EXYNOS5_GPX3(2), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS5_GPX3(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+
+static struct regulator_consumer_supply s5m8767_buck1_consumer =
+ REGULATOR_SUPPLY("vdd_mif", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck2_consumer =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck3_consumer =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck4_consumer =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_init_data s5m8767_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 950000,
+ .max_uV = 1300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck1_consumer,
+};
+
+static struct regulator_init_data s5m8767_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1350000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck2_consumer,
+};
+
+static struct regulator_init_data s5m8767_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 900000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck3_consumer,
+};
+
+static struct regulator_init_data s5m8767_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck4_consumer,
+};
+
+static struct s5m_regulator_data gaia_regulators[] = {
+ {S5M8767_BUCK1, &s5m8767_buck1_data},
+ {S5M8767_BUCK2, &s5m8767_buck2_data},
+ {S5M8767_BUCK3, &s5m8767_buck3_data},
+ {S5M8767_BUCK4, &s5m8767_buck4_data},
+};
+
+struct s5m_opmode_data s5m8767_opmode_data[S5M8767_REG_MAX] = {
+ [S5M8767_BUCK1] = {S5M8767_BUCK1, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK2] = {S5M8767_BUCK2, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK3] = {S5M8767_BUCK3, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK4] = {S5M8767_BUCK4, S5M_OPMODE_STANDBY},
+};
+
+static struct s5m_platform_data smdk5250_s5m8767_pdata = {
+ .device_type = S5M8767X,
+ .irq_base = IRQ_BOARD_START,
+ .num_regulators = ARRAY_SIZE(gaia_regulators),
+ .regulators = gaia_regulators,
+ .cfg_pmic_irq = s5m_cfg_irq,
+ .wakeup = 1,
+ .opmode_data = s5m8767_opmode_data,
+ .wtsr_smpl = 1,
+
+ .buck2_voltage[0] = 1250000,
+ .buck2_voltage[1] = 1200000,
+ .buck2_voltage[2] = 1150000,
+ .buck2_voltage[3] = 1100000,
+ .buck2_voltage[4] = 1050000,
+ .buck2_voltage[5] = 1000000,
+ .buck2_voltage[6] = 950000,
+ .buck2_voltage[7] = 900000,
+
+ .buck3_voltage[0] = 1100000,
+ .buck3_voltage[1] = 1000000,
+ .buck3_voltage[2] = 950000,
+ .buck3_voltage[3] = 900000,
+ .buck3_voltage[4] = 1100000,
+ .buck3_voltage[5] = 1000000,
+ .buck3_voltage[6] = 950000,
+ .buck3_voltage[7] = 900000,
+
+ .buck4_voltage[0] = 1200000,
+ .buck4_voltage[1] = 1150000,
+ .buck4_voltage[2] = 1200000,
+ .buck4_voltage[3] = 1100000,
+ .buck4_voltage[4] = 1100000,
+ .buck4_voltage[5] = 1100000,
+ .buck4_voltage[6] = 1100000,
+ .buck4_voltage[7] = 1100000,
+
+ .buck_ramp_delay = 25,
+ .buck2_ramp_enable = true,
+ .buck3_ramp_enable = true,
+ .buck4_ramp_enable = true,
+};
+/* End of S5M8767 */
+#endif
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+#ifdef CONFIG_REGULATOR_S5M8767
+ {
+ I2C_BOARD_INFO("s5m87xx", 0xCC >> 1),
+ .platform_data = &smdk5250_s5m8767_pdata,
+ .irq = IRQ_EINT(26),
+ },
+#else
+ {
+ I2C_BOARD_INFO("max8997", 0x66),
+ .platform_data = &smdk5250_max8997_info,
+ }, {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &smdk5250_max77686_info,
+ },
+#endif
+};
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+#endif
+
+static struct platform_device exynos5_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+
+#ifdef CONFIG_EXYNOS_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct tmu_data exynos_tmu_data __initdata = {
+ .ts = {
+ .stop_throttle = 82,
+ .start_throttle = 85,
+ .stop_warning = 95,
+ .start_warning = 103,
+ .start_tripping = 110, /* temp to do tripping */
+ },
+ .efuse_value = 55,
+ .slope = 0x10008802,
+ .mode = 0,
+};
+#endif
+
+static struct platform_device *smdk5250_power_devices[] __initdata = {
+ /* Samsung Power Domain */
+ &exynos5_device_pd[PD_MFC],
+ &exynos5_device_pd[PD_G3D],
+ &exynos5_device_pd[PD_ISP],
+ &exynos5_device_pd[PD_GSCL],
+ &exynos5_device_pd[PD_DISP1],
+ &s3c_device_i2c0,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+#ifdef CONFIG_EXYNOS_SETUP_THERMAL
+ &exynos_device_tmu,
+#endif
+ &exynos5_busfreq,
+};
+
+static int smdk5250_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ int mode = 0;
+
+ if ((code == SYS_RESTART) && _cmd)
+ if (!strcmp((char *)_cmd, "recovery"))
+ mode = 0xf;
+
+ __raw_writel(mode, REG_INFORM4);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block smdk5250_reboot_notifier = {
+ .notifier_call = smdk5250_notifier_call,
+};
+
+void __init exynos5_smdk5250_power_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+#if defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)
+ exynos_pd_enable(&exynos5_device_pd[PD_MFC].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_G3D].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_ISP].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_GSCL].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_DISP1].dev);
+#elif defined(CONFIG_EXYNOS_DEV_PD)
+ /*
+ * These power domains should be always on
+ * without runtime pm support.
+ */
+ exynos_pd_enable(&exynos5_device_pd[PD_MFC].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_G3D].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_ISP].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_GSCL].dev);
+ exynos_pd_enable(&exynos5_device_pd[PD_DISP1].dev);
+#endif
+
+#ifdef CONFIG_EXYNOS_SETUP_THERMAL
+ s5p_tmu_set_platdata(&exynos_tmu_data);
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_C], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_R1], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_L], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_RIGHT0_BUS], &exynos5_busfreq.dev);
+#endif
+ register_reboot_notifier(&smdk5250_reboot_notifier);
+
+ platform_add_devices(smdk5250_power_devices,
+ ARRAY_SIZE(smdk5250_power_devices));
+}
diff --git a/arch/arm/mach-exynos/board-smdk5250-spi.c b/arch/arm/mach-exynos/board-smdk5250-spi.c
new file mode 100644
index 0000000..0d149de
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-spi.c
@@ -0,0 +1,176 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-spi.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/s3c64xx-spi.h>
+
+#include <mach/spi-clocks.h>
+
+#include "board-smdk5250.h"
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS5_GPA2(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+};
+
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+ [0] = {
+ .line = EXYNOS5_GPA2(5),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi1_csi[0],
+ }
+};
+
+static struct s3c64xx_spi_csinfo spi2_csi[] = {
+ [0] = {
+ .line = EXYNOS5_GPB1(2),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi2_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi2_csi[0],
+ }
+};
+
+static struct platform_device *smdk5250_spi_devices[] __initdata = {
+ &exynos_device_spi0,
+ &exynos_device_spi1,
+ &exynos_device_spi2,
+};
+
+void __init exynos5_smdk5250_spi_init(void)
+{
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+ struct device *spi1_dev = &exynos_device_spi1.dev;
+ struct device *spi2_dev = &exynos_device_spi2.dev;
+
+ sclk = clk_get(spi0_dev, "sclk_spi0");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+ prnt = clk_get(spi0_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS5_GPA2(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS5_GPA2(1), 1);
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS5_GPA2(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+ sclk = clk_get(spi1_dev, "sclk_spi1");
+ if (IS_ERR(sclk))
+ dev_err(spi1_dev, "failed to get sclk for SPI-1\n");
+ prnt = clk_get(spi1_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi1_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS5_GPA2(5), "SPI_CS1")) {
+ gpio_direction_output(EXYNOS5_GPA2(5), 1);
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(5), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS5_GPA2(5), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi1_csi));
+ }
+
+ spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info));
+
+ sclk = clk_get(spi2_dev, "sclk_spi2");
+ if (IS_ERR(sclk))
+ dev_err(spi2_dev, "failed to get sclk for SPI-2\n");
+ prnt = clk_get(spi2_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi2_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS5_GPB1(2), "SPI_CS2")) {
+ gpio_direction_output(EXYNOS5_GPB1(2), 1);
+ s3c_gpio_cfgpin(EXYNOS5_GPB1(2), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS5_GPB1(2), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi2_csi));
+ }
+
+ spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
+
+ platform_add_devices(smdk5250_spi_devices,
+ ARRAY_SIZE(smdk5250_spi_devices));
+}
+#endif
diff --git a/arch/arm/mach-exynos/board-smdk5250-usb.c b/arch/arm/mach-exynos/board-smdk5250-usb.c
new file mode 100644
index 0000000..28b40da
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250-usb.c
@@ -0,0 +1,201 @@
+/* linux/arch/arm/mach-exynos/board-smdk5250-usb.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/platform_data/exynos_usb3_drd.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#include <plat/usb-switch.h>
+
+#include "board-smdk5250.h"
+
+static struct s5p_ehci_platdata smdk5250_ehci_pdata;
+
+static void __init smdk5250_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk5250_ehci_pdata;
+
+#ifndef CONFIG_USB_EXYNOS_SWITCH
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ if (gpio_request_one(EXYNOS5_GPX2(6), GPIOF_OUT_INIT_HIGH,
+ "HOST_VBUS_CONTROL"))
+ printk(KERN_ERR "failed to request gpio_host_vbus\n");
+ else {
+ s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPX2(6));
+ }
+ }
+#endif
+ s5p_ehci_set_platdata(pdata);
+}
+
+static struct s5p_ohci_platdata smdk5250_ohci_pdata;
+
+static void __init smdk5250_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk5250_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+
+/* USB GADGET */
+static struct s5p_usbgadget_platdata smdk5250_usbgadget_pdata;
+
+static void __init smdk5250_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdk5250_usbgadget_pdata;
+
+ s5p_usbgadget_set_platdata(pdata);
+}
+
+static struct exynos_usb3_drd_pdata smdk5250_ss_udc_pdata;
+
+static void __init smdk5250_ss_udc_init(void)
+{
+ struct exynos_usb3_drd_pdata *pdata = &smdk5250_ss_udc_pdata;
+
+ exynos_ss_udc_set_platdata(pdata);
+}
+
+static struct exynos_usb3_drd_pdata smdk5250_xhci_pdata;
+
+static void __init smdk5250_xhci_init(void)
+{
+ struct exynos_usb3_drd_pdata *pdata = &smdk5250_xhci_pdata;
+
+ exynos_xhci_set_platdata(pdata);
+}
+
+static struct s5p_usbswitch_platdata smdk5250_usbswitch_pdata;
+
+static void __init smdk5250_usbswitch_init(void)
+{
+ struct s5p_usbswitch_platdata *pdata = &smdk5250_usbswitch_pdata;
+ int err;
+
+ /* USB 2.0 detect GPIO */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ pdata->gpio_device_detect = 0;
+ pdata->gpio_host_vbus = 0;
+ } else {
+#if defined(CONFIG_USB_EHCI_S5P) || defined(CONFIG_USB_OHCI_S5P)
+ pdata->gpio_host_detect = EXYNOS5_GPX1(6);
+ err = gpio_request_one(pdata->gpio_host_detect, GPIOF_IN,
+ "HOST_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request host gpio\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_host_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_host_detect, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_host_detect);
+
+ pdata->gpio_host_vbus = EXYNOS5_GPX2(6);
+ err = gpio_request_one(pdata->gpio_host_vbus,
+ GPIOF_OUT_INIT_LOW,
+ "HOST_VBUS_CONTROL");
+ if (err) {
+ printk(KERN_ERR "failed to request host_vbus gpio\n");
+ return;
+ }
+
+ s3c_gpio_setpull(pdata->gpio_host_vbus, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_host_vbus);
+#endif
+
+#ifdef CONFIG_USB_S3C_OTGD
+ pdata->gpio_device_detect = EXYNOS5_GPX3(4);
+ err = gpio_request_one(pdata->gpio_device_detect, GPIOF_IN,
+ "DEVICE_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request device gpio\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_device_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_device_detect, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_device_detect);
+#endif
+ }
+
+ /* USB 3.0 DRD detect GPIO */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ pdata->gpio_drd_host_detect = 0;
+ pdata->gpio_drd_device_detect = 0;
+ } else {
+#ifdef CONFIG_USB_XHCI_EXYNOS
+ pdata->gpio_drd_host_detect = EXYNOS5_GPX1(7);
+ err = gpio_request_one(pdata->gpio_drd_host_detect, GPIOF_IN,
+ "DRD_HOST_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request drd_host gpio\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_drd_host_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_drd_host_detect,
+ S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_drd_host_detect);
+#endif
+
+#ifdef CONFIG_USB_EXYNOS_SS_UDC
+ pdata->gpio_drd_device_detect = EXYNOS5_GPX0(6);
+ err = gpio_request_one(pdata->gpio_drd_device_detect, GPIOF_IN,
+ "DRD_DEVICE_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request drd_device\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_drd_device_detect,
+ S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_drd_device_detect,
+ S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_drd_device_detect);
+#endif
+ }
+
+ s5p_usbswitch_set_platdata(pdata);
+}
+
+static struct platform_device *smdk5250_usb_devices[] __initdata = {
+ &s5p_device_ehci,
+ &s5p_device_ohci,
+ &s3c_device_usbgadget,
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#ifdef CONFIG_USB_ANDROID
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+ &exynos_device_ss_udc,
+ &exynos_device_xhci,
+};
+
+void __init exynos5_smdk5250_usb_init(void)
+{
+ smdk5250_ehci_init();
+ smdk5250_ohci_init();
+ smdk5250_usbgadget_init();
+ smdk5250_ss_udc_init();
+ smdk5250_xhci_init();
+ smdk5250_usbswitch_init();
+
+ platform_add_devices(smdk5250_usb_devices,
+ ARRAY_SIZE(smdk5250_usb_devices));
+}
diff --git a/arch/arm/mach-exynos/board-smdk5250.h b/arch/arm/mach-exynos/board-smdk5250.h
new file mode 100644
index 0000000..0395d9c
--- /dev/null
+++ b/arch/arm/mach-exynos/board-smdk5250.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_EXYNOS_BOARD_SMDK5250_H
+#define __MACH_EXYNOS_BOARD_SMDK5250_H
+
+void exynos5_smdk5250_mmc_init(void);
+void exynos5_smdk5250_display_init(void);
+void exynos5_smdk5250_power_init(void);
+void exynos5_smdk5250_audio_init(void);
+void exynos5_smdk5250_usb_init(void);
+void exynos5_smdk5250_input_init(void);
+void exynos5_smdk5250_spi_init(void);
+
+#endif
diff --git a/arch/arm/mach-exynos/board-u1-lgt-modems.c b/arch/arm/mach-exynos/board-u1-lgt-modems.c
new file mode 100644
index 0000000..9fce9e3
--- /dev/null
+++ b/arch/arm/mach-exynos/board-u1-lgt-modems.c
@@ -0,0 +1,1461 @@
+/* linux/arch/arm/mach-xxxx/board-u1-lgt-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/if_arp.h>
+
+/* inlcude platform specific file */
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <mach/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-srom.h>
+
+#include <plat/devs.h>
+#include <plat/ehci.h>
+
+#define SROM_CS0_BASE 0x04000000
+#define SROM_WIDTH 0x01000000
+#define SROM_NUM_ADDR_BITS 14
+
+/* For "bus width and wait control (BW)" register */
+enum sromc_attr {
+ SROMC_DATA_16 = 0x1, /* 16-bit data bus */
+ SROMC_BYTE_ADDR = 0x2, /* Byte base address */
+ SROMC_WAIT_EN = 0x4, /* Wait enabled */
+ SROMC_BYTE_EN = 0x8, /* Byte access enabled */
+ SROMC_MASK = 0xF
+};
+
+/* DPRAM configuration */
+struct sromc_cfg {
+ enum sromc_attr attr;
+ unsigned size;
+ unsigned csn; /* CSn # */
+ unsigned addr; /* Start address (physical) */
+ unsigned end; /* End address (physical) */
+};
+
+/* DPRAM access timing configuration */
+struct sromc_access_cfg {
+ u32 tacs; /* Address set-up before CSn */
+ u32 tcos; /* Chip selection set-up before OEn */
+ u32 tacc; /* Access cycle */
+ u32 tcoh; /* Chip selection hold on OEn */
+ u32 tcah; /* Address holding time after CSn */
+ u32 tacp; /* Page mode access cycle at Page mode */
+ u32 pmc; /* Page Mode config */
+};
+
+/* For CBP7.2 EDPRAM (External DPRAM) */
+#define CBP_EDPRAM_SIZE 0x8000 /* 32 KB */
+
+
+#define INT_MASK_REQ_ACK_F 0x0020
+#define INT_MASK_REQ_ACK_R 0x0010
+#define INT_MASK_RES_ACK_F 0x0008
+#define INT_MASK_RES_ACK_R 0x0004
+#define INT_MASK_SEND_F 0x0002
+#define INT_MASK_SEND_R 0x0001
+
+#define INT_MASK_REQ_ACK_RFS 0x0400 /* Request RES_ACK_RFS */
+#define INT_MASK_RES_ACK_RFS 0x0200 /* Response of REQ_ACK_RFS */
+#define INT_MASK_SEND_RFS 0x0100 /* Indicate sending RFS data */
+
+
+/* Function prototypes */
+static void config_dpram_port_gpio(void);
+static void init_sromc(void);
+static void setup_sromc(unsigned csn, struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg);
+static int __init init_modem(void);
+
+static struct sromc_cfg cbp_edpram_cfg = {
+ .attr = (SROMC_DATA_16 | SROMC_WAIT_EN | SROMC_BYTE_EN),
+ .size = CBP_EDPRAM_SIZE,
+};
+
+static struct sromc_access_cfg cbp_edpram_access_cfg[] = {
+ [DPRAM_SPEED_LOW] = {
+ .tacs = 0x2 << 28,
+ .tcos = 0x2 << 24,
+ .tacc = 0x3 << 16,
+ .tcoh = 0x2 << 12,
+ .tcah = 0x2 << 8,
+ .tacp = 0x2 << 4,
+ .pmc = 0x0 << 0,
+ },
+};
+
+/*
+ magic_code +
+ access_enable +
+ fmt_tx_head + fmt_tx_tail + fmt_tx_buff +
+ raw_tx_head + raw_tx_tail + raw_tx_buff +
+ fmt_rx_head + fmt_rx_tail + fmt_rx_buff +
+ raw_rx_head + raw_rx_tail + raw_rx_buff +
+ padding +
+ mbx_cp2ap +
+ mbx_ap2cp
+ = 2 +
+ 2 +
+ 2 + 2 + 4092 +
+ 2 + 2 + 12272 +
+ 2 + 2 + 4092 +
+ 2 + 2 + 12272 +
+ 16 +
+ 2 +
+ 2
+ = 32768
+*/
+
+#define CBP_DP_FMT_TX_BUFF_SZ 4092
+#define CBP_DP_RAW_TX_BUFF_SZ 12272
+#define CBP_DP_FMT_RX_BUFF_SZ 4092
+#define CBP_DP_RAW_RX_BUFF_SZ 12272
+
+#define MAX_CBP_EDPRAM_IPC_DEV 2 /* FMT, RAW */
+
+struct cbp_edpram_ipc_cfg {
+ u16 magic;
+ u16 access;
+
+ u16 fmt_tx_head;
+ u16 fmt_tx_tail;
+ u8 fmt_tx_buff[CBP_DP_FMT_TX_BUFF_SZ];
+
+ u16 raw_tx_head;
+ u16 raw_tx_tail;
+ u8 raw_tx_buff[CBP_DP_RAW_TX_BUFF_SZ];
+
+ u16 fmt_rx_head;
+ u16 fmt_rx_tail;
+ u8 fmt_rx_buff[CBP_DP_FMT_RX_BUFF_SZ];
+
+ u16 raw_rx_head;
+ u16 raw_rx_tail;
+ u8 raw_rx_buff[CBP_DP_RAW_RX_BUFF_SZ];
+
+ u8 padding[16];
+ u16 mbx_ap2cp;
+ u16 mbx_cp2ap;
+};
+
+struct cbp_edpram_boot_map {
+ u8 __iomem *buff;
+ u16 __iomem *frame_size;
+ u16 __iomem *tag;
+ u16 __iomem *count;
+};
+
+static struct dpram_ipc_map cbp_ipc_map;
+
+struct _param_nv {
+ unsigned char *addr;
+ unsigned int size;
+ unsigned int count;
+ unsigned int tag;
+};
+
+/*
+------------------
+Buffer : 31KByte
+------------------
+Reserved: 1014Byte
+------------------
+SIZE: 2Byte
+------------------
+TAG: 2Byte
+------------------
+COUNT: 2Byte
+------------------
+AP -> CP Intr : 2Byte
+------------------
+CP -> AP Intr : 2Byte
+------------------
+*/
+#define DP_BOOT_CLEAR_OFFSET 4
+#define DP_BOOT_RSRVD_OFFSET 0x7C00
+#define DP_BOOT_SIZE_OFFSET 0x7FF6
+#define DP_BOOT_TAG_OFFSET 0x7FF8
+#define DP_BOOT_COUNT_OFFSET 0x7FFA
+
+
+#define DP_BOOT_FRAME_SIZE_LIMIT 0x7C00 /* 31KB = 31744byte = 0x7C00 */
+
+
+struct _param_check {
+ unsigned int total_size;
+ unsigned int rest_size;
+ unsigned int send_size;
+ unsigned int copy_start;
+ unsigned int copy_complete;
+ unsigned int boot_complete;
+};
+
+static struct _param_nv *data_param;
+static struct _param_check check_param;
+
+static unsigned int boot_start_complete;
+static struct cbp_edpram_boot_map cbp_edpram_bt_map;
+
+static void cbp_edpram_reset(void);
+static void cbp_edpram_clr_intr(void);
+static u16 cbp_edpram_recv_intr(void);
+static void cbp_edpram_send_intr(u16 irq_mask);
+static u16 cbp_edpram_recv_msg(void);
+static void cbp_edpram_send_msg(u16 msg);
+
+static u16 cbp_edpram_get_magic(void);
+static void cbp_edpram_set_magic(u16 value);
+static u16 cbp_edpram_get_access(void);
+static void cbp_edpram_set_access(u16 value);
+
+static u32 cbp_edpram_get_tx_head(int dev_id);
+static u32 cbp_edpram_get_tx_tail(int dev_id);
+static void cbp_edpram_set_tx_head(int dev_id, u32 head);
+static void cbp_edpram_set_tx_tail(int dev_id, u32 tail);
+static u8 __iomem *cbp_edpram_get_tx_buff(int dev_id);
+static u32 cbp_edpram_get_tx_buff_size(int dev_id);
+
+static u32 cbp_edpram_get_rx_head(int dev_id);
+static u32 cbp_edpram_get_rx_tail(int dev_id);
+static void cbp_edpram_set_rx_head(int dev_id, u32 head);
+static void cbp_edpram_set_rx_tail(int dev_id, u32 tail);
+static u8 __iomem *cbp_edpram_get_rx_buff(int dev_id);
+static u32 cbp_edpram_get_rx_buff_size(int dev_id);
+
+static u16 cbp_edpram_get_mask_req_ack(int dev_id);
+static u16 cbp_edpram_get_mask_res_ack(int dev_id);
+static u16 cbp_edpram_get_mask_send(int dev_id);
+
+static void msm_vbus_on(void);
+static void msm_vbus_off(void);
+
+static void mdm_log_disp(struct modemlink_dpram_control *dpctl);
+static int mdm_uload_step1(struct modemlink_dpram_control *dpctl);
+static int mdm_uload_step2(void *arg, struct modemlink_dpram_control *dpctl);
+static int mdm_dload_prep(struct modemlink_dpram_control *dpctl);
+static int mdm_dload(void *arg, struct modemlink_dpram_control *dpctl);
+static int mdm_nv_load(void *arg, struct modemlink_dpram_control *dpctl);
+static int mdm_boot_start(struct modemlink_dpram_control *dpctl);
+static int mdm_boot_start_post_proc(void);
+static void mdm_boot_start_handler(struct modemlink_dpram_control *dpctl);
+static void mdm_dload_handler(struct modemlink_dpram_control *dpctl, u16 cmd);
+static void mdm_bt_map_init(struct modemlink_dpram_control *dpctl);
+static void mdm_load_init(struct modemlink_dpram_control *dpctl);
+
+static struct modemlink_dpram_control cbp_edpram_ctrl = {
+ .reset = cbp_edpram_reset,
+
+ .clear_intr = cbp_edpram_clr_intr,
+ .recv_intr = cbp_edpram_recv_intr,
+ .send_intr = cbp_edpram_send_intr,
+ .recv_msg = cbp_edpram_recv_msg,
+ .send_msg = cbp_edpram_send_msg,
+
+ .get_magic = cbp_edpram_get_magic,
+ .set_magic = cbp_edpram_set_magic,
+ .get_access = cbp_edpram_get_access,
+ .set_access = cbp_edpram_set_access,
+
+ .get_tx_head = cbp_edpram_get_tx_head,
+ .get_tx_tail = cbp_edpram_get_tx_tail,
+ .set_tx_head = cbp_edpram_set_tx_head,
+ .set_tx_tail = cbp_edpram_set_tx_tail,
+ .get_tx_buff = cbp_edpram_get_tx_buff,
+ .get_tx_buff_size = cbp_edpram_get_tx_buff_size,
+
+ .get_rx_head = cbp_edpram_get_rx_head,
+ .get_rx_tail = cbp_edpram_get_rx_tail,
+ .set_rx_head = cbp_edpram_set_rx_head,
+ .set_rx_tail = cbp_edpram_set_rx_tail,
+ .get_rx_buff = cbp_edpram_get_rx_buff,
+ .get_rx_buff_size = cbp_edpram_get_rx_buff_size,
+
+ .get_mask_req_ack = cbp_edpram_get_mask_req_ack,
+ .get_mask_res_ack = cbp_edpram_get_mask_res_ack,
+ .get_mask_send = cbp_edpram_get_mask_send,
+
+ .log_disp = mdm_log_disp,
+ .cpupload_step1 = mdm_uload_step1,
+ .cpupload_step2 = mdm_uload_step2,
+ .cpimage_load_prepare = mdm_dload_prep,
+ .cpimage_load = mdm_dload,
+ .nvdata_load = mdm_nv_load,
+ .phone_boot_start = mdm_boot_start,
+ .phone_boot_start_post_process = mdm_boot_start_post_proc,
+ .phone_boot_start_handler = mdm_boot_start_handler,
+ .dload_cmd_hdlr = mdm_dload_handler,
+ .bt_map_init = mdm_bt_map_init,
+ .load_init = mdm_load_init,
+
+ .dp_base = NULL,
+ .dp_size = 0,
+ .dp_type = EXT_DPRAM,
+
+ .dpram_irq = IRQ_EINT(8),
+ .dpram_irq_flags = IRQF_TRIGGER_FALLING,
+ .dpram_irq_name = "MDM6600_EDPRAM_IRQ",
+ .dpram_wlock_name = "MDM6600_EDPRAM_WLOCK",
+
+ .max_ipc_dev = IPC_RFS,
+};
+
+/*
+** CDMA target platform data
+*/
+static struct modem_io_t cdma_io_devices[] = {
+ [0] = {
+ .name = "cdma_boot0",
+ .id = 0x1,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [1] = {
+ .name = "cdma_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [2] = {
+ .name = "cdma_multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [3] = {
+ .name = "cdma_CSD",
+ .id = (1|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [4] = {
+ .name = "cdma_FOTA",
+ .id = (2|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [5] = {
+ .name = "cdma_GPS",
+ .id = (5|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [6] = {
+ .name = "cdma_XTRA",
+ .id = (6|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [7] = {
+ .name = "cdma_CDMA",
+ .id = (7|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [8] = {
+ .name = "cdma_EFS",
+ .id = (8|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [9] = {
+ .name = "cdma_TRFB",
+ .id = (9|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [10] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [11] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [12] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [13] = {
+ .name = "rmnet3",
+ .id = 0x2D,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [14] = {
+ .name = "cdma_SMD",
+ .id = (25|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [15] = {
+ .name = "cdma_VTVD",
+ .id = (26|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [16] = {
+ .name = "cdma_VTAD",
+ .id = (27|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [17] = {
+ .name = "cdma_VTCTRL",
+ .id = (28|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [18] = {
+ .name = "cdma_VTENT",
+ .id = (29|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [19] = {
+ .name = "cdma_ramdump0",
+ .id = 0x1,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+ [20] = {
+ .name = "umts_loopback0",
+ .id = (31|0x20),
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_DPRAM),
+ },
+};
+
+static struct modem_data cdma_modem_data = {
+ .name = "mdm6600",
+
+ .gpio_cp_on = GPIO_PHONE_ON,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_cp_reset_msm = GPIO_CP_RST_MSM,
+ .gpio_boot_sw_sel = GPIO_BOOT_SW_SEL,
+ .vbus_on = msm_vbus_on,
+ .vbus_off = msm_vbus_off,
+ .cp_vbus = NULL,
+ .gpio_cp_dump_int = 0,
+ .gpio_cp_warm_reset = 0,
+
+ .modem_net = CDMA_NETWORK,
+ .modem_type = QC_MDM6600,
+ .link_types = LINKTYPE(LINKDEV_DPRAM),
+ .link_name = "mdm6600_edpram",
+ .dpram_ctl = &cbp_edpram_ctrl,
+
+ .num_iodevs = ARRAY_SIZE(cdma_io_devices),
+ .iodevs = cdma_io_devices,
+
+ .use_handover = false,
+
+ .ipc_version = SIPC_VER_41,
+};
+
+static struct resource cdma_modem_res[] = {
+ [0] = {
+ .name = "cp_active_irq",
+ .start = IRQ_EINT(14),
+ .end = IRQ_EINT(14),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cdma_modem = {
+ .name = "modem_if",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cdma_modem_res),
+ .resource = cdma_modem_res,
+ .dev = {
+ .platform_data = &cdma_modem_data,
+ },
+};
+
+static void cbp_edpram_reset(void)
+{
+ return;
+}
+
+static void cbp_edpram_clr_intr(void)
+{
+ ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static u16 cbp_edpram_recv_intr(void)
+{
+ return ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static void cbp_edpram_send_intr(u16 irq_mask)
+{
+ iowrite16(irq_mask, cbp_ipc_map.mbx_ap2cp);
+}
+
+static u16 cbp_edpram_recv_msg(void)
+{
+ return ioread16(cbp_ipc_map.mbx_cp2ap);
+}
+
+static void cbp_edpram_send_msg(u16 msg)
+{
+ iowrite16(msg, cbp_ipc_map.mbx_ap2cp);
+}
+
+static u16 cbp_edpram_get_magic(void)
+{
+ return ioread16(cbp_ipc_map.magic);
+}
+
+static void cbp_edpram_set_magic(u16 value)
+{
+ iowrite16(value, cbp_ipc_map.magic);
+}
+
+static u16 cbp_edpram_get_access(void)
+{
+ return ioread16(cbp_ipc_map.access);
+}
+
+static void cbp_edpram_set_access(u16 value)
+{
+ iowrite16(value, cbp_ipc_map.access);
+}
+
+static u32 cbp_edpram_get_tx_head(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].txq.head);
+}
+
+static u32 cbp_edpram_get_tx_tail(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].txq.tail);
+}
+
+static void cbp_edpram_set_tx_head(int dev_id, u32 head)
+{
+ iowrite16((u16)head, cbp_ipc_map.dev[dev_id].txq.head);
+}
+
+static void cbp_edpram_set_tx_tail(int dev_id, u32 tail)
+{
+ iowrite16((u16)tail, cbp_ipc_map.dev[dev_id].txq.tail);
+}
+
+static u8 __iomem *cbp_edpram_get_tx_buff(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].txq.buff;
+}
+
+static u32 cbp_edpram_get_tx_buff_size(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].txq.size;
+}
+
+static u32 cbp_edpram_get_rx_head(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].rxq.head);
+}
+
+static u32 cbp_edpram_get_rx_tail(int dev_id)
+{
+ return ioread16(cbp_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static void cbp_edpram_set_rx_head(int dev_id, u32 head)
+{
+ return iowrite16((u16)head, cbp_ipc_map.dev[dev_id].rxq.head);
+}
+
+static void cbp_edpram_set_rx_tail(int dev_id, u32 tail)
+{
+ return iowrite16((u16)tail, cbp_ipc_map.dev[dev_id].rxq.tail);
+}
+
+static u8 __iomem *cbp_edpram_get_rx_buff(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].rxq.buff;
+}
+
+static u32 cbp_edpram_get_rx_buff_size(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].rxq.size;
+}
+
+static u16 cbp_edpram_get_mask_req_ack(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_req_ack;
+}
+
+static u16 cbp_edpram_get_mask_res_ack(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_res_ack;
+}
+
+static u16 cbp_edpram_get_mask_send(int dev_id)
+{
+ return cbp_ipc_map.dev[dev_id].mask_send;
+}
+
+static void msm_vbus_on(void)
+{
+ int err;
+
+ if (system_rev >= 0x06) {
+#ifdef GPIO_USB_BOOT_EN
+ pr_info("%s : set USB_BOOT_EN\n", __func__);
+ gpio_request(GPIO_USB_BOOT_EN, "USB_BOOT_EN");
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ gpio_free(GPIO_USB_BOOT_EN);
+#endif
+ } else {
+#ifdef GPIO_USB_OTG_EN
+ gpio_request(GPIO_USB_OTG_EN, "USB_OTG_EN");
+ gpio_direction_output(GPIO_USB_OTG_EN, 1);
+ gpio_free(GPIO_USB_OTG_EN);
+#endif
+ }
+ mdelay(10);
+
+ if (!cdma_modem_data.cp_vbus) {
+ cdma_modem_data.cp_vbus = regulator_get(NULL, "safeout2");
+ if (IS_ERR(cdma_modem_data.cp_vbus)) {
+ err = PTR_ERR(cdma_modem_data.cp_vbus);
+ pr_err(" <%s> regualtor: %d\n", __func__, err);
+ cdma_modem_data.cp_vbus = NULL;
+ }
+ }
+
+ if (cdma_modem_data.cp_vbus) {
+ pr_info("%s\n", __func__);
+ regulator_enable(cdma_modem_data.cp_vbus);
+ }
+}
+
+static void msm_vbus_off(void)
+{
+ if (cdma_modem_data.cp_vbus) {
+ pr_info("%s\n", __func__);
+ regulator_disable(cdma_modem_data.cp_vbus);
+ }
+
+ if (system_rev >= 0x06) {
+#ifdef GPIO_USB_BOOT_EN
+ gpio_request(GPIO_USB_BOOT_EN, "USB_BOOT_EN");
+ gpio_direction_output(GPIO_USB_BOOT_EN, 0);
+ gpio_free(GPIO_USB_BOOT_EN);
+#endif
+ } else {
+#ifdef GPIO_USB_OTG_EN
+ gpio_request(GPIO_USB_OTG_EN, "USB_OTG_EN");
+ gpio_direction_output(GPIO_USB_OTG_EN, 0);
+ gpio_free(GPIO_USB_OTG_EN);
+#endif
+ }
+
+}
+
+static void mdm_log_disp(struct modemlink_dpram_control *dpctl)
+{
+ static unsigned char buf[151];
+ u8 __iomem *tmp_buff = NULL;
+
+ tmp_buff = dpctl->get_rx_buff(IPC_FMT);
+ memcpy(buf, tmp_buff, (sizeof(buf)-1));
+
+ pr_info("[LNK] | PHONE ERR MSG\t| CDMA Crash\n");
+ pr_info("[LNK] | PHONE ERR MSG\t| %s\n", buf);
+}
+
+static int mdm_data_upload(struct _param_nv *param,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ u16 in_interrupt = 0;
+ int count = 0;
+
+ while (1) {
+ if (!gpio_get_value(GPIO_DPRAM_INT_N)) {
+ in_interrupt = dpctl->recv_msg();
+ if (in_interrupt == 0xDBAB) {
+ break;
+ } else {
+ pr_err("[LNK][intr]:0x%08x\n", in_interrupt);
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+ msleep_interruptible(1);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ param->size = ioread16(cbp_edpram_bt_map.frame_size);
+ memcpy(param->addr, cbp_edpram_bt_map.buff, param->size);
+ param->tag = ioread16(cbp_edpram_bt_map.tag);
+ param->count = ioread16(cbp_edpram_bt_map.count);
+
+ dpctl->clear_intr();
+ dpctl->send_msg(0xDB12);
+
+ return retval;
+
+}
+
+static int mdm_data_load(struct _param_nv *param,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+
+ if (param->size <= DP_BOOT_FRAME_SIZE_LIMIT) {
+ memcpy(cbp_edpram_bt_map.buff, param->addr, param->size);
+ iowrite16(param->size, cbp_edpram_bt_map.frame_size);
+ iowrite16(param->tag, cbp_edpram_bt_map.tag);
+ iowrite16(param->count, cbp_edpram_bt_map.count);
+
+ dpctl->clear_intr();
+ dpctl->send_msg(0xDB12);
+
+ } else {
+ pr_err("[LNK/E]<%s> size:0x%x\n", __func__, param->size);
+ }
+
+ return retval;
+}
+
+static int mdm_uload_step1(struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ u16 in_interrupt = 0, out_interrupt = 0;
+
+ pr_info("[LNK] +---------------------------------------------+\n");
+ pr_info("[LNK] | UPLOAD PHONE SDRAM |\n");
+ pr_info("[LNK] +---------------------------------------------+\n");
+
+ while (1) {
+ if (!gpio_get_value(GPIO_DPRAM_INT_N)) {
+ in_interrupt = dpctl->recv_msg();
+ pr_info("[LNK] [in_interrupt] 0x%04x\n", in_interrupt);
+ if (in_interrupt == 0x1234) {
+ break;
+ } else {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+ msleep_interruptible(1);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ in_interrupt = dpctl->recv_msg();
+ if (in_interrupt == 0x1234) {
+ pr_info("[LNK] [in_interrupt]: 0x%04x\n",
+ in_interrupt);
+ break;
+ }
+ return -1;
+ }
+ }
+ out_interrupt = 0xDEAD;
+ dpctl->send_msg(out_interrupt);
+
+ return retval;
+}
+
+static int mdm_uload_step2(void *arg,
+ struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ retval = mdm_data_upload(&param, dpctl);
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ if (!(param.count % 500))
+ pr_info("[LNK] [param->count]:%d\n", param.count);
+
+ if (param.tag == 4) {
+ dpctl->clear_intr();
+ enable_irq(cbp_edpram_ctrl.dpram_irq);
+ pr_info("[LNK] [param->tag]:%d\n", param.tag);
+ }
+
+ retval = copy_to_user((unsigned long *)arg, &param, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ return retval;
+}
+
+static int mdm_dload_prep(struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+
+ while (1) {
+ if (check_param.copy_start) {
+ check_param.copy_start = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return retval;
+}
+
+static int mdm_dload(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ unsigned char *img = NULL;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ img = vmalloc(param.size);
+ if (img == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ memset(img, 0, param.size);
+ memcpy(img, param.addr, param.size);
+
+ data_param = kzalloc(sizeof(struct _param_nv), GFP_KERNEL);
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ return -1;
+ }
+
+ check_param.total_size = param.size;
+ check_param.rest_size = param.size;
+ check_param.send_size = 0;
+ check_param.copy_complete = 0;
+
+ data_param->addr = img;
+ data_param->size = DP_BOOT_FRAME_SIZE_LIMIT;
+ data_param->count = param.count;
+ data_param->tag = param.tag;
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ retval = mdm_data_load(data_param, dpctl);
+
+ while (1) {
+ if (check_param.copy_complete) {
+ check_param.copy_complete = 0;
+
+ vfree(img);
+ kfree(data_param);
+
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 2000) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ kfree(data_param);
+ return -1;
+ }
+ }
+
+ return retval;
+
+}
+
+static int mdm_nv_load(void *arg, struct modemlink_dpram_control *dpctl)
+{
+ int retval = 0;
+ int count = 0;
+ unsigned char *img = NULL;
+ struct _param_nv param;
+
+ retval = copy_from_user((void *)&param, (void *)arg, sizeof(param));
+ if (retval < 0) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+
+ img = vmalloc(param.size);
+ if (img == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ memset(img, 0, param.size);
+ memcpy(img, param.addr, param.size);
+
+ data_param = kzalloc(sizeof(struct _param_nv), GFP_KERNEL);
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ return -1;
+ }
+
+ check_param.total_size = param.size;
+ check_param.rest_size = param.size;
+ check_param.send_size = 0;
+ check_param.copy_complete = 0;
+
+ data_param->addr = img;
+ data_param->size = DP_BOOT_FRAME_SIZE_LIMIT;
+ data_param->count = param.count;
+ data_param->tag = param.tag;
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+ retval = mdm_data_load(data_param, dpctl);
+
+ while (1) {
+ if (check_param.copy_complete) {
+ check_param.copy_complete = 0;
+
+ vfree(img);
+ kfree(data_param);
+
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ vfree(img);
+ kfree(data_param);
+ return -1;
+ }
+ }
+
+ return retval;
+
+}
+
+static int mdm_boot_start(struct modemlink_dpram_control *dpctl)
+{
+
+ u16 out_interrupt = 0;
+ int count = 0;
+
+ /* Send interrupt -> '0x4567' */
+ out_interrupt = 0x4567;
+ dpctl->send_msg(out_interrupt);
+
+ while (1) {
+ if (check_param.boot_complete) {
+ check_param.boot_complete = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static struct modemlink_dpram_control *tasklet_dpctl;
+
+static void interruptable_load_tasklet_handler(unsigned long data);
+
+static DECLARE_TASKLET(interruptable_load_tasklet,
+ interruptable_load_tasklet_handler, (unsigned long) &tasklet_dpctl);
+
+static void interruptable_load_tasklet_handler(unsigned long data)
+{
+ struct modemlink_dpram_control *dpctl =
+ (struct modemlink_dpram_control *)
+ (*((struct modemlink_dpram_control **) data));
+
+ if (data_param == NULL) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return;
+ }
+
+ check_param.send_size += data_param->size;
+ check_param.rest_size -= data_param->size;
+ data_param->addr += data_param->size;
+
+ if (check_param.send_size < check_param.total_size) {
+
+ if (check_param.rest_size < DP_BOOT_FRAME_SIZE_LIMIT)
+ data_param->size = check_param.rest_size;
+
+
+ data_param->count += 1;
+
+ mdm_data_load(data_param, dpctl);
+ } else {
+ data_param->tag = 0;
+ check_param.copy_complete = 1;
+ }
+
+}
+
+static int mdm_boot_start_post_proc(void)
+{
+ int count = 0;
+
+ while (1) {
+ if (boot_start_complete) {
+ boot_start_complete = 0;
+ break;
+ }
+ msleep_interruptible(10);
+ count++;
+ if (count > 200) {
+ pr_err("[LNK/E]<%s:%d>\n", __func__, __LINE__);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void mdm_boot_start_handler(struct modemlink_dpram_control *dpctl)
+{
+ boot_start_complete = 1;
+
+ /* Send INIT_END code to CP */
+ pr_info("[LNK] <%s> Send 0x11C2 (INIT_END)\n", __func__);
+
+ /*
+ * INT_MASK_VALID|INT_MASK_CMD|INT_MASK_CP_AIRPLANE_BOOT|
+ * INT_MASK_CP_AP_ANDROID|INT_MASK_CMD_INIT_END
+ */
+ dpctl->send_intr((0x0080|0x0040|0x1000|0x0100|0x0002));
+}
+
+static void mdm_dload_handler(struct modemlink_dpram_control *dpctl, u16 cmd)
+{
+ switch (cmd) {
+ case 0x1234:
+ check_param.copy_start = 1;
+ break;
+
+ case 0xDBAB:
+ tasklet_schedule(&interruptable_load_tasklet);
+ break;
+
+ case 0xABCD:
+ check_param.boot_complete = 1;
+ break;
+
+ default:
+ pr_err("[LNK/Err] <%s> Unknown command.. %x\n", __func__, cmd);
+ }
+}
+
+static void mdm_bt_map_init(struct modemlink_dpram_control *dpctl)
+{
+ cbp_edpram_bt_map.buff = (u8 *)(dpctl->dp_base);
+ cbp_edpram_bt_map.frame_size =
+ (u16 *)(dpctl->dp_base + DP_BOOT_SIZE_OFFSET);
+ cbp_edpram_bt_map.tag =
+ (u16 *)(dpctl->dp_base + DP_BOOT_TAG_OFFSET);
+ cbp_edpram_bt_map.count =
+ (u16 *)(dpctl->dp_base + DP_BOOT_COUNT_OFFSET);
+}
+
+
+static void mdm_load_init(struct modemlink_dpram_control *dpctl)
+{
+ tasklet_dpctl = dpctl;
+ if (tasklet_dpctl == NULL)
+ pr_err("[LNK/Err] failed tasklet_dpctl remap\n");
+
+ check_param.total_size = 0;
+ check_param.rest_size = 0;
+ check_param.send_size = 0;
+ check_param.copy_start = 0;
+ check_param.copy_complete = 0;
+ check_param.boot_complete = 0;
+
+ dpctl->clear_intr();
+}
+
+static void config_cdma_modem_gpio(void)
+{
+ int err;
+
+ unsigned gpio_cp_on = cdma_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = cdma_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = cdma_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = cdma_modem_data.gpio_phone_active;
+ unsigned gpio_cp_reset_msm = cdma_modem_data.gpio_cp_reset_msm;
+ unsigned gpio_boot_sw_sel = cdma_modem_data.gpio_boot_sw_sel;
+
+ pr_info("[MDM] <%s>\n", __func__);
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CP_ON");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "CP_ON", err);
+ }
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "CP_RST", err);
+ }
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+
+ if (gpio_cp_reset_msm) {
+ err = gpio_request(gpio_cp_reset_msm, "CP_RST_MSM");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "CP_RST_MSM", err);
+ }
+ gpio_direction_output(gpio_cp_reset_msm, 0);
+ s3c_gpio_cfgpin(gpio_cp_reset_msm, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(gpio_cp_reset_msm, S3C_GPIO_PULL_NONE);
+ }
+
+ if (gpio_boot_sw_sel) {
+ err = gpio_request(gpio_boot_sw_sel, "BOOT_SW_SEL");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "BOOT_SW_SEL", err);
+ }
+ gpio_direction_output(gpio_boot_sw_sel, 0);
+ s3c_gpio_setpull(gpio_boot_sw_sel, S3C_GPIO_PULL_NONE);
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "PDA_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "PHONE_ACTIVE", err);
+ }
+ gpio_direction_input(gpio_phone_active);
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ }
+
+ printk(KERN_INFO "<%s> done\n", __func__);
+}
+
+
+static u8 *cbp_edpram_remap_mem_region(struct sromc_cfg *cfg)
+{
+ int dp_addr = 0;
+ int dp_size = 0;
+ u8 __iomem *dp_base = NULL;
+ struct cbp_edpram_ipc_cfg *ipc_map = NULL;
+ struct dpram_ipc_device *dev = NULL;
+
+ dp_addr = cfg->addr;
+ dp_size = cfg->size;
+ dp_base = (u8 *)ioremap_nocache(dp_addr, dp_size);
+ if (!dp_base) {
+ pr_err("[MDM] <%s> dpram base ioremap fail\n", __func__);
+ return NULL;
+ }
+ pr_info("[MDM] <%s> DPRAM VA=0x%08X\n", __func__, (int)dp_base);
+
+ cbp_edpram_ctrl.dp_base = (u8 __iomem *)dp_base;
+ cbp_edpram_ctrl.dp_size = dp_size;
+
+ /* Map for IPC */
+ ipc_map = (struct cbp_edpram_ipc_cfg *)dp_base;
+
+ /* Magic code and access enable fields */
+ cbp_ipc_map.magic = (u16 __iomem *)&ipc_map->magic;
+ cbp_ipc_map.access = (u16 __iomem *)&ipc_map->access;
+
+ /* FMT */
+ dev = &cbp_ipc_map.dev[IPC_FMT];
+
+ strcpy(dev->name, "FMT");
+ dev->id = IPC_FMT;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->fmt_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->fmt_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->fmt_tx_buff[0];
+ dev->txq.size = CBP_DP_FMT_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->fmt_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->fmt_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->fmt_rx_buff[0];
+ dev->rxq.size = CBP_DP_FMT_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_F;
+ dev->mask_res_ack = INT_MASK_RES_ACK_F;
+ dev->mask_send = INT_MASK_SEND_F;
+
+ /* RAW */
+ dev = &cbp_ipc_map.dev[IPC_RAW];
+
+ strcpy(dev->name, "RAW");
+ dev->id = IPC_RAW;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->raw_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->raw_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->raw_tx_buff[0];
+ dev->txq.size = CBP_DP_RAW_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->raw_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->raw_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->raw_rx_buff[0];
+ dev->rxq.size = CBP_DP_RAW_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_R;
+ dev->mask_res_ack = INT_MASK_RES_ACK_R;
+ dev->mask_send = INT_MASK_SEND_R;
+
+#if 0
+ /* RFS */
+ dev = &cbp_ipc_map.dev[IPC_RFS];
+
+ strcpy(dev->name, "RFS");
+ dev->id = IPC_RFS;
+
+ dev->txq.head = (u16 __iomem *)&ipc_map->rfs_tx_head;
+ dev->txq.tail = (u16 __iomem *)&ipc_map->rfs_tx_tail;
+ dev->txq.buff = (u8 __iomem *)&ipc_map->rfs_tx_buff[0];
+ dev->txq.size = CBP_DP_RFS_TX_BUFF_SZ;
+
+ dev->rxq.head = (u16 __iomem *)&ipc_map->rfs_rx_head;
+ dev->rxq.tail = (u16 __iomem *)&ipc_map->rfs_rx_tail;
+ dev->rxq.buff = (u8 __iomem *)&ipc_map->rfs_rx_buff[0];
+ dev->rxq.size = CBP_DP_RFS_RX_BUFF_SZ;
+
+ dev->mask_req_ack = INT_MASK_REQ_ACK_RFS;
+ dev->mask_res_ack = INT_MASK_RES_ACK_RFS;
+ dev->mask_send = INT_MASK_SEND_RFS;
+#endif
+
+ /* Mailboxes */
+ cbp_ipc_map.mbx_ap2cp = (u16 __iomem *)&ipc_map->mbx_ap2cp;
+ cbp_ipc_map.mbx_cp2ap = (u16 __iomem *)&ipc_map->mbx_cp2ap;
+
+ return dp_base;
+}
+
+/**
+ * DPRAM GPIO settings
+ *
+ * SROM_NUM_ADDR_BITS value indicate the address line number or
+ * the mux/demux dpram type. if you want to set mux mode, define the
+ * SROM_NUM_ADDR_BITS to zero.
+ *
+ * for CMC22x
+ * CMC22x has 16KB + a SFR register address.
+ * It used 14 bits (13bits for 16KB word address and 1 bit for SFR
+ * register)
+ */
+static void config_dpram_port_gpio(void)
+{
+ int addr_bits = SROM_NUM_ADDR_BITS;
+
+ pr_info("[MDM] <%s> address line = %d bits\n", __func__, addr_bits);
+
+ /*
+ ** Config DPRAM address/data GPIO pins
+ */
+
+ /* Set GPIO for dpram address */
+ switch (addr_bits) {
+ case 0:
+ break;
+
+ case 13 ... 14:
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY3(0), EXYNOS4_GPIO_Y3_NR,
+ S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY4(0),
+ addr_bits - EXYNOS4_GPIO_Y3_NR, S3C_GPIO_SFN(2));
+ pr_info("[MDM] <%s> last data gpio EXYNOS4_GPY4(0) ~ %d\n",
+ __func__, addr_bits - EXYNOS4_GPIO_Y3_NR);
+ break;
+
+ default:
+ pr_err("[MDM/E] <%s> Invalid addr_bits!!!\n", __func__);
+ return;
+ }
+
+ /* Set GPIO for dpram data - 16bit */
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY5(0), 8, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPY6(0), 8, S3C_GPIO_SFN(2));
+
+ /* Setup SROMC CSn pins */
+ s3c_gpio_cfgpin(GPIO_DPRAM_CSN0, S3C_GPIO_SFN(2));
+
+ /* Config OEn, WEn */
+ s3c_gpio_cfgrange_nopull(GPIO_DPRAM_REN, 2, S3C_GPIO_SFN(2));
+
+ /* Config LBn, UBn */
+ s3c_gpio_cfgrange_nopull(GPIO_DPRAM_LBN, 2, S3C_GPIO_SFN(2));
+}
+
+static void init_sromc(void)
+{
+ struct clk *clk = NULL;
+
+ /* SROMC clk enable */
+ clk = clk_get(NULL, "sromc");
+ if (!clk) {
+ pr_err("[MDM/E] <%s> SROMC clock gate fail\n", __func__);
+ return;
+ }
+ clk_enable(clk);
+}
+
+static void setup_sromc
+(
+ unsigned csn,
+ struct sromc_cfg *cfg,
+ struct sromc_access_cfg *acc_cfg
+)
+{
+ unsigned bw = 0;
+ unsigned bc = 0;
+ void __iomem *bank_sfr = S5P_SROM_BC0 + (4 * csn);
+
+ pr_err("[MDM] <%s> SROMC settings for CS%d...\n", __func__, csn);
+
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> Old SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+
+ /* Set the BW control field for the CSn */
+ bw &= ~(SROMC_MASK << (csn << 2));
+ bw |= (cfg->attr << (csn << 2));
+ writel(bw, S5P_SROM_BW);
+
+ /* Set SROMC memory access timing for the CSn */
+ bc = acc_cfg->tacs | acc_cfg->tcos | acc_cfg->tacc |
+ acc_cfg->tcoh | acc_cfg->tcah | acc_cfg->tacp | acc_cfg->pmc;
+
+ writel(bc, bank_sfr);
+
+ /* Verify SROMC settings */
+ bw = __raw_readl(S5P_SROM_BW);
+ bc = __raw_readl(bank_sfr);
+ pr_err("[MDM] <%s> New SROMC settings = BW(0x%08X), BC%d(0x%08X)\n",
+ __func__, bw, csn, bc);
+}
+
+static int __init init_modem(void)
+{
+ struct sromc_cfg *cfg = NULL;
+ struct sromc_access_cfg *acc_cfg = NULL;
+
+ cbp_edpram_cfg.csn = 0;
+ cbp_edpram_ctrl.dpram_irq = IRQ_EINT(8);
+ cbp_edpram_cfg.addr = SROM_CS0_BASE + (SROM_WIDTH * cbp_edpram_cfg.csn);
+ cbp_edpram_cfg.end = cbp_edpram_cfg.addr + cbp_edpram_cfg.size - 1;
+
+ config_dpram_port_gpio();
+ config_cdma_modem_gpio();
+
+ init_sromc();
+
+ cfg = &cbp_edpram_cfg;
+ acc_cfg = &cbp_edpram_access_cfg[DPRAM_SPEED_LOW];
+ setup_sromc(cfg->csn, cfg, acc_cfg);
+
+ if (!cbp_edpram_remap_mem_region(&cbp_edpram_cfg))
+ return -1;
+ platform_device_register(&cdma_modem);
+
+ return 0;
+}
+late_initcall(init_modem);
+/*device_initcall(init_modem);*/
diff --git a/arch/arm/mach-exynos/board-u1-modems.c b/arch/arm/mach-exynos/board-u1-modems.c
new file mode 100644
index 0000000..1b35070
--- /dev/null
+++ b/arch/arm/mach-exynos/board-u1-modems.c
@@ -0,0 +1,512 @@
+/* linux/arch/arm/mach-xxxx/board-midas-modems.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/regulator/machine.h>
+
+#include <plat/gpio-cfg.h>
+
+#include <linux/platform_data/modem.h>
+#include <mach/sec_modem.h>
+#include <linux/interrupt.h>
+
+/* umts target platform data */
+static struct modem_io_t umts_io_devices[] = {
+ [0] = {
+ .name = "umts_ipc0",
+ .id = 0x1,
+ .format = IPC_FMT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [1] = {
+ .name = "umts_rfs0",
+ .id = 0x41,
+ .format = IPC_RFS,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [2] = {
+ .name = "umts_boot0",
+ .id = 0x0,
+ .format = IPC_BOOT,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [3] = {
+ .name = "multipdp",
+ .id = 0x1,
+ .format = IPC_MULTI_RAW,
+ .io_type = IODEV_DUMMY,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [4] = {
+ .name = "rmnet0",
+ .id = 0x2A,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [5] = {
+ .name = "rmnet1",
+ .id = 0x2B,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [6] = {
+ .name = "rmnet2",
+ .id = 0x2C,
+ .format = IPC_RAW,
+ .io_type = IODEV_NET,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [7] = {
+ .name = "umts_router",
+ .id = 0x39,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [8] = {
+ .name = "umts_csd",
+ .id = 0x21,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [9] = {
+ .name = "umts_ramdump0",
+ .id = 0x0,
+ .format = IPC_RAMDUMP,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+ [10] = {
+ .name = "umts_loopback0",
+ .id = 0x3f,
+ .format = IPC_RAW,
+ .io_type = IODEV_MISC,
+ .links = LINKTYPE(LINKDEV_HSIC),
+ },
+};
+
+/* To get modem state, register phone active irq using resource */
+static struct resource umts_modem_res[] = {
+ [0] = {
+ .name = "umts_phone_active",
+ .start = IRQ_EINT14, /* GPIO_PHONE_ACTIVE */
+ .end = IRQ_EINT14, /* GPIO_PHONE_ACTIVE */
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .name = "link_pm_hostwake",
+ .start = IRQ_EINT9, /* GPIO_IPC_HOST_WAKEUP */
+ .end = IRQ_EINT9, /* GPIO_IPC_HOST_WAKEUP */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int umts_link_ldo_enble(bool enable)
+{
+ /* Exynos HSIC V1.2 LDO was controlled by kernel */
+ return 0;
+}
+
+
+static void xmm_gpio_revers_bias_clear(void);
+static void xmm_gpio_revers_bias_restore(void);
+
+
+static int umts_link_reconnect(void);
+static struct modemlink_pm_data modem_link_pm_data = {
+ .name = "link_pm",
+ .link_ldo_enable = umts_link_ldo_enble,
+ .gpio_link_enable = 0,
+ .gpio_link_active = GPIO_ACTIVE_STATE,
+ .gpio_link_hostwake = GPIO_IPC_HOST_WAKEUP,
+ .gpio_link_slavewake = GPIO_IPC_SLAVE_WAKEUP,
+ .link_reconnect = umts_link_reconnect,
+};
+
+static struct modemlink_pm_link_activectl active_ctl;
+
+static struct modem_data umts_modem_data = {
+ .name = "xmm6260",
+
+ .gpio_cp_on = GPIO_PHONE_ON,
+ .gpio_reset_req_n = GPIO_CP_REQ_RESET,
+ .gpio_cp_reset = GPIO_CP_RST,
+ .gpio_pda_active = GPIO_PDA_ACTIVE,
+ .gpio_phone_active = GPIO_PHONE_ACTIVE,
+ .gpio_cp_dump_int = GPIO_CP_DUMP_INT,
+ .gpio_flm_uart_sel = 0,
+ .gpio_cp_warm_reset = 0,
+#if defined(CONFIG_SIM_DETECT)
+ .gpio_sim_detect = GPIO_SIM_DETECT,
+#endif
+
+ .modem_type = IMC_XMM6260,
+ .link_types = LINKTYPE(LINKDEV_HSIC),
+ .modem_net = UMTS_NETWORK,
+ .use_handover = false,
+
+ .num_iodevs = ARRAY_SIZE(umts_io_devices),
+ .iodevs = umts_io_devices,
+
+ .link_pm_data = &modem_link_pm_data,
+ .gpio_revers_bias_clear = xmm_gpio_revers_bias_clear,
+ .gpio_revers_bias_restore = xmm_gpio_revers_bias_restore,
+
+};
+
+static void xmm_gpio_revers_bias_clear(void)
+{
+ gpio_direction_output(umts_modem_data.gpio_reset_req_n, 0);
+ gpio_direction_output(umts_modem_data.gpio_phone_active, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_slavewake, 0);
+ gpio_direction_output(modem_link_pm_data.gpio_link_hostwake, 0);
+ gpio_direction_output(umts_modem_data.gpio_cp_dump_int, 0);
+
+ if (umts_modem_data.gpio_sim_detect)
+ gpio_direction_output(umts_modem_data.gpio_sim_detect, 0);
+
+ msleep(20);
+}
+
+static void xmm_gpio_revers_bias_restore(void)
+{
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+ unsigned gpio_cp_dump_int = umts_modem_data.gpio_cp_dump_int;
+ unsigned gpio_sim_detect = umts_modem_data.gpio_sim_detect;
+
+ s3c_gpio_cfgpin(umts_modem_data.gpio_phone_active, S3C_GPIO_SFN(0xF));
+ gpio_direction_output(gpio_link_hostwake, 0);
+ s3c_gpio_cfgpin(gpio_link_hostwake, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_link_hostwake, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
+ enable_irq_wake(gpio_to_irq(gpio_link_hostwake));
+
+ gpio_direction_input(gpio_cp_dump_int);
+ /*
+ s3c_gpio_cfgpin(gpio_cp_dump_int, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_cp_dump_int, S3C_GPIO_PULL_DOWN);
+ irq_set_irq_type(gpio_to_irq(gpio_cp_dump_int),
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
+ enable_irq_wake(gpio_to_irq(gpio_cp_dump_int));
+ */
+
+ /* gpio_direction_input(mc->gpio_suspend_request); */
+
+ if (umts_modem_data.gpio_sim_detect) {
+ gpio_direction_output(gpio_sim_detect, 0);
+ s3c_gpio_cfgpin(gpio_sim_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_sim_detect, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_to_irq(gpio_sim_detect),
+ IRQ_TYPE_EDGE_BOTH);
+ enable_irq_wake(gpio_to_irq(gpio_sim_detect));
+ }
+}
+
+/* HSIC specific function */
+void set_slave_wake(void)
+{
+ int spin = 20;
+ if (gpio_get_value(modem_link_pm_data.gpio_link_hostwake)) {
+ pr_info("[MODEM_IF]Slave Wake\n");
+ if (gpio_get_value(modem_link_pm_data.gpio_link_slavewake)) {
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 0);
+ mdelay(10);
+ }
+ gpio_direction_output(
+ modem_link_pm_data.gpio_link_slavewake, 1);
+ }
+}
+
+void set_host_states(struct platform_device *pdev, int type)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ if (!val) {
+ pr_info("CP not ready, Active State low\n");
+ return;
+ }
+
+ if (active_ctl.gpio_initialized) {
+ if (type)
+ set_slave_wake();
+ pr_err("[MODEM_IF]Active States =%d, %s\n", type, pdev->name);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active,
+ type);
+ } else
+ active_ctl.gpio_request_host_active = 1;
+}
+
+void set_hsic_lpa_states(int states)
+{
+ int val = gpio_get_value(umts_modem_data.gpio_cp_reset);
+
+ mif_trace("\n");
+
+ if (val) {
+ switch (states) {
+ case STATE_HSIC_LPA_ENTER:
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ gpio_set_value(umts_modem_data.gpio_pda_active, 0);
+ pr_info(LOG_TAG "set hsic lpa enter: "
+ "active state (%d)" ", pda active (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_active),
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_WAKE:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ pr_info(LOG_TAG "set hsic lpa wake: "
+ "pda active (%d)\n",
+ gpio_get_value(umts_modem_data.gpio_pda_active)
+ );
+ break;
+ case STATE_HSIC_LPA_PHY_INIT:
+ gpio_set_value(umts_modem_data.gpio_pda_active, 1);
+ gpio_set_value(modem_link_pm_data.gpio_link_slavewake,
+ 1);
+ pr_info(LOG_TAG "set hsic lpa phy init: "
+ "slave wake-up (%d)\n",
+ gpio_get_value(
+ modem_link_pm_data.gpio_link_slavewake)
+ );
+ break;
+ }
+ }
+}
+
+int get_cp_active_state(void)
+{
+ return gpio_get_value(umts_modem_data.gpio_phone_active);
+}
+
+static int umts_link_reconnect(void)
+{
+ if (gpio_get_value(umts_modem_data.gpio_phone_active) &&
+ gpio_get_value(umts_modem_data.gpio_cp_reset)) {
+ pr_info("[MODEM_IF] trying reconnect link\n");
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 0);
+ mdelay(10);
+ set_slave_wake();
+ gpio_set_value(modem_link_pm_data.gpio_link_active, 1);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+/* if use more than one modem device, then set id num */
+static struct platform_device umts_modem = {
+ .name = "modem_if",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(umts_modem_res),
+ .resource = umts_modem_res,
+ .dev = {
+ .platform_data = &umts_modem_data,
+ },
+};
+
+static void umts_modem_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_reset_req_n = umts_modem_data.gpio_reset_req_n;
+ unsigned gpio_cp_on = umts_modem_data.gpio_cp_on;
+ unsigned gpio_cp_rst = umts_modem_data.gpio_cp_reset;
+ unsigned gpio_pda_active = umts_modem_data.gpio_pda_active;
+ unsigned gpio_phone_active = umts_modem_data.gpio_phone_active;
+ unsigned gpio_cp_dump_int = umts_modem_data.gpio_cp_dump_int;
+ unsigned gpio_flm_uart_sel = umts_modem_data.gpio_flm_uart_sel;
+ unsigned gpio_sim_detect = umts_modem_data.gpio_sim_detect;
+ unsigned irq_phone_active = umts_modem_res[0].start;
+
+ if (gpio_reset_req_n) {
+ err = gpio_request(gpio_reset_req_n, "RESET_REQ_N");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "RESET_REQ_N", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_cp_on) {
+ err = gpio_request(gpio_cp_on, "CP_ON");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "CP_ON", err);
+ }
+ gpio_direction_output(gpio_cp_on, 0);
+ }
+
+ if (gpio_cp_rst) {
+ err = gpio_request(gpio_cp_rst, "CP_RST");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "CP_RST", err);
+ }
+ gpio_direction_output(gpio_cp_rst, 0);
+ s3c_gpio_setpull(gpio_cp_rst, S3C_GPIO_PULL_NONE);
+ }
+
+ if (gpio_pda_active) {
+ err = gpio_request(gpio_pda_active, "PDA_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "PDA_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_pda_active, 0);
+ }
+
+ if (gpio_phone_active) {
+ err = gpio_request(gpio_phone_active, "PHONE_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "PHONE_ACTIVE", err);
+ }
+ /* gpio_direction_input(gpio_phone_active); */
+ s3c_gpio_cfgpin(gpio_phone_active, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_phone_active, S3C_GPIO_PULL_NONE);
+ pr_err("check phone active = %d\n", irq_phone_active);
+ }
+
+ if (gpio_cp_dump_int) {
+ err = gpio_request(gpio_cp_dump_int, "CP_DUMP_INT");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "CP_DUMP_INT", err);
+ }
+ gpio_direction_input(gpio_cp_dump_int);
+ }
+
+ if (gpio_flm_uart_sel) {
+ err = gpio_request(gpio_flm_uart_sel, "GPS_UART_SEL");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "GPS_UART_SEL", err);
+ }
+ gpio_direction_output(gpio_reset_req_n, 0);
+ }
+
+ if (gpio_phone_active)
+ irq_set_irq_type(gpio_to_irq(gpio_phone_active),
+ IRQ_TYPE_LEVEL_HIGH);
+
+ if (gpio_sim_detect) {
+ err = gpio_request(gpio_sim_detect, "SIM_DETECT");
+ if (err)
+ printk(KERN_ERR "fail to request gpio %s: %d\n",
+ "SIM_DETECT", err);
+
+ /* gpio_direction_input(gpio_sim_detect); */
+ s3c_gpio_cfgpin(gpio_sim_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_sim_detect, S3C_GPIO_PULL_NONE);
+ irq_set_irq_type(gpio_to_irq(gpio_sim_detect),
+ IRQ_TYPE_EDGE_BOTH);
+ }
+
+ printk(KERN_INFO "umts_modem_cfg_gpio done\n");
+}
+
+static void modem_link_pm_config_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_link_enable = modem_link_pm_data.gpio_link_enable;
+ unsigned gpio_link_active = modem_link_pm_data.gpio_link_active;
+ unsigned gpio_link_hostwake = modem_link_pm_data.gpio_link_hostwake;
+ unsigned gpio_link_slavewake = modem_link_pm_data.gpio_link_slavewake;
+ /* unsigned irq_link_hostwake = umts_modem_res[1].start; */
+
+ if (gpio_link_enable) {
+ err = gpio_request(gpio_link_enable, "LINK_EN");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "LINK_EN", err);
+ }
+ gpio_direction_output(gpio_link_enable, 0);
+ }
+
+ if (gpio_link_active) {
+ err = gpio_request(gpio_link_active, "LINK_ACTIVE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "LINK_ACTIVE", err);
+ }
+ gpio_direction_output(gpio_link_active, 0);
+ }
+
+ if (gpio_link_hostwake) {
+ err = gpio_request(gpio_link_hostwake, "HOSTWAKE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "HOSTWAKE", err);
+ }
+ gpio_direction_input(gpio_link_hostwake);
+ s3c_gpio_cfgpin(gpio_link_hostwake, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_link_hostwake, S3C_GPIO_PULL_NONE);
+ }
+
+ if (gpio_link_slavewake) {
+ err = gpio_request(gpio_link_slavewake, "SLAVEWAKE");
+ if (err) {
+ printk(KERN_ERR "fail to request gpio %s : %d\n",
+ "SLAVEWAKE", err);
+ }
+ gpio_direction_output(gpio_link_slavewake, 0);
+ s3c_gpio_setpull(gpio_link_slavewake, S3C_GPIO_PULL_NONE);
+ }
+
+ if (gpio_link_hostwake)
+ irq_set_irq_type(gpio_to_irq(gpio_link_hostwake),
+ IRQ_TYPE_EDGE_BOTH);
+
+ active_ctl.gpio_initialized = 1;
+ if (active_ctl.gpio_request_host_active) {
+ pr_err(" [MODEM_IF] Active States = 1, %s\n", __func__);
+ gpio_direction_output(modem_link_pm_data.gpio_link_active, 1);
+ }
+
+ printk(KERN_INFO "modem_link_pm_config_gpio done\n");
+}
+
+static int __init init_modem(void)
+{
+ int ret;
+ printk(KERN_INFO "[MODEM_IF] init_modem\n");
+
+ /* umts gpios configuration */
+ umts_modem_cfg_gpio();
+ modem_link_pm_config_gpio();
+ ret = platform_device_register(&umts_modem);
+ if (ret < 0)
+ return ret;
+
+ return ret;
+}
+late_initcall(init_modem);
diff --git a/arch/arm/mach-exynos/bts.c b/arch/arm/mach-exynos/bts.c
new file mode 100644
index 0000000..7b60750
--- /dev/null
+++ b/arch/arm/mach-exynos/bts.c
@@ -0,0 +1,545 @@
+/* linux/arch/arm/mach-exynos/bts.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/devs.h>
+#include <plat/irqs.h>
+#ifdef CONFIG_EXYNOS_DEV_PD
+#include <plat/pd.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/cpu.h>
+#include <plat/bts.h>
+#include <mach/map-exynos5.h>
+
+
+static struct resource exynos_bts_cpu_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_CPU,
+ .end = EXYNOS5_PA_BTS_CPU + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_jpeg_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_JPEG,
+ .end = EXYNOS5_PA_BTS_JPEG + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_mdma1_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_MDMA1,
+ .end = EXYNOS5_PA_BTS_MDMA1 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_rotator_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_ROTATOR,
+ .end = EXYNOS5_PA_BTS_ROTATOR + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_gscl0_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_GSCL0,
+ .end = EXYNOS5_PA_BTS_GSCL0 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_gscl1_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_GSCL1,
+ .end = EXYNOS5_PA_BTS_GSCL1 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_gscl2_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_GSCL2,
+ .end = EXYNOS5_PA_BTS_GSCL2 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_gscl3_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_GSCL3,
+ .end = EXYNOS5_PA_BTS_GSCL3 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_mfc_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_MFC0,
+ .end = EXYNOS5_PA_BTS_MFC0 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EXYNOS5_PA_BTS_MFC1,
+ .end = EXYNOS5_PA_BTS_MFC1 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_g3dacp_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_G3D_ACP,
+ .end = EXYNOS5_PA_BTS_G3D_ACP + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_isp0_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_FIMC_ISP,
+ .end = EXYNOS5_PA_BTS_FIMC_ISP + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EXYNOS5_PA_BTS_FIMC_FD,
+ .end = EXYNOS5_PA_BTS_FIMC_FD + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = EXYNOS5_PA_BTS_FIMC_SCALER_C,
+ .end = EXYNOS5_PA_BTS_FIMC_SCALER_C + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = EXYNOS5_PA_BTS_FIMC_SCALER_P,
+ .end = EXYNOS5_PA_BTS_FIMC_SCALER_P + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_isp1_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_FIMC_ODC,
+ .end = EXYNOS5_PA_BTS_FIMC_ODC + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EXYNOS5_PA_BTS_FIMC_DIS0,
+ .end = EXYNOS5_PA_BTS_FIMC_DIS0 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = EXYNOS5_PA_BTS_FIMC_DIS1,
+ .end = EXYNOS5_PA_BTS_FIMC_DIS1 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = EXYNOS5_PA_BTS_FIMC_3DNR,
+ .end = EXYNOS5_PA_BTS_FIMC_3DNR + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_disp_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_DISP10,
+ .end = EXYNOS5_PA_BTS_DISP10 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EXYNOS5_PA_BTS_DISP11,
+ .end = EXYNOS5_PA_BTS_DISP11 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_tv_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_TV0,
+ .end = EXYNOS5_PA_BTS_TV0 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EXYNOS5_PA_BTS_TV1,
+ .end = EXYNOS5_PA_BTS_TV1 + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource exynos_bts_c2c_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_BTS_C2C,
+ .end = EXYNOS5_PA_BTS_C2C + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct exynos_fbm_resource fbm_res[] = {
+ {
+ .fbm_group = BTS_FBM_G1_R,
+ .priority = BTS_BE,
+ .base = EXYNOS5_PA_FBM_DDR_R1,
+ }, {
+ .fbm_group = BTS_FBM_G1_L,
+ .priority = BTS_HARDTIME,
+ .base = EXYNOS5_PA_FBM_DDR_R0,
+ }
+};
+
+struct exynos_fbm_pdata fbm_pdata = {
+ .res = fbm_res,
+ .res_num = ARRAY_SIZE(fbm_res),
+};
+
+struct exynos_bts_pdata bts_cpu_res = {
+ .id = BTS_CPU,
+ .def_priority = BTS_BE,
+ .pd_block = PD_TOP,
+ .clk_name = NULL,
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_cpu_resource),
+};
+
+struct exynos_bts_pdata bts_jpeg_res = {
+ .id = BTS_JPEG,
+ .def_priority = BTS_BE,
+ .pd_block = PD_GSCL,
+ .clk_name = "jpeg",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_jpeg_resource),
+};
+
+struct exynos_bts_pdata bts_mdma1_res = {
+ .id = BTS_MDMA1,
+ .def_priority = BTS_BE,
+ .clk_name = "pdma",
+ .pd_block = PD_TOP,
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_mdma1_resource),
+};
+
+struct exynos_bts_pdata bts_rotator_res = {
+ .id = BTS_ROTATOR,
+ .def_priority = BTS_BE,
+ .pd_block = PD_DISP1,
+ .clk_name = "rotator",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_rotator_resource),
+};
+
+struct exynos_bts_pdata bts_gscl0_res = {
+ .id = BTS_GSCL,
+ .def_priority = BTS_BE,
+ .pd_block = PD_GSCL,
+ .clk_name = "gscl",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_gscl0_resource),
+};
+
+struct exynos_bts_pdata bts_gscl1_res = {
+ .id = BTS_GSCL,
+ .def_priority = BTS_BE,
+ .pd_block = PD_GSCL,
+ .clk_name = "gscl",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_gscl1_resource),
+};
+
+struct exynos_bts_pdata bts_gscl2_res = {
+ .id = BTS_GSCL,
+ .def_priority = BTS_BE,
+ .pd_block = PD_GSCL,
+ .clk_name = "gscl",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_gscl2_resource),
+};
+
+struct exynos_bts_pdata bts_gscl3_res = {
+ .id = BTS_GSCL,
+ .def_priority = BTS_BE,
+ .pd_block = PD_GSCL,
+ .clk_name = "gscl",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_gscl3_resource),
+};
+
+struct exynos_bts_pdata bts_mfc_res = {
+ .id = BTS_MFC,
+ .def_priority = BTS_BE,
+ .pd_block = PD_MFC,
+ .clk_name = "mfc",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_mfc_resource),
+};
+
+struct exynos_bts_pdata bts_g3dacp_res = {
+ .id = BTS_G3D_ACP,
+ .def_priority = BTS_BE,
+ .pd_block = PD_G3D,
+ .clk_name = "g3d",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_g3dacp_resource),
+};
+
+struct exynos_bts_pdata bts_isp0_res = {
+ .id = BTS_ISP0,
+ .def_priority = BTS_BE,
+ .pd_block = PD_MFC,
+ .clk_name = "isp0",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_isp0_resource),
+};
+
+struct exynos_bts_pdata bts_isp1_res = {
+ .id = BTS_ISP1,
+ .def_priority = BTS_BE,
+ .pd_block = PD_MFC,
+ .clk_name = "isp1",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_isp1_resource),
+};
+
+struct exynos_bts_pdata bts_disp_res = {
+ .id = BTS_DISP,
+ .def_priority = BTS_HARDTIME,
+ .pd_block = PD_DISP1,
+ .clk_name = "lcd",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_disp_resource),
+};
+
+struct exynos_bts_pdata bts_tv_res = {
+ .id = BTS_TV,
+ .def_priority = BTS_HARDTIME,
+ .pd_block = PD_DISP1,
+ .clk_name = "mixer",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_tv_resource),
+};
+
+struct exynos_bts_pdata bts_c2c_res = {
+ .id = BTS_C2C,
+ .def_priority = BTS_HARDTIME,
+ .clk_name = "c2c",
+ .fbm = &fbm_pdata,
+ .res_num = ARRAY_SIZE(exynos_bts_c2c_resource),
+};
+
+/* bts platform device lists */
+struct platform_device exynos_device_bts_disp = {
+ .name = "exynos-bts",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos_bts_disp_resource),
+ .resource = exynos_bts_disp_resource,
+ .dev = {
+ .platform_data = &bts_disp_res,
+ .parent = &s5p_device_fimd1.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_tv = {
+ .name = "exynos-bts",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos_bts_tv_resource),
+ .resource = exynos_bts_tv_resource,
+ .dev = {
+ .platform_data = &bts_tv_res,
+ .parent = &s5p_device_mixer.dev,
+ },
+};
+
+#if defined(CONFIG_EXYNOS_C2C)
+struct platform_device exynos_device_bts_c2c = {
+ .name = "exynos-bts",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos_bts_c2c_resource),
+ .resource = exynos_bts_c2c_resource,
+ .dev = {
+ .platform_data = &bts_c2c_res,
+ .parent = &exynos_device_c2c.dev,
+ },
+};
+#endif
+
+struct platform_device exynos_device_bts_g3dacp = {
+ .name = "exynos-bts",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(exynos_bts_g3dacp_resource),
+ .resource = exynos_bts_g3dacp_resource,
+ .dev = {
+ .platform_data = &bts_g3dacp_res,
+ },
+};
+
+struct platform_device exynos_device_bts_rotator = {
+ .name = "exynos-bts",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(exynos_bts_rotator_resource),
+ .resource = exynos_bts_rotator_resource,
+ .dev = {
+ .platform_data = &bts_rotator_res,
+ .parent = &exynos_device_rotator.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_jpeg = {
+ .name = "exynos-bts",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(exynos_bts_jpeg_resource),
+ .resource = exynos_bts_jpeg_resource,
+ .dev = {
+ .platform_data = &bts_jpeg_res,
+ },
+};
+
+struct platform_device exynos_device_bts_mdma1 = {
+ .name = "exynos-bts",
+ .id = 6,
+ .num_resources = ARRAY_SIZE(exynos_bts_mdma1_resource),
+ .resource = exynos_bts_mdma1_resource,
+ .dev = {
+ .platform_data = &bts_mdma1_res,
+ .parent = &exynos_device_mdma.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_gscl0 = {
+ .name = "exynos-bts",
+ .id = 7,
+ .num_resources = ARRAY_SIZE(exynos_bts_gscl0_resource),
+ .resource = exynos_bts_gscl0_resource,
+ .dev = {
+ .platform_data = &bts_gscl0_res,
+ .parent = &exynos5_device_gsc0.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_gscl1 = {
+ .name = "exynos-bts",
+ .id = 8,
+ .num_resources = ARRAY_SIZE(exynos_bts_gscl1_resource),
+ .resource = exynos_bts_gscl1_resource,
+ .dev = {
+ .platform_data = &bts_gscl1_res,
+ .parent = &exynos5_device_gsc1.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_gscl2 = {
+ .name = "exynos-bts",
+ .id = 9,
+ .num_resources = ARRAY_SIZE(exynos_bts_gscl2_resource),
+ .resource = exynos_bts_gscl2_resource,
+ .dev = {
+ .platform_data = &bts_gscl2_res,
+ .parent = &exynos5_device_gsc2.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_gscl3 = {
+ .name = "exynos-bts",
+ .id = 10,
+ .num_resources = ARRAY_SIZE(exynos_bts_gscl3_resource),
+ .resource = exynos_bts_gscl3_resource,
+ .dev = {
+ .platform_data = &bts_gscl3_res,
+ .parent = &exynos5_device_gsc3.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_mfc = {
+ .name = "exynos-bts",
+ .id = 11,
+ .num_resources = ARRAY_SIZE(exynos_bts_mfc_resource),
+ .resource = exynos_bts_mfc_resource,
+ .dev = {
+ .platform_data = &bts_mfc_res,
+ .parent = &s5p_device_mfc.dev,
+ },
+};
+
+#if defined(CONFIG_EXYNOS4_DEV_FIMC_IS)
+struct platform_device exynos_device_bts_isp0 = {
+ .name = "exynos-bts",
+ .id = 12,
+ .num_resources = ARRAY_SIZE(exynos_bts_isp0_resource),
+ .resource = exynos_bts_isp0_resource,
+ .dev = {
+ .platform_data = &bts_isp0_res,
+ .parent = &exynos5_device_fimc_is.dev,
+ },
+};
+
+struct platform_device exynos_device_bts_isp1 = {
+ .name = "exynos-bts",
+ .id = 13,
+ .num_resources = ARRAY_SIZE(exynos_bts_isp1_resource),
+ .resource = exynos_bts_isp1_resource,
+ .dev = {
+ .platform_data = &bts_isp1_res,
+ .parent = &exynos5_device_fimc_is.dev,
+ },
+};
+#endif
+
+struct platform_device exynos_device_bts_cpu = {
+ .name = "exynos-bts",
+ .id = 14,
+ .num_resources = ARRAY_SIZE(exynos_bts_cpu_resource),
+ .resource = exynos_bts_cpu_resource,
+ .dev = {
+ .platform_data = &bts_cpu_res,
+ },
+};
+
+static struct platform_device *exynos_bts[] __initdata = {
+ &exynos_device_bts_disp,
+ &exynos_device_bts_tv,
+#if defined(CONFIG_EXYNOS_C2C)
+ &exynos_device_bts_c2c,
+#endif
+ &exynos_device_bts_g3dacp,
+ &exynos_device_bts_rotator,
+ &exynos_device_bts_jpeg,
+ &exynos_device_bts_mdma1,
+ &exynos_device_bts_gscl0,
+ &exynos_device_bts_gscl1,
+ &exynos_device_bts_gscl2,
+ &exynos_device_bts_gscl3,
+ &exynos_device_bts_mfc,
+ &exynos_device_bts_isp0,
+ &exynos_device_bts_isp1,
+ &exynos_device_bts_cpu,
+};
+
+static int __init exynos_bts_init(void)
+{
+ return platform_add_devices(exynos_bts, ARRAY_SIZE(exynos_bts));
+}
+arch_initcall(exynos_bts_init);
diff --git a/arch/arm/mach-exynos/busfreq.c b/arch/arm/mach-exynos/busfreq.c
new file mode 100644
index 0000000..38a31b1
--- /dev/null
+++ b/arch/arm/mach-exynos/busfreq.c
@@ -0,0 +1,974 @@
+/* linux/arch/arm/mach-exynos/busfreq.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - BUS clock frequency scaling support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/cpufreq.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/clk.h>
+#include <linux/pm_qos_params.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/ppmu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/cpufreq.h>
+#include <mach/asv.h>
+#include <mach/sec_debug.h>
+
+#include <plat/map-s5p.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+#define MAX_LOAD 100
+#define DIVIDING_FACTOR 10000
+#define UP_THRESHOLD_DEFAULT 23
+
+#define SYSFS_DEBUG_BUSFREQ
+
+static unsigned up_threshold;
+static struct regulator *int_regulator;
+static struct exynos4_ppmu_hw dmc[2];
+static struct exynos4_ppmu_hw cpu;
+static unsigned int bus_utilization[2];
+static struct cpufreq_freqs *freqs;
+
+static unsigned int g_busfreq_lock_id;
+static enum busfreq_level_request g_busfreq_lock_val[DVFS_LOCK_ID_END];
+static enum busfreq_level_request g_busfreq_lock_level;
+
+const char *const cpufreq_lock_name[DVFS_LOCK_ID_END] = {
+ [DVFS_LOCK_ID_G2D] = "G2D",
+ [DVFS_LOCK_ID_TV] = "TV",
+ [DVFS_LOCK_ID_MFC] = "MFC",
+ [DVFS_LOCK_ID_USB] = "USB",
+ [DVFS_LOCK_ID_CAM] = "CAM",
+ [DVFS_LOCK_ID_PM] = "PM",
+ [DVFS_LOCK_ID_USER] = "USER",
+ [DVFS_LOCK_ID_LCD] = "LCD",
+ [DVFS_LOCK_ID_ROTATION_BOOSTER] = "ROTATION_BOOSTER",
+};
+
+static DEFINE_MUTEX(set_bus_freq_lock);
+
+enum busfreq_level_idx {
+ LV_0,
+ LV_1,
+ LV_2,
+ LV_END
+};
+
+#ifdef SYSFS_DEBUG_BUSFREQ
+static unsigned int time_in_state[LV_END];
+unsigned long prejiffies;
+unsigned long curjiffies;
+#endif
+
+static unsigned int p_idx;
+static unsigned int curr_idx;
+static bool init_done;
+
+struct busfreq_table {
+ unsigned int idx;
+ unsigned int mem_clk;
+ unsigned int volt;
+ unsigned int clk_topdiv;
+ unsigned int clk_dmcdiv;
+};
+
+static struct busfreq_table exynos4_busfreq_table[] = {
+ {LV_0, 400000, 1100000, 0, 0},
+ {LV_1, 267000, 1000000, 0, 0},
+#ifdef CONFIG_BUSFREQ_L2_160M
+ /*L2: 160MHz */
+ {LV_2, 160000, 1000000, 0, 0},
+#else
+ /* L2: 133MHz */
+ {LV_2, 133000, 950000, 0, 0},
+#endif
+ {0, 0, 0, 0, 0},
+};
+
+#ifdef CONFIG_BUSFREQ_QOS
+enum busfreq_qos_target {
+ BUS_QOS_0,
+ BUS_QOS_1,
+ BUS_QOS_MAX,
+};
+
+static enum busfreq_qos_target busfreq_qos = BUS_QOS_0;
+
+/* GDL: [3] MFC_L, [2] G3D, [1] TV, [0] Image */
+/* GDR: [5] MAUDIO, [4] MFC_R, [3] FSYS, [2] LCD1, [1] LCD0, [0] CAM */
+#if defined(CONFIG_BUSFREQ_QOS_NONE)
+static unsigned int exynos4_qos_value[BUS_QOS_MAX][LV_END][4] = {
+ {
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ },
+ {
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ }
+};
+#elif defined(CONFIG_BUSFREQ_QOS_1024X600) /* For P2 */
+static unsigned int exynos4_qos_value[BUS_QOS_MAX][LV_END][4] = {
+ {
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x06, 0x0b, 0x00, 0x00},
+ },
+ {
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x06, 0x0b, 0x00, 0x00},
+ }
+};
+#elif defined(CONFIG_BUSFREQ_QOS_1280X800) /* For Q1, P8 */
+static unsigned int exynos4_qos_value[BUS_QOS_MAX][LV_END][4] = {
+ {
+ {0x07, 0x03, 0x07, 0x0f},
+ {0x07, 0x03, 0x07, 0x0f},
+ {0x03, 0x0b, 0x00, 0x00},
+ },
+ {
+ {0x06, 0x0b, 0x00, 0x00},
+ {0x06, 0x0b, 0x00, 0x00},
+ {0x03, 0x0b, 0x00, 0x00},
+ }
+};
+#endif
+#endif
+
+#define ASV_GROUP 5
+static unsigned int exynos4_asv_volt[ASV_GROUP][LV_END] = {
+ {1150000, 1050000, 1050000},
+ {1125000, 1025000, 1025000},
+ {1100000, 1000000, 1000000},
+ {1075000, 975000, 975000},
+ {1050000, 950000, 950000},
+};
+
+static unsigned int clkdiv_dmc0[LV_END][8] = {
+ /*
+ * Clock divider value for following
+ * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
+ * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
+ */
+
+ /* DMC L0: 400MHz */
+ { 3, 2, 1, 1, 1, 1, 3, 1 },
+
+ /* DMC L1: 266.7MHz */
+ { 4, 2, 1, 2, 1, 1, 3, 1 },
+
+#ifdef CONFIG_BUSFREQ_L2_160M
+ /* DMC L2: 160MHz */
+ { 5, 1, 1, 4, 1, 1, 3, 1 },
+#else
+ /* DMC L2: 133MHz */
+ { 5, 2, 1, 5, 1, 1, 3, 1 },
+#endif
+};
+
+static unsigned int clkdiv_top[LV_END][5] = {
+ /*
+ * Clock divider value for following
+ * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
+ */
+
+ /* ACLK200 L0: 200MHz */
+ { 3, 7, 4, 5, 1 },
+
+ /* ACLK200 L1: 160MHz */
+ { 4, 7, 5, 6, 1 },
+
+ /* ACLK200 L2: 133MHz */
+ { 5, 7, 7, 7, 1 },
+};
+
+static unsigned int clkdiv_lr_bus[LV_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVGDL/R, DIVGPL/R }
+ */
+
+ /* ACLK_GDL/R L1: 200MHz */
+ { 3, 1 },
+
+ /* ACLK_GDL/R L2: 160MHz */
+ { 4, 1 },
+
+ /* ACLK_GDL/R L3: 133MHz */
+ { 5, 1 },
+};
+
+static unsigned int clkdiv_ip_bus[LV_END][3] = {
+ /*
+ * Clock divider value for following
+ * { DIV_MFC, DIV_G2D, DIV_FIMC }
+ */
+
+ /* L0: MFC 200MHz G2D 266MHz FIMC 160MHz */
+ { 3, 2, 4 },
+
+ /* L1: MFC 200MHz G2D 160MHz FIMC 133MHz */
+ /* { 4, 4, 5 }, */
+ { 3, 4, 5 },
+
+ /* L2: MFC 200MHz G2D 133MHz FIMC 100MHz */
+ /* { 5, 5, 7 }, */
+ { 3, 5, 7 },
+};
+
+#ifdef CONFIG_BUSFREQ_QOS
+static void exynos4_set_qos(unsigned int index)
+{
+ /* printk(KERN_INFO "exynos4_set_qos level %d\n", index); */
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][0], S5P_VA_GDL + 0x400);
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][1], S5P_VA_GDL + 0x404);
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][2], S5P_VA_GDR + 0x400);
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][3], S5P_VA_GDR + 0x404);
+}
+#endif
+
+static void exynos4_set_busfreq(unsigned int div_index)
+{
+ unsigned int tmp, val;
+
+ sec_debug_aux_log(SEC_DEBUG_AUXLOG_CPU_BUS_CLOCK_CHANGE,
+ "%s: div_index=%d(%ps)", __func__, div_index,
+ __builtin_return_address(0));
+
+ /* Change Divider - DMC0 */
+ tmp = exynos4_busfreq_table[div_index].clk_dmcdiv;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
+ } while (tmp & 0x11111111);
+
+ /* Change Divider - TOP */
+ tmp = exynos4_busfreq_table[div_index].clk_topdiv;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
+ } while (tmp & 0x11111);
+
+ /* Change Divider - LEFTBUS */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
+
+ tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_lr_bus[div_index][0] << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_lr_bus[div_index][1] << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
+ } while (tmp & 0x11);
+
+ /* Change Divider - RIGHTBUS */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
+
+ tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_lr_bus[div_index][0] << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_lr_bus[div_index][1] << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
+ } while (tmp & 0x11);
+
+ /* Change Divider - SCLK_MFC */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
+
+ tmp &= ~EXYNOS4_CLKDIV_MFC_MASK;
+
+ tmp |= (clkdiv_ip_bus[div_index][0] << EXYNOS4_CLKDIV_MFC_SHIFT);
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
+ } while (tmp & 0x1);
+
+ /* Change Divider - SCLK_G2D */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_IMAGE);
+
+ tmp &= ~EXYNOS4_CLKDIV_IMAGE_MASK;
+
+ tmp |= (clkdiv_ip_bus[div_index][1] << EXYNOS4_CLKDIV_IMAGE_SHIFT);
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_IMAGE);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_IMAGE);
+ } while (tmp & 0x1);
+
+ /* Change Divider - SCLK_FIMC */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
+
+ tmp &= ~EXYNOS4_CLKDIV_CAM_MASK;
+
+ val = clkdiv_ip_bus[div_index][2];
+ tmp |= ((val << 0) | (val << 4) | (val << 8) | (val << 12));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM);
+ } while (tmp & 0x1111);
+}
+
+static unsigned int calc_bus_utilization(struct exynos4_ppmu_hw *ppmu)
+{
+ if (ppmu->ccnt == 0) {
+ pr_err("%s: 0 value is not permitted\n", __func__);
+ return MAX_LOAD;
+ }
+
+ if (!(ppmu->ccnt >> 7))
+ return (ppmu->count[0] * 100) / ppmu->ccnt;
+ else
+ return ((ppmu->count[0] >> 7) * 100) / (ppmu->ccnt >> 7);
+}
+
+static int busfreq_target(struct busfreq_table *freq_table,
+ unsigned int ppc_load,
+ unsigned int ppmu_load,
+ unsigned int pre_idx,
+ unsigned int *index)
+{
+ unsigned int i, target_freq, idx = 0;
+
+ if (ppc_load > MAX_LOAD)
+ return -EINVAL;
+
+ if (ppc_load > 50) {
+ pr_debug("Busfreq: Bus Load is larger than 40(%d)\n", ppc_load);
+ ppc_load = 50;
+ }
+
+#ifdef CONFIG_BUSFREQ_L2_160M
+ target_freq = (ppc_load * freq_table[p_idx].mem_clk) /
+ (up_threshold);
+
+ for (i = 1; i <= LV_END; i++) {
+ if (target_freq >= freq_table[i].mem_clk) {
+ idx = i - 1;
+ break;
+ }
+ }
+
+ idx = freq_table[idx].idx;
+#else
+ if (ppc_load >= up_threshold) {
+ target_freq = freq_table[0].mem_clk;
+ } else {
+ target_freq = (ppc_load * freq_table[pre_idx].mem_clk) /
+ up_threshold;
+
+ if (target_freq >= freq_table[pre_idx].mem_clk) {
+ for (i = 0; (freq_table[i].mem_clk != 0); i++) {
+ unsigned int freq = freq_table[i].mem_clk;
+
+ if (freq <= target_freq) {
+ idx = i;
+ break;
+ }
+ }
+
+ } else {
+ for (i = 0; (freq_table[i].mem_clk != 0); i++) {
+ unsigned int freq = freq_table[i].mem_clk;
+
+ if (freq >= target_freq) {
+ idx = i;
+ continue;
+ }
+
+ if (freq < target_freq)
+ break;
+ }
+ }
+ }
+
+ if ((freqs->new == exynos_info->freq_table[exynos_info->max_support_idx].frequency)
+ && (ppc_load == 0))
+ idx = pre_idx;
+#endif
+
+ if ((idx > LV_1) && (ppmu_load > 5))
+ idx = LV_1;
+
+ if (idx > g_busfreq_lock_level)
+ idx = g_busfreq_lock_level;
+
+ *index = idx;
+
+ return 0;
+}
+
+static void busfreq_mon_reset(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < 2; i++) {
+ exynos4_ppc_reset(&dmc[i]);
+ exynos4_ppc_setevent(&dmc[i], 0x6);
+ exynos4_ppc_start(&dmc[i]);
+ }
+
+ exynos4_ppmu_reset(&cpu);
+
+ exynos4_ppmu_setevent(&cpu, 3);
+
+ exynos4_ppmu_start(&cpu);
+}
+
+static unsigned int busfreq_monitor(void)
+{
+ unsigned int i, index = 0, ret;
+ unsigned long long ppcload, ppmuload;
+#ifdef SYSFS_DEBUG_BUSFREQ
+ unsigned long level_state_jiffies;
+#endif
+
+ for (i = 0; i < 2; i++) {
+ exynos4_ppc_stop(&dmc[i]);
+ exynos4_ppc_update(&dmc[i]);
+ bus_utilization[i] = calc_bus_utilization(&dmc[i]);
+ }
+
+ exynos4_ppmu_stop(&cpu);
+ ppmuload = exynos4_ppmu_update(&cpu, 3);
+
+ if (ppmuload > 10) {
+ index = LV_0;
+ goto out;
+ }
+
+ ppcload = max(bus_utilization[0], bus_utilization[1]);
+ index = p_idx;
+
+ /* Change bus frequency */
+ ret = busfreq_target(exynos4_busfreq_table, ppcload,
+ ppmuload, p_idx, &index);
+ if (ret)
+ pr_err("%s: (%d)\n", __func__, ret);
+
+#ifdef SYSFS_DEBUG_BUSFREQ
+ curjiffies = jiffies;
+ if (prejiffies != 0)
+ level_state_jiffies = curjiffies - prejiffies;
+ else
+ level_state_jiffies = 0;
+
+ prejiffies = jiffies;
+
+ switch (p_idx) {
+ case LV_0:
+ time_in_state[LV_0] += level_state_jiffies;
+ break;
+ case LV_1:
+ time_in_state[LV_1] += level_state_jiffies;
+ break;
+ case LV_2:
+ time_in_state[LV_2] += level_state_jiffies;
+ break;
+ default:
+ break;
+ }
+#endif
+
+out:
+ pr_debug("Bus freq(%d-%d)\n", p_idx, index);
+
+ busfreq_mon_reset();
+
+ return index;
+}
+
+static int exynos4_busfreq_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ unsigned int voltage;
+
+ switch (event) {
+ case CPUFREQ_PRECHANGE:
+ freqs = (struct cpufreq_freqs *)ptr;
+ curr_idx = busfreq_monitor();
+ break;
+ case CPUFREQ_POSTCHANGE:
+ voltage = exynos4_busfreq_table[curr_idx].volt;
+ if (p_idx > curr_idx)
+ regulator_set_voltage(int_regulator, voltage,
+ voltage);
+
+ if (p_idx != curr_idx) {
+#ifdef CONFIG_BUSFREQ_QOS
+ exynos4_set_qos(curr_idx);
+#endif
+ exynos4_set_busfreq(curr_idx);
+ }
+
+ if (p_idx < curr_idx)
+ regulator_set_voltage(int_regulator, voltage,
+ voltage);
+ p_idx = curr_idx;
+ break;
+ case CPUFREQ_RESUMECHANGE:
+ break;
+ default:
+ /* ignore */
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block exynos4_busfreq_notifier = {
+ .notifier_call = exynos4_busfreq_notifier_event,
+};
+
+static int exynos4_buspm_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ exynos4_busfreq_lock(DVFS_LOCK_ID_PM, BUS_L0);
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ exynos4_busfreq_lock_free(DVFS_LOCK_ID_PM);
+ busfreq_mon_reset();
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos4_buspm_notifier = {
+ .notifier_call = exynos4_buspm_notifier_event,
+};
+
+static int exynos4_busfreq_reboot_notify(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ if (exynos4_busfreq_lock(DVFS_LOCK_ID_PM, BUS_L0) < 0)
+ return NOTIFY_BAD;
+
+ printk(KERN_INFO "REBOOT Notifier for BUSFREQ\n");
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos4_busfreq_reboot_notifier = {
+ .notifier_call = exynos4_busfreq_reboot_notify,
+};
+
+#ifdef CONFIG_BUSFREQ_QOS
+static int exynos4_bus_qos_notify(struct notifier_block *nb,
+ unsigned long l, void *v)
+{
+ busfreq_qos = (int)l;
+ printk(KERN_INFO "exynos4_bus_qos_notify table %d\n", busfreq_qos);
+ exynos4_set_qos(curr_idx);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block exynos4_busqos_notifier = {
+ .notifier_call = exynos4_bus_qos_notify,
+};
+#endif
+
+int exynos4_busfreq_lock(unsigned int nId,
+ enum busfreq_level_request busfreq_level)
+{
+ int ret = 0;
+ unsigned int int_volt;
+
+ if (!init_done) {
+ pr_debug("Busfreq does not support on this system\n");
+ return -ENODEV;
+ }
+
+ mutex_lock(&set_bus_freq_lock);
+ if (g_busfreq_lock_id & (1 << nId)) {
+ pr_err("This device [%d] already locked busfreq\n", nId);
+ ret = -EINVAL;
+ goto err;
+ }
+ g_busfreq_lock_id |= (1 << nId);
+ g_busfreq_lock_val[nId] = busfreq_level;
+
+ /* If the requested cpufreq is higher than current min frequency */
+ if (busfreq_level < g_busfreq_lock_level) {
+ g_busfreq_lock_level = busfreq_level;
+ /* get the voltage value */
+ int_volt = exynos4_busfreq_table[busfreq_level].volt;
+#ifdef CONFIG_BUSFREQ_QOS
+ exynos4_set_qos(curr_idx);
+#endif
+ regulator_set_voltage(int_regulator, int_volt,
+ int_volt);
+ exynos4_set_busfreq(busfreq_level);
+ }
+err:
+ mutex_unlock(&set_bus_freq_lock);
+
+ return ret;
+}
+
+void exynos4_busfreq_lock_free(unsigned int nId)
+{
+ unsigned int i;
+
+ if (!init_done) {
+ pr_debug("Busfreq does not support on this system\n");
+ return;
+ }
+
+ mutex_lock(&set_bus_freq_lock);
+ g_busfreq_lock_id &= ~(1 << nId);
+ g_busfreq_lock_val[nId] = BUS_LEVEL_END - 1;
+ g_busfreq_lock_level = BUS_LEVEL_END - 1;
+
+ if (g_busfreq_lock_id) {
+ for (i = 0; i < DVFS_LOCK_ID_END; i++) {
+ if (g_busfreq_lock_val[i] < g_busfreq_lock_level)
+ g_busfreq_lock_level = g_busfreq_lock_val[i];
+ }
+ }
+ mutex_unlock(&set_bus_freq_lock);
+}
+
+void exynos4_request_apply(unsigned long freq, struct device *dev)
+{
+ /* not supported yet */
+}
+
+static void __init exynos4_set_bus_volt(void)
+{
+ unsigned int asv_group;
+ unsigned int i;
+
+ asv_group = exynos_result_of_asv & 0xF;
+
+ printk(KERN_INFO "DVFS : VDD_INT Voltage table set with %d Group\n", asv_group);
+
+ for (i = 0 ; i < LV_END ; i++) {
+
+ switch (asv_group) {
+ case 0:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[0][i];
+ break;
+ case 1:
+ case 2:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[1][i];
+ break;
+ case 3:
+ case 4:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[2][i];
+ break;
+ case 5:
+ case 6:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[3][i];
+ break;
+ case 7:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[4][i];
+ break;
+ }
+ }
+
+ return;
+}
+
+#ifdef SYSFS_DEBUG_BUSFREQ
+static ssize_t show_time_in_state(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < LV_END; i++)
+ len += sprintf(buf + len, "%u: %u\n",
+ exynos4_busfreq_table[i].mem_clk, time_in_state[i]);
+
+ return len;
+}
+
+static ssize_t store_time_in_state(struct kobject *kobj,
+ struct attribute *attr, const char *buf, size_t count)
+{
+ return count;
+}
+
+static struct global_attr busfreq_time_in_state_attr = __ATTR(busfreq_time_in_state,
+ 0644, show_time_in_state, store_time_in_state);
+
+static ssize_t show_up_threshold(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", up_threshold);
+}
+
+static ssize_t store_up_threshold(struct kobject *kobj,
+ struct attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%u", &up_threshold);
+ if (ret != 1)
+ return -EINVAL;
+ printk(KERN_ERR "** Up_Threshold is changed to %u **\n", up_threshold);
+
+ return count;
+}
+
+static struct global_attr busfreq_up_threshold_attr = __ATTR(busfreq_up_threshold,
+ 0644, show_up_threshold, store_up_threshold);
+
+static ssize_t show_busfreq_level_lock(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", g_busfreq_lock_level);
+}
+
+static ssize_t store_busfreq_level_lock(struct kobject *kobj,
+ struct attribute *attr, const char *buf, size_t count)
+{
+ int level;
+ sscanf(buf, "%d", &level);
+ if (level >= BUS_LEVEL_END)
+ return -EINVAL;
+
+ if (level < 0)
+ exynos4_busfreq_lock_free(DVFS_LOCK_ID_USER);
+ else
+ exynos4_busfreq_lock(DVFS_LOCK_ID_USER, level);
+ return count;
+}
+
+static struct global_attr busfreq_level__lock_attr = __ATTR(busfreq_level_lock,
+ 0644, show_busfreq_level_lock, store_busfreq_level_lock);
+
+static ssize_t show_busfreq_level(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ int i;
+ int ret = 0;
+ ret = sprintf(buf, "Lock Name = ");
+ for (i = 0; i < DVFS_LOCK_ID_END; i++) {
+ if (g_busfreq_lock_id & (1 << i))
+ ret += sprintf(&buf[ret], "%s - %d\n",
+ cpufreq_lock_name[i], g_busfreq_lock_val[i]);
+ }
+ ret += sprintf(&buf[ret], "\nCurrent Busfreq Level : %d\n", p_idx);
+ return ret;
+}
+
+static struct global_attr busfreq_level_attr = __ATTR(busfreq_current_level,
+ S_IRUGO, show_busfreq_level, NULL);
+#endif
+
+static int __init busfreq_mon_init(void)
+{
+ unsigned int i;
+ unsigned int tmp;
+ unsigned int val;
+ struct clk *ppmu_clk = NULL;
+
+ if (!soc_is_exynos4210())
+ return -ENODEV;
+
+ val = __raw_readl(S5P_VA_DMC0 + 0x4);
+ val = (val >> 8) & 0xf;
+
+ /* Check Memory Type Only support -> 0x5: 0xLPDDR2 */
+ if (val != 0x05) {
+ pr_err("[ %x ] Memory Type Undertermined.\n", val);
+ return -ENODEV;
+ }
+
+ init_done = true;
+
+ for (i = 0; i < DVFS_LOCK_ID_END; i++)
+ g_busfreq_lock_val[i] = BUS_LEVEL_END - 1;
+
+ g_busfreq_lock_level = BUS_LEVEL_END - 1;
+
+ cpu.hw_base = S5P_VA_PPMU_CPU;
+ cpu.weight = 1;
+ cpu.event[3] = 0x7;
+
+ dmc[DMC0].hw_base = S5P_VA_DMC0;
+ dmc[DMC0].weight = 1;
+ dmc[DMC1].hw_base = S5P_VA_DMC1;
+ dmc[DMC1].weight = 1;
+
+ p_idx = LV_0;
+ up_threshold = UP_THRESHOLD_DEFAULT;
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
+
+ for (i = 0; i < LV_END; i++) {
+ tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+ EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+ EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
+ EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
+ EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
+
+ tmp |= ((clkdiv_dmc0[i][0] << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
+ (clkdiv_dmc0[i][1] << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+ (clkdiv_dmc0[i][2] << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
+ (clkdiv_dmc0[i][3] << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
+ (clkdiv_dmc0[i][4] << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
+ (clkdiv_dmc0[i][5] << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
+ (clkdiv_dmc0[i][6] << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
+ (clkdiv_dmc0[i][7] << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
+
+ exynos4_busfreq_table[i].clk_dmcdiv = tmp;
+ }
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
+
+ for (i = 0; i < LV_END; i++) {
+ tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+ EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
+
+ tmp |= ((clkdiv_top[i][0] << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
+ (clkdiv_top[i][1] << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
+ (clkdiv_top[i][2] << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
+ (clkdiv_top[i][3] << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
+ (clkdiv_top[i][4] << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
+
+ exynos4_busfreq_table[i].clk_topdiv = tmp;
+ }
+
+ exynos4_set_bus_volt();
+
+ int_regulator = regulator_get(NULL, "vdd_int");
+ if (IS_ERR(int_regulator)) {
+ pr_err("failed to get resource %s\n", "vdd_int");
+ return -ENODEV;
+ }
+
+ /* PPMUs using for cpufreq get clk from clk_list */
+ ppmu_clk = clk_get(NULL, "ppmudmc0");
+ if (IS_ERR(ppmu_clk)) {
+ pr_err("Failed to get ppmudmc0 clock\n");
+ goto err_clk;
+ }
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_clk = clk_get(NULL, "ppmudmc1");
+ if (IS_ERR(ppmu_clk)) {
+ pr_err("Failed to get ppmudmc1 clock\n");
+ goto err_clk;
+ }
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_clk = clk_get(NULL, "ppmucpu");
+ if (IS_ERR(ppmu_clk)) {
+ pr_err("Failed to get ppmucpu clock\n");
+ goto err_clk;
+ }
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ busfreq_mon_reset();
+
+ if (cpufreq_register_notifier(&exynos4_busfreq_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER)) {
+ pr_err("Failed to setup cpufreq notifier\n");
+ goto err_cpufreq;
+ }
+
+ if (register_pm_notifier(&exynos4_buspm_notifier)) {
+ pr_err("Failed to setup buspm notifier\n");
+ goto err_pm;
+ }
+
+ if (register_reboot_notifier(&exynos4_busfreq_reboot_notifier))
+ pr_err("Failed to setup reboot notifier\n");
+
+#ifdef SYSFS_DEBUG_BUSFREQ
+ if (sysfs_create_file(cpufreq_global_kobject,
+ &busfreq_level__lock_attr.attr))
+ pr_err("Failed to create sysfs file(lock)\n");
+
+ if (sysfs_create_file(cpufreq_global_kobject,
+ &busfreq_time_in_state_attr.attr))
+ pr_err("Failed to create sysfs file(time_in_state)\n");
+
+ if (sysfs_create_file(cpufreq_global_kobject,
+ &busfreq_up_threshold_attr.attr))
+ pr_err("Failed to create sysfs file(up_threshold)\n");
+
+ if (sysfs_create_file(cpufreq_global_kobject, &busfreq_level_attr.attr))
+ pr_err("Failed to create sysfs file(level)\n");
+#endif
+#ifdef CONFIG_BUSFREQ_QOS
+ pm_qos_add_notifier(PM_QOS_BUS_QOS, &exynos4_busqos_notifier);
+#endif
+
+ return 0;
+
+err_pm:
+ cpufreq_unregister_notifier(&exynos4_busfreq_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER);
+err_cpufreq:
+err_clk:
+ if (!IS_ERR(int_regulator))
+ regulator_put(int_regulator);
+
+ return -ENODEV;
+}
+late_initcall(busfreq_mon_init);
diff --git a/arch/arm/mach-exynos/busfreq_opp_4210.c b/arch/arm/mach-exynos/busfreq_opp_4210.c
new file mode 100644
index 0000000..d566fea
--- /dev/null
+++ b/arch/arm/mach-exynos/busfreq_opp_4210.c
@@ -0,0 +1,298 @@
+/* linux/arch/arm/mach-exynos/busfreq_opp_4210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - BUS clock frequency scaling support with OPP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <mach/busfreq.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/ppmu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/cpufreq.h>
+#include <mach/dev.h>
+#include <mach/asv.h>
+
+#include <plat/map-s5p.h>
+#include <plat/gpio-cfg.h>
+
+enum busfreq_level_idx {
+ LV_0,
+ LV_1,
+ LV_2,
+ LV_END
+};
+
+static struct busfreq_table exynos4_busfreq_table[] = {
+ {LV_0, 400000, 1100000, 0, 0, 0},
+ {LV_1, 267000, 1000000, 0, 0, 0},
+ {LV_2, 133000, 950000, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0},
+};
+
+#define ASV_GROUP 5
+static unsigned int exynos4_asv_volt[ASV_GROUP][LV_END] = {
+ {1150000, 1050000, 1000000},
+ {1125000, 1025000, 1000000},
+ {1100000, 1000000, 975000},
+ {1075000, 975000, 950000},
+ {1050000, 950000, 950000},
+};
+
+static unsigned int clkdiv_dmc0[LV_END][8] = {
+ /*
+ * Clock divider value for following
+ * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
+ * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
+ */
+
+ /* DMC L0: 400MHz */
+ {3, 1, 1, 1, 1, 1, 3, 1},
+
+ /* DMC L1: 266.7MHz */
+ {4, 1, 1, 2, 1, 1, 3, 1},
+
+ /* DMC L2: 133MHz */
+ {5, 1, 1, 5, 1, 1, 3, 1},
+};
+
+static unsigned int clkdiv_top[LV_END][5] = {
+ /*
+ * Clock divider value for following
+ * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
+ */
+
+ /* ACLK200 L0: 200MHz */
+ {3, 7, 4, 5, 1},
+
+ /* ACLK200 L1: 160MHz */
+ {4, 7, 5, 6, 1},
+
+ /* ACLK200 L2: 133MHz */
+ {5, 7, 7, 7, 1},
+};
+
+static unsigned int clkdiv_lr_bus[LV_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVGDL/R, DIVGPL/R }
+ */
+
+ /* ACLK_GDL/R L1: 200MHz */
+ {3, 1},
+
+ /* ACLK_GDL/R L2: 160MHz */
+ {4, 1},
+
+ /* ACLK_GDL/R L3: 133MHz */
+ {5, 1},
+};
+
+static void exynos4210_set_bus_volt(void)
+{
+ unsigned int asv_group;
+ unsigned int i;
+
+ asv_group = exynos_asv->asv_result & 0xF;
+
+ asv_group = 0;
+ printk(KERN_INFO "DVFS : VDD_INT Voltage table set with %d Group\n", asv_group);
+
+ for (i = 0 ; i < LV_END ; i++) {
+ switch (asv_group) {
+ case 0:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[0][i];
+ break;
+ case 1:
+ case 2:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[1][i];
+ break;
+ case 3:
+ case 4:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[2][i];
+ break;
+ case 5:
+ case 6:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[3][i];
+ break;
+ case 7:
+ exynos4_busfreq_table[i].volt =
+ exynos4_asv_volt[4][i];
+ break;
+ }
+ }
+
+ return;
+}
+
+unsigned int exynos4210_target(unsigned int div_index)
+{
+ unsigned int tmp;
+
+ /* Change Divider - DMC0 */
+ tmp = exynos4_busfreq_table[div_index].clk_dmc0div;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
+ } while (tmp & 0x11111111);
+
+ /* Change Divider - TOP */
+ tmp = exynos4_busfreq_table[div_index].clk_topdiv;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
+ } while (tmp & 0x11111);
+
+ /* Change Divider - LEFTBUS */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
+
+ tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_lr_bus[div_index][0] << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_lr_bus[div_index][1] << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
+ } while (tmp & 0x11);
+
+ /* Change Divider - RIGHTBUS */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
+
+ tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_lr_bus[div_index][0] << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_lr_bus[div_index][1] << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
+ } while (tmp & 0x11);
+
+ return div_index;
+}
+
+unsigned int exynos4210_get_table_index(struct opp *opp)
+{
+ unsigned int index;
+
+ for (index = LV_0; index < LV_END; index++)
+ if (opp_get_freq(opp) == exynos4_busfreq_table[index].mem_clk)
+ break;
+
+ return index;
+}
+
+int exynos4210_init(struct device *dev, struct busfreq_data *data)
+{
+ unsigned int i;
+ unsigned int tmp;
+ unsigned long maxfreq = UINT_MAX;
+ int ret;
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
+
+ for (i = 0; i < LV_END; i++) {
+ tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+ EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+ EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMCP_MASK |
+ EXYNOS4_CLKDIV_DMC0_COPY2_MASK |
+ EXYNOS4_CLKDIV_DMC0_CORETI_MASK);
+
+ tmp |= ((clkdiv_dmc0[i][0] << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
+ (clkdiv_dmc0[i][1] << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+ (clkdiv_dmc0[i][2] << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
+ (clkdiv_dmc0[i][3] << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
+ (clkdiv_dmc0[i][4] << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
+ (clkdiv_dmc0[i][5] << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT) |
+ (clkdiv_dmc0[i][6] << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT) |
+ (clkdiv_dmc0[i][7] << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT));
+
+ exynos4_busfreq_table[i].clk_dmc0div = tmp;
+ }
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
+
+ for (i = 0; i < LV_END; i++) {
+ tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK200_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+ EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
+
+ tmp |= ((clkdiv_top[i][0] << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT) |
+ (clkdiv_top[i][1] << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
+ (clkdiv_top[i][2] << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
+ (clkdiv_top[i][3] << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
+ (clkdiv_top[i][4] << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
+
+ exynos4_busfreq_table[i].clk_topdiv = tmp;
+ }
+
+ exynos4210_set_bus_volt();
+
+ for (i = 0; i < LV_END; i++) {
+ ret = opp_add(dev, exynos4_busfreq_table[i].mem_clk,
+ exynos4_busfreq_table[i].volt);
+ if (ret) {
+ dev_err(dev, "Fail to add opp entries.\n");
+ return ret;
+ }
+ }
+
+ data->table = exynos4_busfreq_table;
+ data->table_size = LV_END;
+
+ /* Find max frequency */
+ data->max_opp = opp_find_freq_floor(dev, &maxfreq);
+
+ data->vdd_int = regulator_get(NULL, "vdd_int");
+ if (IS_ERR(data->vdd_int)) {
+ pr_err("failed to get resource %s\n", "vdd_int");
+ return -ENODEV;
+ }
+
+ data->vdd_mif = ERR_PTR(-ENODEV);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/busfreq_opp_4x12.c b/arch/arm/mach-exynos/busfreq_opp_4x12.c
new file mode 100644
index 0000000..5f310ba
--- /dev/null
+++ b/arch/arm/mach-exynos/busfreq_opp_4x12.c
@@ -0,0 +1,939 @@
+/* linux/arch/arm/mach-exynos/busfreq_opp_4x12.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - BUS clock frequency scaling support with OPP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/pm_qos_params.h>
+
+#include <mach/busfreq_exynos4.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/ppmu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/dev.h>
+#include <mach/asv.h>
+#include <mach/smc.h>
+
+#include <plat/map-s5p.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+#define UP_THRESHOLD 30
+#define IDLE_THRESHOLD 4
+#define UP_CPU_THRESHOLD 11
+#define MAX_CPU_THRESHOLD 20
+#define CPU_SLOPE_SIZE 7
+#define PPMU_THRESHOLD 5
+
+unsigned int up_threshold = UP_THRESHOLD;
+unsigned int ppmu_threshold = PPMU_THRESHOLD;
+unsigned int idle_threshold = IDLE_THRESHOLD;
+unsigned int up_cpu_threshold = UP_CPU_THRESHOLD;
+unsigned int max_cpu_threshold = MAX_CPU_THRESHOLD;
+unsigned int cpu_slope_size = CPU_SLOPE_SIZE;
+unsigned int dmc_max_threshold;
+unsigned int load_history_size = LOAD_HISTORY_SIZE;
+
+/* To save/restore DMC_PAUSE_CTRL register */
+static unsigned int dmc_pause_ctrl;
+
+enum busfreq_level_idx {
+ LV_0,
+ LV_1,
+ LV_2,
+ LV_3,
+ LV_4,
+ LV_5,
+ LV_6,
+ LV_END
+};
+
+static struct busfreq_table exynos4_busfreq_table[] = {
+ {LV_0, 400266, 1100000, 0, 0, 0}, /* MIF : 400MHz INT : 200MHz */
+ {LV_1, 400200, 1100000, 0, 0, 0}, /* MIF : 400MHz INT : 200MHz */
+ {LV_2, 267200, 1000000, 0, 0, 0}, /* MIF : 267MHz INT : 200MHz */
+ {LV_3, 267160, 1000000, 0, 0, 0}, /* MIF : 267MHz INT : 160MHz */
+ {LV_4, 160160, 950000, 0, 0, 0}, /* MIF : 160MHz INT : 160MHz */
+ {LV_5, 133133, 950000, 0, 0, 0}, /* MIF : 133MHz INT : 133MHz */
+ {LV_6, 100100, 950000, 0, 0, 0}, /* MIF : 100MHz INT : 100MHz */
+};
+
+enum busfreq_qos_target {
+ BUS_QOS_0,
+ BUS_QOS_1,
+ BUS_QOS_MAX,
+};
+
+static enum busfreq_qos_target busfreq_qos = BUS_QOS_0;
+
+#if defined(CONFIG_BUSFREQ_QOS_1280X800) /* P4NOTE */
+static unsigned int exynos4_qos_value[BUS_QOS_MAX][LV_END][4] = {
+ {
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x06, 0x03, 0x06, 0x0e},
+ {0x06, 0x03, 0x06, 0x0e},
+ {0x03, 0x03, 0x03, 0x0e},
+ {0x03, 0x03, 0x03, 0x0e},
+ {0x03, 0x0B, 0x00, 0x00},
+ },
+ {
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x03, 0x06, 0x0e},
+ {0x04, 0x03, 0x04, 0x0e},
+ {0x03, 0x0b, 0x00, 0x00},
+ },
+};
+#else
+static unsigned int exynos4_qos_value[BUS_QOS_MAX][LV_END][4] = {
+ {
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00},
+ {0x06, 0x03, 0x06, 0x0e},
+ {0x04, 0x03, 0x04, 0x0e},
+ {0x03, 0x0B, 0x00, 0x00},
+ },
+ {
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x0b, 0x06, 0x0f},
+ {0x06, 0x03, 0x06, 0x0e},
+ {0x04, 0x03, 0x04, 0x0e},
+ {0x03, 0x0b, 0x00, 0x00},
+ },
+};
+#endif
+
+#define ASV_GROUP 12
+
+static unsigned int asv_group_index;
+
+static unsigned int (*exynos4_mif_volt)[LV_END];
+static unsigned int (*exynos4_int_volt)[LV_END];
+
+static unsigned int exynos4212_mif_volt[ASV_GROUP][LV_END] = {
+ /* 400 400 267 267 160 133 100 */
+ {1012500, 1012500, 962500, 962500, 912500, 912500, 912500}, /* RESERVED */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV1 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV2 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV3 */
+ {1050000, 1050000, 1000000, 1000000, 900000, 900000, 900000}, /* ASV4 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV5 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV6 */
+ {950000, 950000, 900000, 900000, 900000, 900000, 900000}, /* ASV7 */
+ {950000, 950000, 900000, 900000, 900000, 900000, 850000}, /* ASV8 */
+ {950000, 950000, 900000, 900000, 900000, 900000, 850000}, /* ASV9 */
+ {950000, 950000, 900000, 900000, 900000, 850000, 850000}, /* ASV10 */
+ {937500, 937500, 887500, 887500, 887500, 850000, 850000}, /* RESERVED */
+};
+
+static unsigned int exynos4212_int_volt[ASV_GROUP][LV_END] = {
+ /* 266 200 200 160 160 133 100 */
+ {1300000, 1250000, 1250000, 950000, 950000, 912500, 887500}, /* RESERVED */
+ {1062500, 1012500, 1012500, 937500, 937500, 900000, 875000}, /* ASV1 */
+ {1050000, 1000000, 1000000, 925000, 925000, 887500, 875000}, /* ASV2 */
+ {1050000, 1000000, 1000000, 912500, 912500, 887500, 875000}, /* ASV3 */
+ {1062500, 1012500, 1012500, 925000, 925000, 900000, 875000}, /* ASV4 */
+ {1050000, 1000000, 1000000, 925000, 925000, 887500, 875000}, /* ASV5 */
+ {1050000, 1000000, 1000000, 912500, 912500, 887500, 875000}, /* ASV6 */
+ {1037500, 987500, 987500, 912500, 912500, 875000, 875000}, /* ASV7 */
+ {1037500, 987500, 987500, 900000, 900000, 875000, 875000}, /* ASV8 */
+ {1037500, 987500, 987500, 900000, 900000, 875000, 875000}, /* ASV9 */
+ {1037500, 987500, 987500, 900000, 900000, 862500, 850000}, /* ASV10 */
+ {1035000, 975000, 975000, 887500, 887500, 850000, 850000}, /* RESERVED */
+};
+#if 0
+/* 20120105 DVFS table */
+static unsigned int exynos4412_mif_volt[ASV_GROUP][LV_END] = {
+ /* 400 267 267 160 133 100 */
+ {1100000, 1000000, 1000000, 950000, 950000, 950000}, /* ASV 0 */
+ {1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV 1 */
+ {1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV 2 */
+ {1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV 3 */
+ {1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV 4 */
+ {1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV 5 */
+ {1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV 6 */
+ {1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV 7 */
+ {1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV 8 */
+ {1000000, 950000, 950000, 900000, 900000, 850000}, /* ASV 9 */
+ {1000000, 900000, 900000, 900000, 900000, 850000}, /* ASV10 */
+ {1000000, 900000, 900000, 900000, 900000, 850000}, /* ASV11 */
+};
+
+static unsigned int exynos4412_int_volt[ASV_GROUP][LV_END] = {
+ /* 200 200 160 160 133 100 */
+ {1062500, 1062500, 975000, 975000, 925000, 900000}, /* ASV 0 */
+ {1050000, 1050000, 962500, 962500, 912500, 887500}, /* ASV 1 */
+ {1037500, 1037500, 950000, 950000, 900000, 875000}, /* ASV 2 */
+ {1025000, 1025000, 950000, 950000, 875000, 862500}, /* ASV 3 */
+ {1025000, 1025000, 937500, 937500, 875000, 862500}, /* ASV 4 */
+ {1012500, 1012500, 937500, 937500, 862500, 850000}, /* ASV 5 */
+ {1012500, 1012500, 925000, 925000, 862500, 850000}, /* ASV 6 */
+ {1000000, 1000000, 925000, 925000, 850000, 850000}, /* ASV 7 */
+ {1000000, 1000000, 912500, 912500, 850000, 850000}, /* ASV 8 */
+ {1000000, 1000000, 912500, 912500, 850000, 850000}, /* ASV 9 */
+ {1000000, 1000000, 912500, 912500, 850000, 850000}, /* ASV10 */
+ { 987500, 987500, 900000, 900000, 837500, 837500}, /* ASV11 */
+
+};
+#else
+/* 20120210 DVFS table */
+static unsigned int exynos4412_mif_volt[ASV_GROUP][LV_END] = {
+ /* 400 400 267 267 160 133 100 */
+ {1100000, 1100000, 1000000, 1000000, 950000, 950000, 950000}, /* RESERVED */
+ {1050000, 1050000, 950000, 950000, 900000, 900000, 900000}, /* RESERVED */
+ {1050000, 1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV2 */
+ {1050000, 1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV3 */
+ {1050000, 1050000, 950000, 950000, 900000, 900000, 900000}, /* ASV4 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV5 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV6 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV7 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 900000}, /* ASV8 */
+ {1000000, 1000000, 950000, 950000, 900000, 900000, 850000}, /* ASV9 */
+ {1000000, 1000000, 900000, 900000, 900000, 900000, 850000}, /* ASV10 */
+ {1000000, 1000000, 900000, 900000, 900000, 900000, 850000}, /* RESERVED */
+};
+
+static unsigned int exynos4412_int_volt[ASV_GROUP][LV_END] = {
+ /* GDR : 266 200 200 160 160 133 100 */
+ {1112500, 1062500, 1062500, 975000, 975000, 937500, 900000}, /* RESERVED */
+ {1100000, 1050000, 1050000, 962500, 962500, 925000, 887500}, /* RESERVED */
+ {1075000, 1025000, 1025000, 937500, 937500, 912500, 875000}, /* ASV2 */
+ {1062500, 1012500, 1012500, 937500, 937500, 900000, 862500}, /* ASV3 */
+ {1062500, 1012500, 1012500, 925000, 925000, 900000, 862500}, /* ASV4 */
+ {1050000, 1000000, 1000000, 925000, 925000, 887500, 850000}, /* ASV5 */
+ {1050000, 1000000, 1000000, 912500, 912500, 875000, 850000}, /* ASV6 */
+ {1037500, 987500, 987500, 912500, 912500, 862500, 850000}, /* ASV7 */
+ {1037500, 987500, 987500, 900000, 900000, 862500, 850000}, /* ASV8 */
+ {1037500, 987500, 987500, 900000, 900000, 862500, 850000}, /* ASV9 */
+ {1037500, 987500, 987500, 900000, 900000, 862500, 850000}, /* ASV10 */
+ {1025000, 975000, 975000, 887500, 887500, 850000, 850000}, /* RESERVED */
+};
+
+#endif
+static unsigned int exynos4x12_timingrow[LV_END] = {
+ 0x34498691, 0x34498691, 0x24488490, 0x24488490, 0x154882D0, 0x154882D0, 0x0D488210
+};
+
+static unsigned int clkdiv_dmc0[LV_END][6] = {
+ /*
+ * Clock divider value for following
+ * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
+ * DIVDMCP}
+ */
+
+ /* DMC L0: 400MHz */
+ {3, 1, 1, 1, 1, 1},
+
+ /* DMC L1: 400MHz */
+ {3, 1, 1, 1, 1, 1},
+
+ /* DMC L2: 266.7MHz */
+ {4, 1, 1, 2, 1, 1},
+
+ /* DMC L3: 266.7MHz */
+ {4, 1, 1, 2, 1, 1},
+
+ /* DMC L4: 160MHz */
+ {5, 1, 1, 4, 1, 1},
+
+ /* DMC L5: 133MHz */
+ {5, 1, 1, 5, 1, 1},
+
+ /* DMC L6: 100MHz */
+ {7, 1, 1, 7, 1, 1},
+};
+
+static unsigned int clkdiv_dmc1[LV_END][6] = {
+ /*
+ * Clock divider value for following
+ * { G2DACP, DIVC2C, DIVC2C_ACLK }
+ */
+
+ /* DMC L0: 400MHz */
+ {3, 1, 1},
+
+ /* DMC L1: 400MHz */
+ {3, 1, 1},
+
+ /* DMC L2: 266.7MHz */
+ {4, 2, 1},
+
+ /* DMC L3: 266.7MHz */
+ {4, 2, 1},
+
+ /* DMC L4: 160MHz */
+ {5, 4, 1},
+
+ /* DMC L5: 133MHz */
+ {5, 5, 1},
+
+ /* DMC L6: 100MHz */
+ {7, 7, 1},
+};
+
+static unsigned int clkdiv_top[LV_END][5] = {
+ /*
+ * Clock divider value for following
+ * { DIVACLK266_GPS, DIVACLK100, DIVACLK160,
+ DIVACLK133, DIVONENAND }
+ */
+
+ /* ACLK_GDL/R L0: 266MHz */
+ {2, 7, 4, 5, 1},
+
+ /* ACLK_GDL/R L1: 200MHz */
+ {2, 7, 4, 5, 1},
+
+ /* ACLK_GDL/R L2: 200MHz */
+ {2, 7, 4, 5, 1},
+
+ /* ACLK_GDL/R L3: 160MHz */
+ {4, 7, 5, 7, 1},
+
+ /* ACLK_GDL/R L4: 160MHz */
+ {4, 7, 5, 7, 1},
+
+ /* ACLK_GDL/R L5: 133MHz */
+ {5, 7, 5, 7, 1},
+
+ /* ACLK_GDL/R L6: 100MHz */
+ {7, 7, 7, 7, 1},
+};
+
+static unsigned int clkdiv_l_bus[LV_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVGDL, DIVGPL }
+ */
+
+ /* ACLK_GDL L0: 200MHz */
+ {3, 1},
+
+ /* ACLK_GDL L1: 200MHz */
+ {3, 1},
+
+ /* ACLK_GDL L2: 200MHz */
+ {3, 1},
+
+ /* ACLK_GDL L3: 160MHz */
+ {4, 1},
+
+ /* ACLK_GDL L4: 160MHz */
+ {4, 1},
+
+ /* ACLK_GDL L5: 133MHz */
+ {5, 1},
+
+ /* ACLK_GDL L6: 100MHz */
+ {7, 1},
+};
+
+static unsigned int clkdiv_r_bus[LV_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVGDR, DIVGPR }
+ */
+
+ /* ACLK_GDR L0: 266MHz */
+ {2, 1},
+
+ /* ACLK_GDR L1: 200MHz */
+ {3, 1},
+
+ /* ACLK_GDR L2: 200MHz */
+ {3, 1},
+
+ /* ACLK_GDR L3: 160MHz */
+ {4, 1},
+
+ /* ACLK_GDR L4: 160MHz */
+ {4, 1},
+
+ /* ACLK_GDR L5: 133MHz */
+ {5, 1},
+
+ /* ACLK_GDR L6: 100MHz */
+ {7, 1},
+};
+
+static unsigned int clkdiv_sclkip[LV_END][3] = {
+ /*
+ * Clock divider value for following
+ * { DIVMFC, DIVJPEG, DIVFIMC0~3}
+ */
+
+ /* SCLK_MFC: 200MHz */
+ {3, 3, 4},
+
+ /* SCLK_MFC: 200MHz */
+ {3, 3, 4},
+
+ /* SCLK_MFC: 200MHz */
+ {3, 3, 4},
+
+ /* SCLK_MFC: 160MHz */
+ {4, 4, 5},
+
+ /* SCLK_MFC: 160MHz */
+ {4, 4, 5},
+
+ /* SCLK_MFC: 133MHz */
+ {5, 5, 5},
+
+ /* SCLK_MFC: 100MHz */
+ {7, 7, 7},
+};
+
+static void exynos4x12_set_bus_volt(void)
+{
+ unsigned int i;
+
+ asv_group_index = exynos_result_of_asv;
+
+ if (asv_group_index == 0xff)
+ asv_group_index = 0;
+
+ printk(KERN_INFO "DVFS : VDD_INT Voltage table set with %d Group\n", asv_group_index);
+
+ for (i = 0 ; i < LV_END ; i++)
+ exynos4_busfreq_table[i].volt =
+ exynos4_mif_volt[asv_group_index][i];
+
+ return;
+}
+
+void exynos4x12_target(int index)
+{
+ unsigned int tmp;
+
+ /* Change Divider - DMC0 */
+ tmp = exynos4_busfreq_table[index].clk_dmc0div;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_DMC0);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC0);
+ } while (tmp & 0x111111);
+
+ /* Change Divider - DMC1 */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
+
+ tmp &= ~(EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK |
+ EXYNOS4_CLKDIV_DMC1_C2C_MASK |
+ EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK);
+
+ tmp |= ((clkdiv_dmc1[index][0] << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT) |
+ (clkdiv_dmc1[index][1] << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT) |
+ (clkdiv_dmc1[index][2] << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_DMC1);
+ } while (tmp & 0x1011);
+
+ /* Change Divider - TOP */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_TOP);
+
+ tmp &= ~(EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK100_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK160_MASK |
+ EXYNOS4_CLKDIV_TOP_ACLK133_MASK |
+ EXYNOS4_CLKDIV_TOP_ONENAND_MASK);
+
+ tmp |= ((clkdiv_top[index][0] << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT) |
+ (clkdiv_top[index][1] << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT) |
+ (clkdiv_top[index][2] << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT) |
+ (clkdiv_top[index][3] << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT) |
+ (clkdiv_top[index][4] << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_TOP);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_TOP);
+ } while (tmp & 0x11111);
+
+ /* Change Divider - LEFTBUS */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_LEFTBUS);
+
+ tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_l_bus[index][0] << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_l_bus[index][1] << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_LEFTBUS);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_LEFTBUS);
+ } while (tmp & 0x11);
+
+ /* Change Divider - RIGHTBUS */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_RIGHTBUS);
+
+ tmp &= ~(EXYNOS4_CLKDIV_BUS_GDLR_MASK | EXYNOS4_CLKDIV_BUS_GPLR_MASK);
+
+ tmp |= ((clkdiv_r_bus[index][0] << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT) |
+ (clkdiv_r_bus[index][1] << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_RIGHTBUS);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_RIGHTBUS);
+ } while (tmp & 0x11);
+
+ /* Change Divider - MFC */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_MFC);
+
+ tmp &= ~(EXYNOS4_CLKDIV_MFC_MASK);
+
+ tmp |= ((clkdiv_sclkip[index][0] << EXYNOS4_CLKDIV_MFC_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_MFC);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_MFC);
+ } while (tmp & 0x1);
+
+ /* Change Divider - JPEG */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CAM1);
+
+ tmp &= ~(EXYNOS4_CLKDIV_CAM1_JPEG_MASK);
+
+ tmp |= ((clkdiv_sclkip[index][1] << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CAM1);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
+ } while (tmp & 0x1);
+
+ /* Change Divider - FIMC0~3 */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CAM);
+
+ tmp &= ~(EXYNOS4_CLKDIV_CAM_FIMC0_MASK | EXYNOS4_CLKDIV_CAM_FIMC1_MASK |
+ EXYNOS4_CLKDIV_CAM_FIMC2_MASK | EXYNOS4_CLKDIV_CAM_FIMC3_MASK);
+
+ tmp |= ((clkdiv_sclkip[index][2] << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT) |
+ (clkdiv_sclkip[index][2] << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT) |
+ (clkdiv_sclkip[index][2] << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT) |
+ (clkdiv_sclkip[index][2] << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CAM);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STAT_CAM1);
+ } while (tmp & 0x1111);
+
+ if (soc_is_exynos4412() && (exynos_result_of_asv > 3)) {
+ if (index == LV_6) { /* MIF:100 / INT:100 */
+ exynos4x12_set_abb_member(ABB_INT, ABB_MODE_100V);
+ exynos4x12_set_abb_member(ABB_MIF, ABB_MODE_100V);
+ } else {
+ exynos4x12_set_abb_member(ABB_INT, ABB_MODE_130V);
+ exynos4x12_set_abb_member(ABB_MIF, ABB_MODE_130V);
+ }
+ }
+}
+
+unsigned int exynos4x12_get_table_index(struct opp *opp)
+{
+ unsigned int index;
+
+ for (index = LV_0; index < LV_END; index++)
+ if (opp_get_freq(opp) == exynos4_busfreq_table[index].mem_clk)
+ break;
+
+ return index;
+}
+
+void exynos4x12_prepare(unsigned int index)
+{
+ unsigned int timing0 = 0;
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc_readsfr(EXYNOS4_PA_DMC0_4212 + TIMINGROW_OFFSET, &timing0);
+ timing0 |= exynos4x12_timingrow[index];
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC0_4212 + TIMINGROW_OFFSET),
+ timing0, 0);
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC0_4212 + TIMINGROW_OFFSET),
+ exynos4x12_timingrow[index], 0);
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC1_4212 + TIMINGROW_OFFSET),
+ timing0, 0);
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC1_4212 + TIMINGROW_OFFSET),
+ exynos4x12_timingrow[index], 0);
+#else
+ timing0 = __raw_readl(S5P_VA_DMC0 + TIMINGROW_OFFSET);
+ timing0 |= exynos4x12_timingrow[index];
+ __raw_writel(timing0, S5P_VA_DMC0 + TIMINGROW_OFFSET);
+ __raw_writel(exynos4x12_timingrow[index], S5P_VA_DMC0 + TIMINGROW_OFFSET);
+ __raw_writel(timing0, S5P_VA_DMC1 + TIMINGROW_OFFSET);
+ __raw_writel(exynos4x12_timingrow[index], S5P_VA_DMC1 + TIMINGROW_OFFSET);
+#endif
+}
+
+void exynos4x12_post(unsigned int index)
+{
+ unsigned int timing0 = 0;
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc_readsfr(EXYNOS4_PA_DMC0_4212 + TIMINGROW_OFFSET, &timing0);
+ timing0 |= exynos4x12_timingrow[index];
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC0_4212 + TIMINGROW_OFFSET),
+ timing0, 0);
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC0_4212 + TIMINGROW_OFFSET),
+ exynos4x12_timingrow[index], 0);
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC1_4212 + TIMINGROW_OFFSET),
+ timing0, 0);
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_SFR_W(EXYNOS4_PA_DMC1_4212 + TIMINGROW_OFFSET),
+ exynos4x12_timingrow[index], 0);
+#else
+ timing0 = __raw_readl(S5P_VA_DMC0 + TIMINGROW_OFFSET);
+ timing0 |= exynos4x12_timingrow[index];
+ __raw_writel(timing0, S5P_VA_DMC0 + TIMINGROW_OFFSET);
+ __raw_writel(exynos4x12_timingrow[index], S5P_VA_DMC0 + TIMINGROW_OFFSET);
+ __raw_writel(timing0, S5P_VA_DMC1 + TIMINGROW_OFFSET);
+ __raw_writel(exynos4x12_timingrow[index], S5P_VA_DMC1 + TIMINGROW_OFFSET);
+#endif
+}
+
+void exynos4x12_set_qos(unsigned int index)
+{
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][0], S5P_VA_GDL + 0x400);
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][1], S5P_VA_GDL + 0x404);
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][2], S5P_VA_GDR + 0x400);
+ __raw_writel(exynos4_qos_value[busfreq_qos][index][3], S5P_VA_GDR + 0x404);
+}
+
+void exynos4x12_suspend(void)
+{
+ /* Nothing to do */
+}
+
+void exynos4x12_resume(void)
+{
+ __raw_writel(dmc_pause_ctrl, EXYNOS4_DMC_PAUSE_CTRL);
+}
+
+/**
+ * exynos4x12_find_busfreq_by_volt - find busfreq by requested
+ * voltage.
+ *
+ * This function finds the busfreq to set for voltage above req_volt
+ * and return its value.
+ */
+int exynos4x12_find_busfreq_by_volt(unsigned int req_volt, unsigned int *freq)
+{
+ unsigned int volt_cmp;
+ int i;
+
+ /* check if req_volt has value or not */
+ if (!req_volt) {
+ pr_err("%s: req_volt has no value.\n", __func__);
+ return -EINVAL;
+ }
+
+ /* find busfreq level in busfreq_table */
+ for (i = LV_END - 1; i >= 0; i--) {
+ volt_cmp = min(exynos4_int_volt[asv_group_index][i],
+ exynos4_mif_volt[asv_group_index][i]);
+
+ if (volt_cmp >= req_volt) {
+ *freq = exynos4_busfreq_table[i].mem_clk;
+ return 0;
+ }
+ }
+ pr_err("%s: %u volt can't support\n", __func__, req_volt);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(exynos4x12_find_busfreq_by_volt);
+
+unsigned int exynos4x12_get_int_volt(unsigned long index)
+{
+ return exynos4_int_volt[asv_group_index][index];
+}
+
+struct opp *exynos4x12_monitor(struct busfreq_data *data)
+{
+ struct opp *opp = data->curr_opp;
+ int i;
+ unsigned int cpu_load_average = 0;
+ unsigned int dmc0_load_average = 0;
+ unsigned int dmc1_load_average = 0;
+ unsigned int dmc_load_average;
+ unsigned long cpufreq = 0;
+ unsigned long lockfreq;
+ unsigned long dmcfreq;
+ unsigned long newfreq;
+ unsigned long currfreq = opp_get_freq(data->curr_opp) / 1000;
+ unsigned long maxfreq = opp_get_freq(data->max_opp) / 1000;
+ unsigned long cpu_load;
+ unsigned long dmc0_load;
+ unsigned long dmc1_load;
+ unsigned long dmc_load;
+ int cpu_load_slope;
+
+ ppmu_update(data->dev, 3);
+
+ /* Convert from base xxx to base maxfreq */
+ cpu_load = ppmu_load[PPMU_CPU];
+ dmc0_load = div64_u64(ppmu_load[PPMU_DMC0] * currfreq, maxfreq);
+ dmc1_load = div64_u64(ppmu_load[PPMU_DMC1] * currfreq, maxfreq);
+
+ cpu_load_slope = cpu_load -
+ data->load_history[PPMU_CPU]
+ [data->index ? data->index - 1 : load_history_size - 1];
+
+ data->load_history[PPMU_CPU][data->index] = cpu_load;
+ data->load_history[PPMU_DMC0][data->index] = dmc0_load;
+ data->load_history[PPMU_DMC1][data->index++] = dmc1_load;
+
+ if (data->index >= load_history_size)
+ data->index = 0;
+
+ for (i = 0; i < load_history_size; i++) {
+ cpu_load_average += data->load_history[PPMU_CPU][i];
+ dmc0_load_average += data->load_history[PPMU_DMC0][i];
+ dmc1_load_average += data->load_history[PPMU_DMC1][i];
+ }
+
+ /* Calculate average Load */
+ cpu_load_average /= load_history_size;
+ dmc0_load_average /= load_history_size;
+ dmc1_load_average /= load_history_size;
+
+ if (dmc0_load >= dmc1_load) {
+ dmc_load = dmc0_load;
+ dmc_load_average = dmc0_load_average;
+ } else {
+ dmc_load = dmc1_load;
+ dmc_load_average = dmc1_load_average;
+ }
+
+ if (cpu_load >= up_cpu_threshold) {
+ cpufreq = opp_get_freq(data->max_opp);
+ if (cpu_load < max_cpu_threshold) {
+ opp = data->curr_opp;
+ if (cpu_load_slope > cpu_slope_size) {
+ cpufreq--;
+ opp = opp_find_freq_floor(data->dev, &cpufreq);
+ }
+ cpufreq = opp_get_freq(opp);
+ }
+ }
+
+ if (dmc_load >= dmc_max_threshold) {
+ dmcfreq = opp_get_freq(data->max_opp);
+ } else if (dmc_load < idle_threshold) {
+ if (dmc_load_average < idle_threshold)
+ opp = step_down(data, 1);
+ else
+ opp = data->curr_opp;
+ dmcfreq = opp_get_freq(opp);
+ } else {
+ if (dmc_load < dmc_load_average) {
+ dmc_load = dmc_load_average;
+ if (dmc_load >= dmc_max_threshold)
+ dmc_load = dmc_max_threshold;
+ }
+ dmcfreq = div64_u64(maxfreq * dmc_load * 1000, dmc_max_threshold);
+ }
+
+ lockfreq = dev_max_freq(data->dev);
+
+ newfreq = max3(lockfreq, dmcfreq, cpufreq);
+
+ if (samsung_rev() < EXYNOS4412_REV_1_0)
+ newfreq = opp_get_freq(data->max_opp);
+
+ pr_debug("curfreq %ld, newfreq %ld, dmc0_load %ld, dmc1_load %ld, cpu_load %ld\n",
+ currfreq, newfreq, dmc0_load, dmc1_load, cpu_load);
+
+ opp = opp_find_freq_ceil(data->dev, &newfreq);
+ if (IS_ERR(opp))
+ opp = data->max_opp;
+
+ return opp;
+}
+
+static int exynos4x12_bus_qos_notifiy(struct notifier_block *nb,
+ unsigned long l, void *v)
+{
+ struct busfreq_data *bus_data = container_of(nb, struct busfreq_data,
+ exynos_busqos_notifier);
+
+ busfreq_qos = (int)l;
+ exynos4x12_set_qos(bus_data->get_table_index(bus_data->curr_opp));
+
+ return NOTIFY_OK;
+}
+
+static inline void exynos4x12_bus_qos_notifier_init(struct notifier_block *n)
+{
+ pm_qos_add_notifier(PM_QOS_BUS_QOS, n);
+}
+
+#define ARM_INT_CORRECTION 160160
+
+static int exynos4x12_busfreq_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
+ struct busfreq_data *bus_data = container_of(nb, struct busfreq_data,
+ exynos_cpufreq_notifier);
+
+ switch (val) {
+ case CPUFREQ_PRECHANGE:
+ if (freqs->new > 900000 && freqs->old < 1000000)
+ dev_lock(bus_data->dev, bus_data->dev, ARM_INT_CORRECTION);
+ break;
+ case CPUFREQ_POSTCHANGE:
+ if (freqs->old > 900000 && freqs->new < 1000000)
+ dev_unlock(bus_data->dev, bus_data->dev);
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+int exynos4x12_init(struct device *dev, struct busfreq_data *data)
+{
+ unsigned int i;
+ unsigned int tmp;
+ unsigned long maxfreq = 400200;
+ unsigned long minfreq = 0;
+ unsigned long freq;
+ struct clk *sclk_dmc;
+ int ret;
+
+ if (soc_is_exynos4212()) {
+ exynos4_mif_volt = exynos4212_mif_volt;
+ exynos4_int_volt = exynos4212_int_volt;
+ dmc_max_threshold = EXYNOS4212_DMC_MAX_THRESHOLD;
+ } else if (soc_is_exynos4412()) {
+ exynos4_mif_volt = exynos4412_mif_volt;
+ exynos4_int_volt = exynos4412_int_volt;
+ dmc_max_threshold = EXYNOS4412_DMC_MAX_THRESHOLD;
+ } else {
+ pr_err("Unsupported model.\n");
+ return -EINVAL;
+ }
+
+ /* Enable pause function for DREX2 DVFS */
+ dmc_pause_ctrl = __raw_readl(EXYNOS4_DMC_PAUSE_CTRL);
+ dmc_pause_ctrl |= DMC_PAUSE_ENABLE;
+ __raw_writel(dmc_pause_ctrl, EXYNOS4_DMC_PAUSE_CTRL);
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_DMC0);
+
+ for (i = 0; i < LV_END; i++) {
+ tmp &= ~(EXYNOS4_CLKDIV_DMC0_ACP_MASK |
+ EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK |
+ EXYNOS4_CLKDIV_DMC0_DPHY_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMC_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMCD_MASK |
+ EXYNOS4_CLKDIV_DMC0_DMCP_MASK);
+
+ tmp |= ((clkdiv_dmc0[i][0] << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT) |
+ (clkdiv_dmc0[i][1] << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT) |
+ (clkdiv_dmc0[i][2] << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT) |
+ (clkdiv_dmc0[i][3] << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT) |
+ (clkdiv_dmc0[i][4] << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT) |
+ (clkdiv_dmc0[i][5] << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT));
+
+ exynos4_busfreq_table[i].clk_dmc0div = tmp;
+ }
+
+ exynos4x12_set_bus_volt();
+
+ for (i = 0; i < LV_END; i++) {
+ ret = opp_add(dev, exynos4_busfreq_table[i].mem_clk,
+ exynos4_busfreq_table[i].volt);
+ if (ret) {
+ dev_err(dev, "Fail to add opp entries.\n");
+ return ret;
+ }
+ }
+
+ /* Disable MIF 267 INT 200 Level */
+ /* opp_disable(dev, 267200); */
+
+ data->table = exynos4_busfreq_table;
+ data->table_size = LV_END;
+
+ /* Find max frequency */
+ data->max_opp = opp_find_freq_floor(dev, &maxfreq);
+ data->min_opp = opp_find_freq_ceil(dev, &minfreq);
+
+ sclk_dmc = clk_get(NULL, "sclk_dmc");
+
+ if (IS_ERR(sclk_dmc)) {
+ pr_err("Failed to get sclk_dmc.!\n");
+ data->curr_opp = data->max_opp;
+ } else {
+ freq = clk_get_rate(sclk_dmc) / 1000;
+ clk_put(sclk_dmc);
+ data->curr_opp = opp_find_freq_ceil(dev, &freq);
+ }
+
+ data->vdd_int = regulator_get(NULL, "vdd_int");
+ if (IS_ERR(data->vdd_int)) {
+ pr_err("failed to get resource %s\n", "vdd_int");
+ return -ENODEV;
+ }
+
+ data->vdd_mif = regulator_get(NULL, "vdd_mif");
+ if (IS_ERR(data->vdd_mif)) {
+ pr_err("failed to get resource %s\n", "vdd_mif");
+ regulator_put(data->vdd_int);
+ return -ENODEV;
+ }
+
+ data->exynos_cpufreq_notifier.notifier_call =
+ exynos4x12_busfreq_cpufreq_transition;
+
+ if (cpufreq_register_notifier(&data->exynos_cpufreq_notifier,
+ CPUFREQ_TRANSITION_NOTIFIER))
+ pr_err("Falied to register cpufreq notifier\n");
+
+ data->exynos_busqos_notifier.notifier_call = exynos4x12_bus_qos_notifiy;
+ exynos4x12_bus_qos_notifier_init(&data->exynos_busqos_notifier);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/busfreq_opp_5250.c b/arch/arm/mach-exynos/busfreq_opp_5250.c
new file mode 100644
index 0000000..bcedb46
--- /dev/null
+++ b/arch/arm/mach-exynos/busfreq_opp_5250.c
@@ -0,0 +1,892 @@
+/* linux/arch/arm/mach-exynos/busfreq_opp_5250.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS5 - BUS clock frequency scaling support with OPP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <mach/busfreq_exynos5.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/ppmu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/dev.h>
+#include <mach/asv.h>
+#include <mach/regs-pmu-5250.h>
+
+#include <plat/map-s5p.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#undef BUSFREQ_PROFILE_DEBUG
+
+#define IDLE_THRESHOLD 4
+#define MIF_R1_THRESHOLD 20
+#define MIF_MAX_THRESHOLD 20
+#define INT_MAX_THRESHOLD 20
+#define INT_RIGHT0_THRESHOLD 25
+#define INT_VIDEOPLAY_LIMIT_FREQ 200000UL
+#define INT_RBB 6 /* +300mV */
+
+static struct device busfreq_for_int;
+
+/* To save/restore DREX2_PAUSE_CTRL register */
+static unsigned int drex2_pause_ctrl;
+
+static struct busfreq_table exynos5_busfreq_table_for800[] = {
+ {LV_0, 800000, 1000000, 0, 0, 0},
+ {LV_1, 400000, 1000000, 0, 0, 0},
+ {LV_2, 160000, 1000000, 0, 0, 0},
+};
+
+static struct busfreq_table exynos5_busfreq_table_for667[] = {
+ {LV_0, 667000, 1000000, 0, 0, 0},
+ {LV_1, 334000, 1000000, 0, 0, 0},
+ {LV_2, 111000, 1000000, 0, 0, 0},
+};
+
+static struct busfreq_table exynos5_busfreq_table_for533[] = {
+ {LV_0, 533000, 1000000, 0, 0, 0},
+ {LV_1, 267000, 1000000, 0, 0, 0},
+ {LV_2, 107000, 1000000, 0, 0, 0},
+};
+
+static struct busfreq_table exynos5_busfreq_table_for400[] = {
+ {LV_0, 400000, 1000000, 0, 0, 0},
+ {LV_1, 267000, 1000000, 0, 0, 0},
+ {LV_2, 100000, 1000000, 0, 0, 0},
+};
+#define ASV_GROUP 10
+static unsigned int asv_group_index;
+
+static unsigned int exynos5_mif_volt_for800[ASV_GROUP+1][LV_MIF_END] = {
+ /* L0 L1 L2 */
+ { 0, 0, 0}, /* ASV0 */
+ {1200000, 1000000, 950000}, /* ASV1 */
+ {1200000, 1000000, 900000}, /* ASV2 */
+ {1200000, 1050000, 950000}, /* ASV3 */
+ {1150000, 1000000, 900000}, /* ASV4 */
+ {1150000, 1050000, 950000}, /* ASV5 */
+ {1150000, 1050000, 950000}, /* ASV6 */
+ {1100000, 1000000, 900000}, /* ASV7 */
+ {1100000, 1000000, 900000}, /* ASV8 */
+ {1100000, 1000000, 900000}, /* ASV9 */
+ {1100000, 1000000, 900000}, /* ASV10 */
+};
+
+static unsigned int exynos5_mif_volt_for667[ASV_GROUP+1][LV_MIF_END] = {
+ /* L0 L1 L2 */
+ { 0, 0, 0}, /* ASV0 */
+ {1100000, 1000000, 950000}, /* ASV1 */
+ {1050000, 1000000, 950000}, /* ASV2 */
+ {1050000, 1050000, 950000}, /* ASV3 */
+ {1050000, 1000000, 950000}, /* ASV4 */
+ {1050000, 1050000, 1000000}, /* ASV5 */
+ {1050000, 1050000, 950000}, /* ASV6 */
+ {1050000, 1000000, 900000}, /* ASV7 */
+ {1050000, 1000000, 900000}, /* ASV8 */
+ {1050000, 1000000, 900000}, /* ASV9 */
+ {1050000, 1000000, 900000}, /* ASV10 */
+};
+
+static unsigned int exynos5_mif_volt_for533[ASV_GROUP+1][LV_MIF_END] = {
+ /* L0 L1 L2 */
+ { 0, 0, 0}, /* ASV0 */
+ {1050000, 1000000, 950000}, /* ASV1 */
+ {1000000, 950000, 950000}, /* ASV2 */
+ {1050000, 1000000, 950000}, /* ASV3 */
+ {1000000, 950000, 950000}, /* ASV4 */
+ {1050000, 1000000, 1000000}, /* ASV5 */
+ {1050000, 950000, 950000}, /* ASV6 */
+ {1000000, 950000, 900000}, /* ASV7 */
+ {1000000, 950000, 900000}, /* ASV8 */
+ {1000000, 950000, 900000}, /* ASV9 */
+ {1000000, 950000, 900000}, /* ASV10 */
+};
+
+static unsigned int exynos5_mif_volt_for400[ASV_GROUP+1][LV_MIF_END] = {
+ /* L0 L1 L2 */
+ { 0, 0, 0}, /* ASV0 */
+ {1000000, 1000000, 950000}, /* ASV1 */
+ {1000000, 950000, 900000}, /* ASV2 */
+ {1050000, 1000000, 950000}, /* ASV3 */
+ {1000000, 950000, 900000}, /* ASV4 */
+ {1050000, 1000000, 950000}, /* ASV5 */
+ {1050000, 950000, 950000}, /* ASV6 */
+ {1000000, 950000, 900000}, /* ASV7 */
+ {1000000, 950000, 900000}, /* ASV8 */
+ {1000000, 950000, 900000}, /* ASV9 */
+ {1000000, 950000, 900000}, /* ASV10 */
+};
+
+static struct busfreq_table *exynos5_busfreq_table_mif;
+
+static unsigned int (*exynos5_mif_volt)[LV_MIF_END];
+
+static struct busfreq_table exynos5_busfreq_table_int[] = {
+ {LV_0, 267000, 1000000, 0, 0, 0},
+ {LV_1, 200000, 1000000, 0, 0, 0},
+ {LV_2, 160000, 1000000, 0, 0, 0},
+ {LV_3, 133000, 1000000, 0, 0, 0},
+};
+
+static unsigned int exynos5_int_volt[ASV_GROUP+1][LV_INT_END] = {
+ /* L0 L1 L2 L3 */
+ { 0, 0, 0, 0}, /* ASV0 */
+ {1025000, 987500, 975000, 950000}, /* ASV1 */
+ {1012500, 975000, 962500, 937500}, /* ASV2 */
+ {1012500, 987500, 975000, 950000}, /* ASV3 */
+ {1000000, 975000, 962500, 937500}, /* ASV4 */
+ {1012500, 987500, 975000, 950000}, /* ASV5 */
+ {1000000, 975000, 962500, 937500}, /* ASV6 */
+ { 987500, 962500, 950000, 925000}, /* ASV7 */
+ { 975000, 950000, 937500, 912500}, /* ASV8 */
+ { 962500, 937500, 925000, 900000}, /* ASV9 */
+ { 962500, 937500, 925000, 900000}, /* ASV10 */
+};
+
+
+/* For CMU_LEX */
+static unsigned int clkdiv_lex[LV_INT_END][2] = {
+ /*
+ * Clock divider value for following
+ * { DIVATCLK_LEX, DIVPCLK_LEX }
+ */
+
+ /* ATCLK_LEX L0 : 200MHz */
+ {0, 1},
+
+ /* ATCLK_LEX L1 : 166MHz */
+ {0, 1},
+
+ /* ATCLK_LEX L2 : 133MHz */
+ {0, 1},
+
+ /* ATCLK_LEX L3 : 114MHz */
+ {0, 1},
+};
+
+/* For CMU_R0X */
+static unsigned int clkdiv_r0x[LV_INT_END][1] = {
+ /*
+ * Clock divider value for following
+ * { DIVPCLK_R0X }
+ */
+
+ /* ACLK_PR0X L0 : 133MHz */
+ {1},
+
+ /* ACLK_DR0X L1 : 100MHz */
+ {1},
+
+ /* ACLK_PR0X L2 : 80MHz */
+ {1},
+
+ /* ACLK_PR0X L3 : 67MHz */
+ {1},
+};
+
+/* For CMU_R1X */
+static unsigned int clkdiv_r1x[LV_INT_END][1] = {
+ /*
+ * Clock divider value for following
+ * { DIVPCLK_R1X }
+ */
+
+ /* ACLK_PR1X L0 : 133MHz */
+ {1},
+
+ /* ACLK_DR1X L1 : 100MHz */
+ {1},
+
+ /* ACLK_PR1X L2 : 80MHz */
+ {1},
+
+ /* ACLK_PR1X L3 : 67MHz */
+ {1},
+};
+
+/* For CMU_TOP */
+static unsigned int clkdiv_top[LV_INT_END][10] = {
+ /*
+ * Clock divider value for following
+ * { DIVACLK400_ISP, DIVACLK400_IOP, DIVACLK266, DIVACLK_200, DIVACLK_66_PRE,
+ DIVACLK_66, DIVACLK_333, DIVACLK_166, DIVACLK_300_DISP1, DIVACLK300_GSCL }
+ */
+
+ /* ACLK_400_ISP L0 : 400MHz */
+ {1, 1, 2, 3, 1, 5, 0, 1, 2, 2},
+
+ /* ACLK_400_ISP L1 : 267MHz */
+ {2, 3, 3, 4, 1, 5, 1, 2, 2, 2},
+
+ /* ACLK_400_ISP L2 : 200MHz */
+ {3, 3, 4, 4, 1, 5, 2, 3, 2, 2},
+
+ /* ACLK_400_ISP L3 : 160MHz */
+ {4, 4, 5, 5, 1, 5, 2, 3, 5, 5},
+};
+
+/* For CMU_CDREX */
+static unsigned int clkdiv_cdrex_for800[LV_MIF_END][9] = {
+ /*
+ * Clock divider value for following
+ * { DIVMCLK_DPHY, DIVMCLK_CDREX2, DIVACLK_CDREX, DIVMCLK_CDREX,
+ DIVPCLK_CDREX, DIVC2C, DIVC2C_ACLK, DIVMCLK_EFPHY, DIVACLK_EFCON }
+ */
+
+ /* MCLK_CDREX L0: 800MHz */
+ {0, 0, 1, 0, 5, 1, 1, 4, 1},
+
+ /* MCLK_CDREX L1: 400MHz */
+ {0, 1, 1, 1, 3, 2, 1, 5, 1},
+
+ /* MCLK_CDREX L2: 100MHz */
+ {0, 4, 1, 1, 7, 7, 1, 15, 1},
+};
+
+static unsigned int clkdiv_cdrex_for667[LV_MIF_END][9] = {
+ /*
+ * Clock divider value for following
+ * { DIVMCLK_DPHY, DIVMCLK_CDREX2, DIVACLK_CDREX, DIVMCLK_CDREX,
+ DIVPCLK_CDREX, DIVC2C, DIVC2C_ACLK, DIVMCLK_EFPHY, DIVACLK_EFCON }
+ */
+
+ /* MCLK_CDREX L0: 667MHz */
+ {0, 0, 1, 0, 4, 1, 1, 4, 1},
+
+ /* MCLK_CDREX L1: 334MHz */
+ {0, 1, 1, 1, 4, 2, 1, 5, 1},
+
+ /* MCLK_CDREX L2: 111MHz */
+ {0, 5, 1, 4, 4, 5, 1, 8, 1},
+};
+
+static unsigned int clkdiv_cdrex_for533[LV_MIF_END][9] = {
+ /*
+ * Clock divider value for following
+ * { DIVMCLK_DPHY, DIVMCLK_CDREX2, DIVACLK_CDREX, DIVMCLK_CDREX,
+ DIVPCLK_CDREX, DIVC2C, DIVC2C_ACLK, DIVMCLK_EFPHY, DIVACLK_EFCON }
+ */
+
+ /* MCLK_CDREX L0: 533MHz */
+ {0, 0, 1, 0, 3, 1, 1, 4, 1},
+
+ /* MCLK_CDREX L1: 267MHz */
+ {0, 1, 1, 1, 3, 2, 1, 5, 1},
+
+ /* MCLK_CDREX L2: 107MHz */
+ {0, 4, 1, 4, 3, 5, 1, 8, 1},
+};
+
+static unsigned int __maybe_unused clkdiv_cdrex_for400[LV_MIF_END][9] = {
+ /*
+ * Clock divider value for following
+ * { DIVMCLK_DPHY, DIVMCLK_CDREX2, DIVACLK_CDREX, DIVMCLK_CDREX,
+ DIVPCLK_CDREX, DIVC2C, DIVC2C_ACLK, DIVMCLK_EFPHY, DIVACLK_EFCON }
+ */
+
+ /* MCLK_CDREX L0: 400MHz */
+ {1, 1, 1, 0, 5, 1, 1, 4, 1},
+
+ /* MCLK_CDREX L1: 267MHz */
+ {1, 2, 1, 2, 2, 2, 1, 5, 1},
+
+ /* MCLK_CDREX L2: 100MHz */
+ {1, 7, 1, 2, 7, 7, 1, 15, 1},
+};
+
+static unsigned int (*clkdiv_cdrex)[9];
+
+static void exynos5250_set_bus_volt(void)
+{
+ unsigned int i;
+
+ if (soc_is_exynos5250() && samsung_rev() < EXYNOS5250_REV_1_0)
+ asv_group_index = 0;
+ else
+ asv_group_index = exynos_result_of_asv;
+
+ if (asv_group_index == 0xff)
+ asv_group_index = 0;
+
+ printk(KERN_INFO "DVFS : VDD_INT Voltage table set with %d Group\n", asv_group_index);
+ printk(KERN_INFO "DVFS : VDD_INT Voltage of L0 level is %d \n", exynos5_mif_volt[asv_group_index][0]);
+
+ for (i = LV_0; i < LV_MIF_END; i++)
+ exynos5_busfreq_table_mif[i].volt =
+ exynos5_mif_volt[asv_group_index][i];
+
+ for (i = LV_0; i < LV_INT_END; i++)
+ exynos5_busfreq_table_int[i].volt =
+ exynos5_int_volt[asv_group_index][i];
+ return;
+}
+
+static void exynos5250_target_for_mif(struct busfreq_data *data, int div_index)
+{
+ unsigned int tmp;
+
+ /* Change Divider - CDREX */
+ tmp = data->cdrex_divtable[div_index];
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_CDREX);
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_CDREX);
+ } while (tmp & 0x11111111);
+ } else {
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_CDREX);
+ } while (tmp & 0x11110011); \
+ }
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ tmp = data->cdrex2_divtable[div_index];
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_CDREX2);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_CDREX2);
+ } while (tmp & 0x1);
+ }
+}
+
+static void exynos5250_target_for_int(struct busfreq_data *data, int div_index)
+{
+ unsigned int tmp;
+ unsigned int tmp2;
+
+ /* Change Divider - TOP */
+ tmp = __raw_readl(EXYNOS5_CLKDIV_TOP0);
+
+ tmp &= ~(EXYNOS5_CLKDIV_TOP0_ACLK266_MASK |
+ EXYNOS5_CLKDIV_TOP0_ACLK200_MASK |
+ EXYNOS5_CLKDIV_TOP0_ACLK66_MASK |
+ EXYNOS5_CLKDIV_TOP0_ACLK333_MASK |
+ EXYNOS5_CLKDIV_TOP0_ACLK166_MASK |
+ EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_MASK);
+
+ tmp |= ((clkdiv_top[div_index][2] << EXYNOS5_CLKDIV_TOP0_ACLK266_SHIFT) |
+ (clkdiv_top[div_index][3] << EXYNOS5_CLKDIV_TOP0_ACLK200_SHIFT) |
+ (clkdiv_top[div_index][5] << EXYNOS5_CLKDIV_TOP0_ACLK66_SHIFT) |
+ (clkdiv_top[div_index][6] << EXYNOS5_CLKDIV_TOP0_ACLK333_SHIFT) |
+ (clkdiv_top[div_index][7] << EXYNOS5_CLKDIV_TOP0_ACLK166_SHIFT) |
+ (clkdiv_top[div_index][8] << EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_SHIFT));
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_TOP0);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_TOP0);
+ } while (tmp & 0x151101);
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_TOP1);
+
+ tmp &= ~(EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_MASK |
+ EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_MASK |
+ EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_MASK |
+ EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_MASK);
+
+ tmp |= ((clkdiv_top[div_index][0] << EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_SHIFT) |
+ (clkdiv_top[div_index][1] << EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_SHIFT) |
+ (clkdiv_top[div_index][4] << EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_SHIFT) |
+ (clkdiv_top[div_index][9] << EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_SHIFT));
+
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_TOP1);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_TOP1);
+ tmp2 = __raw_readl(EXYNOS5_CLKDIV_STAT_TOP0);
+ } while ((tmp & 0x1110000) && (tmp2 & 0x80000));
+
+ /* Change Divider - LEX */
+ tmp = data->lex_divtable[div_index];
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_LEX);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_LEX);
+ } while (tmp & 0x110);
+
+ /* Change Divider - R0X */
+ tmp = __raw_readl(EXYNOS5_CLKDIV_R0X);
+
+ tmp &= ~EXYNOS5_CLKDIV_R0X_PCLK_R0X_MASK;
+
+ tmp |= (clkdiv_r0x[div_index][0] << EXYNOS5_CLKDIV_R0X_PCLK_R0X_SHIFT);
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_R0X);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_R0X);
+ } while (tmp & 0x10);
+
+ /* Change Divider - R1X */
+ tmp = data->r1x_divtable[div_index];
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_R1X);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_R1X);
+ } while (tmp & 0x10);
+}
+
+static void exynos5250_target(struct busfreq_data *data, enum ppmu_type type,
+ int index)
+{
+ if (type == PPMU_MIF)
+ exynos5250_target_for_mif(data, index);
+ else
+ exynos5250_target_for_int(data, index);
+}
+
+static int exynos5250_get_table_index(unsigned long freq, enum ppmu_type type)
+{
+ int index;
+
+ if (type == PPMU_MIF) {
+ for (index = LV_0; index < LV_MIF_END; index++)
+ if (freq == exynos5_busfreq_table_mif[index].mem_clk)
+ return index;
+ } else {
+ for (index = LV_0; index < LV_INT_END; index++)
+ if (freq == exynos5_busfreq_table_int[index].mem_clk)
+ return index;
+ }
+ return -EINVAL;
+}
+
+static void exynos5250_suspend(void)
+{
+ /* Nothing to do */
+}
+
+static void exynos5250_resume(void)
+{
+ __raw_writel(drex2_pause_ctrl, EXYNOS5_DREX2_PAUSE);
+}
+
+static void exynos5250_monitor(struct busfreq_data *data,
+ struct opp **mif_opp, struct opp **int_opp)
+{
+ int i;
+ unsigned int cpu_load_average = 0;
+ unsigned int ddr_c_load_average = 0;
+ unsigned int ddr_l_load_average = 0;
+ unsigned int ddr_r1_load_average = 0;
+ unsigned int right0_load_average = 0;
+ unsigned int ddr_load_average;
+ unsigned long cpufreq = 0;
+ unsigned long freq_int_right0 = 0;
+ unsigned long lockfreq[PPMU_TYPE_END];
+ unsigned long freq[PPMU_TYPE_END];
+ unsigned long cpu_load;
+ unsigned long ddr_load=0;
+ unsigned long ddr_load_int=0;
+ unsigned long ddr_c_load;
+ unsigned long ddr_r1_load;
+ unsigned long ddr_l_load;
+ unsigned long right0_load;
+ struct opp *opp[PPMU_TYPE_END];
+ unsigned long newfreq[PPMU_TYPE_END];
+
+ ppmu_update(data->dev[PPMU_MIF], 3);
+
+ /* Convert from base xxx to base maxfreq */
+ cpu_load = div64_u64(ppmu_load[PPMU_CPU] * data->curr_freq[PPMU_MIF], data->max_freq[PPMU_MIF]);
+ ddr_c_load = div64_u64(ppmu_load[PPMU_DDR_C] * data->curr_freq[PPMU_MIF], data->max_freq[PPMU_MIF]);
+ ddr_r1_load = div64_u64(ppmu_load[PPMU_DDR_R1] * data->curr_freq[PPMU_MIF], data->max_freq[PPMU_MIF]);
+ ddr_l_load = div64_u64(ppmu_load[PPMU_DDR_L] * data->curr_freq[PPMU_MIF], data->max_freq[PPMU_MIF]);
+ right0_load = div64_u64(ppmu_load[PPMU_RIGHT0_BUS] * data->curr_freq[PPMU_INT], data->max_freq[PPMU_INT]);
+
+ data->load_history[PPMU_CPU][data->index] = cpu_load;
+ data->load_history[PPMU_DDR_C][data->index] = ddr_c_load;
+ data->load_history[PPMU_DDR_R1][data->index] = ddr_r1_load;
+ data->load_history[PPMU_DDR_L][data->index] = ddr_l_load;
+ data->load_history[PPMU_RIGHT0_BUS][data->index++] = right0_load;
+
+ if (data->index >= LOAD_HISTORY_SIZE)
+ data->index = 0;
+
+ for (i = 0; i < LOAD_HISTORY_SIZE; i++) {
+ cpu_load_average += data->load_history[PPMU_CPU][i];
+ ddr_c_load_average += data->load_history[PPMU_DDR_C][i];
+ ddr_r1_load_average += data->load_history[PPMU_DDR_R1][i];
+ ddr_l_load_average += data->load_history[PPMU_DDR_L][i];
+ right0_load_average += data->load_history[PPMU_RIGHT0_BUS][i];
+ }
+
+ /* Calculate average Load */
+ cpu_load_average /= LOAD_HISTORY_SIZE;
+ ddr_c_load_average /= LOAD_HISTORY_SIZE;
+ ddr_r1_load_average /= LOAD_HISTORY_SIZE;
+ ddr_l_load_average /= LOAD_HISTORY_SIZE;
+ right0_load_average /= LOAD_HISTORY_SIZE;
+
+ if (ddr_c_load >= ddr_l_load) {
+ ddr_load = ddr_c_load;
+ ddr_load_average = ddr_c_load_average;
+ } else {
+ ddr_load = ddr_l_load;
+ ddr_load_average = ddr_l_load_average;
+ }
+
+ ddr_load_int = ddr_load;
+
+ //Calculate MIF/INT frequency level
+ if (ddr_r1_load >= MIF_R1_THRESHOLD) {
+ freq[PPMU_MIF] = data->max_freq[PPMU_MIF];
+ if (right0_load >= INT_RIGHT0_THRESHOLD) {
+ freq[PPMU_INT] = data->max_freq[PPMU_INT];
+ goto go_max;
+ } else {
+ freq_int_right0 = div64_u64(data->max_freq[PPMU_INT] * right0_load, INT_RIGHT0_THRESHOLD);
+ }
+ } else {
+ // Caculate next MIF frequency
+ if (ddr_load >= MIF_MAX_THRESHOLD) {
+ freq[PPMU_MIF] = data->max_freq[PPMU_MIF];
+ } else if ( ddr_load < IDLE_THRESHOLD) {
+ if (ddr_load_average < IDLE_THRESHOLD)
+ freq[PPMU_MIF] = step_down(data, PPMU_MIF, 1);
+ else
+ freq[PPMU_MIF] = data->curr_freq[PPMU_MIF];
+ } else {
+ if (ddr_load < ddr_load_average) {
+ ddr_load = ddr_load_average;
+ if (ddr_load >= MIF_MAX_THRESHOLD)
+ ddr_load = MIF_MAX_THRESHOLD;
+ }
+ freq[PPMU_MIF] = div64_u64(data->max_freq[PPMU_MIF] * ddr_load, MIF_MAX_THRESHOLD);
+ }
+
+ freq_int_right0 = div64_u64(data->max_freq[PPMU_INT] * right0_load, INT_RIGHT0_THRESHOLD);
+ }
+
+ // Caculate next INT frequency
+ if (ddr_load_int >= INT_MAX_THRESHOLD) {
+ freq[PPMU_INT] = data->max_freq[PPMU_INT];
+ } else if ( ddr_load_int < IDLE_THRESHOLD) {
+ if (ddr_load_average < IDLE_THRESHOLD)
+ freq[PPMU_INT] = step_down(data, PPMU_INT, 1);
+ else
+ freq[PPMU_INT] = data->curr_freq[PPMU_INT];
+ } else {
+ if (ddr_load_int < ddr_load_average) {
+ ddr_load_int = ddr_load_average;
+ if (ddr_load_int >= INT_MAX_THRESHOLD)
+ ddr_load_int = INT_MAX_THRESHOLD;
+ }
+ freq[PPMU_INT] = div64_u64(data->max_freq[PPMU_INT] * ddr_load_int, INT_MAX_THRESHOLD);
+ }
+
+ freq[PPMU_INT] = max(freq[PPMU_INT], freq_int_right0);
+
+ if (freq[PPMU_INT] == data->max_freq[PPMU_INT])
+ freq[PPMU_MIF] = data->max_freq[PPMU_MIF];
+
+go_max:
+#ifdef BUSFREQ_PROFILE_DEBUG
+ printk(KERN_DEBUG "cpu[%ld] l[%ld] c[%ld] r1[%ld] rt[%ld] m_load[%ld] i_load[%ld]\n",
+ cpu_load, ddr_l_load, ddr_c_load, ddr_r1_load, right0_load, ddr_load, ddr_load_int);
+#endif
+ lockfreq[PPMU_MIF] = (dev_max_freq(data->dev[PPMU_MIF])/1000)*1000;
+ lockfreq[PPMU_INT] = (dev_max_freq(data->dev[PPMU_MIF])%1000)*1000;
+#ifdef BUSFREQ_PROFILE_DEBUG
+ printk(KERN_DEBUG "i_cf[%ld] m_cf[%ld] i_nf[%ld] m_nf[%ld] lock_Mfreq[%ld] lock_Ifreq[%ld]\n",
+ data->curr_freq[PPMU_INT],data->curr_freq[PPMU_MIF],freq[PPMU_INT], freq[PPMU_MIF], lockfreq[PPMU_MIF], lockfreq[PPMU_INT]);
+#endif
+ newfreq[PPMU_MIF] = max(lockfreq[PPMU_MIF], freq[PPMU_MIF]);
+ newfreq[PPMU_INT] = max(lockfreq[PPMU_INT], freq[PPMU_INT]);
+ opp[PPMU_MIF] = opp_find_freq_ceil(data->dev[PPMU_MIF], &newfreq[PPMU_MIF]);
+ opp[PPMU_INT] = opp_find_freq_ceil(data->dev[PPMU_INT], &newfreq[PPMU_INT]);
+
+ *mif_opp = opp[PPMU_MIF];
+ *int_opp = opp[PPMU_INT];
+}
+
+static void busfreq_early_suspend(struct early_suspend *h)
+{
+ unsigned long freq;
+ struct busfreq_data *data = container_of(h, struct busfreq_data,
+ busfreq_early_suspend_handler);
+ freq = data->min_freq[PPMU_MIF] + data->min_freq[PPMU_INT] / 1000;
+ //dev_lock(data->dev[PPMU_MIF], data->dev[PPMU_MIF], freq);
+ dev_unlock(data->dev[PPMU_MIF], data->dev[PPMU_MIF]);
+}
+
+static void busfreq_late_resume(struct early_suspend *h)
+{
+ struct busfreq_data *data = container_of(h, struct busfreq_data,
+ busfreq_early_suspend_handler);
+ /* Request min MIF/INT 300MHz */
+ dev_lock(data->dev[PPMU_MIF], data->dev[PPMU_MIF], 300150);
+}
+
+int exynos5250_init(struct device *dev, struct busfreq_data *data)
+{
+ unsigned int i, tmp;
+ unsigned long maxfreq = ULONG_MAX;
+ unsigned long minfreq = 0;
+ unsigned long cdrexfreq;
+ unsigned long lrbusfreq;
+ struct clk *clk;
+ int ret;
+
+ /* Enable pause function for DREX2 DVFS */
+ drex2_pause_ctrl = __raw_readl(EXYNOS5_DREX2_PAUSE);
+ drex2_pause_ctrl |= DMC_PAUSE_ENABLE;
+ __raw_writel(drex2_pause_ctrl, EXYNOS5_DREX2_PAUSE);
+
+ clk = clk_get(NULL, "mclk_cdrex");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "Fail to get mclk_cdrex clock");
+ ret = PTR_ERR(clk);
+ return ret;
+ }
+ cdrexfreq = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ clk = clk_get(NULL, "aclk_266");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "Fail to get aclk_266 clock");
+ ret = PTR_ERR(clk);
+ return ret;
+ }
+ lrbusfreq = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ if (cdrexfreq == 800000) {
+ clkdiv_cdrex = clkdiv_cdrex_for800;
+ exynos5_busfreq_table_mif = exynos5_busfreq_table_for800;
+ exynos5_mif_volt = exynos5_mif_volt_for800;
+ } else if (cdrexfreq == 666857) {
+ clkdiv_cdrex = clkdiv_cdrex_for667;
+ exynos5_busfreq_table_mif = exynos5_busfreq_table_for667;
+ exynos5_mif_volt = exynos5_mif_volt_for667;
+ } else if (cdrexfreq == 533000) {
+ clkdiv_cdrex = clkdiv_cdrex_for533;
+ exynos5_busfreq_table_mif = exynos5_busfreq_table_for533;
+ exynos5_mif_volt = exynos5_mif_volt_for533;
+ } else if (cdrexfreq == 400000) {
+ clkdiv_cdrex = clkdiv_cdrex_for400;
+ exynos5_busfreq_table_mif = exynos5_busfreq_table_for400;
+ exynos5_mif_volt = exynos5_mif_volt_for400;
+ } else {
+ dev_err(dev, "Don't support cdrex table\n");
+ return -EINVAL;
+ }
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_LEX);
+
+ for (i = LV_0; i < LV_INT_END; i++) {
+ tmp &= ~(EXYNOS5_CLKDIV_LEX_ATCLK_LEX_MASK | EXYNOS5_CLKDIV_LEX_PCLK_LEX_MASK);
+
+ tmp |= ((clkdiv_lex[i][0] << EXYNOS5_CLKDIV_LEX_ATCLK_LEX_SHIFT) |
+ (clkdiv_lex[i][1] << EXYNOS5_CLKDIV_LEX_PCLK_LEX_SHIFT));
+
+ data->lex_divtable[i] = tmp;
+ }
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_R0X);
+
+ for (i = LV_0; i < LV_INT_END; i++) {
+
+ tmp &= ~EXYNOS5_CLKDIV_R0X_PCLK_R0X_MASK;
+
+ tmp |= (clkdiv_r0x[i][0] << EXYNOS5_CLKDIV_R0X_PCLK_R0X_SHIFT);
+
+ data->r0x_divtable[i] = tmp;
+ }
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_R1X);
+
+ for (i = LV_0; i < LV_INT_END; i++) {
+ tmp &= ~EXYNOS5_CLKDIV_R1X_PCLK_R1X_MASK;
+
+ tmp |= (clkdiv_r1x[i][0] << EXYNOS5_CLKDIV_R1X_PCLK_R1X_SHIFT);
+
+ data->r1x_divtable[i] = tmp;
+ }
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_CDREX);
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ for (i = LV_0; i < LV_MIF_END; i++) {
+ tmp &= ~(EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_MASK |
+ EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_MASK |
+ EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_MASK |
+ EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_MASK |
+ EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_MASK |
+ EXYNOS5_CLKDIV_CDREX_ACLK_CLK400_MASK |
+ EXYNOS5_CLKDIV_CDREX_ACLK_C2C200_MASK |
+ EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_MASK);
+
+ tmp |= ((clkdiv_cdrex[i][0] << EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_SHIFT) |
+ (clkdiv_cdrex[i][1] << EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_SHIFT) |
+ (clkdiv_cdrex[i][2] << EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_SHIFT) |
+ (clkdiv_cdrex[i][3] << EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_SHIFT) |
+ (clkdiv_cdrex[i][4] << EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_SHIFT) |
+ (clkdiv_cdrex[i][5] << EXYNOS5_CLKDIV_CDREX_ACLK_CLK400_SHIFT) |
+ (clkdiv_cdrex[i][6] << EXYNOS5_CLKDIV_CDREX_ACLK_C2C200_SHIFT) |
+ (clkdiv_cdrex[i][8] << EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_SHIFT));
+
+ data->cdrex_divtable[i] = tmp;
+ }
+ } else {
+ for (i = LV_0; i < LV_MIF_END; i++) {
+ tmp &= ~(EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_MASK |
+ EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_MASK |
+ EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_MASK |
+ EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_MASK |
+ EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_MASK |
+ EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_MASK);
+
+ tmp |= ((clkdiv_cdrex[i][0] << EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_SHIFT) |
+ (clkdiv_cdrex[i][1] << EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_SHIFT) |
+ (clkdiv_cdrex[i][2] << EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_SHIFT) |
+ (clkdiv_cdrex[i][3] << EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_SHIFT) |
+ (clkdiv_cdrex[i][4] << EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_SHIFT) |
+ (clkdiv_cdrex[i][8] << EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_SHIFT));
+
+ data->cdrex_divtable[i] = tmp;
+ }
+ }
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_CDREX2);
+
+ for (i = LV_0; i < LV_MIF_END; i++) {
+ tmp &= ~EXYNOS5_CLKDIV_CDREX2_MCLK_EFPHY_MASK;
+
+ tmp |= clkdiv_cdrex[i][7] << EXYNOS5_CLKDIV_CDREX2_MCLK_EFPHY_SHIFT;
+
+ data->cdrex2_divtable[i] = tmp;
+
+ }
+ }
+
+ exynos5250_set_bus_volt();
+
+ data->dev[PPMU_MIF] = dev;
+ data->dev[PPMU_INT] = &busfreq_for_int;
+
+ for (i = LV_0; i < LV_MIF_END; i++) {
+ ret = opp_add(data->dev[PPMU_MIF], exynos5_busfreq_table_mif[i].mem_clk,
+ exynos5_busfreq_table_mif[i].volt);
+ if (ret) {
+ dev_err(dev, "Fail to add opp entries.\n");
+ return ret;
+ }
+ }
+
+#if defined(CONFIG_DP_60HZ_P11) || defined(CONFIG_DP_60HZ_P10)
+ if (cdrexfreq == 666857) {
+ opp_disable(data->dev[PPMU_MIF], 334000);
+ opp_disable(data->dev[PPMU_MIF], 110000);
+ } else if (cdrexfreq == 533000) {
+ opp_disable(data->dev[PPMU_MIF], 267000);
+ opp_disable(data->dev[PPMU_MIF], 107000);
+ } else if (cdrexfreq == 400000) {
+ opp_disable(data->dev[PPMU_MIF], 267000);
+ opp_disable(data->dev[PPMU_MIF], 100000);
+ }
+#endif
+
+ for (i = LV_0; i < LV_INT_END; i++) {
+ ret = opp_add(data->dev[PPMU_INT], exynos5_busfreq_table_int[i].mem_clk,
+ exynos5_busfreq_table_int[i].volt);
+ if (ret) {
+ dev_err(dev, "Fail to add opp entries.\n");
+ return ret;
+ }
+ }
+
+ data->target = exynos5250_target;
+ data->get_table_index = exynos5250_get_table_index;
+ data->monitor = exynos5250_monitor;
+ data->busfreq_suspend = exynos5250_suspend;
+ data->busfreq_resume = exynos5250_resume;
+ data->sampling_rate = usecs_to_jiffies(100000);
+
+ data->table[PPMU_MIF] = exynos5_busfreq_table_mif;
+ data->table[PPMU_INT] = exynos5_busfreq_table_int;
+
+ /* Find max frequency for mif */
+ data->max_freq[PPMU_MIF] =
+ opp_get_freq(opp_find_freq_floor(data->dev[PPMU_MIF], &maxfreq));
+ data->min_freq[PPMU_MIF] =
+ opp_get_freq(opp_find_freq_ceil(data->dev[PPMU_MIF], &minfreq));
+ data->curr_freq[PPMU_MIF] =
+ opp_get_freq(opp_find_freq_ceil(data->dev[PPMU_MIF], &cdrexfreq));
+ /* Find max frequency for int */
+ maxfreq = ULONG_MAX;
+ minfreq = 0;
+ data->max_freq[PPMU_INT] =
+ opp_get_freq(opp_find_freq_floor(data->dev[PPMU_INT], &maxfreq));
+ data->min_freq[PPMU_INT] =
+ opp_get_freq(opp_find_freq_ceil(data->dev[PPMU_INT], &minfreq));
+ data->curr_freq[PPMU_INT] =
+ opp_get_freq(opp_find_freq_ceil(data->dev[PPMU_INT], &lrbusfreq));
+
+ data->vdd_reg[PPMU_INT] = regulator_get(NULL, "vdd_int");
+ if (IS_ERR(data->vdd_reg[PPMU_INT])) {
+ pr_err("failed to get resource %s\n", "vdd_int");
+ return -ENODEV;
+ }
+
+ data->vdd_reg[PPMU_MIF] = regulator_get(NULL, "vdd_mif");
+ if (IS_ERR(data->vdd_reg[PPMU_MIF])) {
+ pr_err("failed to get resource %s\n", "vdd_mif");
+ regulator_put(data->vdd_reg[PPMU_INT]);
+ return -ENODEV;
+ }
+
+ data->busfreq_early_suspend_handler.suspend = &busfreq_early_suspend;
+ data->busfreq_early_suspend_handler.resume = &busfreq_late_resume;
+
+ data->busfreq_early_suspend_handler.suspend = &busfreq_early_suspend;
+ data->busfreq_early_suspend_handler.resume = &busfreq_late_resume;
+
+ /* Request min 300MHz for MIF and 150MHz for INT*/
+ dev_lock(dev, dev, 300150);
+
+ register_early_suspend(&data->busfreq_early_suspend_handler);
+
+ tmp = __raw_readl(EXYNOS5_ABBG_INT_CONTROL);
+ tmp &= ~(0x1f | (1 << 31) | (1 << 7));
+ tmp |= ((8 + INT_RBB) | (1 << 31) | (1 << 7));
+ __raw_writel(tmp, EXYNOS5_ABBG_INT_CONTROL);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/busfreq_opp_exynos4.c b/arch/arm/mach-exynos/busfreq_opp_exynos4.c
new file mode 100644
index 0000000..e6b28c9
--- /dev/null
+++ b/arch/arm/mach-exynos/busfreq_opp_exynos4.c
@@ -0,0 +1,677 @@
+/* linux/arch/arm/mach-exynos/busfreq_opp_exynos4.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - BUS clock frequency scaling support with OPP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/ppmu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/cpufreq.h>
+#include <mach/dev.h>
+#include <mach/busfreq_exynos4.h>
+#include <mach/smc.h>
+
+#include <plat/map-s5p.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#define BUSFREQ_DEBUG 1
+
+static DEFINE_MUTEX(busfreq_lock);
+
+struct busfreq_control {
+ struct opp *opp_lock;
+ struct device *dev;
+ struct busfreq_data *data;
+ bool init_done;
+};
+
+static struct busfreq_control bus_ctrl;
+
+void update_busfreq_stat(struct busfreq_data *data, unsigned int index)
+{
+#ifdef BUSFREQ_DEBUG
+ unsigned long long cur_time = get_jiffies_64();
+ data->time_in_state[index] = cputime64_add(data->time_in_state[index], cputime_sub(cur_time, data->last_time));
+ data->last_time = cur_time;
+#endif
+}
+
+static struct opp __maybe_unused *step_up(struct busfreq_data *data, int step)
+{
+ int i;
+ struct opp *opp = data->curr_opp;
+ unsigned long newfreq;
+
+ if (data->max_opp == data->curr_opp)
+ return data->curr_opp;
+
+ for (i = 0; i < step; i++) {
+ newfreq = opp_get_freq(opp) + 1;
+ opp = opp_find_freq_ceil(data->dev, &newfreq);
+
+ if (opp == data->max_opp)
+ break;
+ }
+
+ return opp;
+}
+
+struct opp *step_down(struct busfreq_data *data, int step)
+{
+ int i;
+ struct opp *opp = data->curr_opp;
+ unsigned long newfreq;
+
+ if (data->min_opp == data->curr_opp)
+ return data->curr_opp;
+
+ for (i = 0; i < step; i++) {
+ newfreq = opp_get_freq(opp) - 1;
+ opp = opp_find_freq_floor(data->dev, &newfreq);
+
+ if (opp == data->min_opp)
+ break;
+ }
+
+ return opp;
+}
+
+static unsigned int _target(struct busfreq_data *data, struct opp *new)
+{
+ unsigned int index;
+ unsigned int voltage;
+ unsigned long newfreq;
+ unsigned long currfreq;
+
+ newfreq = opp_get_freq(new);
+ currfreq = opp_get_freq(data->curr_opp);
+
+ index = data->get_table_index(new);
+
+ if (newfreq == 0 || newfreq == currfreq || data->use == false)
+ return data->get_table_index(data->curr_opp);
+
+ voltage = opp_get_voltage(new);
+ if (newfreq > currfreq) {
+ regulator_set_voltage(data->vdd_mif, voltage,
+ voltage + 25000);
+ voltage = data->get_int_volt(index);
+ regulator_set_voltage(data->vdd_int, voltage,
+ voltage + 25000);
+ /*if (data->busfreq_prepare)
+ data->busfreq_prepare(index);*/
+ }
+ if (data->set_qos)
+ data->set_qos(index);
+
+ data->target(index);
+
+ if (newfreq < currfreq) {
+ /*if (data->busfreq_post)
+ data->busfreq_post(index);*/
+ regulator_set_voltage(data->vdd_mif, voltage,
+ voltage + 25000);
+ voltage = data->get_int_volt(index);
+ regulator_set_voltage(data->vdd_int, voltage,
+ voltage + 25000);
+ }
+ data->curr_opp = new;
+
+ return index;
+}
+
+static void exynos_busfreq_timer(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct busfreq_data *data = container_of(delayed_work, struct busfreq_data,
+ worker);
+ struct opp *opp;
+ unsigned int index;
+
+ opp = data->monitor(data);
+
+ ppmu_start(data->dev);
+
+ mutex_lock(&busfreq_lock);
+
+ if (bus_ctrl.opp_lock)
+ opp = bus_ctrl.opp_lock;
+
+ index = _target(data, opp);
+
+ update_busfreq_stat(data, index);
+ mutex_unlock(&busfreq_lock);
+ queue_delayed_work(system_freezable_wq, &data->worker, data->sampling_rate);
+}
+
+static int exynos_buspm_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct busfreq_data *data = container_of(this, struct busfreq_data,
+ exynos_buspm_notifier);
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ mutex_lock(&busfreq_lock);
+ _target(data, data->max_opp);
+ data->use = false;
+ mutex_unlock(&busfreq_lock);
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ data->use = true;
+ return NOTIFY_OK;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static int exynos_busfreq_reboot_event(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ struct busfreq_data *data = container_of(this, struct busfreq_data,
+ exynos_reboot_notifier);
+
+ unsigned long voltage = opp_get_voltage(data->max_opp);
+ unsigned int index = data->get_table_index(data->max_opp);
+
+ mutex_lock(&busfreq_lock);
+
+ regulator_set_voltage(data->vdd_mif, voltage, voltage + 25000);
+ voltage = data->get_int_volt(index);
+ regulator_set_voltage(data->vdd_int, voltage, voltage + 25000);
+ data->use = false;
+
+ mutex_unlock(&busfreq_lock);
+
+ printk(KERN_INFO "REBOOT Notifier for BUSFREQ\n");
+ return NOTIFY_DONE;
+}
+
+int exynos_busfreq_lock(unsigned int nId,
+ enum busfreq_level_request busfreq_level)
+{
+ return 0;
+}
+
+void exynos_busfreq_lock_free(unsigned int nId)
+{
+}
+
+static ssize_t show_level_lock(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(bus_ctrl.dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ int len = 0;
+ unsigned long freq;
+
+ freq = bus_ctrl.opp_lock == NULL ? 0 : opp_get_freq(bus_ctrl.opp_lock);
+
+ len = sprintf(buf, "Current Freq(MIF/INT) : %lu\n", opp_get_freq(data->curr_opp));
+ len += sprintf(buf + len, "Current Lock Freq(MIF/INT) : %lu\n", freq);
+
+ return len;
+}
+
+static ssize_t store_level_lock(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct platform_device *pdev = to_platform_device(bus_ctrl.dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ struct opp *opp;
+ unsigned long freq;
+ unsigned long maxfreq = opp_get_freq(data->max_opp);
+ int ret;
+
+ ret = sscanf(buf, "%lu", &freq);
+ if ((freq == 0) || (ret == 0)) {
+ pr_info("Release bus level lock.\n");
+ bus_ctrl.opp_lock = NULL;
+ return count;
+ }
+
+ if (freq > maxfreq)
+ freq = maxfreq;
+
+ opp = opp_find_freq_ceil(bus_ctrl.dev, &freq);
+ bus_ctrl.opp_lock = opp;
+ pr_info("Lock Freq : %lu\n", opp_get_freq(opp));
+ return count;
+}
+
+static ssize_t show_locklist(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ return dev_lock_list(bus_ctrl.dev, buf);
+}
+
+static ssize_t show_time_in_state(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(bus_ctrl.dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < data->table_size; i++)
+ len += sprintf(buf + len, "%u %llu\n", data->table[i].mem_clk,
+ (unsigned long long)cputime64_to_clock_t(data->time_in_state[i]));
+
+ return len;
+}
+
+static ssize_t show_up_threshold(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", up_threshold);
+
+ return len;
+}
+static ssize_t store_up_threshold(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &up_threshold);
+ return count;
+}
+
+static ssize_t show_ppmu_threshold(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", ppmu_threshold);
+
+ return len;
+}
+static ssize_t store_ppmu_threshold(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &ppmu_threshold);
+ return count;
+}
+
+static ssize_t show_idle_threshold(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", idle_threshold);
+
+ return len;
+}
+static ssize_t store_idle_threshold(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &idle_threshold);
+ return count;
+}
+
+static ssize_t show_up_cpu_threshold(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", up_cpu_threshold);
+
+ return len;
+}
+static ssize_t store_up_cpu_threshold(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &up_cpu_threshold);
+ return count;
+}
+
+static ssize_t show_max_cpu_threshold(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", max_cpu_threshold);
+
+ return len;
+}
+static ssize_t store_max_cpu_threshold(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &max_cpu_threshold);
+ return count;
+}
+
+static ssize_t show_cpu_slope_size(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", cpu_slope_size);
+
+ return len;
+}
+static ssize_t store_cpu_slope_size(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &cpu_slope_size);
+ return count;
+}
+
+static ssize_t show_dmc_max_threshold(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", dmc_max_threshold);
+
+ return len;
+}
+static ssize_t store_dmc_max_threshold(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &dmc_max_threshold);
+ if (dmc_max_threshold < 1)
+ dmc_max_threshold = 1;
+ return count;
+}
+
+static ssize_t show_load_history_size(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ len = sprintf(buf, "%d\n", load_history_size);
+
+ return len;
+}
+static ssize_t store_load_history_size(struct device *device,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%d", &load_history_size);
+ if (load_history_size < 1)
+ load_history_size = 1;
+ if (load_history_size > LOAD_HISTORY_SIZE)
+ load_history_size = LOAD_HISTORY_SIZE;
+ return count;
+}
+
+static DEVICE_ATTR(curr_freq, 0664, show_level_lock, store_level_lock);
+static DEVICE_ATTR(lock_list, 0664, show_locklist, NULL);
+static DEVICE_ATTR(time_in_state, 0664, show_time_in_state, NULL);
+static DEVICE_ATTR(up_threshold, 0664, show_up_threshold, store_up_threshold);
+static DEVICE_ATTR(ppmu_threshold, 0664, show_ppmu_threshold,
+ store_ppmu_threshold);
+static DEVICE_ATTR(idle_threshold, 0664, show_idle_threshold,
+ store_idle_threshold);
+static DEVICE_ATTR(up_cpu_threshold, 0664, show_up_cpu_threshold,
+ store_up_cpu_threshold);
+static DEVICE_ATTR(max_cpu_threshold, 0664, show_max_cpu_threshold,
+ store_max_cpu_threshold);
+static DEVICE_ATTR(cpu_slope_size, 0664, show_cpu_slope_size,
+ store_cpu_slope_size);
+static DEVICE_ATTR(dmc_max_threshold, 0664, show_dmc_max_threshold,
+ store_dmc_max_threshold);
+static DEVICE_ATTR(load_history_size, 0664, show_load_history_size,
+ store_load_history_size);
+
+static struct attribute *busfreq_attributes[] = {
+ &dev_attr_curr_freq.attr,
+ &dev_attr_lock_list.attr,
+ &dev_attr_time_in_state.attr,
+ &dev_attr_up_threshold.attr,
+ &dev_attr_ppmu_threshold.attr,
+ &dev_attr_idle_threshold.attr,
+ &dev_attr_up_cpu_threshold.attr,
+ &dev_attr_max_cpu_threshold.attr,
+ &dev_attr_cpu_slope_size.attr,
+ &dev_attr_dmc_max_threshold.attr,
+ &dev_attr_load_history_size.attr,
+
+ NULL
+};
+
+void exynos_request_apply(unsigned long freq)
+{
+ struct opp *opp;
+ unsigned int index;
+
+ mutex_lock(&busfreq_lock);
+
+ if (!bus_ctrl.init_done)
+ goto out;
+
+ opp = bus_ctrl.data->curr_opp;
+
+ opp = opp_find_freq_ceil(bus_ctrl.data->dev, &freq);
+
+ if (bus_ctrl.opp_lock)
+ opp = bus_ctrl.opp_lock;
+
+ if (opp_get_freq(bus_ctrl.data->curr_opp) >= opp_get_freq(opp))
+ goto out;
+
+ index = _target(bus_ctrl.data, opp);
+
+ update_busfreq_stat(bus_ctrl.data, index);
+
+out:
+ mutex_unlock(&busfreq_lock);
+}
+
+static __devinit int exynos_busfreq_probe(struct platform_device *pdev)
+{
+ struct busfreq_data *data;
+ unsigned int val = 0;
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc_readsfr(EXYNOS4_PA_DMC0_4212 + 0x4, &val);
+#else
+ val = __raw_readl(S5P_VA_DMC0 + 0x4);
+#endif
+ val = (val >> 8) & 0xf;
+
+ /* Check Memory Type Only support -> 0x5: 0xLPDDR2 */
+ if (val != 0x05) {
+ pr_err("[ %x ] Memory Type Undertermined.\n", val);
+ return -ENODEV;
+ }
+
+ data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL);
+ if (!data) {
+ pr_err("Unable to create busfreq_data struct.\n");
+ return -ENOMEM;
+ }
+
+ data->exynos_buspm_notifier.notifier_call =
+ exynos_buspm_notifier_event;
+ data->exynos_reboot_notifier.notifier_call =
+ exynos_busfreq_reboot_event;
+ data->busfreq_attr_group.attrs = busfreq_attributes;
+
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ data->init = exynos4x12_init;
+ data->target = exynos4x12_target;
+ data->get_int_volt = exynos4x12_get_int_volt;
+ data->get_table_index = exynos4x12_get_table_index;
+ data->monitor = exynos4x12_monitor;
+ data->busfreq_prepare = exynos4x12_prepare;
+ data->busfreq_post = exynos4x12_post;
+ data->set_qos = exynos4x12_set_qos;
+ data->busfreq_suspend = exynos4x12_suspend;
+ data->busfreq_resume = exynos4x12_resume;
+ } else {
+ pr_err("Unsupport device type.\n");
+ goto err_busfreq;
+ }
+
+ data->dev = &pdev->dev;
+ data->sampling_rate = usecs_to_jiffies(100000);
+ bus_ctrl.opp_lock = NULL;
+ bus_ctrl.dev = data->dev;
+ bus_ctrl.data = data;
+
+ INIT_DELAYED_WORK(&data->worker, exynos_busfreq_timer);
+
+ if (data->init(&pdev->dev, data)) {
+ pr_err("Failed to init busfreq.\n");
+ goto err_busfreq;
+ }
+
+ data->time_in_state = kzalloc(sizeof(cputime64_t) * data->table_size, GFP_KERNEL);
+ if (!data->time_in_state) {
+ pr_err("Unable to create time_in_state.\n");
+ goto err_busfreq;
+ }
+
+
+ data->last_time = get_jiffies_64();
+
+ data->busfreq_kobject = kobject_create_and_add("busfreq",
+ &cpu_sysdev_class.kset.kobj);
+ if (!data->busfreq_kobject)
+ pr_err("Failed to create busfreq kobject.!\n");
+
+ if (sysfs_create_group(data->busfreq_kobject, &data->busfreq_attr_group))
+ pr_err("Failed to create attributes group.!\n");
+
+ if (register_pm_notifier(&data->exynos_buspm_notifier)) {
+ pr_err("Failed to setup buspm notifier\n");
+ goto err_pm_notifier;
+ }
+
+ data->use = true;
+ bus_ctrl.init_done = true;
+
+ if (register_reboot_notifier(&data->exynos_reboot_notifier))
+ pr_err("Failed to setup reboot notifier\n");
+
+ platform_set_drvdata(pdev, data);
+
+ queue_delayed_work(system_freezable_wq, &data->worker, 10 * data->sampling_rate);
+ return 0;
+
+err_pm_notifier:
+ kfree(data->time_in_state);
+
+err_busfreq:
+ if (!IS_ERR(data->vdd_int))
+ regulator_put(data->vdd_int);
+
+ if (!IS_ERR(data->vdd_mif))
+ regulator_put(data->vdd_mif);
+
+ kfree(data);
+ return -ENODEV;
+}
+
+static __devexit int exynos_busfreq_remove(struct platform_device *pdev)
+{
+ struct busfreq_data *data = platform_get_drvdata(pdev);
+
+ unregister_pm_notifier(&data->exynos_buspm_notifier);
+ unregister_reboot_notifier(&data->exynos_reboot_notifier);
+ regulator_put(data->vdd_int);
+ regulator_put(data->vdd_mif);
+ sysfs_remove_group(data->busfreq_kobject, &data->busfreq_attr_group);
+ kfree(data->time_in_state);
+ kfree(data);
+
+ return 0;
+}
+
+static int exynos_busfreq_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+
+ if (data->busfreq_suspend)
+ data->busfreq_suspend();
+ return 0;
+}
+
+static int exynos_busfreq_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ ppmu_reset(dev);
+
+ if (data->busfreq_resume)
+ data->busfreq_resume();
+ return 0;
+}
+
+static const struct dev_pm_ops exynos_busfreq_pm = {
+ .suspend = exynos_busfreq_suspend,
+ .resume = exynos_busfreq_resume,
+};
+
+static struct platform_driver exynos_busfreq_driver = {
+ .probe = exynos_busfreq_probe,
+ .remove = __devexit_p(exynos_busfreq_remove),
+ .driver = {
+ .name = "exynos-busfreq",
+ .owner = THIS_MODULE,
+ .pm = &exynos_busfreq_pm,
+ },
+};
+
+static int __init exynos_busfreq_init(void)
+{
+ return platform_driver_register(&exynos_busfreq_driver);
+}
+late_initcall(exynos_busfreq_init);
+
+static void __exit exynos_busfreq_exit(void)
+{
+ platform_driver_unregister(&exynos_busfreq_driver);
+}
+module_exit(exynos_busfreq_exit);
diff --git a/arch/arm/mach-exynos/busfreq_opp_exynos5.c b/arch/arm/mach-exynos/busfreq_opp_exynos5.c
new file mode 100644
index 0000000..b685cd2
--- /dev/null
+++ b/arch/arm/mach-exynos/busfreq_opp_exynos5.c
@@ -0,0 +1,498 @@
+/* linux/arch/arm/mach-exynos/busfreq_opp_exynos5.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - BUS clock frequency scaling support with OPP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/ppmu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/cpufreq.h>
+#include <mach/dev.h>
+#include <mach/busfreq_exynos5.h>
+
+#include <plat/map-s5p.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#define BUSFREQ_DEBUG 1
+
+static DEFINE_MUTEX(busfreq_lock);
+BLOCKING_NOTIFIER_HEAD(exynos_busfreq_notifier_list);
+
+struct busfreq_control {
+ struct opp *lock[PPMU_TYPE_END];
+ struct device *dev[PPMU_TYPE_END];
+};
+
+static struct busfreq_control bus_ctrl;
+
+void update_busfreq_stat(struct busfreq_data *data,
+ enum ppmu_type type, unsigned int index)
+{
+#ifdef BUSFREQ_DEBUG
+ unsigned long long cur_time = get_jiffies_64();
+ data->time_in_state[type][index] =
+ cputime64_add(data->time_in_state[type][index], cputime_sub(cur_time, data->last_time[type]));
+ data->last_time[type] = cur_time;
+#endif
+}
+
+
+static unsigned long __maybe_unused step_up(struct busfreq_data *data,
+ enum ppmu_type type, int step)
+{
+ int i;
+ struct opp *opp;
+ unsigned long newfreq = data->curr_freq[type];
+
+ if (data->max_freq[type] == data->curr_freq[type])
+ return newfreq;
+
+ for (i = 0; i < step; i++) {
+ newfreq += 1;
+ opp = opp_find_freq_ceil(data->dev[type], &newfreq);
+
+ if (opp_get_freq(opp) == data->max_freq[type])
+ break;
+ }
+
+ return newfreq;
+}
+
+unsigned long step_down(struct busfreq_data *data,
+ enum ppmu_type type, int step)
+{
+ int i;
+ struct opp *opp;
+ unsigned long newfreq = data->curr_freq[type];
+
+ if (data->min_freq[type] == data->curr_freq[type])
+ return newfreq;
+
+ for (i = 0; i < step; i++) {
+ newfreq -= 1;
+ opp = opp_find_freq_floor(data->dev[type], &newfreq);
+
+ if (opp_get_freq(opp) == data->min_freq[type])
+ break;
+ }
+
+ return newfreq;
+}
+
+static void _target(struct busfreq_data *data,
+ enum ppmu_type type, unsigned long newfreq)
+{
+ struct opp *opp;
+ unsigned int voltage;
+ int index;
+
+ opp = opp_find_freq_exact(data->dev[type], newfreq, true);
+
+ if (bus_ctrl.lock[type]) {
+ opp = bus_ctrl.lock[type];
+ newfreq = opp_get_freq(opp);
+ }
+
+ index = data->get_table_index(newfreq, type);
+
+ if (newfreq == 0 || newfreq == data->curr_freq[type] ||
+ data->use == false) {
+ update_busfreq_stat(data, type, index);
+ return;
+ }
+
+ voltage = opp_get_voltage(opp);
+
+ if (newfreq > data->curr_freq[type]) {
+ regulator_set_voltage(data->vdd_reg[type], voltage,
+ voltage + 25000);
+ if (type == PPMU_MIF && data->busfreq_prepare)
+ data->busfreq_prepare(index);
+ }
+
+ data->target(data, type, index);
+
+ if (newfreq < data->curr_freq[type]) {
+ if (type == PPMU_MIF && data->busfreq_post)
+ data->busfreq_post(index);
+ regulator_set_voltage(data->vdd_reg[type], voltage,
+ voltage + 25000);
+ }
+ data->curr_freq[type] = newfreq;
+
+ update_busfreq_stat(data, type, index);
+}
+
+static void exynos_busfreq_timer(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct busfreq_data *data = container_of(delayed_work, struct busfreq_data,
+ worker);
+ int i;
+ struct opp *opp[PPMU_TYPE_END];
+ unsigned long newfreq;
+
+ data->monitor(data, &opp[PPMU_MIF], &opp[PPMU_INT]);
+
+ ppmu_start(data->dev[PPMU_MIF]);
+
+ mutex_lock(&busfreq_lock);
+
+ for (i = PPMU_MIF; i < PPMU_TYPE_END; i++) {
+ newfreq = opp_get_freq(opp[i]);
+ _target(data, i, newfreq);
+ }
+
+ mutex_unlock(&busfreq_lock);
+ queue_delayed_work(system_freezable_wq, &data->worker, data->sampling_rate);
+}
+
+static int exynos_buspm_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct busfreq_data *data = container_of(this, struct busfreq_data,
+ exynos_buspm_notifier);
+ int i;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ mutex_lock(&busfreq_lock);
+ for (i = PPMU_MIF; i < PPMU_TYPE_END; i++)
+ _target(data, i, data->max_freq[i]);
+ mutex_unlock(&busfreq_lock);
+ data->use = false;
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ data->use = true;
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static int exynos_busfreq_reboot_event(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ struct busfreq_data *data = container_of(this, struct busfreq_data,
+ exynos_reboot_notifier);
+ int i;
+ struct opp *opp;
+ unsigned int voltage[PPMU_TYPE_END];
+ for (i = PPMU_MIF; i < PPMU_TYPE_END; i++) {
+ opp = opp_find_freq_exact(data->dev[i], data->max_freq[i], true);
+ voltage[i] = opp_get_voltage(opp);
+
+ regulator_set_voltage(data->vdd_reg[i], voltage[i], voltage[i] + 25000);
+ }
+ data->use = false;
+
+ printk(KERN_INFO "REBOOT Notifier for BUSFREQ\n");
+ return NOTIFY_DONE;
+}
+
+static int exynos_busfreq_request_event(struct notifier_block *this,
+ unsigned long req_newfreq, void *device)
+{
+ struct busfreq_data *data = container_of(this, struct busfreq_data,
+ exynos_request_notifier);
+ int i;
+ struct opp *opp[PPMU_TYPE_END];
+ unsigned long newfreq[PPMU_TYPE_END];
+ unsigned long freq;
+
+ if (req_newfreq == 0 || data->use == false)
+ return -EINVAL;
+
+ mutex_lock(&busfreq_lock);
+
+ newfreq[PPMU_MIF] = (req_newfreq / 1000) * 1000;
+ newfreq[PPMU_INT] = (req_newfreq % 1000) * 1000;
+
+ for (i = PPMU_MIF; i < PPMU_TYPE_END; i++) {
+ opp[i] = opp_find_freq_ceil(data->dev[i], &newfreq[i]);
+ freq = opp_get_freq(opp[i]);
+ if (freq > data->curr_freq[i])
+ _target(data, i, freq);
+ }
+
+ mutex_unlock(&busfreq_lock);
+ printk(KERN_INFO "REQUEST Notifier for BUSFREQ\n");
+ return NOTIFY_DONE;
+}
+
+int exynos_busfreq_lock(unsigned int nId,
+ enum busfreq_level_request busfreq_level)
+{
+ return 0;
+}
+
+void exynos_busfreq_lock_free(unsigned int nId)
+{
+}
+
+static ssize_t show_level_lock(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(bus_ctrl.dev[PPMU_MIF]);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ int len = 0;
+ unsigned long mif_freq, int_freq;
+
+ mif_freq = bus_ctrl.lock[PPMU_MIF] == NULL ? 0 : opp_get_freq(bus_ctrl.lock[PPMU_MIF]);
+ int_freq = bus_ctrl.lock[PPMU_INT] == NULL ? 0 : opp_get_freq(bus_ctrl.lock[PPMU_INT]);
+
+ len = sprintf(buf, "Current Freq(MIF/INT) : (%lu - %lu)\n",
+ data->curr_freq[PPMU_MIF], data->curr_freq[PPMU_INT]);
+ len += sprintf(buf + len, "Current Lock Freq(MIF/INT) : (%lu - %lu)\n", mif_freq, int_freq);
+
+ return len;
+}
+
+static ssize_t store_level_lock(struct device *device, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct platform_device *pdev = to_platform_device(bus_ctrl.dev[PPMU_MIF]);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ struct opp *opp[PPMU_TYPE_END];
+ unsigned long freq[PPMU_TYPE_END];
+ int i;
+ int ret;
+
+ ret = sscanf(buf, "%lu %lu", &freq[PPMU_MIF], &freq[PPMU_INT]);
+ if (freq[PPMU_MIF] == 0 || freq[PPMU_INT] == 0 || ret != 2) {
+ pr_info("Release bus level lock.\n");
+ bus_ctrl.lock[PPMU_MIF] = NULL;
+ bus_ctrl.lock[PPMU_INT] = NULL;
+ return count;
+ }
+
+ for (i = PPMU_MIF; i < PPMU_TYPE_END; i++) {
+ if (freq[i] > data->max_freq[i])
+ freq[i] = data->max_freq[i];
+
+ opp[i] = opp_find_freq_ceil(bus_ctrl.dev[i], &freq[i]);
+ bus_ctrl.lock[i] = opp[i];
+ }
+ pr_info("Lock Freq : MIF/INT(%lu - %lu)\n", opp_get_freq(opp[PPMU_MIF]), opp_get_freq(opp[PPMU_INT]));
+ return count;
+}
+
+static ssize_t show_locklist(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ return dev_lock_list(bus_ctrl.dev[PPMU_MIF], buf);
+}
+
+static ssize_t show_time_in_state(struct device *device,
+ struct device_attribute *attr, char *buf)
+{
+ struct platform_device *pdev = to_platform_device(bus_ctrl.dev[PPMU_MIF]);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ struct busfreq_table *table;
+ ssize_t len = 0;
+ int i;
+
+ table = data->table[PPMU_MIF];
+ len += sprintf(buf, "%s\n", "MIF stat");
+ for (i = LV_0; i < LV_MIF_END; i++)
+ len += sprintf(buf + len, "%u %llu\n", table[i].mem_clk,
+ (unsigned long long)cputime64_to_clock_t(data->time_in_state[PPMU_MIF][i]));
+
+ table = data->table[PPMU_INT];
+ len += sprintf(buf + len, "\n%s\n", "INT stat");
+ for (i = LV_0; i < LV_INT_END; i++)
+ len += sprintf(buf + len, "%u %llu\n", table[i].mem_clk,
+ (unsigned long long)cputime64_to_clock_t(data->time_in_state[PPMU_INT][i]));
+ return len;
+}
+
+static DEVICE_ATTR(curr_freq, 0664, show_level_lock, store_level_lock);
+static DEVICE_ATTR(lock_list, 0664, show_locklist, NULL);
+static DEVICE_ATTR(time_in_state, 0664, show_time_in_state, NULL);
+
+static struct attribute *busfreq_attributes[] = {
+ &dev_attr_curr_freq.attr,
+ &dev_attr_lock_list.attr,
+ &dev_attr_time_in_state.attr,
+ NULL
+};
+
+int exynos_request_register(struct notifier_block *n)
+{
+ return blocking_notifier_chain_register(&exynos_busfreq_notifier_list, n);
+}
+
+void exynos_request_apply(unsigned long freq)
+{
+ blocking_notifier_call_chain(&exynos_busfreq_notifier_list, freq, NULL);
+}
+
+static __devinit int exynos_busfreq_probe(struct platform_device *pdev)
+{
+ struct busfreq_data *data;
+
+ data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL);
+ if (!data) {
+ pr_err("Unable to create busfreq_data struct.\n");
+ return -ENOMEM;
+ }
+
+ data->exynos_buspm_notifier.notifier_call =
+ exynos_buspm_notifier_event;
+ data->exynos_reboot_notifier.notifier_call =
+ exynos_busfreq_reboot_event;
+ data->busfreq_attr_group.attrs = busfreq_attributes;
+ data->exynos_request_notifier.notifier_call =
+ exynos_busfreq_request_event;
+
+ INIT_DELAYED_WORK(&data->worker, exynos_busfreq_timer);
+
+ if (soc_is_exynos5250()) {
+ data->init = exynos5250_init;
+ } else {
+ pr_err("Unsupport device type.\n");
+ goto err_busfreq;
+ }
+
+ if (data->init(&pdev->dev, data)) {
+ pr_err("Failed to init busfreq.\n");
+ goto err_busfreq;
+ }
+
+ bus_ctrl.dev[PPMU_MIF] = data->dev[PPMU_MIF];
+ bus_ctrl.dev[PPMU_INT] = data->dev[PPMU_INT];
+
+ data->last_time[PPMU_MIF] = get_jiffies_64();
+ data->last_time[PPMU_INT] = get_jiffies_64();
+
+ data->busfreq_kobject = kobject_create_and_add("busfreq",
+ &cpu_sysdev_class.kset.kobj);
+ if (!data->busfreq_kobject)
+ pr_err("Failed to create busfreq kobject.!\n");
+
+ if (sysfs_create_group(data->busfreq_kobject, &data->busfreq_attr_group))
+ pr_err("Failed to create attributes group.!\n");
+
+ if (register_pm_notifier(&data->exynos_buspm_notifier)) {
+ pr_err("Failed to setup buspm notifier\n");
+ goto err_busfreq;
+ }
+
+ data->use = true;
+
+ if (register_reboot_notifier(&data->exynos_reboot_notifier))
+ pr_err("Failed to setup reboot notifier\n");
+
+ if (exynos_request_register(&data->exynos_request_notifier))
+ pr_err("Failed to setup request notifier\n");
+
+ platform_set_drvdata(pdev, data);
+
+ queue_delayed_work(system_freezable_wq, &data->worker, data->sampling_rate);
+ return 0;
+
+err_busfreq:
+ if (!IS_ERR(data->vdd_reg[PPMU_INT]))
+ regulator_put(data->vdd_reg[PPMU_INT]);
+
+ if (!IS_ERR(data->vdd_reg[PPMU_MIF]))
+ regulator_put(data->vdd_reg[PPMU_MIF]);
+
+ kfree(data);
+ return -ENODEV;
+}
+
+static __devexit int exynos_busfreq_remove(struct platform_device *pdev)
+{
+ struct busfreq_data *data = platform_get_drvdata(pdev);
+
+ unregister_pm_notifier(&data->exynos_buspm_notifier);
+ unregister_reboot_notifier(&data->exynos_reboot_notifier);
+ regulator_put(data->vdd_reg[PPMU_INT]);
+ regulator_put(data->vdd_reg[PPMU_MIF]);
+ sysfs_remove_group(data->busfreq_kobject, &data->busfreq_attr_group);
+ kfree(data);
+
+ return 0;
+}
+
+static int exynos_busfreq_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+
+ if (data->busfreq_suspend)
+ data->busfreq_suspend();
+ return 0;
+}
+
+static int exynos_busfreq_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct busfreq_data *data = (struct busfreq_data *)platform_get_drvdata(pdev);
+ ppmu_reset(dev);
+
+ if (data->busfreq_resume)
+ data->busfreq_resume();
+ return 0;
+}
+
+static const struct dev_pm_ops exynos_busfreq_pm = {
+ .suspend = exynos_busfreq_suspend,
+ .resume = exynos_busfreq_resume,
+};
+
+static struct platform_driver exynos_busfreq_driver = {
+ .probe = exynos_busfreq_probe,
+ .remove = __devexit_p(exynos_busfreq_remove),
+ .driver = {
+ .name = "exynos-busfreq",
+ .owner = THIS_MODULE,
+ .pm = &exynos_busfreq_pm,
+ },
+};
+
+static int __init exynos_busfreq_init(void)
+{
+ return platform_driver_register(&exynos_busfreq_driver);
+}
+late_initcall(exynos_busfreq_init);
+
+static void __exit exynos_busfreq_exit(void)
+{
+ platform_driver_unregister(&exynos_busfreq_driver);
+}
+module_exit(exynos_busfreq_exit);
diff --git a/arch/arm/mach-exynos/clock-domain.c b/arch/arm/mach-exynos/clock-domain.c
new file mode 100644
index 0000000..187dfa1
--- /dev/null
+++ b/arch/arm/mach-exynos/clock-domain.c
@@ -0,0 +1,105 @@
+/* linux/arch/arm/mach-exynos/clock-domain.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - Clock Domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/cpufreq.h>
+#include <linux/list.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+#include <linux/device.h>
+
+#include <plat/clock.h>
+
+#include <mach/clock-domain.h>
+
+static LIST_HEAD(clock_domain_list);
+/* Lock to allow exclusive modification to the clock domain list */
+static DEFINE_MUTEX(clock_domain_list_lock);
+
+static struct clock_domain *find_clock_domain(unsigned int flag)
+{
+ struct clock_domain *tmp_domain, *domain = ERR_PTR(-ENODEV);
+
+ list_for_each_entry_rcu(tmp_domain, &clock_domain_list, node) {
+ if (tmp_domain->flag & flag) {
+ domain = tmp_domain;
+ break;
+ }
+ }
+
+ return domain;
+}
+
+int clock_domain_enabled(unsigned int flag)
+{
+ struct clock_domain *domain;
+ struct clock *clock;
+
+ domain = find_clock_domain(flag);
+ if (IS_ERR(domain)) {
+ pr_err("Unable to find Clock Domain\n");
+ return -EINVAL;
+ }
+
+ list_for_each_entry_rcu(clock, &domain->domain_list, node) {
+ if (clock->clk->usage)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int clock_add_domain(unsigned int flag, struct clk *clk)
+{
+ struct clock_domain *domain = NULL;
+ struct clock *clock;
+
+ /* allocate new clock node */
+ clock = kzalloc(sizeof(struct clock), GFP_KERNEL);
+ if (!clock) {
+ pr_err("Unable to create new Clock node\n");
+ return -ENOMEM;
+ }
+
+ /* Hold our list modification lock here */
+ mutex_lock(&clock_domain_list_lock);
+
+ /* Check for existing list for 'dev' */
+ domain = find_clock_domain(flag);
+ if (IS_ERR(domain)) {
+ /*
+ * Allocate a new Clock Doamin.*/
+ domain = kzalloc(sizeof(struct clock_domain), GFP_KERNEL);
+ if (!domain) {
+ mutex_unlock(&clock_domain_list_lock);
+ kfree(clock);
+ pr_err("Unable to create Clock Domain structure\n");
+ return -ENOMEM;
+ }
+
+ domain->flag = flag;
+ INIT_LIST_HEAD(&domain->domain_list);
+
+ list_add_rcu(&domain->node, &clock_domain_list);
+ }
+
+ clock->clk = clk;
+
+ list_add_rcu(&clock->node, &domain->domain_list);
+ mutex_unlock(&clock_domain_list_lock);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
new file mode 100644
index 0000000..ad5d5b4
--- /dev/null
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -0,0 +1,2480 @@
+/* linux/arch/arm/mach-exynos/clock-exynos4.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-audss.h>
+#include <mach/dev-sysmmu.h>
+#include <mach/exynos-clock.h>
+#include <mach/clock-domain.h>
+
+#ifdef CONFIG_PM
+static struct sleep_save exynos4_clock_save[] = {
+ /* CMU side */
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC),
+ SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU),
+ SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS),
+ SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS),
+ SAVE_ITEM(EXYNOS4_CLKDIV_CAM),
+ SAVE_ITEM(EXYNOS4_CLKDIV_TV),
+ SAVE_ITEM(EXYNOS4_CLKDIV_MFC),
+ SAVE_ITEM(EXYNOS4_CLKDIV_G3D),
+ SAVE_ITEM(EXYNOS4_CLKDIV_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2),
+ SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4),
+ SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5),
+ SAVE_ITEM(EXYNOS4_CLKDIV_TOP),
+ SAVE_ITEM(EXYNOS4_CLKSRC_TOP0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_TOP1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_CAM),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MFC),
+ SAVE_ITEM(EXYNOS4_CLKSRC_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKSRC_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_DMC),
+ SAVE_ITEM(EXYNOS4_CLKSRC_CPU),
+};
+#endif
+
+struct clk exynos4_clk_sclk_hdmi27m = {
+ .name = "sclk_hdmi27m",
+ .rate = 27000000,
+};
+
+struct clk exynos4_clk_sclk_hdmiphy = {
+ .name = "sclk_hdmiphy",
+};
+
+struct clk exynos4_clk_sclk_usbphy0 = {
+ .name = "sclk_usbphy0",
+ .rate = 27000000,
+};
+
+struct clk exynos4_clk_sclk_usbphy1 = {
+ .name = "sclk_usbphy1",
+};
+
+static struct clk exynos4_clk_audiocdclk1 = {
+ .name = "audiocdclk",
+};
+
+static struct clk exynos4_clk_audiocdclk2 = {
+ .name = "audiocdclk",
+};
+
+static struct clk exynos4_clk_spdifcdclk = {
+ .name = "spdifcdclk",
+};
+
+static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable);
+}
+
+static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable);
+}
+
+int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD1, clk, enable);
+}
+
+int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable);
+}
+
+static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable);
+}
+
+static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable);
+}
+
+int exynos4_clk_ip_leftbus_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LEFTBUS, clk, enable);
+}
+
+static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable);
+}
+
+int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable);
+}
+
+int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
+}
+
+static int exynos4_clk_ip_g3d_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_G3D, clk, enable);
+}
+
+int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
+}
+
+int exynos4_clk_ip_rightbus_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_RIGHTBUS, clk, enable);
+}
+
+static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable);
+}
+
+int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable);
+}
+
+int exynos4_clk_ip_gps_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_GPS, clk, enable);
+}
+
+int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable);
+}
+
+int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
+}
+
+static int exynos4_clksrc_mask_maudio_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_MAUDIO, clk, enable);
+}
+
+static int exynos4_clk_audss_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_AUDSS, clk, enable);
+}
+
+static int __maybe_unused exynos4_clk_epll_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_EPLL_CON0, clk, enable);
+}
+
+static int exynos4_clk_vpll_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_VPLL_CON0, clk, enable);
+}
+
+int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
+}
+
+static int exynos4_clk_sclkapll_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_SCLKCPU, clk, enable);
+}
+
+static int exynos4_clk_ip_cpu_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CPU, clk, enable);
+}
+
+static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
+static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
+}
+
+/* Core list of CMU_CPU side */
+
+static struct clksrc_clk exynos4_clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 },
+};
+
+struct clksrc_clk exynos4_clk_sclk_apll = {
+ .clk = {
+ .name = "sclk_apll",
+ .parent = &exynos4_clk_mout_apll.clk,
+ .enable = exynos4_clk_sclkapll_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 },
+};
+
+struct clksrc_clk exynos4_clk_audiocdclk0 = {
+ .clk = {
+ .name = "audiocdclk",
+ .rate = 16934400,
+ },
+};
+
+struct clksrc_clk exynos4_clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .parent = &clk_fout_epll,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 },
+};
+
+struct clksrc_clk exynos4_clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ },
+ .sources = &clk_src_mpll,
+ /* reg_src will be added in SoC's clock */
+};
+
+static struct clk *exynos4_clkset_moutcore_list[] = {
+ [0] = &exynos4_clk_mout_apll.clk,
+ [1] = &exynos4_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_moutcore = {
+ .sources = exynos4_clkset_moutcore_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_moutcore_list),
+};
+
+static struct clksrc_clk exynos4_clk_moutcore = {
+ .clk = {
+ .name = "moutcore",
+ },
+ .sources = &exynos4_clkset_moutcore,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_coreclk = {
+ .clk = {
+ .name = "core_clk",
+ .parent = &exynos4_clk_moutcore.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_armclk = {
+ .clk = {
+ .name = "armclk",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corem0 = {
+ .clk = {
+ .name = "aclk_corem0",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_cores = {
+ .clk = {
+ .name = "aclk_cores",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corem1 = {
+ .clk = {
+ .name = "aclk_corem1",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_periphclk = {
+ .clk = {
+ .name = "periphclk",
+ .parent = &exynos4_clk_coreclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 },
+};
+
+/* Core list of CMU_CORE side */
+
+struct clk *exynos4_clkset_corebus_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_mout_corebus = {
+ .sources = exynos4_clkset_corebus_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_corebus_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_corebus = {
+ .clk = {
+ .name = "mout_corebus",
+ },
+ .sources = &exynos4_clkset_mout_corebus,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_dmc = {
+ .clk = {
+ .name = "sclk_dmc",
+ .parent = &exynos4_clk_mout_corebus.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_cored = {
+ .clk = {
+ .name = "aclk_cored",
+ .parent = &exynos4_clk_sclk_dmc.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_corep = {
+ .clk = {
+ .name = "aclk_corep",
+ .parent = &exynos4_clk_aclk_cored.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_acp = {
+ .clk = {
+ .name = "aclk_acp",
+ .parent = &exynos4_clk_mout_corebus.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_pclk_acp = {
+ .clk = {
+ .name = "pclk_acp",
+ .parent = &exynos4_clk_aclk_acp.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 },
+};
+
+static struct clk *exynos4_clkset_c2c_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_c2c = {
+ .sources = exynos4_clkset_c2c_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_c2c_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_c2c = {
+ .clk = {
+ .name = "sclk_c2c",
+ .id = -1,
+ },
+ .sources = &exynos4_clkset_mout_c2c,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 0, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_c2c = {
+ .clk = {
+ .name = "aclk_c2c",
+ .id = -1,
+ .parent = &exynos4_clk_sclk_c2c.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 12, .size = 3 },
+};
+
+/* Core list of CMU_TOP side */
+
+struct clk *exynos4_clkset_aclk_top_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_aclk = {
+ .sources = exynos4_clkset_aclk_top_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_top_list),
+};
+
+struct clksrc_clk exynos4_clk_aclk_200 = {
+ .clk = {
+ .name = "aclk_200",
+ },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_100 = {
+ .clk = {
+ .name = "aclk_100",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 },
+};
+
+struct clksrc_clk exynos4_clk_aclk_160 = {
+ .clk = {
+ .name = "aclk_160",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 },
+};
+
+struct clksrc_clk exynos4_clk_aclk_133 = {
+ .clk = {
+ .name = "aclk_133",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 },
+};
+
+/* CMU_LEFT/RIGHTBUS side */
+static struct clk *exynos4_clkset_aclk_lrbus_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_aclk_lrbus = {
+ .sources = exynos4_clkset_aclk_lrbus_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_aclk_lrbus_list),
+};
+
+static struct clksrc_clk exynos4_clk_aclk_gdl = {
+ .clk = {
+ .name = "aclk_gdl",
+ },
+ .sources = &exynos4_clkset_aclk_lrbus,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LEFTBUS, .shift = 0, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LEFTBUS, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_aclk_gdr = {
+ .clk = {
+ .name = "aclk_gdr",
+ },
+ .sources = &exynos4_clkset_aclk_lrbus,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_RIGHTBUS, .shift = 0, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_RIGHTBUS, .shift = 0, .size = 3 },
+};
+
+static struct clk *exynos4_clkset_vpllsrc_list[] = {
+ [0] = &clk_fin_vpll,
+ [1] = &exynos4_clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources exynos4_clkset_vpllsrc = {
+ .sources = exynos4_clkset_vpllsrc_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk exynos4_clk_vpllsrc = {
+ .clk = {
+ .name = "vpll_src",
+ .enable = exynos4_clksrc_mask_top_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_vpllsrc,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_vpll_list[] = {
+ [0] = &exynos4_clk_vpllsrc.clk,
+ [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_vpll = {
+ .sources = exynos4_clkset_sclk_vpll_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
+};
+
+struct clksrc_clk exynos4_clk_sclk_vpll = {
+ .clk = {
+ .name = "sclk_vpll",
+ },
+ .sources = &exynos4_clkset_sclk_vpll,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_dac_list[] = {
+ [0] = &exynos4_clk_sclk_vpll.clk,
+ [1] = &exynos4_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_dac = {
+ .sources = exynos4_clkset_sclk_dac_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_dac = {
+ .clk = {
+ .name = "sclk_dac",
+ .enable = exynos4_clksrc_mask_tv_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_sclk_dac,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_pixel = {
+ .clk = {
+ .name = "sclk_pixel",
+ .parent = &exynos4_clk_sclk_vpll.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_sclk_hdmi_list[] = {
+ [0] = &exynos4_clk_sclk_pixel.clk,
+ [1] = &exynos4_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_hdmi = {
+ .sources = exynos4_clkset_sclk_hdmi_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_hdmi = {
+ .clk = {
+ .name = "sclk_hdmi",
+ .enable = exynos4_clksrc_mask_tv_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_sclk_hdmi,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_mixer_list[] = {
+ [0] = &exynos4_clk_sclk_dac.clk,
+ [1] = &exynos4_clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_mixer = {
+ .sources = exynos4_clkset_sclk_mixer_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_mixer = {
+ .clk = {
+ .name = "sclk_mixer",
+ .id = -1,
+ .enable = exynos4_clksrc_mask_tv_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_sclk_mixer,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk *exynos4_sclk_tv[] = {
+ &exynos4_clk_sclk_dac,
+ &exynos4_clk_sclk_pixel,
+ &exynos4_clk_sclk_hdmi,
+ &exynos4_clk_sclk_mixer,
+};
+
+static struct clk exynos4_init_clocks_off[] = {
+ {
+ .name = "ppmuright",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "ppmuleft",
+ .enable = exynos4_clk_ip_leftbus_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "timers",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1<<24),
+ }, {
+ .name = "csis",
+ .devname = "s3c-csis.0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "csis",
+ .devname = "s3c-csis.1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "fimc",
+ .devname = "s3c-fimc.0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "fimc",
+ .devname = "s3c-fimc.1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "fimc",
+ .devname = "s3c-fimc.2",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "fimc",
+ .devname = "s3c-fimc.3",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "jpeg",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = ((1 << 11) | (1 << 6)),
+ }, {
+ .name = "pxl_async0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "pxl_async1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "ppmucamif",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "jpeg",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "rotator",
+ .devname = "exynos-rot",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.0",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.1",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.2",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.3",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "dwmci",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "adc",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "keypad",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "rtc",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "watchdog",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "hdmicec",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "sromc",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "usbhost",
+ .enable = exynos4_clk_ip_fsys_ctrl ,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "usbotg",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.0",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "pcm",
+ .devname = "samsung-pcm.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "pcm",
+ .devname = "samsung-pcm.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "slimbus",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "spdif",
+ .devname = "samsung-spdif",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "ac97",
+ .devname = "samsung-ac97",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "i2c-hdmiphy",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "ppmutv",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "hdmi",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "dac",
+ .devname = "s5p-sdo",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "mixer",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "vp",
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "ppmuimage",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "qerotator",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "rotator",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "hdmiphy",
+ .devname = "exynos4-hdmi",
+ .enable = exynos4_clk_hdmiphy_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "dacphy",
+ .devname = "s5p-sdo",
+ .enable = exynos4_clk_dac_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(sss, 0),
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(fimc0, 1),
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(fimc1, 2),
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(fimc2, 3),
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(fimc3, 4),
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(jpeg, 5),
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(fimd0, 6),
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(rot, 10),
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "sysmmu",
+
+ .devname = SYSMMU_CLOCK_NAME(mdma, 11),
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(tv, 12),
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(mfc_l, 13),
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(mfc_r, 14),
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(gps, 16),
+ .enable = exynos4_clk_ip_gps_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "gps",
+ .enable = exynos4_clk_ip_gps_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "ppmumfc",
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = ((0x1 << 4) | (0x1 << 3)),
+ }, {
+ .name = "mfc",
+ .devname = "s3c-mfc",
+ .enable = exynos4_clk_ip_mfc_ctrl,
+ .ctrlbit = (0x1 << 0),
+ }, {
+ .name = "tsi",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "onenand",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "nfcon",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "ppmufsys",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "ppmug3d",
+ .enable = exynos4_clk_ip_g3d_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "ppmucam",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "hpm",
+ .enable = exynos4_clk_ip_cpu_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "iec",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "apc",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "ppmuacp",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "ppmucpu",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "ppmudmc1",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "ppmudmc0",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 8),
+#ifdef CONFIG_CPU_EXYNOS4210
+ }, {
+ .name = "qesss",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "id_remapper",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "qecpu",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "fbm_dmc1",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "seckey",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.5",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.4",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.3",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.2",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.1",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.0",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 5),
+#endif
+ }, {
+ .name = "qefimc",
+ .devname = "s5p-qe.3",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "qefimc",
+ .devname = "s5p-qe.2",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "qefimc",
+ .devname = "s5p-qe.1",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "qefimc",
+ .devname = "s5p-qe.0",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "qeg3d",
+ .enable = exynos4_clk_ip_g3d_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "secss",
+ .parent = &exynos4_clk_aclk_acp.clk,
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+};
+
+static struct clk exynos4_i2cs_clocks[] = {
+ {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.0",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.1",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.2",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.3",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.4",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.5",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.6",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.7",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-hdmiphy-i2c",
+ .parent = &exynos4_clk_aclk_100.clk,
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 14),
+ }
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+ [0] = &exynos4_clk_audiocdclk0.clk,
+ [1] = NULL,
+ [2] = &exynos4_clk_sclk_hdmi27m,
+ [3] = &exynos4_clk_sclk_usbphy0,
+ [4] = &clk_ext_xtal_mux,
+ [5] = &clk_xusbxti,
+ [6] = &exynos4_clk_mout_mpll.clk,
+ [7] = &exynos4_clk_mout_epll.clk,
+ [8] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_audio0 = {
+ .sources = clkset_sclk_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_audio0 = {
+ .clk = {
+ .name = "audio-bus",
+ .enable = exynos4_clksrc_mask_maudio_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_sclk_audio0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MAUDIO, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_mout_audss_list[] = {
+ &clk_ext_xtal_mux,
+ &clk_fout_epll,
+};
+
+static struct clksrc_sources clkset_mout_audss = {
+ .sources = exynos4_clkset_mout_audss_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_audss_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_audss = {
+ .clk = {
+ .name = "mout_audss",
+ },
+ .sources = &clkset_mout_audss,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_sclk_audss_list[] = {
+ &exynos4_clk_mout_audss.clk,
+ &exynos4_clk_audiocdclk0.clk,
+ &exynos4_clk_sclk_audio0.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_audss = {
+ .sources = exynos4_clkset_sclk_audss_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_audss_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_audss_i2s = {
+ .clk = {
+ .name = "i2sclk",
+ .parent = &exynos4_clk_mout_audss.clk,
+ .enable = exynos4_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_I2SSPECIAL,
+ },
+ .sources = &exynos4_clkset_sclk_audss,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 2, .size = 2 },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_audss_srp = {
+ .clk = {
+ .name = "dout_srp",
+ .parent = &exynos4_clk_mout_audss.clk,
+ },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_sclk_audss_bus = {
+ .clk = {
+ .name = "busclk",
+ .parent = &exynos4_clk_dout_audss_srp.clk,
+ .enable = exynos4_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_I2SBUS,
+ },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 4, .size = 4 },
+};
+
+static struct clk exynos4_init_audss_clocks[] = {
+ {
+ .name = "srpclk",
+ .enable = exynos4_clk_audss_ctrl,
+ .parent = &exynos4_clk_dout_audss_srp.clk,
+ .ctrlbit = S5P_AUDSS_CLKGATE_RP | S5P_AUDSS_CLKGATE_UART
+ | S5P_AUDSS_CLKGATE_TIMER,
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.0",
+ .enable = exynos4_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_I2SSPECIAL | S5P_AUDSS_CLKGATE_I2SBUS,
+ }, {
+ .name = "pcm",
+ .devname = "samsung-pcm.0",
+ .enable = exynos4_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_PCMSPECIAL | S5P_AUDSS_CLKGATE_PCMBUS,
+ },
+};
+
+static struct clk *exynos4_clkset_sclk_audio1_list[] = {
+ [0] = &exynos4_clk_audiocdclk1,
+ [1] = NULL,
+ [2] = &exynos4_clk_sclk_hdmi27m,
+ [3] = &exynos4_clk_sclk_usbphy0,
+ [4] = &clk_ext_xtal_mux,
+ [5] = &clk_xusbxti,
+ [6] = &exynos4_clk_mout_mpll.clk,
+ [7] = &exynos4_clk_mout_epll.clk,
+ [8] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_audio1 = {
+ .sources = exynos4_clkset_sclk_audio1_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_audio1_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_audio1 = {
+ .clk = {
+ .name = "audio-bus1",
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_sclk_audio1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL4, .shift = 0, .size = 8 },
+};
+
+static struct clk *exynos4_clkset_sclk_audio2_list[] = {
+ [0] = &exynos4_clk_audiocdclk2,
+ [1] = NULL,
+ [2] = &exynos4_clk_sclk_hdmi27m,
+ [3] = &exynos4_clk_sclk_usbphy0,
+ [4] = &clk_ext_xtal_mux,
+ [5] = &clk_xusbxti,
+ [6] = &exynos4_clk_mout_mpll.clk,
+ [7] = &exynos4_clk_mout_epll.clk,
+ [8] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_audio2 = {
+ .sources = exynos4_clkset_sclk_audio2_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_audio2_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_audio2 = {
+ .clk = {
+ .name = "audio-bus2",
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_sclk_audio2,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL4, .shift = 16, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_sclk_spdif_list[] = {
+ [0] = &exynos4_clk_sclk_audio0.clk,
+ [1] = &exynos4_clk_sclk_audio1.clk,
+ [2] = &exynos4_clk_sclk_audio2.clk,
+ [3] = &exynos4_clk_spdifcdclk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_spdif = {
+ .sources = exynos4_clkset_sclk_spdif_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_sclk_spdif_list),
+};
+
+static struct clksrc_clk exynos4_clk_sclk_spdif = {
+ .clk = {
+ .name = "sclk_spdif",
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 8),
+ .ops = &s5p_sclk_spdif_ops,
+ },
+ .sources = &exynos4_clkset_sclk_spdif,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 8, .size = 2 },
+};
+
+struct clk exynos4_init_dmaclocks[] = {
+ {
+ .name = "pdma",
+ .devname = "s3c-pl330.0",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = ((1 << 8) | (1 << 5) | (1 << 2)),
+ }, {
+ .name = "pdma",
+ .devname = "s3c-pl330.1",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "pdma",
+ .devname = "s3c-pl330.2",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 1),
+ },
+};
+
+static struct clk exynos4_init_clocks[] = {
+ {
+#ifndef CONFIG_CPU_EXYNOS4210
+ .name = "seckey",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.5",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.4",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.3",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.2",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.1",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "tzpc",
+ .devname = "exnos4-tzpc.0",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+#endif
+ .name = "cssys",
+ .enable = exynos4_clk_ip_cpu_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "gic",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 20),
+#ifndef CONFIG_CPU_EXYNOS4210
+ }, {
+ .name = "qesss",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "id_remapper",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "qecpu",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "fbm_dmc1",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 6),
+#endif
+ }, {
+ .name = "fbm_dmc0",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "int_comb",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "g3d",
+ .enable = exynos4_clk_ip_g3d_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "tmu",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "mct",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "cmu_top",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "pmu_apb",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "sysreg",
+ .enable = exynos4_clk_ip_perir_ctrl ,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "chipid",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.0",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.1",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.2",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.3",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.4",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+#if 1
+ .name = "lcd",
+ .devname = "s3cfb.0",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "mie0",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "mdnie0",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "dsim0",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "ppmulcd",
+ .enable = exynos4_clk_ip_lcd0_ctrl,
+ .ctrlbit = (1 << 5),
+ },
+#endif
+};
+
+struct clk *exynos4_clkset_group_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_xusbxti,
+ [2] = &exynos4_clk_sclk_hdmi27m,
+ [3] = &exynos4_clk_sclk_usbphy0,
+ [4] = &exynos4_clk_sclk_usbphy1,
+ [5] = &exynos4_clk_sclk_hdmiphy,
+ [6] = &exynos4_clk_mout_mpll.clk,
+ [7] = &exynos4_clk_mout_epll.clk,
+ [8] = &exynos4_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_group = {
+ .sources = exynos4_clkset_group_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_group_list),
+};
+
+static struct clksrc_clk clk_sclk_mipidphy4l = {
+ .clk = {
+ .name = "sclk_mipidphy4l",
+ .id = -1,
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_sclk_mipidphy2l = {
+ .clk = {
+ .name = "sclk_mipidphy2l",
+ .id = -1,
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD1, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD1, .shift = 16, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d0_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d0 = {
+ .sources = exynos4_clkset_mout_g2d0_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
+};
+
+struct clksrc_clk exynos4_clk_mout_g2d0 = {
+ .clk = {
+ .name = "mout_g2d0",
+ },
+ .sources = &exynos4_clkset_mout_g2d0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d1_list[] = {
+ [0] = &exynos4_clk_mout_epll.clk,
+ [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos4_clkset_mout_g2d1 = {
+ .sources = exynos4_clkset_mout_g2d1_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
+};
+
+struct clksrc_clk exynos4_clk_mout_g2d1 = {
+ .clk = {
+ .name = "mout_g2d1",
+ },
+ .sources = &exynos4_clkset_mout_g2d1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g2d_list[] = {
+ [0] = &exynos4_clk_mout_g2d0.clk,
+ [1] = &exynos4_clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g2d = {
+ .sources = exynos4_clkset_mout_g2d_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d_list),
+};
+
+struct clksrc_clk exynos4_clk_sclk_fimg2d = {
+ .clk = {
+ .name = "sclk_fimg2d",
+ .devname = "s5p-fimg2d",
+ },
+ .sources = &exynos4_clkset_mout_g2d,
+};
+
+struct clk exynos4_clk_fimg2d = {
+ .name = "fimg2d",
+ .devname = "s5p-fimg2d",
+};
+
+struct clk *exynos4_clkset_mout_mfc0_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc0 = {
+ .sources = exynos4_clkset_mout_mfc0_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_mfc0 = {
+ .clk = {
+ .name = "mout_mfc0",
+ },
+ .sources = &exynos4_clkset_mout_mfc0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_mfc1_list[] = {
+ [0] = &exynos4_clk_mout_epll.clk,
+ [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc1 = {
+ .sources = exynos4_clkset_mout_mfc1_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_mfc1 = {
+ .clk = {
+ .name = "mout_mfc1",
+ },
+ .sources = &exynos4_clkset_mout_mfc1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_mfc_list[] = {
+ [0] = &exynos4_clk_mout_mfc0.clk,
+ [1] = &exynos4_clk_mout_mfc1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_mfc = {
+ .sources = exynos4_clkset_mout_mfc_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_mfc_list),
+};
+
+static struct clk *exynos4_clkset_mout_g3d0_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g3d0 = {
+ .sources = exynos4_clkset_mout_g3d0_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g3d0_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_g3d0 = {
+ .clk = {
+ .name = "mout_g3d0",
+ },
+ .sources = &exynos4_clkset_mout_g3d0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_G3D, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g3d1_list[] = {
+ [0] = &exynos4_clk_mout_epll.clk,
+ [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g3d1 = {
+ .sources = exynos4_clkset_mout_g3d1_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g3d1_list),
+};
+
+static struct clksrc_clk exynos4_clk_mout_g3d1 = {
+ .clk = {
+ .name = "mout_g3d1",
+ },
+ .sources = &exynos4_clkset_mout_g3d1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_G3D, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4_clkset_mout_g3d_list[] = {
+ [0] = &exynos4_clk_mout_g3d0.clk,
+ [1] = &exynos4_clk_mout_g3d1.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_mout_g3d = {
+ .sources = exynos4_clkset_mout_g3d_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g3d_list),
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc0 = {
+ .clk = {
+ .name = "dout_mmc0",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc1 = {
+ .clk = {
+ .name = "dout_mmc1",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc2 = {
+ .clk = {
+ .name = "dout_mmc2",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc3 = {
+ .clk = {
+ .name = "dout_mmc3",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_mmc4 = {
+ .clk = {
+ .name = "dout_mmc4",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos4_clkset_mout_hpm_list[] = {
+ [0] = &exynos4_clk_mout_apll.clk,
+ [1] = &exynos4_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos4_clkset_sclk_hpm = {
+ .sources = exynos4_clkset_mout_hpm_list,
+ .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_hpm_list),
+};
+
+static struct clksrc_clk exynos4_clk_dout_copy = {
+ .clk = {
+ .name = "dout_copy",
+ },
+ .sources = &exynos4_clkset_sclk_hpm,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 20, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU1, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_spi0 = {
+ .clk = {
+ .name = "dout_spi0",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_spi1 = {
+ .clk = {
+ .name = "dout_spi1",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clk_dout_spi2 = {
+ .clk = {
+ .name = "dout_spi2",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos4_clksrcs[] = {
+ {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.0",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.1",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.2",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.3",
+ .enable = exynos4_clksrc_mask_peril0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .devname = "s3c-csis.0",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .devname = "s3c-csis.1",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 28),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam0",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam1",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "s3c-fimc.0",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "s3c-fimc.1",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "s3c-fimc.2",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .devname = "s3c-fimc.3",
+ .enable = exynos4_clksrc_mask_cam_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .devname = "s3cfb.0",
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .devname = "s3cfb.1",
+ .enable = exynos4_clksrc_mask_lcd1_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD1, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD1, .shift = 0, .size = 4 },
+#if defined(CONFIG_FB_S5P_MDNIE) || defined(CONFIG_MDNIE_SUPPORT)
+ }, {
+ .clk = {
+ .name = "sclk_mdnie",
+ .id = -1,
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mdnie",
+ .id = 1,
+ .enable = exynos4_clksrc_mask_lcd1_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD1, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD1, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mdnie_pwm",
+ .id = -1,
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mdnie_pwm",
+ .id = 1,
+ .enable = exynos4_clksrc_mask_lcd1_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD1, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD1, .shift = 8, .size = 4 },
+#endif
+#ifdef CONFIG_FB_MDNIE_PWM
+ }, {
+ .clk = {
+ .name = "sclk_mdnie_pwm_pre",
+ .id = -1,
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mdnie_pwm_pre",
+ .id = 1,
+ .enable = exynos4_clksrc_mask_lcd1_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LCD1, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD1, .shift = 12, .size = 4 },
+#endif
+ }, {
+ .clk = {
+ .name = "sclk_mipi",
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+ .id = -1,
+#else
+ .id = 0,
+#endif
+ .parent = &clk_sclk_mipidphy4l.clk,
+ .enable = exynos4_clksrc_mask_lcd0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mipi",
+ .id = 1,
+ .parent = &clk_sclk_mipidphy2l.clk,
+ .enable = exynos4_clksrc_mask_lcd1_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_LCD1, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .parent = &exynos4_clk_dout_mmc0.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .parent = &exynos4_clk_dout_mmc1.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .parent = &exynos4_clk_dout_mmc2.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 3,
+ .parent = &exynos4_clk_dout_mmc3.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_dwmci",
+ .id = -1,
+ .parent = &exynos4_clk_dout_mmc4.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.0",
+ .parent = &exynos4_clk_dout_spi0.clk,
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.1",
+ .parent = &exynos4_clk_dout_spi1.clk,
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.2",
+ .parent = &exynos4_clk_dout_spi2.clk,
+ .enable = exynos4_clksrc_mask_peril1_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mfc",
+ },
+ .sources = &exynos4_clkset_mout_mfc,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_g3d",
+ .enable = exynos4_clk_ip_g3d_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_mout_g3d,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_G3D, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_G3D, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.0",
+ .parent = &exynos4_clk_dout_mmc0.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.1",
+ .parent = &exynos4_clk_dout_mmc1.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.2",
+ .parent = &exynos4_clk_dout_mmc2.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.3",
+ .parent = &exynos4_clk_dout_mmc3.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_dwmci",
+ .parent = &exynos4_clk_dout_mmc4.clk,
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_pcm",
+ .parent = &exynos4_clk_sclk_audio0.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_MAUDIO, .shift = 4, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_pcm",
+ .parent = &exynos4_clk_sclk_audio1.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL4, .shift = 4, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_pcm",
+ .parent = &exynos4_clk_sclk_audio2.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL4, .shift = 20, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_i2s",
+ .parent = &exynos4_clk_sclk_audio1.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL5, .shift = 0, .size = 6 },
+ }, {
+ .clk = {
+ .name = "sclk_i2s",
+ .parent = &exynos4_clk_sclk_audio2.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL5, .shift = 8, .size = 6 },
+ }, {
+ .clk = {
+ .name = "sclk_hpm",
+ .parent = &exynos4_clk_dout_copy.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CPU1, .shift = 4, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_pwi",
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 8, .size = 4 },
+ },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *exynos4_sysclks[] = {
+ &exynos4_clk_audiocdclk0,
+ &exynos4_clk_mout_apll,
+ &exynos4_clk_sclk_apll,
+ &exynos4_clk_mout_epll,
+ &exynos4_clk_mout_mpll,
+ &exynos4_clk_moutcore,
+ &exynos4_clk_coreclk,
+ &exynos4_clk_armclk,
+ &exynos4_clk_aclk_corem0,
+ &exynos4_clk_aclk_cores,
+ &exynos4_clk_aclk_corem1,
+ &exynos4_clk_periphclk,
+ &exynos4_clk_mout_corebus,
+ &exynos4_clk_sclk_dmc,
+ &exynos4_clk_aclk_cored,
+ &exynos4_clk_aclk_corep,
+ &exynos4_clk_aclk_acp,
+ &exynos4_clk_pclk_acp,
+ &exynos4_clk_vpllsrc,
+ &exynos4_clk_sclk_vpll,
+ &exynos4_clk_aclk_200,
+ &exynos4_clk_aclk_100,
+ &exynos4_clk_aclk_160,
+ &exynos4_clk_aclk_133,
+ &exynos4_clk_aclk_gdl,
+ &exynos4_clk_aclk_gdr,
+ &exynos4_clk_mout_mfc0,
+ &exynos4_clk_mout_mfc1,
+ &exynos4_clk_dout_mmc0,
+ &exynos4_clk_dout_mmc1,
+ &exynos4_clk_dout_mmc2,
+ &exynos4_clk_dout_mmc3,
+ &exynos4_clk_dout_mmc4,
+ &exynos4_clk_mout_audss,
+ &exynos4_clk_sclk_audss_bus,
+ &exynos4_clk_sclk_audss_i2s,
+ &exynos4_clk_dout_audss_srp,
+ &exynos4_clk_sclk_audio0,
+ &exynos4_clk_sclk_audio1,
+ &exynos4_clk_sclk_audio2,
+ &exynos4_clk_sclk_spdif,
+ &exynos4_clk_mout_g2d0,
+ &exynos4_clk_mout_g2d1,
+ &exynos4_clk_dout_copy,
+ &exynos4_clk_mout_g3d0,
+ &exynos4_clk_mout_g3d1,
+ &exynos4_clk_dout_spi0,
+ &exynos4_clk_dout_spi1,
+ &exynos4_clk_dout_spi2,
+#ifdef CONFIG_CPU_EXYNOS4212
+ &exynos4_clk_sclk_c2c,
+ &exynos4_clk_aclk_c2c,
+#endif
+ &exynos4_clk_sclk_fimg2d,
+};
+
+struct clk_ops exynos4_epll_ops;
+struct clk_ops exynos4_vpll_ops;
+
+static int xtal_rate;
+
+static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
+{
+ if (soc_is_exynos4210())
+ return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0), pll_4508);
+ else
+ return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
+}
+
+static struct clk_ops exynos4_fout_apll_ops = {
+ .get_rate = exynos4_fout_apll_get_rate,
+};
+
+void __init_or_cpufreq exynos4_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned long vpll;
+ unsigned long vpllsrc;
+ unsigned long xtal;
+ unsigned long armclk;
+ unsigned long sclk_dmc;
+ unsigned long aclk_200;
+ unsigned long aclk_160;
+ unsigned long aclk_133;
+ unsigned long aclk_100;
+ unsigned int ptr;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+
+ xtal_rate = xtal;
+
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ if (soc_is_exynos4210()) {
+ apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0), pll_4508);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0), pll_4508);
+ epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
+ __raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
+
+ vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
+ vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
+ __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
+ } else {
+ apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0));
+ mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0));
+ epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
+ __raw_readl(EXYNOS4_EPLL_CON1));
+
+ vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
+ vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
+ __raw_readl(EXYNOS4_VPLL_CON1));
+ }
+
+ clk_fout_apll.ops = &exynos4_fout_apll_ops;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_vpll.rate = vpll;
+
+ printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+ apll, mpll, epll, vpll);
+
+ armclk = clk_get_rate(&exynos4_clk_armclk.clk);
+ sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk);
+
+ aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk);
+ aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk);
+ aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk);
+ aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk);
+
+ printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
+ "ACLK160=%ld, ACLK133=%ld, ACLK100=%ld\n",
+ armclk, sclk_dmc, aclk_200,
+ aclk_160, aclk_133, aclk_100);
+#ifdef CONFIG_CPU_EXYNOS4212
+ printk(KERN_INFO "EXYNOS4: ACLK400=%ld ACLK266=%ld\n",
+ clk_get_rate(&exynos4212_clk_aclk_400_mcuisp.clk), clk_get_rate(&exynos4212_clk_aclk_266.clk));
+#endif
+
+ clk_f.rate = armclk;
+ clk_h.rate = sclk_dmc;
+ clk_p.rate = aclk_100;
+
+ clk_fout_epll.ops = &exynos4_epll_ops;
+
+#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
+ if (clk_set_parent(&exynos4_clk_dout_mmc3.clk, &exynos4_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_mout_epll.clk.name, exynos4_clk_dout_mmc3.clk.name);
+#endif
+
+#ifdef CONFIG_EXYNOS4_MSHC_EPLL_45MHZ
+ if (clk_set_parent(&exynos4_clk_dout_mmc4.clk, &exynos4_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_mout_epll.clk.name, exynos4_clk_dout_mmc4.clk.name);
+#endif
+#ifdef CONFIG_EXYNOS4_MSHC_VPLL_46MHZ
+ if (clk_set_parent(&exynos4_clk_dout_mmc4.clk, &exynos4_clk_sclk_vpll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_sclk_vpll.clk.name, exynos4_clk_dout_mmc4.clk.name);
+ if (clk_set_parent(&exynos4_clk_sclk_vpll.clk, &exynos4_clk_fout_vpll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_fout_vpll.clk.name, exynos4_clk_sclk_vpll.clk.name);
+#endif
+
+ if (clk_set_parent(&exynos4_clk_mout_audss.clk, &clk_fout_epll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ clk_fout_epll.name, exynos4_clk_mout_audss.clk.name);
+
+#if defined(CONFIG_SND_SAMSUNG_PCM) && !defined(CONFIG_SND_SAMSUNG_PCM_USE_EPLL)
+ if (clk_set_parent(&exynos4_clk_sclk_audio0.clk, &exynos4_clk_audiocdclk0.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_audiocdclk0.clk.name, exynos4_clk_sclk_audio0.clk.name);
+#else
+ if (clk_set_parent(&exynos4_clk_sclk_audio0.clk, &exynos4_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_mout_epll.clk.name, exynos4_clk_sclk_audio0.clk.name);
+#endif
+
+ if (clk_set_parent(&exynos4_clk_sclk_audio1.clk, &exynos4_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_mout_epll.clk.name, exynos4_clk_sclk_audio1.clk.name);
+ if (clk_set_parent(&exynos4_clk_sclk_audio2.clk, &exynos4_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos4_clk_mout_epll.clk.name, exynos4_clk_sclk_audio2.clk.name);
+ if (clk_set_parent(&exynos4_clk_mout_epll.clk, &clk_fout_epll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ clk_fout_epll.name, exynos4_clk_mout_epll.clk.name);
+
+ clk_fout_vpll.enable = exynos4_clk_vpll_ctrl;
+ clk_fout_vpll.ops = &exynos4_vpll_ops;
+
+ clk_set_rate(&exynos4_clk_sclk_apll.clk, 100000000);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
+ s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
+}
+
+static struct clk *exynos4_clks[] __initdata = {
+ &exynos4_clk_sclk_hdmi27m,
+ &exynos4_clk_sclk_hdmiphy,
+};
+
+#ifdef CONFIG_PM
+static int exynos4_clock_suspend(void)
+{
+ unsigned int tmp;
+
+ if (!soc_is_exynos4210()) {
+ tmp = __raw_readl(EXYNOS4_CLKSRC_TOP1);
+ tmp &= ~(0x1 << EXYNOS4_CLKDIV_TOP1_ACLK200_SUB_SHIFT |
+ 0x1 << EXYNOS4_CLKDIV_TOP1_ACLK400_MCUISP_SUB_SHIFT);
+ __raw_writel(tmp, EXYNOS4_CLKSRC_TOP1);
+ }
+
+ s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+
+ return 0;
+}
+
+static void exynos4_clock_resume(void)
+{
+ s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
+}
+#else
+#define exynos4_clock_suspend NULL
+#define exynos4_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4_clock_syscore_ops = {
+ .suspend = exynos4_clock_suspend,
+ .resume = exynos4_clock_resume,
+};
+
+void __init exynos4_register_clocks(void)
+{
+ int ptr;
+
+ s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++)
+ s3c_register_clksrc(exynos4_sysclks[ptr], 1);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++)
+ s3c_register_clksrc(exynos4_sclk_tv[ptr], 1);
+
+ s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs));
+ s3c_register_clocks(exynos4_init_clocks, ARRAY_SIZE(exynos4_init_clocks));
+
+ s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
+ s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
+
+ s3c_register_clocks(exynos4_init_audss_clocks, ARRAY_SIZE(exynos4_init_audss_clocks));
+ s3c_disable_clocks(exynos4_init_audss_clocks, ARRAY_SIZE(exynos4_init_audss_clocks));
+
+ /* Register DMA Clock */
+ s3c_register_clocks(exynos4_init_dmaclocks, ARRAY_SIZE(exynos4_init_dmaclocks));
+ s3c_disable_clocks(exynos4_init_dmaclocks, ARRAY_SIZE(exynos4_init_dmaclocks));
+ s3c_register_clocks(exynos4_i2cs_clocks, ARRAY_SIZE(exynos4_i2cs_clocks));
+ s3c_disable_clocks(exynos4_i2cs_clocks, ARRAY_SIZE(exynos4_i2cs_clocks));
+
+ s3c_register_clocks(&exynos4_clk_fimg2d, 1);
+ s3c_disable_clocks(&exynos4_clk_fimg2d, 1);
+
+ register_syscore_ops(&exynos4_clock_syscore_ops);
+ s3c_pwmclk_init();
+}
+
+static int __init clock_domain_init(void)
+{
+ int index;
+
+ clock_add_domain(LPA_DOMAIN, &exynos4_init_dmaclocks[0]);
+ clock_add_domain(LPA_DOMAIN, &exynos4_init_dmaclocks[1]);
+ clock_add_domain(LPA_DOMAIN, &exynos4_init_dmaclocks[2]);
+ for (index = 0; index < ARRAY_SIZE(exynos4_i2cs_clocks); index++)
+ clock_add_domain(LPA_DOMAIN, &exynos4_i2cs_clocks[index]);
+
+ return 0;
+}
+late_initcall(clock_domain_init);
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
new file mode 100644
index 0000000..569c523
--- /dev/null
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
@@ -0,0 +1,426 @@
+/*
+ * linux/arch/arm/mach-exynos/clock-exynos4210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4210 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/dev-sysmmu.h>
+#include <mach/exynos-clock.h>
+#include <mach/dev-sysmmu.h>
+
+static struct clksrc_clk *sysclks[] = {
+ /* nothing here yet */
+};
+
+#ifdef CONFIG_PM
+static struct sleep_save exynos4210_clock_save[] = {
+ /* CMU side */
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD1),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_IMAGE_4210),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD1),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIR_4210),
+ SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
+ SAVE_ITEM(EXYNOS4_CLKDIV_LCD1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
+ SAVE_ITEM(EXYNOS4_CLKSRC_LCD1),
+};
+
+static struct sleep_save exynos4210_epll_save[] = {
+ SAVE_ITEM(EXYNOS4_EPLL_LOCK),
+ SAVE_ITEM(EXYNOS4_EPLL_CON0),
+ SAVE_ITEM(EXYNOS4_EPLL_CON1),
+};
+
+static struct sleep_save exynos4210_vpll_save[] = {
+ SAVE_ITEM(EXYNOS4_VPLL_LOCK),
+ SAVE_ITEM(EXYNOS4_VPLL_CON0),
+ SAVE_ITEM(EXYNOS4_VPLL_CON1),
+};
+#endif
+
+static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD1, clk, enable);
+}
+
+static struct clk init_clocks_off[] = {
+ {
+ .name = "qeg2d",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "fimg2d",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "tvenc",
+ .parent = &exynos4_clk_aclk_160.clk,
+ .enable = exynos4_clk_ip_tv_ctrl,
+ .ctrlbit = (1 << 2),
+#if !defined(CONFIG_VIDEO_TSI)
+ }, {
+ .name = "tsi",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+#endif
+ }, {
+ .name = "sataphy",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "sata",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "ppmulcd1",
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(fimd1, 7),
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(g2d, 9),
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "dsim1",
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "mdnie1",
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "mie1",
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "lcd",
+ .devname = "s3cfb.1",
+ .enable = exynos4_clk_ip_lcd1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "pciephy",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "pcie",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(pcie, 8),
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(2d, 9),
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "modem",
+ .enable = exynos4_clk_ip_peril_ctrl,
+ .ctrlbit = (1 << 28),
+ }
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "cmu_dmcpart",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 4),
+#if defined(CONFIG_VIDEO_TSI)
+ }, {
+ .name = "tsi",
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+#endif
+ }, {
+ .name = "dmc1",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "dmc0",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_sata",
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos4_clkset_mout_corebus,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+ },
+};
+
+
+static u32 epll_div_4210[][6] = {
+ { 192000000, 0, 48, 3, 1, 0 },
+ { 180000000, 0, 45, 3, 1, 0 },
+ { 73728000, 1, 73, 3, 3, 47710 },
+ { 67737600, 1, 90, 4, 3, 20762 },
+ { 49152000, 0, 49, 3, 3, 9961 },
+ { 45158400, 0, 45, 3, 3, 10381 },
+ { 180633600, 0, 45, 3, 1, 10381 },
+};
+
+static unsigned long exynos4210_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos4210_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+ unsigned int tmp;
+ unsigned int epll_rate;
+ unsigned int locktime;
+ unsigned int lockcnt;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ if (clk->parent)
+ epll_rate = clk_get_rate(clk->parent);
+ else
+ epll_rate = clk_ext_xtal_mux.rate;
+
+ if (epll_rate != 24000000) {
+ pr_err("Invalid Clock : recommended clock is 24MHz.\n");
+ return -EINVAL;
+ }
+
+
+ epll_con = __raw_readl(EXYNOS4_EPLL_CON0);
+ epll_con &= ~(0x1 << 27 | \
+ PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
+ PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
+ PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div_4210); i++) {
+ if (epll_div_4210[i][0] == rate) {
+ epll_con_k = epll_div_4210[i][5] << 0;
+ epll_con |= epll_div_4210[i][1] << 27;
+ epll_con |= epll_div_4210[i][2] << PLL46XX_MDIV_SHIFT;
+ epll_con |= epll_div_4210[i][3] << PLL46XX_PDIV_SHIFT;
+ epll_con |= epll_div_4210[i][4] << PLL46XX_SDIV_SHIFT;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div_4210)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ epll_rate /= 1000000;
+
+ /* 3000 max_cycls : specification data */
+ locktime = 3000 / epll_rate * epll_div_4210[i][3];
+ lockcnt = locktime * 10000 / (10000 / epll_rate);
+
+ __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK);
+
+ __raw_writel(epll_con, EXYNOS4_EPLL_CON0);
+ __raw_writel(epll_con_k, EXYNOS4_EPLL_CON1);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_EPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT));
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+
+static struct vpll_div_data vpll_div_4210[] = {
+ {54000000, 3, 53, 3, 1024, 0, 17, 0},
+ {108000000, 3, 53, 2, 1024, 0, 17, 0},
+ {260000000, 3, 63, 1, 1950, 0, 20, 1},
+ {330000000, 2, 53, 1, 2048, 1, 1, 1},
+#ifdef CONFIG_EXYNOS4_MSHC_VPLL_46MHZ
+ {370882812, 3, 44, 0, 2417, 0, 14, 0},
+#endif
+};
+
+static unsigned long exynos4210_vpll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos4210_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int vpll_con0, vpll_con1;
+ unsigned int i;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+ vpll_con0 &= ~(0x1 << 27 | \
+ PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT | \
+ PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT | \
+ PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
+
+ vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
+ vpll_con1 &= ~(0x1f << 24 | \
+ 0x3f << 16 | \
+ 0xfff << 0);
+
+ for (i = 0; i < ARRAY_SIZE(vpll_div_4210); i++) {
+ if (vpll_div_4210[i].rate == rate) {
+ vpll_con0 |= vpll_div_4210[i].vsel << 27;
+ vpll_con0 |= vpll_div_4210[i].pdiv << PLL90XX_PDIV_SHIFT;
+ vpll_con0 |= vpll_div_4210[i].mdiv << PLL90XX_MDIV_SHIFT;
+ vpll_con0 |= vpll_div_4210[i].sdiv << PLL90XX_SDIV_SHIFT;
+ vpll_con1 |= vpll_div_4210[i].mrr << 24;
+ vpll_con1 |= vpll_div_4210[i].mfr << 16;
+ vpll_con1 |= vpll_div_4210[i].k << 0;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(vpll_div_4210)) {
+ printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
+ __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int exynos4210_clock_suspend(void)
+{
+ s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
+ s3c_pm_do_save(exynos4210_epll_save, ARRAY_SIZE(exynos4210_epll_save));
+ s3c_pm_do_save(exynos4210_vpll_save, ARRAY_SIZE(exynos4210_vpll_save));
+
+ return 0;
+}
+
+static void exynos4210_clock_resume(void)
+{
+ unsigned int tmp;
+
+ s3c_pm_do_restore_core(exynos4210_epll_save, ARRAY_SIZE(exynos4210_epll_save));
+ s3c_pm_do_restore_core(exynos4210_vpll_save, ARRAY_SIZE(exynos4210_vpll_save));
+
+ /* waiting epll & vpll locking time */
+ do {
+ tmp = __raw_readl(EXYNOS4_EPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT));
+
+ do {
+ tmp = __raw_readl(EXYNOS4_VPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT));
+
+ s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
+}
+#else
+#define exynos4210_clock_suspend NULL
+#define exynos4210_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4210_clock_syscore_ops = {
+ .suspend = exynos4210_clock_suspend,
+ .resume = exynos4210_clock_resume,
+};
+
+void __init exynos4210_register_clocks(void)
+{
+ int ptr;
+
+ exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU;
+ exynos4_clk_mout_mpll.reg_src.shift = 8;
+ exynos4_clk_mout_mpll.reg_src.size = 1;
+
+ exynos4_clk_aclk_200.sources = &exynos4_clkset_aclk;
+ exynos4_clk_aclk_200.reg_src.reg = EXYNOS4_CLKSRC_TOP0;
+ exynos4_clk_aclk_200.reg_src.shift = 12;
+ exynos4_clk_aclk_200.reg_src.size = 1;
+ exynos4_clk_aclk_200.reg_div.reg = EXYNOS4_CLKDIV_TOP;
+ exynos4_clk_aclk_200.reg_div.shift = 0;
+ exynos4_clk_aclk_200.reg_div.size = 3;
+
+ exynos4_clk_fimg2d.enable = exynos4_clk_ip_image_ctrl;
+ exynos4_clk_fimg2d.ctrlbit = (1 << 3) | (1 << 0);
+
+ exynos4_clk_mout_g2d0.reg_src.reg = EXYNOS4_CLKSRC_IMAGE;
+ exynos4_clk_mout_g2d0.reg_src.shift = 0;
+ exynos4_clk_mout_g2d0.reg_src.size = 1;
+
+ exynos4_clk_mout_g2d1.reg_src.reg = EXYNOS4_CLKSRC_IMAGE;
+ exynos4_clk_mout_g2d1.reg_src.shift = 4;
+ exynos4_clk_mout_g2d1.reg_src.size = 1;
+
+ exynos4_clk_sclk_fimg2d.reg_src.reg = EXYNOS4_CLKSRC_IMAGE;
+ exynos4_clk_sclk_fimg2d.reg_src.shift = 8;
+ exynos4_clk_sclk_fimg2d.reg_src.size = 1;
+ exynos4_clk_sclk_fimg2d.reg_div.reg = EXYNOS4_CLKDIV_IMAGE;
+ exynos4_clk_sclk_fimg2d.reg_div.shift = 0;
+ exynos4_clk_sclk_fimg2d.reg_div.size = 4;
+
+ exynos4_init_dmaclocks[2].parent = &exynos4_init_dmaclocks[1];
+
+ exynos4_epll_ops.get_rate = exynos4210_epll_get_rate;
+ exynos4_epll_ops.set_rate = exynos4210_epll_set_rate;
+ exynos4_vpll_ops.get_rate = exynos4210_vpll_get_rate;
+ exynos4_vpll_ops.set_rate = exynos4210_vpll_set_rate;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+ s3c_register_clksrc(sysclks[ptr], 1);
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ register_syscore_ops(&exynos4210_clock_syscore_ops);
+}
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
new file mode 100644
index 0000000..9e14ed9
--- /dev/null
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
@@ -0,0 +1,1151 @@
+/*
+ * linux/arch/arm/mach-exynos/clock-exynos4212.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4212 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/dev-sysmmu.h>
+#include <mach/exynos-clock.h>
+#include <mach/dev-sysmmu.h>
+
+#ifdef CONFIG_PM
+static struct sleep_save exynos4212_clock_save[] = {
+ /* CMU side */
+ SAVE_ITEM(EXYNOS4_DMC_PAUSE_CTRL),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_ISP),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC1),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_IMAGE_4212),
+ SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIR_4212),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_LEFTBUS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_IMAGE),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_RIGHTBUS),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_PERIR),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_PERIL),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_DMC0),
+ SAVE_ITEM(EXYNOS4_CLKGATE_BUS_DMC1),
+ SAVE_ITEM(EXYNOS4_CLKGATE_SCLK_DMC),
+ SAVE_ITEM(EXYNOS4_CLKDIV_CAM1),
+ SAVE_ITEM(EXYNOS4_CLKDIV_ISP),
+ SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_ISP),
+ SAVE_ITEM(EXYNOS4_CLKSRC_ISP),
+ SAVE_ITEM(EXYNOS4_CLKSRC_CAM1),
+ SAVE_ITEM(EXYNOS4_CLKOUT_CMU_LEFTBUS),
+ SAVE_ITEM(EXYNOS4_CLKOUT_CMU_RIGHTBUS),
+ SAVE_ITEM(EXYNOS4_CLKOUT_CMU_TOP),
+ SAVE_ITEM(EXYNOS4_CLKOUT_CMU_DMC),
+ SAVE_ITEM(EXYNOS4_CLKOUT_CMU_CPU),
+#ifdef CONFIG_EXYNOS4_ENABLE_CLOCK_DOWN
+ SAVE_ITEM(EXYNOS4_PWR_CTRL1),
+ SAVE_ITEM(EXYNOS4_PWR_CTRL2),
+#endif
+};
+
+static struct sleep_save exynos4212_epll_save[] = {
+ SAVE_ITEM(EXYNOS4_EPLL_LOCK),
+ SAVE_ITEM(EXYNOS4_EPLL_CON0),
+ SAVE_ITEM(EXYNOS4_EPLL_CON1),
+ SAVE_ITEM(EXYNOS4_EPLL_CON2),
+};
+
+static struct sleep_save exynos4212_vpll_save[] = {
+ SAVE_ITEM(EXYNOS4_VPLL_LOCK),
+ SAVE_ITEM(EXYNOS4_VPLL_CON0),
+ SAVE_ITEM(EXYNOS4_VPLL_CON1),
+ SAVE_ITEM(EXYNOS4_VPLL_CON2),
+};
+#endif
+
+struct exynos4_cmu_conf {
+ void __iomem *reg;
+ unsigned long val;
+};
+
+static struct exynos4_cmu_conf exynos4x12_cmu_config[] = {
+ /* Register Address Value */
+ { EXYNOS4_CLKOUT_CMU_LEFTBUS, 0x0},
+ { EXYNOS4_CLKOUT_CMU_RIGHTBUS, 0x0},
+ { EXYNOS4_CLKOUT_CMU_TOP, 0x0},
+ { EXYNOS4_CLKOUT_CMU_DMC, 0x0},
+ { EXYNOS4_CLKOUT_CMU_CPU, 0x0},
+ { EXYNOS4_CLKOUT_CMU_ISP, 0x0},
+};
+
+static int exynos4212_clk_bus_dmc0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_BUS_DMC0, clk, enable);
+}
+
+static int exynos4212_clk_bus_dmc1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_BUS_DMC1, clk, enable);
+}
+
+static int exynos4212_clk_sclk_dmc_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_SCLK_DMC, clk, enable);
+}
+
+static int __maybe_unused exynos4212_clk_bus_peril_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_BUS_PERIL, clk, enable);
+}
+
+static int __maybe_unused exynos4212_clk_bus_perir_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_BUS_PERIR, clk, enable);
+}
+
+static int exynos4212_clk_ip_audio_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MAUDIO, clk, enable);
+}
+
+static int exynos4212_clk_ip_dmc1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC1, clk, enable);
+}
+
+static int exynos4212_clk_ip_isp_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP, clk, enable);
+}
+
+static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable);
+}
+
+static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable);
+}
+
+static struct clk *exynos4212_clk_src_mpll_user_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos4_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos4212_clk_src_mpll_user = {
+ .sources = exynos4212_clk_src_mpll_user_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clk_src_mpll_user_list),
+};
+
+static struct clksrc_clk exynos4212_clk_mout_mpll_user = {
+ .clk = {
+ .name = "mout_mpll_user",
+ },
+ .sources = &exynos4212_clk_src_mpll_user,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 },
+};
+
+static struct clk *exynos4212_clkset_aclk_lrbus_user_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos4_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_aclk_lrbus_user = {
+ .sources = exynos4212_clkset_aclk_lrbus_user_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clkset_aclk_lrbus_user_list),
+};
+
+static struct clksrc_clk exynos4212_clk_aclk_gdl_user = {
+ .clk = {
+ .name = "aclk_gdl_user",
+ },
+ .sources = &exynos4212_clkset_aclk_lrbus_user,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_LEFTBUS, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk exynos4212_clk_aclk_gdr_user = {
+ .clk = {
+ .name = "aclk_gdr_user",
+ },
+ .sources = &exynos4212_clkset_aclk_lrbus_user,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_RIGHTBUS, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk exynos4212_clk_mout_aclk_266 = {
+ .clk = {
+ .name = "mout_aclk_266",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 4, .size = 1 },
+};
+
+static struct clksrc_clk exynos4212_clk_dout_aclk_266 = {
+ .clk = {
+ .name = "dout_aclk_266",
+ .parent = &exynos4212_clk_mout_aclk_266.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk exynos4212_clk_mout_aclk_200 = {
+ .clk = {
+ .name = "mout_aclk_200",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 },
+};
+
+static struct clksrc_clk exynos4212_clk_dout_aclk_200 = {
+ .clk = {
+ .name = "dout_aclk_200",
+ .parent = &exynos4212_clk_mout_aclk_200.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos4212_clk_mout_aclk_400_mcuisp = {
+ .clk = {
+ .name = "mout_aclk_400_mcuisp",
+ },
+ .sources = &exynos4_clkset_aclk,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk exynos4212_clk_dout_aclk_400_mcuisp = {
+ .clk = {
+ .name = "dout_aclk_400_mcuisp",
+ .parent = &exynos4212_clk_mout_aclk_400_mcuisp.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 24, .size = 3 },
+};
+
+static struct clk *exynos4212_clk_aclk_400_mcuisp_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos4212_clk_dout_aclk_400_mcuisp.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_aclk_400_mcuisp = {
+ .sources = exynos4212_clk_aclk_400_mcuisp_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clk_aclk_400_mcuisp_list),
+};
+
+struct clksrc_clk exynos4212_clk_aclk_400_mcuisp = {
+ .clk = {
+ .name = "aclk_400_mcuisp",
+ },
+ .sources = &exynos4212_clkset_aclk_400_mcuisp,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 24, .size = 1 },
+};
+
+static struct clk *exynos4212_clk_aclk_266_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos4212_clk_dout_aclk_266.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_aclk_266 = {
+ .sources = exynos4212_clk_aclk_266_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clk_aclk_266_list),
+};
+
+struct clksrc_clk exynos4212_clk_aclk_266 = {
+ .clk = {
+ .name = "aclk_266",
+ },
+ .sources = &exynos4212_clkset_aclk_266,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 16, .size = 1 },
+};
+
+static struct clk *exynos4212_clk_aclk_200_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos4212_clk_dout_aclk_200.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_aclk_200 = {
+ .sources = exynos4212_clk_aclk_200_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clk_aclk_200_list),
+};
+
+static struct clk *exynos4212_clkset_mout_jpeg0_list[] = {
+ [0] = &exynos4212_clk_mout_mpll_user.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_mout_jpeg0 = {
+ .sources = exynos4212_clkset_mout_jpeg0_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clkset_mout_jpeg0_list),
+};
+
+struct clksrc_clk exynos4212_clk_mout_jpeg0 = {
+ .clk = {
+ .name = "mout_jpeg0",
+ },
+ .sources = &exynos4212_clkset_mout_jpeg0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM1, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos4212_clkset_mout_jpeg1_list[] = {
+ [0] = &exynos4_clk_mout_epll.clk,
+ [1] = &exynos4_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos4212_clkset_mout_jpeg1 = {
+ .sources = exynos4212_clkset_mout_jpeg1_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clkset_mout_jpeg1_list),
+};
+
+struct clksrc_clk exynos4212_clk_mout_jpeg1 = {
+ .clk = {
+ .name = "mout_jpeg1",
+ },
+ .sources = &exynos4212_clkset_mout_jpeg1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM1, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4212_clkset_mout_jpeg_list[] = {
+ [0] = &exynos4212_clk_mout_jpeg0.clk,
+ [1] = &exynos4212_clk_mout_jpeg1.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_mout_jpeg = {
+ .sources = exynos4212_clkset_mout_jpeg_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clkset_mout_jpeg_list),
+};
+
+struct clksrc_clk exynos4212_clk_aclk_jpeg = {
+ .clk = {
+ .name = "aclk_clk_jpeg",
+ },
+ .sources = &exynos4212_clkset_mout_jpeg,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_CAM1, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_CAM1, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos4212_clkset_c2c_list[] = {
+ [0] = &exynos4_clk_mout_mpll.clk,
+ [1] = &exynos4_clk_sclk_apll.clk,
+};
+
+static struct clksrc_sources exynos4212_clkset_sclk_c2c = {
+ .sources = exynos4212_clkset_c2c_list,
+ .nr_sources = ARRAY_SIZE(exynos4212_clkset_c2c_list),
+};
+
+static struct clksrc_clk exynos4212_clk_sclk_c2c = {
+ .clk = {
+ .name = "sclk_c2c",
+ .id = -1,
+ },
+ .sources = &exynos4212_clkset_sclk_c2c,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 0, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4212_clk_aclk_c2c = {
+ .clk = {
+ .name = "aclk_c2c",
+ .id = -1,
+ .parent = &exynos4212_clk_sclk_c2c.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk *exynos4212_sysclks[] = {
+ &exynos4212_clk_mout_mpll_user,
+ &exynos4212_clk_aclk_gdl_user,
+ &exynos4212_clk_aclk_gdr_user,
+ &exynos4212_clk_mout_aclk_400_mcuisp,
+ &exynos4212_clk_mout_aclk_266,
+ &exynos4212_clk_mout_aclk_200,
+ &exynos4212_clk_dout_aclk_200,
+ &exynos4212_clk_aclk_400_mcuisp,
+ &exynos4212_clk_aclk_266,
+ &exynos4212_clk_mout_jpeg0,
+ &exynos4212_clk_mout_jpeg1,
+ &exynos4212_clk_aclk_jpeg,
+ &exynos4212_clk_sclk_c2c,
+ &exynos4212_clk_aclk_c2c,
+};
+
+static struct clk exynos4212_init_clocks_off[] = {
+ {
+ .name = "qejpeg",
+ .enable = exynos4_clk_ip_cam_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "async_tvx",
+ .enable = exynos4_clk_ip_leftbus_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "mipihsi",
+ .parent = &exynos4_clk_aclk_133.clk,
+ .enable = exynos4_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "ppmuisp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 21 | 1 << 20),
+ }, {
+ .name = "qegps",
+ .enable = exynos4_clk_ip_gps_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "ppmugps",
+ .enable = exynos4_clk_ip_gps_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(g2d_acp, 15),
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 24),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(ispcx, 22),
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(lite1, 21),
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(lite0, 20),
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(is_isp, 16),
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(is_drc, 17),
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(is_fd, 18),
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "sysmmu",
+ .devname = SYSMMU_CLOCK_NAME(is_cpu, 19),
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "qec2c",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 30),
+#ifndef CONFIG_SAMSUNG_C2C
+ }, {
+ .name = "c2c",
+ .devname = "samsung-c2c",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+#ifdef CONFIG_MACH_M0_CTC
+ .ctrlbit = (1 << 26 | 1 << 27),
+#else
+ .ctrlbit = (1 << 26 | 1 << 27 | 1 << 31),
+#endif
+ }, {
+ .name = "sclk_c2c_off",
+ .enable = exynos4212_clk_sclk_dmc_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "pclk_c2c_off",
+ .enable = exynos4212_clk_bus_dmc1_ctrl,
+ .ctrlbit = (1 << 27 | 1 << 30),
+ }, {
+ .name = "aclk_c2c_off",
+ .enable = exynos4212_clk_bus_dmc0_ctrl,
+ .ctrlbit = (1 << 21 | 1 << 22 | 1 << 24),
+#endif
+ }, {
+ .name = "mtcadc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "i2c0_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "mpwm_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 24),
+ }, {
+ .name = "qelite1",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "qelite0",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "qefd",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "qedrc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "qeisp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "lite0",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "spi1_isp",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "spi0_isp",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+};
+
+static struct clk exynos4212_init_clocks[] = {
+ {
+ .name = "cmu_isp",
+ .enable = exynos4_clk_ip_perir_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "async_maudiox",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "async_mfcr",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "async_fsysd",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "async_camx",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "async_axim",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "uart_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 31),
+ }, {
+ .name = "wdt_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 30),
+ }, {
+ .name = "pwm_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "i2c1_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "mcuctl_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "gic_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "mcuisp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "lite1",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "fimc_fd",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "fimc_drc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "fimc_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "tzasc_lr",
+ .enable = exynos4212_clk_ip_dmc1_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "tzasc_lw",
+ .enable = exynos4212_clk_ip_dmc1_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "tzasc_rr",
+ .enable = exynos4212_clk_ip_dmc1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "tzasc_rw",
+ .enable = exynos4212_clk_ip_dmc1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+#ifdef CONFIG_MACH_M0_CTC
+ .name = "gpioc2c",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 31),
+ }, {
+#endif
+ .name = "qegdl",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 29),
+ }, {
+ .name = "async_cpu_xiur",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "async_gdr",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "async_gdl",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "drex2",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "i2s0",
+ .enable = exynos4212_clk_ip_audio_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "pcm0",
+ .enable = exynos4212_clk_ip_audio_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "imem",
+ .enable = exynos4212_clk_ip_audio_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "audioss",
+ .enable = exynos4212_clk_ip_audio_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "async_ispmx",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "async_lcd0x",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "gpio_right",
+ .enable = exynos4_clk_ip_rightbus_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "async_g3d",
+ .enable = exynos4_clk_ip_leftbus_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "async_mfcl",
+ .enable = exynos4_clk_ip_leftbus_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "gpio_left",
+ .enable = exynos4_clk_ip_leftbus_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "qeg2d_acp",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "g2d_acp",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "uart_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 31),
+ }, {
+ .name = "wdt_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 30),
+ }, {
+ .name = "pwm_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "mtcadc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "i2c1_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "i2c0_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "mpwm_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 24),
+ }, {
+ .name = "mcuctl_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "qelite1",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "qelite0",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "qefd",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "qedrc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "qeisp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "sysmmu_lite1",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "sysmmu_lite0",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "gic_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "mcu_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "lite1",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "lite0",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "fd",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "drc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "spi1_isp",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "spi0_isp",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "aync_caxim",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "sysmmu_fd",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "sysmmu_drc",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "sysmmu_isp",
+ .enable = exynos4212_clk_ip_isp0_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "sysmmu_ispcx",
+ .enable = exynos4212_clk_ip_isp1_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+};
+
+static struct clksrc_clk exynos4212_clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_mipihsi",
+ .enable = exynos4_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos4_clkset_mout_corebus,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+ },
+};
+
+static struct clk exynos4212_clk_isp[] = {
+ {
+ .name = "aclk_400_mcuisp_muxed",
+ .parent = &exynos4212_clk_aclk_400_mcuisp.clk,
+ }, {
+ .name = "aclk_200_muxed",
+ .parent = &exynos4_clk_aclk_200.clk,
+ },
+};
+
+static struct clksrc_clk exynos4212_clk_isp_srcs_div0 = {
+ .clk = {
+ .name = "sclk_mcuisp_div0",
+ .parent = &exynos4212_clk_aclk_400_mcuisp.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP1, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos4212_clk_isp_srcs[] = {
+ {
+ .clk = {
+ .name = "sclk_mcuisp_div1",
+ .parent = &exynos4212_clk_isp_srcs_div0.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP1, .shift = 8, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_aclk_div0",
+ .parent = &exynos4_clk_aclk_200.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP0, .shift = 0, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_aclk_div1",
+ .parent = &exynos4_clk_aclk_200.clk,
+ },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP0, .shift = 4, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_uart_isp",
+ .enable = exynos4212_clk_ip_isp_ctrl,
+ .ctrlbit = (1 << 3),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_ISP, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi1_isp",
+ .enable = exynos4212_clk_ip_isp_ctrl,
+ .ctrlbit = (1 << 2),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_ISP, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP, .shift = 16, .size = 12 },
+ }, {
+ .clk = {
+ .name = "sclk_spi0_isp",
+ .enable = exynos4212_clk_ip_isp_ctrl,
+ .ctrlbit = (1 << 1),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_ISP, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP, .shift = 4, .size = 12 },
+ }, {
+ .clk = {
+ .name = "sclk_pwm_isp",
+ .enable = exynos4212_clk_ip_isp_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos4_clkset_group,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_ISP, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_ISP, .shift = 0, .size = 4 },
+ },
+};
+
+static u32 epll_div_4212[][6] = {
+ { 416000000, 0, 104, 3, 1, 0 },
+ { 408000000, 0, 68, 2, 1, 0 },
+ { 400000000, 0, 100, 3, 1, 0 },
+ { 200000000, 0, 100, 3, 2, 0 },
+ { 192000000, 0, 64, 2, 2, 0 },
+ { 180633600, 0, 90, 3, 2, 20762 },
+ { 180000000, 0, 60, 2, 2, 0 },
+};
+
+static unsigned long exynos4212_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos4212_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+ unsigned int tmp;
+ unsigned int epll_rate;
+ unsigned int locktime;
+ unsigned int lockcnt;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ if (clk->parent)
+ epll_rate = clk_get_rate(clk->parent);
+ else
+ epll_rate = clk_ext_xtal_mux.rate;
+
+ if (epll_rate != 24000000) {
+ pr_err("Invalid Clock : recommended clock is 24MHz.\n");
+ return -EINVAL;
+ }
+
+ epll_con = __raw_readl(EXYNOS4_EPLL_CON0);
+ epll_con &= ~(0x1 << 27 | \
+ PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT | \
+ PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT | \
+ PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div_4212); i++) {
+ if (epll_div_4212[i][0] == rate) {
+ epll_con_k = epll_div_4212[i][5] << 0;
+ epll_con |= epll_div_4212[i][2] << PLL36XX_MDIV_SHIFT;
+ epll_con |= epll_div_4212[i][3] << PLL36XX_PDIV_SHIFT;
+ epll_con |= epll_div_4212[i][4] << PLL36XX_SDIV_SHIFT;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div_4212)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ epll_rate /= 1000000;
+
+ /* 3000 max_cycls : specification data */
+ locktime = 3000 / epll_rate * epll_div_4212[i][3];
+ lockcnt = locktime * 10000 / (10000 / epll_rate);
+
+ __raw_writel(lockcnt, EXYNOS4_EPLL_LOCK);
+ __raw_writel(epll_con, EXYNOS4_EPLL_CON0);
+ __raw_writel(epll_con_k, EXYNOS4_EPLL_CON1);
+
+
+ do {
+ tmp = __raw_readl(EXYNOS4_EPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT));
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct vpll_div_data vpll_div_4212[] = {
+ {54000000, 2, 72, 4, 0, 0, 0, 0},
+ {108000000, 2, 72, 3, 0, 0, 0, 0},
+ {160000000, 3, 160, 3, 0, 0, 0, 0},
+ {266000000, 3, 133, 2, 0, 0, 0, 0},
+ {275000000, 2, 92, 2, 43692, 0, 0, 0},
+ {300000000, 2, 100, 2, 0, 0, 0, 0},
+ {333000000, 2, 111, 2, 0, 0, 0, 0},
+ {350000000, 3, 175, 2, 0, 0, 0, 0},
+ {440000000, 3, 110, 1, 0, 0, 0, 0},
+};
+
+static unsigned long exynos4212_vpll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos4212_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int vpll_con0, vpll_con1;
+ unsigned int i;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+ vpll_con0 &= ~(PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT | \
+ PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT | \
+ PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
+
+ vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
+ vpll_con1 &= ~(0xffff << 0);
+
+ for (i = 0; i < ARRAY_SIZE(vpll_div_4212); i++) {
+ if (vpll_div_4212[i].rate == rate) {
+ vpll_con0 |= vpll_div_4212[i].pdiv << PLL36XX_PDIV_SHIFT;
+ vpll_con0 |= vpll_div_4212[i].mdiv << PLL36XX_MDIV_SHIFT;
+ vpll_con0 |= vpll_div_4212[i].sdiv << PLL36XX_SDIV_SHIFT;
+ vpll_con1 |= vpll_div_4212[i].k << 0;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(vpll_div_4212)) {
+ printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
+ __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
+
+ do {
+ vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
+ } while (!(vpll_con0 & 0x1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT));
+
+ clk->rate = rate;
+
+ return 0;
+}
+#ifdef CONFIG_PM
+static int exynos4212_clock_suspend(void)
+{
+ s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
+ s3c_pm_do_save(exynos4212_vpll_save, ARRAY_SIZE(exynos4212_vpll_save));
+#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
+ s3c_pm_do_save(exynos4212_epll_save, ARRAY_SIZE(exynos4212_epll_save));
+#endif
+
+ return 0;
+}
+
+static void exynos4212_clock_resume(void)
+{
+ unsigned int tmp;
+
+ s3c_pm_do_restore_core(exynos4212_vpll_save, ARRAY_SIZE(exynos4212_vpll_save));
+#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
+ s3c_pm_do_restore_core(exynos4212_epll_save, ARRAY_SIZE(exynos4212_epll_save));
+#endif
+
+ /* waiting epll & vpll locking time */
+ do {
+ tmp = __raw_readl(EXYNOS4_EPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS4_EPLLCON0_LOCKED_SHIFT));
+
+ do {
+ tmp = __raw_readl(EXYNOS4_VPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS4_VPLLCON0_LOCKED_SHIFT));
+
+ s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
+}
+#else
+#define exynos4212_clock_suspend NULL
+#define exynos4212_clock_resume NULL
+#endif
+
+struct syscore_ops exynos4212_clock_syscore_ops = {
+ .suspend = exynos4212_clock_suspend,
+ .resume = exynos4212_clock_resume,
+};
+
+void __init exynos4212_register_clocks(void)
+{
+ int ptr;
+ unsigned int tmp;
+
+ /* usbphy1 is removed in exynos 4212 */
+ exynos4_clkset_group_list[4] = NULL;
+
+ /* mout_mpll_user is used instead of mout_mpll in exynos 4212 */
+ exynos4_clkset_group_list[6] = &exynos4212_clk_mout_mpll_user.clk;
+ exynos4_clkset_aclk_top_list[0] = &exynos4212_clk_mout_mpll_user.clk;
+ exynos4_clkset_mout_mfc0_list[0] = &exynos4212_clk_mout_mpll_user.clk;
+
+ exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC;
+ exynos4_clk_mout_mpll.reg_src.shift = 12;
+ exynos4_clk_mout_mpll.reg_src.size = 1;
+
+ exynos4_clk_aclk_200.sources = &exynos4212_clkset_aclk_200;
+ exynos4_clk_aclk_200.reg_src.reg = EXYNOS4_CLKSRC_TOP1;
+ exynos4_clk_aclk_200.reg_src.shift = 20;
+ exynos4_clk_aclk_200.reg_src.size = 1;
+
+ exynos4_clk_fimg2d.enable = exynos4_clk_ip_dmc_ctrl;
+ exynos4_clk_fimg2d.ctrlbit = (1 << 23);
+
+ exynos4_clk_mout_g2d0.reg_src.reg = EXYNOS4_CLKSRC_DMC;
+ exynos4_clk_mout_g2d0.reg_src.shift = 20;
+ exynos4_clk_mout_g2d0.reg_src.size = 1;
+
+ exynos4_clk_mout_g2d1.reg_src.reg = EXYNOS4_CLKSRC_DMC;
+ exynos4_clk_mout_g2d1.reg_src.shift = 24;
+ exynos4_clk_mout_g2d1.reg_src.size = 1;
+
+ exynos4_clk_sclk_fimg2d.reg_src.reg = EXYNOS4_CLKSRC_DMC;
+ exynos4_clk_sclk_fimg2d.reg_src.shift = 28;
+ exynos4_clk_sclk_fimg2d.reg_src.size = 1;
+ exynos4_clk_sclk_fimg2d.reg_div.reg = EXYNOS4_CLKDIV_DMC1;
+ exynos4_clk_sclk_fimg2d.reg_div.shift = 0;
+ exynos4_clk_sclk_fimg2d.reg_div.size = 4;
+
+ exynos4_epll_ops.get_rate = exynos4212_epll_get_rate;
+ exynos4_epll_ops.set_rate = exynos4212_epll_set_rate;
+ exynos4_vpll_ops.get_rate = exynos4212_vpll_get_rate;
+ exynos4_vpll_ops.set_rate = exynos4212_vpll_set_rate;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos4212_sysclks); ptr++)
+ s3c_register_clksrc(exynos4212_sysclks[ptr], 1);
+
+ s3c_register_clksrc(exynos4212_clksrcs, ARRAY_SIZE(exynos4212_clksrcs));
+ s3c_register_clocks(exynos4212_init_clocks, ARRAY_SIZE(exynos4212_init_clocks));
+
+ s3c_register_clocks(exynos4212_init_clocks_off, ARRAY_SIZE(exynos4212_init_clocks_off));
+ s3c_disable_clocks(exynos4212_init_clocks_off, ARRAY_SIZE(exynos4212_init_clocks_off));
+
+ s3c_register_clksrc(&exynos4212_clk_isp_srcs_div0, 1);
+ s3c_register_clksrc(exynos4212_clk_isp_srcs, ARRAY_SIZE(exynos4212_clk_isp_srcs));
+ s3c_register_clocks(exynos4212_clk_isp, ARRAY_SIZE(exynos4212_clk_isp));
+ s3c_disable_clocks(&exynos4212_clk_isp_srcs[3].clk, 1);
+ s3c_disable_clocks(&exynos4212_clk_isp_srcs[4].clk, 1);
+ s3c_disable_clocks(&exynos4212_clk_isp_srcs[5].clk, 1);
+ s3c_disable_clocks(&exynos4212_clk_isp_srcs[6].clk, 1);
+
+ /* To save power,
+ * Disable CLKOUT of LEFTBUS, RIGHTBUS, TOP, DMC, CPU and ISP
+ */
+ for (ptr = 0 ; ptr < ARRAY_SIZE(exynos4x12_cmu_config) ; ptr++) {
+ tmp = __raw_readl(exynos4x12_cmu_config[ptr].reg);
+ tmp &= ~(0x1 << 16);
+ tmp |= (exynos4x12_cmu_config[ptr].val << 16);
+ __raw_writel(tmp, exynos4x12_cmu_config[ptr].reg);
+ }
+
+ register_syscore_ops(&exynos4212_clock_syscore_ops);
+}
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
new file mode 100644
index 0000000..8ee9e42
--- /dev/null
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -0,0 +1,2921 @@
+/* linux/arch/arm/mach-exynos/clock-exynos5.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-audss.h>
+#include <mach/sysmmu.h>
+#include <mach/exynos-clock.h>
+#include <mach/clock-domain.h>
+
+#ifdef CONFIG_PM
+static struct sleep_save exynos5_clock_save[] = {
+ /* CMU side */
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_TOP),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_GSCL),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_DISP1_0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_FSYS),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_MAUDIO),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC1),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_ISP),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_SYSRGT),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_ACP),
+ SAVE_ITEM(EXYNOS5_CLKGATE_ISP0),
+ SAVE_ITEM(EXYNOS5_CLKGATE_ISP1),
+ SAVE_ITEM(EXYNOS5_CLKGATE_SCLK_ISP),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_GSCL),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_DISP1),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_MFC),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_G3D),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_GEN),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_FSYS),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIC),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIS),
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_CDREX),
+ SAVE_ITEM(EXYNOS5_CLKGATE_BLOCK),
+ SAVE_ITEM(EXYNOS5_CLKDIV_ACP),
+ SAVE_ITEM(EXYNOS5_CLKDIV_ISP0),
+ SAVE_ITEM(EXYNOS5_CLKDIV_ISP1),
+ SAVE_ITEM(EXYNOS5_CLKDIV_ISP2),
+ SAVE_ITEM(EXYNOS5_CLKDIV_TOP0),
+ SAVE_ITEM(EXYNOS5_CLKDIV_TOP1),
+ SAVE_ITEM(EXYNOS5_CLKDIV_GSCL),
+ SAVE_ITEM(EXYNOS5_CLKDIV_DISP1_0),
+ SAVE_ITEM(EXYNOS5_CLKDIV_GEN),
+ SAVE_ITEM(EXYNOS5_CLKDIV_MAUDIO),
+ SAVE_ITEM(EXYNOS5_CLKDIV_FSYS0),
+ SAVE_ITEM(EXYNOS5_CLKDIV_FSYS1),
+ SAVE_ITEM(EXYNOS5_CLKDIV_FSYS2),
+ SAVE_ITEM(EXYNOS5_CLKDIV_FSYS3),
+ SAVE_ITEM(EXYNOS5_CLKDIV_PERIC0),
+ SAVE_ITEM(EXYNOS5_CLKDIV_PERIC1),
+ SAVE_ITEM(EXYNOS5_CLKDIV_PERIC2),
+ SAVE_ITEM(EXYNOS5_CLKDIV_PERIC3),
+ SAVE_ITEM(EXYNOS5_CLKDIV_PERIC4),
+ SAVE_ITEM(EXYNOS5_CLKDIV_PERIC5),
+ SAVE_ITEM(EXYNOS5_SCLK_DIV_ISP),
+ SAVE_ITEM(EXYNOS5_CLKDIV2_RATIO0),
+ SAVE_ITEM(EXYNOS5_CLKDIV2_RATIO1),
+ SAVE_ITEM(EXYNOS5_CLKDIV4_RATIO),
+ SAVE_ITEM(EXYNOS5_CLKSRC_TOP0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_TOP1),
+ SAVE_ITEM(EXYNOS5_CLKSRC_TOP2),
+ SAVE_ITEM(EXYNOS5_CLKSRC_TOP3),
+ SAVE_ITEM(EXYNOS5_CLKSRC_GSCL),
+ SAVE_ITEM(EXYNOS5_CLKSRC_DISP1_0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MAUDIO),
+ SAVE_ITEM(EXYNOS5_CLKSRC_FSYS),
+ SAVE_ITEM(EXYNOS5_CLKSRC_PERIC0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_PERIC1),
+ SAVE_ITEM(EXYNOS5_SCLK_SRC_ISP),
+#ifdef CONFIG_EXYNOS5_ENABLE_CLOCK_DOWN
+ SAVE_ITEM(EXYNOS5_PWR_CTRL1),
+ SAVE_ITEM(EXYNOS5_PWR_CTRL2),
+#endif
+};
+
+static struct sleep_save exynos5_epll_save[] = {
+ SAVE_ITEM(EXYNOS5_EPLL_LOCK),
+ SAVE_ITEM(EXYNOS5_EPLL_CON0),
+ SAVE_ITEM(EXYNOS5_EPLL_CON1),
+ SAVE_ITEM(EXYNOS5_EPLL_CON2),
+};
+
+static struct sleep_save exynos5_vpll_save[] = {
+ SAVE_ITEM(EXYNOS5_VPLL_LOCK),
+ SAVE_ITEM(EXYNOS5_VPLL_CON0),
+ SAVE_ITEM(EXYNOS5_VPLL_CON1),
+ SAVE_ITEM(EXYNOS5_VPLL_CON2),
+#ifdef CONFIG_EXYNOS5_ENABLE_CLOCK_DOWN
+ SAVE_ITEM(EXYNOS5_PWR_CTRL1),
+ SAVE_ITEM(EXYNOS5_PWR_CTRL2),
+#endif
+};
+
+static struct sleep_save exynos5_gpll_save[] = {
+ SAVE_ITEM(EXYNOS5_GPLL_LOCK),
+ SAVE_ITEM(EXYNOS5_GPLL_CON0),
+ SAVE_ITEM(EXYNOS5_GPLL_CON1),
+};
+
+static struct sleep_save exynos5250_clock_save_rev0[] = {
+ SAVE_ITEM(EXYNOS5_CLKGATE_IP_GPS),
+};
+
+#endif
+
+static struct clk exynos5_clk_sclk_hdmi24m = {
+ .name = "sclk_hdmi24m",
+ .rate = 24000000,
+};
+
+static struct clk exynos5_clk_sclk_hdmi27m = {
+ .name = "sclk_hdmi27m",
+ .rate = 27000000,
+};
+
+static struct clk exynos5_clk_sclk_hdmiphy = {
+ .name = "sclk_hdmiphy",
+};
+
+static struct clk exynos5_clk_sclk_dptxphy = {
+ .name = "sclk_dptx",
+};
+
+static struct clk exynos5_clk_sclk_usbphy = {
+ .name = "sclk_usbphy",
+ .rate = 48000000,
+};
+
+struct clksrc_clk exynos5_clk_audiocdclk0 = {
+ .clk = {
+ .name = "audiocdclk",
+ .rate = 16934400,
+ },
+};
+
+static struct clk exynos5_clk_audiocdclk1 = {
+ .name = "audiocdclk",
+};
+
+static struct clk exynos5_clk_audiocdclk2 = {
+ .name = "audiocdclk",
+};
+
+static struct clk exynos5_clk_spdifcdclk = {
+ .name = "spdifcdclk",
+};
+
+static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable);
+}
+
+static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
+}
+
+static int exynos5_clk_ip_sysrgt_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_SYSRGT, clk, enable);
+}
+
+static int exynos5_clk_ip_cpu_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CPU, clk, enable);
+}
+
+static int exynos5_clk_ip_gps_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS, clk, enable);
+}
+
+static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable);
+}
+
+static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
+}
+
+static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
+}
+
+static int exynos5_clksrc_mask_peric1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC1, clk, enable);
+}
+
+static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable);
+}
+
+static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable);
+}
+
+static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable);
+}
+
+static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int exynos5_clk_ip_g3d_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_G3D, clk, enable);
+}
+
+static int exynos5_clk_hdmiphy_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
+}
+
+static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable);
+}
+
+static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable);
+}
+
+static int exynos5_clksrc_mask_maudio_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_MAUDIO, clk, enable);
+}
+
+static int exynos5_clk_audss_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_AUDSS, clk, enable);
+}
+
+static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable);
+}
+
+static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable);
+}
+
+static int exynos5_clksrc_mask_gen_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GEN, clk, enable);
+}
+
+static int exynos5_clk_gate_block(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable);
+}
+
+static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
+}
+
+static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_ISP0, clk, enable);
+}
+
+static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKGATE_ISP1, clk, enable);
+}
+
+static int exynos5_clk_clkout_cpu_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_CPU, clk, enable);
+}
+
+static int exynos5_clk_clkout_core_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_CORE, clk, enable);
+}
+
+static int exynos5_clk_clkout_acp_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_ACP, clk, enable);
+}
+
+static int exynos5_clk_clkout_isp_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_ISP, clk, enable);
+}
+
+static int exynos5_clk_clkout_top_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_TOP, clk, enable);
+}
+
+static int exynos5_clk_clkout_lex_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_LEX, clk, enable);
+}
+
+static int exynos5_clk_clkout_r0x_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_R0X, clk, enable);
+}
+
+static int exynos5_clk_clkout_r1x_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_R1X, clk, enable);
+}
+
+static int exynos5_clk_clkout_cdrex_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(EXYNOS5_CLKOUT_CMU_CDREX, clk, enable);
+}
+
+/* BPLL clock output
+ * No need .ctrlbit, this is always on
+*/
+static struct clk clk_fout_bpll = {
+ .name = "fout_bpll",
+ .id = -1,
+};
+
+/* MOUT_BPLL_FOUT
+ * No need .ctrlbit, this is always on
+*/
+static struct clk clk_fout_bpll_div2 = {
+ .name = "fout_bpll_div2",
+ .id = -1,
+};
+
+/* MOUT_MPLL_FOUT
+ * No need .ctrlbit, this is always on
+*/
+static struct clk clk_fout_mpll_div2 = {
+ .name = "fout_mpll_div2",
+ .id = -1,
+};
+
+/* Possible clock sources for BPLL Mux */
+static struct clk *clk_src_bpll_list[] = {
+ [0] = &clk_fin_bpll,
+ [1] = &clk_fout_bpll,
+};
+
+static struct clksrc_sources clk_src_bpll = {
+ .sources = clk_src_bpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_bpll_list),
+};
+
+/* Possible clock source for BPLL_FOUT Mux */
+static struct clk *exynos5_clkset_mout_bpll_fout_list[] = {
+ [0] = &clk_fout_bpll_div2,
+ [1] = &clk_fout_bpll,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_bpll_fout = {
+ .sources = exynos5_clkset_mout_bpll_fout_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_bpll_fout_list),
+};
+
+/* GPLL clock output */
+static struct clk clk_fout_gpll = {
+ .name = "fout_gpll",
+ .id = -1,
+};
+
+/* Possible clock sources for GPLL Mux */
+static struct clk *clk_src_gpll_list[] = {
+ [0] = &clk_fin_gpll,
+ [1] = &clk_fout_gpll,
+};
+
+static struct clksrc_sources clk_src_gpll = {
+ .sources = clk_src_gpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_gpll_list),
+};
+
+/* CPLL clock output */
+static struct clk clk_fout_cpll = {
+ .name = "fout_cpll",
+ .id = -1,
+};
+
+/* Possible clock sources for CPLL Mux */
+static struct clk *clk_src_cpll_list[] = {
+ [0] = &clk_fin_cpll,
+ [1] = &clk_fout_cpll,
+};
+
+static struct clksrc_sources clk_src_cpll = {
+ .sources = clk_src_cpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_cpll_list),
+};
+
+/* Possible clock source for MPLL_FOUT Mux */
+static struct clk *exynos5_clkset_mout_mpll_fout_list[] = {
+ [0] = &clk_fout_mpll_div2,
+ [1] = &clk_fout_mpll,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_mpll_fout = {
+ .sources = exynos5_clkset_mout_mpll_fout_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_mpll_fout_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_mpll_fout = {
+ .clk = {
+ .name = "mout_mpll_fout",
+ },
+ .sources = &exynos5_clkset_mout_mpll_fout,
+ .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 4, .size = 1 },
+};
+
+/* Possible clock source for MPLL Mux */
+static struct clk *exynos5_clkset_mout_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos5_clk_mout_mpll_fout.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_mpll = {
+ .sources = exynos5_clkset_mout_mpll_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_mpll_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_bpll_fout = {
+ .clk = {
+ .name = "mout_bpll_fout",
+ },
+ .sources = &exynos5_clkset_mout_bpll_fout,
+ .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 0, .size = 1 },
+};
+
+/* Possible clock source for BPLL Mux */
+static struct clk *exynos5_clkset_mout_bpll_list[] = {
+ [0] = &clk_fin_bpll,
+ [1] = &exynos5_clk_mout_bpll_fout.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_bpll = {
+ .sources = exynos5_clkset_mout_bpll_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_bpll_list),
+};
+
+/* Core list of CMU_CPU side */
+static struct clksrc_clk exynos5_clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_apll = {
+ .clk = {
+ .name = "sclk_apll",
+ .parent = &exynos5_clk_mout_apll.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_bpll = {
+ .clk = {
+ .name = "mout_bpll",
+ },
+ .sources = &clk_src_bpll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_gpll = {
+ .clk = {
+ .name = "mout_gpll",
+ },
+ .sources = &clk_src_gpll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_cpll = {
+ .clk = {
+ .name = "mout_cpll",
+ },
+ .sources = &clk_src_cpll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
+};
+
+struct clksrc_clk exynos5_clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
+};
+
+/* CMU_ACP */
+static struct clksrc_clk exynos5_clk_aclk_acp = {
+ .clk = {
+ .name = "aclk_acp",
+ .parent = &exynos5_clk_mout_mpll.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_pclk_acp = {
+ .clk = {
+ .name = "pclk_acp",
+ .parent = &exynos5_clk_aclk_acp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 },
+};
+
+/* For VPLL */
+static struct clk *exynos5_clkset_mout_vpllsrc_list[] = {
+ [0] = &clk_fin_vpll,
+ [1] = &exynos5_clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_vpllsrc = {
+ .sources = exynos5_clkset_mout_vpllsrc_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_vpllsrc_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_vpllsrc = {
+ .clk = {
+ .name = "vpll_src",
+ .enable = exynos5_clksrc_mask_top_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos5_clkset_mout_vpllsrc,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos5_clkset_sclk_vpll_list[] = {
+ [0] = &exynos5_clk_mout_vpllsrc.clk,
+ [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_vpll = {
+ .sources = exynos5_clkset_sclk_vpll_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_vpll = {
+ .clk = {
+ .name = "sclk_vpll",
+ },
+ .sources = &exynos5_clkset_sclk_vpll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_pixel = {
+ .clk = {
+ .name = "sclk_pixel",
+ .parent = &exynos5_clk_sclk_vpll.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 },
+};
+
+static struct clk *exynos5_clkset_sclk_hdmi_list[] = {
+ [0] = &exynos5_clk_sclk_pixel.clk,
+ [1] = &exynos5_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_hdmi = {
+ .sources = exynos5_clkset_sclk_hdmi_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_hdmi = {
+ .clk = {
+ .name = "sclk_hdmi",
+ .enable = exynos5_clksrc_mask_disp1_0_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &exynos5_clkset_sclk_hdmi,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
+};
+
+static struct clk *exynos5_clkset_sclk_cec_list[] = {
+ [0] = &exynos5_clk_sclk_pixel.clk,
+ [1] = &exynos5_clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_cec = {
+ .sources = exynos5_clkset_sclk_cec_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_cec_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_cec = {
+ .clk = {
+ .name = "sclk_cec",
+ .enable = exynos5_clksrc_mask_disp1_0_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &exynos5_clkset_sclk_cec,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
+};
+
+static struct clksrc_clk *exynos5_sclk_tv[] = {
+ &exynos5_clk_sclk_pixel,
+ &exynos5_clk_sclk_hdmi,
+ &exynos5_clk_sclk_cec,
+};
+
+/* BPLL USER */
+static struct clk *exynos5_clk_src_bpll_user_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos5_clk_mout_bpll.clk,
+};
+
+static struct clksrc_sources exynos5_clk_src_bpll_user = {
+ .sources = exynos5_clk_src_bpll_user_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clk_src_bpll_user_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_bpll_user = {
+ .clk = {
+ .name = "mout_bpll_user",
+ },
+ .sources = &exynos5_clk_src_bpll_user,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
+};
+
+/* MPLL USER */
+static struct clk *exynos5_clk_src_mpll_user_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &exynos5_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos5_clk_src_mpll_user = {
+ .sources = exynos5_clk_src_mpll_user_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clk_src_mpll_user_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_mpll_user = {
+ .clk = {
+ .name = "mout_mpll_user",
+ },
+ .sources = &exynos5_clk_src_mpll_user,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 },
+};
+
+static struct clk *exynos5_clkset_mout_cpu_list[] = {
+ [0] = &exynos5_clk_mout_apll.clk,
+ [1] = &exynos5_clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_mout_cpu = {
+ .sources = exynos5_clkset_mout_cpu_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_cpu_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_cpu = {
+ .clk = {
+ .name = "moutcpu",
+ },
+ .sources = &exynos5_clkset_mout_cpu,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_armclk = {
+ .clk = {
+ .name = "dout_arm_clk",
+ .parent = &exynos5_clk_mout_cpu.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_arm2clk = {
+ .clk = {
+ .name = "dout_arm_clk",
+ .parent = &exynos5_clk_dout_armclk.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 },
+};
+
+static struct clk exynos5_clk_armclk = {
+ .name = "armclk",
+ .parent = &exynos5_clk_dout_arm2clk.clk,
+};
+
+/* Core list of CMU_CDREX side */
+
+static struct clk *exynos5_clkset_cdrex_list[] = {
+ [0] = &exynos5_clk_mout_mpll.clk,
+ [1] = &exynos5_clk_mout_bpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_mclk_cdrex = {
+ .sources = exynos5_clkset_cdrex_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_cdrex_list),
+};
+
+static struct clksrc_clk exynos5_clk_mclk_cdrex = {
+ .clk = {
+ .name = "mclk_cdrex",
+ },
+ .sources = &exynos5_clkset_mclk_cdrex,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 28, .size = 3 },
+};
+
+/* Core list of CMU_TOP side */
+
+struct clk *exynos5_clkset_aclk_top_list[] = {
+ [0] = &exynos5_clk_mout_mpll_user.clk,
+ [1] = &exynos5_clk_mout_bpll_user.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk = {
+ .sources = exynos5_clkset_aclk_top_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_top_list),
+};
+
+/* For ACLK_400_G3D_MID */
+static struct clksrc_clk exynos5_clk_aclk_400_g3d_mid = {
+ .clk = {
+ .name = "aclk_400_g3d_mid",
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
+};
+
+/* For ACLK_400_G3D */
+struct clk *exynos5_clkset_aclk_g3d_list[] = {
+ [0] = &exynos5_clk_aclk_400_g3d_mid.clk,
+ [1] = &exynos5_clk_mout_gpll.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk_g3d = {
+ .sources = exynos5_clkset_aclk_g3d_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_g3d_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_400 = {
+ .clk = {
+ .name = "aclk_400",
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 28, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
+};
+
+/* For ACLK_333 */
+struct clk *exynos5_clkset_mout_aclk_333_166_list[] = {
+ [0] = &exynos5_clk_mout_cpll.clk,
+ [1] = &exynos5_clk_mout_mpll_user.clk,
+};
+
+struct clksrc_sources exynos5_clkset_mout_aclk_333_166 = {
+ .sources = exynos5_clkset_mout_aclk_333_166_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_aclk_333_166_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_aclk_333 = {
+ .clk = {
+ .name = "mout_aclk_333",
+ },
+ .sources = &exynos5_clkset_mout_aclk_333_166,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_aclk_333 = {
+ .clk = {
+ .name = "dout_aclk_333",
+ .parent = &exynos5_clk_mout_aclk_333.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 },
+};
+
+struct clk *exynos5_clkset_aclk_333_sub_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &exynos5_clk_dout_aclk_333.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk_333_sub = {
+ .sources = exynos5_clkset_aclk_333_sub_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_333_sub_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_333 = {
+ .clk = {
+ .name = "aclk_333",
+ },
+ .sources = &exynos5_clkset_aclk_333_sub,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 24, .size = 1 },
+};
+
+/* For ACLK_300_disp1_mid */
+static struct clksrc_clk exynos5_clk_mout_aclk_300_disp1_mid = {
+ .clk = {
+ .name = "mout_aclk_300_disp1_mid",
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 14, .size = 1 },
+};
+
+static struct clk *clk_src_mid1_list[] = {
+ [0] = &exynos5_clk_sclk_vpll.clk,
+ [1] = &exynos5_clk_mout_cpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_mid1 = {
+ .sources = clk_src_mid1_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mid1_list),
+};
+
+/* For ACLK_300_disp1_mid1 */
+static struct clksrc_clk exynos5_clk_mout_aclk_300_disp1_mid1 = {
+ .clk = {
+ .name = "mout_aclk_300_disp1_mid1",
+ },
+ .sources = &exynos5_clkset_mid1,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 8, .size = 1 },
+};
+
+/* For ACLK_300_disp1 */
+struct clk *exynos5_clkset_mout_aclk_300_disp1_list[] = {
+ [0] = &exynos5_clk_mout_aclk_300_disp1_mid.clk,
+ [1] = &exynos5_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos5_clkset_mout_aclk_300_disp1 = {
+ .sources = exynos5_clkset_mout_aclk_300_disp1_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_aclk_300_disp1_list),
+};
+
+struct clk *exynos5_clkset_mout_aclk_300_disp1_rev1_list[] = {
+ [0] = &exynos5_clk_mout_aclk_300_disp1_mid.clk,
+ [1] = &exynos5_clk_mout_aclk_300_disp1_mid1.clk,
+};
+
+struct clksrc_sources exynos5_clkset_mout_aclk_300_disp1_rev1 = {
+ .sources = exynos5_clkset_mout_aclk_300_disp1_rev1_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_aclk_300_disp1_rev1_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_aclk_300_disp1 = {
+ .clk = {
+ .name = "mout_aclk_300_disp1",
+ },
+ .sources = &exynos5_clkset_mout_aclk_300_disp1,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 15, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_aclk_300_disp1 = {
+ .clk = {
+ .name = "dout_aclk_300_disp1",
+ .parent = &exynos5_clk_mout_aclk_300_disp1.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 28, .size = 3 },
+};
+
+static struct clk *clk_src_aclk_300_disp1_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &exynos5_clk_dout_aclk_300_disp1.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_aclk_300_disp1 = {
+ .sources = clk_src_aclk_300_disp1_list,
+ .nr_sources = ARRAY_SIZE(clk_src_aclk_300_disp1_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_300_disp1 = {
+ .clk = {
+ .name = "aclk_300_disp1",
+ },
+ .sources = &exynos5_clkset_aclk_300_disp1,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 6, .size = 1 },
+};
+
+/* For ACLK_300_gscl_mid */
+static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl_mid = {
+ .clk = {
+ .name = "mout_aclk_300_gscl_mid",
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 24, .size = 1 },
+};
+
+/* For ACLK_300_gscl_mid1 */
+static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl_mid1 = {
+ .clk = {
+ .name = "mout_aclk_300_gscl_mid1",
+ },
+ .sources = &exynos5_clkset_mid1,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 12, .size = 1 },
+};
+
+/* For ACLK_300_gscl */
+struct clk *exynos5_clkset_aclk_300_gscl_list[] = {
+ [0] = &exynos5_clk_mout_aclk_300_gscl_mid.clk,
+ [1] = &exynos5_clk_sclk_vpll.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk_300_gscl = {
+ .sources = exynos5_clkset_aclk_300_gscl_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_300_gscl_list),
+};
+
+struct clk *exynos5_clkset_aclk_300_gscl_rev1_list[] = {
+ [0] = &exynos5_clk_mout_aclk_300_gscl_mid.clk,
+ [1] = &exynos5_clk_mout_aclk_300_gscl_mid1.clk,
+};
+
+struct clksrc_sources exynos5_clkset_aclk_300_gscl_rev1 = {
+ .sources = exynos5_clkset_aclk_300_gscl_rev1_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_300_gscl_rev1_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl = {
+ .clk = {
+ .name = "mout_aclk_300_gscl",
+ },
+ .sources = &exynos5_clkset_aclk_300_gscl,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 25, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_aclk_300_gscl = {
+ .clk = {
+ .name = "dout_aclk_300_gscl",
+ .parent = &exynos5_clk_mout_aclk_300_gscl.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 12, .size = 3 },
+};
+
+/* Possible clock sources for aclk_300_gscl_sub Mux */
+static struct clk *clk_src_gscl_300_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &exynos5_clk_dout_aclk_300_gscl.clk,
+};
+
+static struct clksrc_sources clk_src_gscl_300 = {
+ .sources = clk_src_gscl_300_list,
+ .nr_sources = ARRAY_SIZE(clk_src_gscl_300_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_300_gscl = {
+ .clk = {
+ .name = "aclk_300_gscl",
+ },
+ .sources = &clk_src_gscl_300,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 10, .size = 1 },
+};
+
+/* For ACLK_266 */
+static struct clksrc_clk exynos5_clk_aclk_266 = {
+ .clk = {
+ .name = "aclk_266",
+ .parent = &exynos5_clk_mout_mpll_user.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 },
+};
+
+/* For ACLK_200 */
+static struct clksrc_clk exynos5_clk_aclk_200 = {
+ .clk = {
+ .name = "aclk_200",
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 },
+};
+
+/* For ACLK_166 */
+static struct clksrc_clk exynos5_clk_aclk_166 = {
+ .clk = {
+ .name = "aclk_166",
+ },
+ .sources = &exynos5_clkset_mout_aclk_333_166,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 },
+};
+
+/* For ACLK_66 */
+static struct clksrc_clk exynos5_clk_dout_aclk_66_pre = {
+ .clk = {
+ .name = "aclk_66_pre",
+ .parent = &exynos5_clk_mout_mpll_user.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_66 = {
+ .clk = {
+ .name = "aclk_66",
+ .parent = &exynos5_clk_dout_aclk_66_pre.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 },
+};
+
+static struct clk *clk_src_aclk_200_disp1_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &exynos5_clk_aclk_200.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_aclk_200_disp1 = {
+ .sources = clk_src_aclk_200_disp1_list,
+ .nr_sources = ARRAY_SIZE(clk_src_aclk_200_disp1_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_200_disp1 = {
+ .clk = {
+ .name = "aclk_200_disp1",
+ },
+ .sources = &exynos5_clkset_aclk_200_disp1,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 4, .size = 1 },
+};
+
+static struct clk exynos5_init_clocks[] = {
+ {
+ .name = "uart",
+ .devname = "s5pv210-uart.0",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.1",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.2",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.3",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.4",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "uart",
+ .devname = "s5pv210-uart.5",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 5),
+ },
+};
+
+
+/* TN Feature.. these clocks was enabled at booloader */
+
+static struct clk exynos5_init_clock_on[] = {
+ {
+ .name = "timers",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1<<24),
+ }, {
+ .name = "lcd",
+ .devname = "s3cfb.1",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = ((0x7 << 10) | (1 << 0)),
+ }, {
+ .name = "dp",
+ .devname = "s5p-dp",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+};
+
+static struct clk exynos5_init_clocks_off[] = {
+ {
+ .name = "watchdog",
+ .enable = exynos5_clk_ip_peris_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "hdmicec",
+ .enable = exynos5_clk_ip_peris_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "rtc",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peris_ctrl,
+ .ctrlbit = (1<<20),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.0",
+ .parent = &exynos5_clk_aclk_200.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.1",
+ .parent = &exynos5_clk_aclk_200.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.2",
+ .parent = &exynos5_clk_aclk_200.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 14),
+ }, {
+ .name = "hsmmc",
+ .devname = "s3c-sdhci.3",
+ .parent = &exynos5_clk_aclk_200.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "dwmci",
+ .parent = &exynos5_clk_aclk_200.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "sata",
+ .devname = "ahci",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "sata_phy",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 24),
+ }, {
+ .name = "sata_phy_i2c",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "usbdrd30",
+ .parent = &exynos5_clk_aclk_200.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "mfc",
+ .devname = "s3c-mfc",
+ .enable = exynos5_clk_ip_mfc_ctrl,
+ .ctrlbit = ((1 << 4) | (1 << 3) | (1 << 0)),
+ }, {
+ .name = "g3d",
+ .enable = exynos5_clk_ip_g3d_ctrl,
+ .ctrlbit = ((1 << 1) | (1 << 0)),
+ }, {
+ .name = "g3d",
+ .enable = exynos5_clk_ip_g3d_ctrl,
+ .ctrlbit = ((1 << 1) | (1 << 0)),
+ }, {
+ .name = "isp0",
+ .devname = "exynos5-fimc-is",
+ .enable = exynos5_clk_ip_isp0_ctrl,
+ .ctrlbit = (0xDFFFC0FF << 0),
+ }, {
+ .name = "isp1",
+ .devname = "exynos5-fimc-is",
+ .enable = exynos5_clk_ip_isp1_ctrl,
+ .ctrlbit = (0x3F07 << 0),
+ }, {
+ .name = "hdmi",
+ .devname = "exynos5-hdmi",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "mixer",
+ .devname = "s5p-mixer",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = ((0x3 << 13) | (1 << 5)),
+ }, {
+ .name = "hdmiphy",
+ .devname = "exynos5-hdmi",
+ .enable = exynos5_clk_hdmiphy_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "gscl",
+ .devname = "exynos-gsc.0",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = ((1 << 15) | (1 << 0)),
+ }, {
+ .name = "gscl",
+ .devname = "exynos-gsc.1",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = ((1 << 16) | (1 << 1)),
+ }, {
+ .name = "gscl",
+ .devname = "exynos-gsc.2",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = ((1 << 17) | (1 << 2)),
+ }, {
+ .name = "gscl",
+ .devname = "exynos-gsc.3",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = ((1 << 18) | (1 << 3)),
+ }, {
+ .name = "camif_top",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "gscl_wrap0",
+ .devname = "s5p-mipi-csis.0",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "gscl_wrap1",
+ .devname = "s5p-mipi-csis.1",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "rotator",
+ .devname = "exynos-rot",
+ .enable = exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = ((1 << 11) | (1 << 1)),
+ }, {
+ .name = "jpeg",
+ .enable = exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = ((1 << 12) | (1 << 2)),
+ }, {
+ .name = "dsim0",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.1",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.2",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "pcm",
+ .devname = "samsung-pcm.1",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "pcm",
+ .devname = "samsung-pcm.2",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "spdif",
+ .devname = "samsung-spdif",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "ac97",
+ .devname = "samsung-ac97",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(mfc_lr, 0),
+ .enable = &exynos5_clk_ip_mfc_ctrl,
+ .ctrlbit = (3 << 1),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(tv, 2),
+ .enable = &exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = (1 << 9)
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(jpeg, 3),
+ .enable = &exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(rot, 4),
+ .enable = &exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = (1 << 6)
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc0, 5),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc1, 6),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc2, 7),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(gsc3, 8),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
+ .enable = &exynos5_clk_ip_isp0_ctrl,
+ .ctrlbit = (0x3F << 8),
+ }, {
+ .name = SYSMMU_CLOCK_NAME2,
+ .devname = SYSMMU_CLOCK_DEVNAME(isp, 9),
+ .enable = &exynos5_clk_ip_isp1_ctrl,
+ .ctrlbit = (0xF << 4),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(camif0, 12),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(camif1, 13),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(camif2, 14),
+ .enable = &exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = SYSMMU_CLOCK_NAME,
+ .devname = SYSMMU_CLOCK_DEVNAME(2d, 15),
+ .enable = &exynos5_clk_ip_acp_ctrl,
+ .ctrlbit = (1 << 7)
+ }, {
+ .name = "usbhost",
+ .enable = exynos5_clk_ip_fsys_ctrl ,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "usbotg",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "fimg2d",
+ .devname = "s5p-fimg2d",
+ .enable = exynos5_clk_ip_acp_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "gps",
+ .enable = exynos5_clk_ip_gps_ctrl,
+ .ctrlbit = ((1 << 3) | (1 << 2) | (1 << 1) | (1 << 0)),
+ }, {
+ .name = "nfcon",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 22),
+ },
+#ifdef CONFIG_CPU_EXYNOS5250
+ {
+ .name = "iop",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = ((1 << 30) | (1 << 26) | (1 << 23)),
+ }, {
+ .name = "core_iop",
+ .enable = exynos5_clk_ip_core_ctrl,
+ .ctrlbit = ((1 << 21) | (1 << 3)),
+ }, {
+ .name = "mcu_iop",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "adc",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.0",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.1",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .devname = "s3c64xx-spi.2",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 18),
+ },
+#endif
+ {
+ .name = "ppmufsys",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = ((1 << 29) | (1 << 28)),
+ }, {
+ .name = "ppmudisp1",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = ((1 << 17) | (1 << 18)),
+ }, {
+ .name = "ppmumfc",
+ .enable = exynos5_clk_ip_mfc_ctrl,
+ .ctrlbit = ((1 << 5) | (1 << 6)),
+ }, {
+ .name = "ppmug3d",
+ .enable = exynos5_clk_ip_g3d_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "ppmugen",
+ .enable = exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "ppmugscl",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "acp",
+ .enable = exynos5_clk_ip_acp_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "rtic",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = ((1 << 11) | (1 << 9)),
+ }, {
+ .name = "disp1",
+ .enable = exynos5_clk_ip_disp1_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "gscl",
+ .enable = exynos5_clk_ip_gscl_ctrl,
+ .ctrlbit = ((0xF << 11) | (1 << 19)),
+ }, {
+ .name = "secss",
+ .parent = &exynos5_clk_aclk_acp.clk,
+ .enable = exynos5_clk_ip_acp_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "sromc",
+ .enable = exynos5_clk_ip_fsys_ctrl ,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "mipi-hsi",
+ .enable = exynos5_clk_ip_fsys_ctrl ,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "mie",
+ .enable = exynos5_clk_ip_disp1_ctrl ,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "clkout_cpu",
+ .enable = exynos5_clk_clkout_cpu_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_core",
+ .enable = exynos5_clk_clkout_core_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_acp",
+ .enable = exynos5_clk_clkout_acp_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_isp",
+ .enable = exynos5_clk_clkout_isp_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_top",
+ .enable = exynos5_clk_clkout_top_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_lex",
+ .enable = exynos5_clk_clkout_lex_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_r0x",
+ .enable = exynos5_clk_clkout_r0x_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_r1x",
+ .enable = exynos5_clk_clkout_r1x_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "clkout_cdrex",
+ .enable = exynos5_clk_clkout_cdrex_ctrl,
+ .ctrlbit = (1 << 16),
+ }
+};
+
+static struct clk exynos5_i2cs_clocks[] = {
+ {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.0",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.1",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.2",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.3",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.4",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.5",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.6",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-i2c.7",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "i2c",
+ .devname = "s3c2440-hdmiphy-i2c",
+ .parent = &exynos5_clk_aclk_66.clk,
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 14),
+ }
+};
+
+struct clk exynos5_uis_clocks[] = {
+ {
+ .name = "uis",
+ .devname = "s3c2440-uis.0",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "uis",
+ .devname = "exynos-uis.1",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 29),
+ }, {
+ .name = "uis",
+ .devname = "exynos-uis.2",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 30),
+ }, {
+ .name = "uis",
+ .devname = "exynos-uis.3",
+ .enable = exynos5_clk_ip_peric_ctrl,
+ .ctrlbit = (1 << 31),
+ },
+};
+
+struct clk exynos5_init_dmaclocks[] = {
+ {
+ .name = "pdma",
+ .devname = "s3c-pl330.0",
+ .enable = exynos5_clk_ip_gen_ctrl,
+ .ctrlbit = ((1 << 4) | (1 << 14)),
+ }, {
+ .name = "pdma",
+ .devname = "s3c-pl330.1",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "pdma",
+ .devname = "s3c-pl330.2",
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "pdma",
+ .enable = exynos5_clk_ip_acp_ctrl,
+ .ctrlbit = ((1 << 1) | (1 << 8)),
+ },
+};
+
+#ifndef CONFIG_SAMSUNG_C2C
+struct clk exynos5_c2c_clock = {
+ .name = "c2c",
+ .devname = "samsung-c2c",
+ .enable = exynos5_clk_ip_cpu_ctrl,
+ .ctrlbit = (0x3f << 11),
+};
+#endif
+
+static struct clk *clkset_sclk_audio0_list[] = {
+ [0] = &exynos5_clk_audiocdclk0.clk,
+ [1] = &clk_ext_xtal_mux,
+ [2] = &exynos5_clk_sclk_hdmi27m,
+ [3] = &exynos5_clk_sclk_dptxphy,
+ [4] = &exynos5_clk_sclk_usbphy,
+ [5] = &exynos5_clk_sclk_hdmiphy,
+ [6] = &exynos5_clk_mout_mpll.clk,
+ [7] = &exynos5_clk_mout_epll.clk,
+ [8] = &exynos5_clk_sclk_vpll.clk,
+ [9] = &exynos5_clk_mout_cpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_audio0 = {
+ .sources = clkset_sclk_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_audio0 = {
+ .clk = {
+ .name = "audio-bus",
+ .enable = exynos5_clksrc_mask_maudio_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos5_clkset_sclk_audio0,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_MAUDIO, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_MAUDIO, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos5_clkset_mout_audss_list[] = {
+ &clk_ext_xtal_mux,
+ &clk_fout_epll,
+};
+
+static struct clksrc_sources clkset_mout_audss = {
+ .sources = exynos5_clkset_mout_audss_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_mout_audss_list),
+};
+
+static struct clksrc_clk exynos5_clk_mout_audss = {
+ .clk = {
+ .name = "mout_audss",
+ },
+ .sources = &clkset_mout_audss,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 0, .size = 1 },
+};
+
+static struct clk *exynos5_clkset_sclk_audss_list[] = {
+ &exynos5_clk_mout_audss.clk,
+ &exynos5_clk_audiocdclk0.clk,
+ &exynos5_clk_sclk_audio0.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_audss = {
+ .sources = exynos5_clkset_sclk_audss_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_audss_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_audss_i2s = {
+ .clk = {
+ .name = "i2sclk",
+ .enable = exynos5_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_I2SSPECIAL,
+ },
+ .sources = &exynos5_clkset_sclk_audss,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 2, .size = 2 },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_audss_srp = {
+ .clk = {
+ .name = "dout_srp",
+ .parent = &exynos5_clk_mout_audss.clk,
+ },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_audss_bus = {
+ .clk = {
+ .name = "busclk",
+ .parent = &exynos5_clk_dout_audss_srp.clk,
+ .enable = exynos5_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_I2SBUS,
+ },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 4, .size = 4 },
+};
+
+static struct clk exynos5_init_audss_clocks[] = {
+ {
+ .name = "srpclk",
+ .parent = &exynos5_clk_dout_audss_srp.clk,
+ .enable = exynos5_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_RP | S5P_AUDSS_CLKGATE_UART
+ | S5P_AUDSS_CLKGATE_TIMER,
+ }, {
+ .name = "iis",
+ .devname = "samsung-i2s.0",
+ .enable = exynos5_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_I2SSPECIAL |
+ S5P_AUDSS_CLKGATE_I2SBUS,
+ }, {
+ .name = "pcm",
+ .devname = "samsung-pcm.0",
+ .enable = exynos5_clk_audss_ctrl,
+ .ctrlbit = S5P_AUDSS_CLKGATE_PCMSPECIAL |
+ S5P_AUDSS_CLKGATE_PCMBUS,
+ },
+};
+
+static struct clk *exynos5_clkset_sclk_audio1_list[] = {
+ [0] = &exynos5_clk_audiocdclk1,
+ [1] = &clk_ext_xtal_mux,
+ [2] = &exynos5_clk_sclk_hdmi27m,
+ [3] = &exynos5_clk_sclk_dptxphy,
+ [4] = &exynos5_clk_sclk_usbphy,
+ [5] = &exynos5_clk_sclk_hdmiphy,
+ [6] = &exynos5_clk_mout_mpll.clk,
+ [7] = &exynos5_clk_mout_epll.clk,
+ [8] = &exynos5_clk_sclk_vpll.clk,
+ [9] = &exynos5_clk_mout_cpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_audio1 = {
+ .sources = exynos5_clkset_sclk_audio1_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_audio1_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_audio1 = {
+ .clk = {
+ .name = "audio-bus1",
+ .enable = exynos5_clksrc_mask_peric1_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos5_clkset_sclk_audio1,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC4, .shift = 0, .size = 4 },
+};
+
+static struct clk *exynos5_clkset_sclk_audio2_list[] = {
+ [0] = &exynos5_clk_audiocdclk2,
+ [1] = &clk_ext_xtal_mux,
+ [2] = &exynos5_clk_sclk_hdmi27m,
+ [3] = &exynos5_clk_sclk_dptxphy,
+ [4] = &exynos5_clk_sclk_usbphy,
+ [5] = &exynos5_clk_sclk_hdmiphy,
+ [6] = &exynos5_clk_mout_mpll.clk,
+ [7] = &exynos5_clk_mout_epll.clk,
+ [8] = &exynos5_clk_sclk_vpll.clk,
+ [9] = &exynos5_clk_mout_cpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_audio2 = {
+ .sources = exynos5_clkset_sclk_audio2_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_audio2_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_audio2 = {
+ .clk = {
+ .name = "audio-bus2",
+ .enable = exynos5_clksrc_mask_peric1_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos5_clkset_sclk_audio2,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC4, .shift = 16, .size = 4 },
+};
+
+static struct clk *exynos5_clkset_sclk_spdif_list[] = {
+ [0] = &exynos5_clk_sclk_audio0.clk,
+ [1] = &exynos5_clk_sclk_audio1.clk,
+ [2] = &exynos5_clk_sclk_audio2.clk,
+ [3] = &exynos5_clk_spdifcdclk,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_spdif = {
+ .sources = exynos5_clkset_sclk_spdif_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_sclk_spdif_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_spdif = {
+ .clk = {
+ .name = "sclk_spdif",
+ .enable = exynos5_clksrc_mask_peric1_ctrl,
+ .ctrlbit = (1 << 8),
+ .ops = &s5p_sclk_spdif_ops,
+ },
+ .sources = &exynos5_clkset_sclk_spdif,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 8, .size = 2 },
+};
+
+struct clk *exynos5_clkset_usbdrd30_list[] = {
+ [0] = &exynos5_clk_mout_mpll.clk,
+ [1] = &exynos5_clk_mout_cpll.clk,
+};
+
+struct clksrc_sources exynos5_clkset_usbdrd30 = {
+ .sources = exynos5_clkset_usbdrd30_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_usbdrd30_list),
+};
+
+struct clk *exynos5_clkset_group_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = NULL,
+ [2] = &exynos5_clk_sclk_hdmi24m,
+ [3] = &exynos5_clk_sclk_dptxphy,
+ [4] = &exynos5_clk_sclk_usbphy,
+ [5] = &exynos5_clk_sclk_hdmiphy,
+ [6] = &exynos5_clk_mout_mpll_user.clk,
+ [7] = &exynos5_clk_mout_epll.clk,
+ [8] = &exynos5_clk_sclk_vpll.clk,
+ [9] = &exynos5_clk_mout_cpll.clk,
+};
+
+struct clksrc_sources exynos5_clkset_group = {
+ .sources = exynos5_clkset_group_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_group_list),
+};
+
+/* Possible clock sources for aclk_266_gscl_sub Mux */
+static struct clk *clk_src_gscl_266_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &exynos5_clk_aclk_266.clk,
+};
+
+static struct clksrc_sources clk_src_gscl_266 = {
+ .sources = clk_src_gscl_266_list,
+ .nr_sources = ARRAY_SIZE(clk_src_gscl_266_list),
+};
+
+/* For ACLK_400_ISP */
+static struct clksrc_clk exynos5_clk_mout_aclk_400_isp = {
+ .clk = {
+ .name = "mout_aclk_400_isp",
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_dout_aclk_400_isp = {
+ .clk = {
+ .name = "dout_aclk_400_isp",
+ .parent = &exynos5_clk_mout_aclk_400_isp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 20, .size = 3 },
+};
+
+static struct clk *exynos5_clkset_aclk_400_isp_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &exynos5_clk_dout_aclk_400_isp.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_aclk_400_isp = {
+ .sources = exynos5_clkset_aclk_400_isp_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_400_isp_list),
+};
+
+static struct clksrc_clk exynos5_clk_aclk_400_isp = {
+ .clk = {
+ .name = "aclk_400_isp",
+ },
+ .sources = &exynos5_clkset_aclk_400_isp,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 20, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_uart_isp = {
+ .clk = {
+ .name = "sclk_uart_src_isp",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_SCLK_SRC_ISP, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_266_isp = {
+ .clk = {
+ .name = "aclk_266_isp",
+
+ },
+ .sources = &clk_src_gscl_266,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
+ .clk = {
+ .name = "sclk_mmc0",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
+ .clk = {
+ .name = "sclk_mmc1",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
+ .clk = {
+ .name = "sclk_mmc2",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
+ .clk = {
+ .name = "sclk_mmc3",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_mmc4 = {
+ .clk = {
+ .name = "sclk_mmc4",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_spi0 = {
+ .clk = {
+ .name = "sclk_spi0",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_spi1 = {
+ .clk = {
+ .name = "sclk_spi1",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 20, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_spi2 = {
+ .clk = {
+ .name = "sclk_spi2",
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 0, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clksrcs[] = {
+ {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.0",
+ .enable = exynos5_clksrc_mask_peric0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0,
+ .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0,
+ .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.1",
+ .enable = exynos5_clksrc_mask_peric0_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0,
+ .shift = 4, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0,
+ .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.2",
+ .enable = exynos5_clksrc_mask_peric0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .devname = "s5pv210-uart.3",
+ .enable = exynos5_clksrc_mask_peric0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_usbdrd30",
+ .enable = exynos5_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 28),
+ },
+ .sources = &exynos5_clkset_usbdrd30,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 28, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.0",
+ .parent = &exynos5_clk_sclk_mmc0.clk,
+ .enable = exynos5_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.1",
+ .parent = &exynos5_clk_sclk_mmc1.clk,
+ .enable = exynos5_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.2",
+ .parent = &exynos5_clk_sclk_mmc2.clk,
+ .enable = exynos5_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .devname = "s3c-sdhci.3",
+ .parent = &exynos5_clk_sclk_mmc3.clk,
+ .enable = exynos5_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_dwmci",
+ .parent = &exynos5_clk_sclk_mmc4.clk,
+ .enable = exynos5_clksrc_mask_fsys_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_pcm",
+ .parent = &exynos5_clk_sclk_audio0.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_MAUDIO, .shift = 4, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_pcm",
+ .parent = &exynos5_clk_sclk_audio1.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC4, .shift = 4, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_pcm",
+ .parent = &exynos5_clk_sclk_audio2.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC4, .shift = 20, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_i2s",
+ .parent = &exynos5_clk_sclk_audio1.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC5, .shift = 0, .size = 6 },
+ }, {
+ .clk = {
+ .name = "sclk_i2s",
+ .parent = &exynos5_clk_sclk_audio2.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC5, .shift = 8, .size = 6 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .devname = "s3cfb.1",
+ .enable = exynos5_clksrc_mask_disp1_0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "aclk_266_gscl",
+ .parent = &exynos5_clk_aclk_266.clk,
+ },
+ .sources = &clk_src_gscl_266,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
+ }, {
+ .clk = {
+ .name = "sclk_g3d",
+ .devname = "mali-t604.0",
+ .enable = exynos5_clk_gate_block,
+ .ctrlbit = (1 << 1),
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_sata",
+ .devname = "ahci",
+ .parent = &exynos5_clk_mout_mpll_user.clk,
+ .enable = exynos5_clk_ip_fsys_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos5_clkset_aclk,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_gscl_wrap0",
+ .devname = "s5p-mipi-csis.0",
+ .enable = exynos5_clksrc_mask_gscl_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_gscl_wrap1",
+ .devname = "s5p-mipi-csis.1",
+ .enable = exynos5_clksrc_mask_gscl_ctrl,
+ .ctrlbit = (1 << 28),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam0",
+ .enable = exynos5_clksrc_mask_gscl_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam1",
+ .enable = exynos5_clksrc_mask_gscl_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "aclk_266_isp_div0",
+ .parent = &exynos5_clk_aclk_266_isp.clk,
+
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ISP0, .shift = 0, .size = 3 },
+ }, {
+ .clk = {
+ .name = "aclk_266_isp_div1",
+ .parent = &exynos5_clk_aclk_266_isp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ISP0, .shift = 4, .size = 3 },
+ }, {
+ .clk = {
+ .name = "aclk_266_isp_divmpwm",
+ .parent = &exynos5_clk_aclk_266_isp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ISP2, .shift = 0, .size = 3 },
+ }, {
+ .clk = {
+ .name = "aclk_400_isp_div0",
+ .parent = &exynos5_clk_aclk_400_isp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ISP1, .shift = 0, .size = 3 },
+ }, {
+ .clk = {
+ .name = "aclk_400_isp_div1",
+ .parent = &exynos5_clk_aclk_400_isp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_ISP1, .shift = 4, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_uart_isp",
+ .parent = &exynos5_clk_sclk_uart_isp.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_SCLK_DIV_ISP, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.0",
+ .parent = &exynos5_clk_sclk_spi0.clk,
+ .enable = exynos5_clksrc_mask_peric1_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 8, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.1",
+ .parent = &exynos5_clk_sclk_spi1.clk,
+ .enable = exynos5_clksrc_mask_peric1_ctrl,
+ .ctrlbit = (1 << 20),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 24, .size = 8 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .devname = "s3c64xx-spi.2",
+ .parent = &exynos5_clk_sclk_spi2.clk,
+ .enable = exynos5_clksrc_mask_peric1_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 8, .size = 8 },
+ },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_jpeg = {
+ .clk = {
+ .name = "sclk_jpeg",
+ .enable = exynos5_clksrc_mask_gen_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &exynos5_clkset_group,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_GEN, .shift = 0, .size = 4 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk exynos5_clk_sclk_c2c = {
+ .clk = {
+ .name = "sclk_c2c",
+ .id = -1,
+ },
+ .sources = &exynos5_clkset_mout_mpll,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_SYSRGT, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_c2c = {
+ .clk = {
+ .name = "aclk_c2c",
+ .id = -1,
+ .parent = &exynos5_clk_sclk_c2c.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_SYSRGT, .shift = 8, .size = 3 },
+};
+
+static struct clk *exynos5_clkset_c2c_list[] = {
+ [0] = &exynos5_clk_mout_mpll.clk,
+ [1] = &exynos5_clk_mout_bpll.clk,
+};
+
+static struct clksrc_sources exynos5_clkset_sclk_c2c = {
+ .sources = exynos5_clkset_c2c_list,
+ .nr_sources = ARRAY_SIZE(exynos5_clkset_c2c_list),
+};
+
+static struct clksrc_clk exynos5_clk_sclk_c2c_rev0 = {
+ .clk = {
+ .name = "sclk_c2c",
+ .id = -1,
+ },
+ .sources = &exynos5_clkset_sclk_c2c,
+ .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 12, .size = 1 },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk exynos5_clk_aclk_c2c_rev0 = {
+ .clk = {
+ .name = "aclk_c2c",
+ .id = -1,
+ .parent = &exynos5_clk_sclk_c2c.clk,
+ },
+ .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 12, .size = 3 },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *exynos5_sysclks[] = {
+ &exynos5_clk_audiocdclk0,
+ &exynos5_clk_mout_apll,
+ &exynos5_clk_sclk_apll,
+ &exynos5_clk_mout_bpll,
+ &exynos5_clk_mout_bpll_user,
+ &exynos5_clk_mout_gpll,
+ &exynos5_clk_mout_cpll,
+ &exynos5_clk_mout_epll,
+ &exynos5_clk_mout_mpll_fout,
+ &exynos5_clk_mout_bpll_fout,
+ &exynos5_clk_mout_mpll,
+ &exynos5_clk_mout_mpll_user,
+ &exynos5_clk_mout_vpllsrc,
+ &exynos5_clk_sclk_vpll,
+ &exynos5_clk_mout_cpu,
+ &exynos5_clk_dout_armclk,
+ &exynos5_clk_dout_arm2clk,
+ &exynos5_clk_mclk_cdrex,
+ &exynos5_clk_aclk_400,
+ &exynos5_clk_aclk_400_g3d_mid,
+ &exynos5_clk_mout_aclk_333,
+ &exynos5_clk_dout_aclk_333,
+ &exynos5_clk_aclk_333,
+ &exynos5_clk_mout_aclk_300_disp1_mid,
+ &exynos5_clk_mout_aclk_300_disp1_mid1,
+ &exynos5_clk_mout_aclk_300_disp1,
+ &exynos5_clk_dout_aclk_300_disp1,
+ &exynos5_clk_aclk_300_disp1,
+ &exynos5_clk_mout_aclk_300_gscl_mid,
+ &exynos5_clk_mout_aclk_300_gscl_mid1,
+ &exynos5_clk_mout_aclk_300_gscl,
+ &exynos5_clk_dout_aclk_300_gscl,
+ &exynos5_clk_aclk_300_gscl,
+ &exynos5_clk_aclk_266,
+ &exynos5_clk_aclk_200,
+ &exynos5_clk_aclk_166,
+ &exynos5_clk_dout_aclk_66_pre,
+ &exynos5_clk_aclk_200_disp1,
+ &exynos5_clk_mout_aclk_400_isp,
+ &exynos5_clk_dout_aclk_400_isp,
+ &exynos5_clk_aclk_400_isp,
+ &exynos5_clk_aclk_66,
+ &exynos5_clk_sclk_mmc0,
+ &exynos5_clk_sclk_mmc1,
+ &exynos5_clk_sclk_mmc2,
+ &exynos5_clk_sclk_mmc3,
+ &exynos5_clk_sclk_mmc4,
+ &exynos5_clk_mout_audss,
+ &exynos5_clk_sclk_audss_bus,
+ &exynos5_clk_sclk_audss_i2s,
+ &exynos5_clk_dout_audss_srp,
+ &exynos5_clk_sclk_audio0,
+ &exynos5_clk_sclk_audio1,
+ &exynos5_clk_sclk_audio2,
+ &exynos5_clk_sclk_spdif,
+ &exynos5_clk_aclk_acp,
+ &exynos5_clk_pclk_acp,
+ &exynos5_clk_aclk_266_isp,
+ &exynos5_clk_sclk_uart_isp,
+ &exynos5_clk_sclk_c2c,
+ &exynos5_clk_aclk_c2c,
+ &exynos5_clk_sclk_spi0,
+ &exynos5_clk_sclk_spi1,
+ &exynos5_clk_sclk_spi2,
+ &exynos5_clk_sclk_jpeg,
+};
+
+static unsigned long exynos5_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static struct clk *exynos5_clks[] __initdata = {
+ &exynos5_clk_sclk_hdmi27m,
+ &exynos5_clk_sclk_hdmiphy,
+ &clk_fout_bpll,
+ &clk_fout_cpll,
+ &clk_fout_mpll_div2,
+ &clk_fout_bpll_div2,
+ &clk_fout_gpll,
+ &exynos5_clk_armclk,
+};
+
+static u32 epll_div[][6] = {
+ { 192000000, 0, 48, 3, 1, 0 },
+ { 180000000, 0, 45, 3, 1, 0 },
+ { 73728000, 1, 73, 3, 3, 47710 },
+ { 67737600, 1, 90, 4, 3, 20762 },
+ { 49152000, 0, 49, 3, 3, 9961 },
+ { 45158400, 0, 45, 3, 3, 10381 },
+ { 180633600, 0, 45, 3, 1, 10381 },
+};
+
+static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+ unsigned int tmp;
+ unsigned int epll_rate;
+ unsigned int locktime;
+ unsigned int lockcnt;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ if (clk->parent)
+ epll_rate = clk_get_rate(clk->parent);
+ else
+ epll_rate = clk_ext_xtal_mux.rate;
+
+ if (epll_rate != 24000000) {
+ pr_err("Invalid Clock : recommended clock is 24MHz.\n");
+ return -EINVAL;
+ }
+
+ epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
+ epll_con &= ~(0x1 << 27 | \
+ PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \
+ PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
+ PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k = epll_div[i][5] << 0;
+ epll_con |= epll_div[i][1] << 27;
+ epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
+ epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
+ epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ epll_rate /= 1000000;
+
+ /* 3000 max_cycls : specification data */
+ locktime = 3000 / epll_rate * epll_div[i][3];
+ lockcnt = locktime * 10000 / (10000 / epll_rate);
+
+ __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
+
+ __raw_writel(epll_con, EXYNOS5_EPLL_CON0);
+ __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_EPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops exynos5_epll_ops = {
+ .get_rate = exynos5_epll_get_rate,
+ .set_rate = exynos5_epll_set_rate,
+};
+
+static int xtal_rate;
+
+static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
+{
+ return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
+}
+
+static struct clk_ops exynos5_fout_apll_ops = {
+ .get_rate = exynos5_fout_apll_get_rate,
+};
+
+static struct vpll_div_data exynos5_vpll_div[] = {
+ {268000000, 6, 268, 2, 41104, 0, 0, 0},
+ {86000000, 6, 344, 4, 2936, 0, 0, 0},
+};
+
+static unsigned long exynos5_vpll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos5_vpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int vpll_con0, vpll_con1;
+ unsigned int tmp;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ vpll_con0 = __raw_readl(EXYNOS5_VPLL_CON0);
+ vpll_con0 &= ~(PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT | \
+ PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT | \
+ PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
+
+ vpll_con1 = __raw_readl(EXYNOS5_VPLL_CON1);
+ vpll_con1 &= ~(0xffff << 0);
+#if 0
+ for (i = 0; i < ARRAY_SIZE(exynos5_vpll_div); i++) {
+ if (exynos5_vpll_div[i].rate == rate) {
+ vpll_con0 |= exynos5_vpll_div[i].pdiv << PLL36XX_PDIV_SHIFT;
+ vpll_con0 |= exynos5_vpll_div[i].mdiv << PLL36XX_MDIV_SHIFT;
+ vpll_con0 |= exynos5_vpll_div[i].sdiv << PLL36XX_SDIV_SHIFT;
+ vpll_con1 |= exynos5_vpll_div[i].k << 0;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(exynos5_vpll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* 3000 max_cycls : specification data */
+ locktime = 3000 * exynos5_vpll_div[i].pdiv + 1;
+
+ __raw_writel(locktime, EXYNOS5_VPLL_LOCK);
+#endif
+#if defined(CONFIG_DP_40HZ_P11) || defined(CONFIG_DP_40HZ_P10)
+ vpll_con0 = 0xA0b30602;
+ vpll_con1 = 0x15b5;
+#elif defined(CONFIG_DP_60HZ_P11) || defined(CONFIG_DP_60HZ_P10)
+ vpll_con0 = 0xA10c0602;
+ vpll_con1 = 0xA090;
+#endif
+
+
+ __raw_writel(vpll_con0, EXYNOS5_VPLL_CON0);
+ __raw_writel(vpll_con1, EXYNOS5_VPLL_CON1);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_VPLL_CON0);
+ } while (!(tmp & (0x1 << EXYNOS5_VPLLCON0_LOCKED_SHIFT)));
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops exynos5_vpll_ops = {
+ .get_rate = exynos5_vpll_get_rate,
+ .set_rate = exynos5_vpll_set_rate,
+};
+
+static u32 exynos5_gpll_div[][6] = {
+ /*rate, P, M, S, AFC_DNB, AFC*/
+ {1400000000, 3, 175, 0, 0, 0}, /* for 466MHz */
+ {800000000, 3, 100, 0, 0, 0}, /* for 400MHz, 200MHz */
+ {667000000, 7, 389, 1, 0, 0}, /* for 333MHz, 222MHz, 166MHz */
+ {600000000, 4, 200, 1, 0, 0}, /* for 300MHz, 200MHz, 150MHz */
+ {533000000, 12, 533, 1, 0, 0}, /* for 533MHz, 266MHz, 133MHz */
+ {450000000, 12, 450, 1, 0, 0}, /* for 450 Hz */
+ {400000000, 3, 100, 1, 0, 0},
+ {333000000, 4, 222, 2, 0, 0},
+ {200000000, 3, 100, 2, 0, 0},
+};
+
+static unsigned long exynos5_gpll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static int exynos5_gpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int gpll_con0;
+ unsigned int locktime;
+ unsigned int tmp;
+ unsigned int i;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ gpll_con0 = __raw_readl(EXYNOS5_GPLL_CON0);
+ gpll_con0 &= ~(PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT | \
+ PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT | \
+ PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(exynos5_gpll_div); i++) {
+ if (exynos5_gpll_div[i][0] == rate) {
+ gpll_con0 |= exynos5_gpll_div[i][1] << PLL35XX_PDIV_SHIFT;
+ gpll_con0 |= exynos5_gpll_div[i][2] << PLL35XX_MDIV_SHIFT;
+ gpll_con0 |= exynos5_gpll_div[i][3] << PLL35XX_SDIV_SHIFT;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(exynos5_gpll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock GPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* 250 max_cycls : specification data */
+ /* 270@p=1, 1cycle=1/24=41.6ns */
+ /* calc >> p=5, 270 * 5 = 1350cycle * 41.6ns = 56.16us */
+
+ locktime = 270 * exynos5_gpll_div[i][1] + 1;
+
+ __raw_writel(locktime, EXYNOS5_GPLL_LOCK);
+
+ __raw_writel(gpll_con0, EXYNOS5_GPLL_CON0);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_GPLL_CON0);
+ } while (!(tmp & (0x1 << EXYNOS5_GPLLCON0_LOCKED_SHIFT)));
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops exynos5_gpll_ops = {
+ .get_rate = exynos5_gpll_get_rate,
+ .set_rate = exynos5_gpll_set_rate,
+};
+
+#ifdef CONFIG_PM
+static int exynos5_clock_suspend(void)
+{
+ s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0)
+ s3c_pm_do_save(exynos5250_clock_save_rev0,
+ ARRAY_SIZE(exynos5250_clock_save_rev0));
+
+ s3c_pm_do_save(exynos5_epll_save, ARRAY_SIZE(exynos5_epll_save));
+ s3c_pm_do_save(exynos5_vpll_save, ARRAY_SIZE(exynos5_vpll_save));
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ s3c_pm_do_save(exynos5_gpll_save, ARRAY_SIZE(exynos5_gpll_save));
+ return 0;
+}
+
+static void exynos5_clock_resume(void)
+{
+ unsigned int tmp;
+
+ s3c_pm_do_restore_core(exynos5_epll_save, ARRAY_SIZE(exynos5_epll_save));
+ s3c_pm_do_restore_core(exynos5_vpll_save, ARRAY_SIZE(exynos5_vpll_save));
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ s3c_pm_do_restore_core(exynos5_gpll_save, ARRAY_SIZE(exynos5_gpll_save));
+
+ /* waiting epll & vpll locking time */
+ do {
+ tmp = __raw_readl(EXYNOS5_EPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
+
+ do {
+ tmp = __raw_readl(EXYNOS5_VPLL_CON0);
+ } while (!(tmp & 0x1 << EXYNOS5_VPLLCON0_LOCKED_SHIFT));
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ do {
+ tmp = __raw_readl(EXYNOS5_GPLL_CON0);
+ } while (!(tmp & (0x1 << EXYNOS5_GPLLCON0_LOCKED_SHIFT)));
+ }
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0)
+ s3c_pm_do_restore_core(exynos5250_clock_save_rev0,
+ ARRAY_SIZE(exynos5250_clock_save_rev0));
+
+ s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
+}
+#else
+#define exynos5_clock_suspend NULL
+#define exynos5_clock_resume NULL
+#endif
+
+struct syscore_ops exynos5_clock_syscore_ops = {
+ .suspend = exynos5_clock_suspend,
+ .resume = exynos5_clock_resume,
+};
+
+void __init_or_cpufreq exynos5_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long apll;
+ unsigned long bpll;
+ unsigned long cpll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned long vpll;
+ unsigned long gpll;
+ unsigned long vpllsrc;
+ unsigned long xtal;
+ unsigned long armclk;
+ unsigned long mclk_cdrex;
+ unsigned long aclk_400;
+ unsigned long aclk_333;
+ unsigned long aclk_266;
+ unsigned long aclk_200;
+ unsigned long aclk_166;
+ unsigned long aclk_66;
+ unsigned int ptr;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+
+ xtal_rate = xtal;
+
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+#if defined(CONFIG_MACH_P10_DP_01)
+ /* setting vpll 268627200 Hz */
+ if (exynos5_vpll_set_rate(&clk_fout_vpll, 268000000))
+ printk(KERN_ERR "Unable to set %s of clock vpll.\n", clk_fout_vpll.name);
+#elif defined(CONFIG_MACH_P10_DP_00)
+ /* setting vpll 86011199 Hz */
+ if (exynos5_vpll_set_rate(&clk_fout_vpll, 86000000))
+ printk(KERN_ERR "Unable to set %s of clock vpll.\n", clk_fout_vpll.name);
+#endif
+
+ /* Set and check PLLs */
+ apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
+ bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
+ cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
+ mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
+ epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
+ __raw_readl(EXYNOS5_EPLL_CON1));
+
+ if ((soc_is_exynos5250() && samsung_rev() >= EXYNOS5250_REV_1_0))
+ gpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_GPLL_CON0));
+ else
+ gpll = 0;
+
+ vpllsrc = clk_get_rate(&exynos5_clk_mout_vpllsrc.clk);
+ vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
+ __raw_readl(EXYNOS5_VPLL_CON1));
+
+ clk_fout_apll.ops = &exynos5_fout_apll_ops;
+ clk_fout_bpll.rate = bpll;
+ clk_fout_bpll_div2.rate = bpll / 2;
+ clk_fout_cpll.rate = cpll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_mpll_div2.rate = mpll / 2;
+ clk_fout_epll.rate = epll;
+ clk_fout_vpll.rate = vpll;
+
+ if (soc_is_exynos5250() && samsung_rev() >= EXYNOS5250_REV_1_0) {
+ gpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_GPLL_CON0));
+ clk_fout_gpll.rate = gpll;
+
+ printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
+ "M=%ld, E=%ld, V=%ld, G=%ld\n",
+ apll, bpll, cpll, mpll, epll, vpll, gpll);
+ } else {
+ printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
+ "M=%ld, E=%ld, V=%ld\n",
+ apll, bpll, cpll, mpll, epll, vpll);
+ }
+
+ /* Set parent for bus clocks */
+ if ((soc_is_exynos5250() && samsung_rev() >= EXYNOS5250_REV_1_0))
+ clk_set_parent(&exynos5_clk_mout_mpll.clk,
+ &exynos5_clk_mout_mpll_fout.clk);
+
+ armclk = clk_get_rate(&exynos5_clk_armclk);
+ mclk_cdrex = clk_get_rate(&exynos5_clk_mclk_cdrex.clk);
+
+ aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
+ aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
+ aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
+ aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
+ aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
+ aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
+
+ printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
+ "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
+ "ACLK166=%ld, ACLK66=%ld\n",
+ armclk, mclk_cdrex, aclk_400,
+ aclk_333, aclk_266, aclk_200,
+ aclk_166, aclk_66);
+
+ clk_fout_epll.ops = &exynos5_epll_ops;
+ clk_fout_vpll.ops = &exynos5_vpll_ops;
+ clk_fout_gpll.ops = &exynos5_gpll_ops;
+
+ if (clk_set_parent(&exynos5_clk_mout_audss.clk, &clk_fout_epll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ clk_fout_epll.name, exynos5_clk_mout_audss.clk.name);
+#if defined(CONFIG_SND_SAMSUNG_PCM) && !defined(CONFIG_SND_SAMSUNG_PCM_USE_EPLL)
+ if (clk_set_parent(&exynos5_clk_sclk_audio0.clk, &exynos5_clk_audiocdclk0.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_audiocdclk0.clk.name, exynos5_clk_sclk_audio0.clk.name);
+#else
+ if (clk_set_parent(&exynos5_clk_sclk_audio0.clk, &exynos5_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_mout_epll.clk.name, exynos5_clk_sclk_audio0.clk.name);
+#endif
+ if (clk_set_parent(&exynos5_clk_sclk_audio1.clk, &exynos5_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_mout_epll.clk.name, exynos5_clk_sclk_audio1.clk.name);
+ if (clk_set_parent(&exynos5_clk_sclk_audio2.clk, &exynos5_clk_mout_epll.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_mout_epll.clk.name, exynos5_clk_sclk_audio2.clk.name);
+ if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
+
+ if (clk_set_parent(&exynos5_clk_mout_aclk_400_isp.clk, &exynos5_clk_mout_mpll_user.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_mout_mpll_user.clk.name, exynos5_clk_mout_aclk_400_isp.clk.name);
+ if (clk_set_parent(&exynos5_clk_aclk_266_isp.clk, &exynos5_clk_aclk_266.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_aclk_266.clk.name, exynos5_clk_aclk_266_isp.clk.name);
+ if (clk_set_parent(&exynos5_clk_aclk_400_isp.clk, &exynos5_clk_dout_aclk_400_isp.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_mout_aclk_400_isp.clk.name, exynos5_clk_aclk_400_isp.clk.name);
+ if (clk_set_parent(&exynos5_clk_sclk_uart_isp.clk, &exynos5_clk_mout_mpll_user.clk))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ exynos5_clk_mout_mpll_user.clk.name, exynos5_clk_sclk_uart_isp.clk.name);
+
+ clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
+ clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
+
+ clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
+ clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
+ s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
+}
+
+void __init exynos5_register_clocks(void)
+{
+ int ptr;
+
+ if (soc_is_exynos5250() && samsung_rev() >= EXYNOS5250_REV_1_0) {
+ exynos5_clk_mout_mpll.sources = &exynos5_clkset_mout_mpll;
+ exynos5_clk_mout_bpll.sources = &exynos5_clkset_mout_bpll;
+ exynos5_clk_aclk_400.sources = &exynos5_clkset_aclk_g3d;
+ exynos5_clk_mout_aclk_300_gscl.sources = &exynos5_clkset_aclk_300_gscl_rev1;
+ exynos5_clk_mout_aclk_300_disp1.sources = &exynos5_clkset_mout_aclk_300_disp1_rev1;
+ } else if (soc_is_exynos5250() && samsung_rev() < EXYNOS5250_REV_1_0) {
+ exynos5_clk_sclk_jpeg.sources = NULL;
+ exynos5_clk_sclk_jpeg.reg_src.reg = 0;
+ exynos5_clk_sclk_jpeg.clk.parent = &exynos5_clk_mout_cpll.clk;
+ exynos5_clk_sclk_jpeg.clk.enable = NULL;
+ exynos5_clk_sclk_jpeg.clk.ctrlbit = 0;
+ }
+
+ s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
+ s3c_register_clksrc(exynos5_sysclks[ptr], 1);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
+ s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
+
+ s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
+ s3c_register_clocks(exynos5_init_clocks, ARRAY_SIZE(exynos5_init_clocks));
+
+ s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
+ s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
+
+ /* TN Feature.. these clocks was enabled at booloader */
+ s3c_register_clocks(exynos5_init_clock_on, ARRAY_SIZE(exynos5_init_clock_on));
+
+ s3c_register_clocks(exynos5_init_audss_clocks, ARRAY_SIZE(exynos5_init_audss_clocks));
+ s3c_disable_clocks(exynos5_init_audss_clocks, ARRAY_SIZE(exynos5_init_audss_clocks));
+
+ if (soc_is_exynos5250() && (samsung_rev() < EXYNOS5250_REV_1_0))
+ exynos5_init_dmaclocks[2].ctrlbit = exynos5_init_dmaclocks[1].ctrlbit;
+ s3c_register_clocks(exynos5_init_dmaclocks, ARRAY_SIZE(exynos5_init_dmaclocks));
+ s3c_disable_clocks(exynos5_init_dmaclocks, ARRAY_SIZE(exynos5_init_dmaclocks));
+
+ s3c_register_clocks(exynos5_i2cs_clocks, ARRAY_SIZE(exynos5_i2cs_clocks));
+ s3c_disable_clocks(exynos5_i2cs_clocks, ARRAY_SIZE(exynos5_i2cs_clocks));
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ s3c_register_clocks(exynos5_uis_clocks, ARRAY_SIZE(exynos5_uis_clocks));
+ s3c_disable_clocks(exynos5_uis_clocks, ARRAY_SIZE(exynos5_uis_clocks));
+ }
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ s3c_register_clksrc(&exynos5_clk_sclk_c2c_rev0, 1);
+ s3c_register_clksrc(&exynos5_clk_aclk_c2c_rev0, 1);
+ }
+
+#ifndef CONFIG_SAMSUNG_C2C
+ if (soc_is_exynos5250() && (samsung_rev() >= EXYNOS5250_REV_1_0)) {
+ exynos5_c2c_clock.enable = exynos5_clk_ip_sysrgt_ctrl;
+ exynos5_c2c_clock.ctrlbit = ((1 << 2) | (1 << 1));
+ }
+
+ s3c24xx_register_clock(&exynos5_c2c_clock);
+ s3c_disable_clocks(&exynos5_c2c_clock, 1);
+#endif
+
+ register_syscore_ops(&exynos5_clock_syscore_ops);
+ s3c_pwmclk_init();
+}
+
+static int __init clock_domain_init(void)
+{
+ int index;
+
+ /* Add dma clock */
+ for (index = 0; index < ARRAY_SIZE(exynos5_init_dmaclocks); index++)
+ clock_add_domain(LPA_DOMAIN, &exynos5_init_dmaclocks[index]);
+
+ /* Add i2c clock */
+ for (index = 0; index < ARRAY_SIZE(exynos5_i2cs_clocks); index++)
+ clock_add_domain(LPA_DOMAIN, &exynos5_i2cs_clocks[index]);
+
+ return 0;
+}
+late_initcall(clock_domain_init);
diff --git a/arch/arm/mach-exynos/cpu-exynos4.c b/arch/arm/mach-exynos/cpu-exynos4.c
new file mode 100644
index 0000000..ffd9387
--- /dev/null
+++ b/arch/arm/mach-exynos/cpu-exynos4.c
@@ -0,0 +1,466 @@
+/* linux/arch/arm/mach-exynos/cpu.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/cacheflush.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
+#include <plat/exynos4.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/fimc-core.h>
+#include <plat/adc-core.h>
+#include <plat/pm.h>
+#include <plat/iic-core.h>
+#include <plat/ace-core.h>
+#include <plat/reset.h>
+#include <plat/audio.h>
+#include <plat/tv-core.h>
+#include <plat/rtc-core.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-pmu.h>
+#include <mach/smc.h>
+
+unsigned int gic_bank_offset __read_mostly;
+
+extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
+ unsigned int irq_start);
+extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
+
+/* Initial IO mappings */
+static struct map_desc exynos4_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_CMU,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
+ .length = SZ_128K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PMU,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_L2CC,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO1,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO2,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO3,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO4,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO4),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GIC_CPU,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GIC_DIST,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_AUDSS,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_AUDSS),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_CPU,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_PPMU_CPU),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_DMC0,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_PPMU_DMC0),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_DMC1,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_PPMU_DMC1),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GDL,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GDL),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GDR,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_GDR),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos4210_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC1,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM_NS),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos4210_iodesc_rev_0[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSRAM,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos4210_iodesc_rev_1[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSRAM,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos4212_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0_4212),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC1,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1_4212),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSRAM,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
+ .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM_NS_4212),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void exynos4_idle(void)
+{
+ if (!need_resched())
+ cpu_do_idle();
+
+ local_irq_enable();
+}
+
+/*
+ * exynos4_map_io
+ *
+ * register the standard cpu IO areas
+ */
+void __init exynos4_map_io(void)
+{
+ iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
+
+ if (soc_is_exynos4210()) {
+ iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
+ if (samsung_rev() == EXYNOS4210_REV_0)
+ iotable_init(exynos4210_iodesc_rev_0,
+ ARRAY_SIZE(exynos4210_iodesc_rev_0));
+ else
+ iotable_init(exynos4210_iodesc_rev_1,
+ ARRAY_SIZE(exynos4210_iodesc_rev_1));
+ } else {
+ iotable_init(exynos4212_iodesc, ARRAY_SIZE(exynos4212_iodesc));
+ }
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ exynos4_default_sdhci0();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ exynos4_default_sdhci1();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ exynos4_default_sdhci2();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ exynos4_default_sdhci3();
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ exynos4_default_mshci();
+#endif
+ exynos4_i2sv3_setup_resource();
+
+ s3c_fimc_setname(0, "exynos4-fimc");
+ s3c_fimc_setname(1, "exynos4-fimc");
+ s3c_fimc_setname(2, "exynos4-fimc");
+ s3c_fimc_setname(3, "exynos4-fimc");
+#ifdef CONFIG_S3C_DEV_RTC
+ s3c_rtc_setname("exynos-rtc");
+#endif
+#ifdef CONFIG_FB_S3C
+ s5p_fb_setname(0, "exynos4-fb"); /* FIMD0 */
+#endif
+ if (soc_is_exynos4210())
+ s3c_adc_setname("samsung-adc-v3");
+ else
+ s3c_adc_setname("samsung-adc-v4");
+
+ s5p_hdmi_setname("exynos4-hdmi");
+
+ /* The I2C bus controllers are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+ s3c_i2c2_setname("s3c2440-i2c");
+
+#ifdef CONFIG_S5P_DEV_ACE
+ s5p_ace_setname("exynos4-ace");
+#endif
+}
+
+void __init exynos4_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+
+ if (soc_is_exynos4210())
+ exynos4210_register_clocks();
+ else
+ exynos4212_register_clocks();
+
+ s5p_register_clocks(xtal);
+ exynos4_register_clocks();
+ exynos4_setup_clocks();
+}
+
+#define COMBINER_MAP(x) ((x < 16) ? IRQ_SPI(x) : \
+ (x == 16) ? IRQ_SPI(107) : \
+ (x == 17) ? IRQ_SPI(108) : \
+ (x == 18) ? IRQ_SPI(48) : \
+ (x == 19) ? IRQ_SPI(49) : 0)
+
+void __init exynos4_init_irq(void)
+{
+ int irq;
+
+ gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
+
+ gic_init(0, IRQ_PPI_MCT_L, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
+ gic_arch_extn.irq_set_wake = s3c_irq_wake;
+
+ for (irq = 0; irq < COMMON_COMBINER_NR; irq++) {
+ combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
+ COMBINER_IRQ(irq, 0));
+ combiner_cascade_irq(irq, COMBINER_MAP(irq));
+ }
+
+ if (soc_is_exynos4412() && (samsung_rev() >= EXYNOS4412_REV_1_0)) {
+ for (irq = COMMON_COMBINER_NR; irq < MAX_COMBINER_NR; irq++) {
+ combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
+ COMBINER_IRQ(irq, 0));
+ combiner_cascade_irq(irq, COMBINER_MAP(irq));
+ }
+ }
+
+ /* The parameters of s5p_init_irq() are for VIC init.
+ * Theses parameters should be NULL and 0 because EXYNOS4
+ * uses GIC instead of VIC.
+ */
+ s5p_init_irq(NULL, 0);
+}
+
+struct sysdev_class exynos4_sysclass = {
+ .name = "exynos4-core",
+};
+
+static struct sys_device exynos4_sysdev = {
+ .cls = &exynos4_sysclass,
+};
+
+static int __init exynos4_core_init(void)
+{
+ return sysdev_class_register(&exynos4_sysclass);
+}
+
+core_initcall(exynos4_core_init);
+
+#ifdef CONFIG_CACHE_L2X0
+#ifdef CONFIG_ARM_TRUSTZONE
+#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
+static void exynos4_l2x0_set_debug(unsigned long val)
+{
+ exynos_smc(SMC_CMD_L2X0DEBUG, val, 0, 0);
+}
+#endif
+#endif
+
+static int __init exynos4_l2x0_cache_init(void)
+{
+ u32 tag_latency = 0x110;
+ u32 data_latency = soc_is_exynos4210() ? 0x110 : 0x120;
+ u32 prefetch = (soc_is_exynos4412() &&
+ samsung_rev() >= EXYNOS4412_REV_1_0) ?
+ 0x71000007 : 0x30000007;
+ u32 aux_val = 0x7C470001;
+ u32 aux_mask = 0xC200FFFF;
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_L2X0SETUP1, tag_latency, data_latency, prefetch);
+ exynos_smc(SMC_CMD_L2X0SETUP2,
+ L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
+ aux_val, aux_mask);
+ exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
+ exynos_smc(SMC_CMD_L2X0CTRL, 1, 0, 0);
+#else
+ __raw_writel(tag_latency, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
+ __raw_writel(data_latency, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
+ __raw_writel(prefetch, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
+ __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
+ S5P_VA_L2CC + L2X0_POWER_CTRL);
+#endif
+
+ l2x0_init(S5P_VA_L2CC, aux_val, aux_mask);
+
+#ifdef CONFIG_ARM_TRUSTZONE
+#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
+ outer_cache.set_debug = exynos4_l2x0_set_debug;
+#endif
+#endif
+ /* Enable the full line of zero */
+ enable_cache_foz();
+ return 0;
+}
+
+//early_initcall(exynos4_l2x0_cache_init);
+early_initcall(exynos4_l2x0_cache_init);
+#endif
+
+static void exynos4_sw_reset(void)
+{
+ int count = 3;
+
+ while (count--) {
+ __raw_writel(0x1, S5P_SWRESET);
+ mdelay(500);
+ }
+}
+
+static void __iomem *exynos4_pmu_init_zero[] = {
+ S5P_CMU_RESET_ISP_SYS,
+ S5P_CMU_SYSCLK_ISP_SYS,
+};
+
+int __init exynos4_init(void)
+{
+ unsigned int value;
+ unsigned int tmp;
+ unsigned int i;
+
+ printk(KERN_INFO "EXYNOS4: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = exynos4_idle;
+
+ /*
+ * on exynos4x12, CMU reset system power register should to be set 0x0
+ */
+ if (!soc_is_exynos4210()) {
+ for (i = 0; i < ARRAY_SIZE(exynos4_pmu_init_zero); i++)
+ __raw_writel(0x0, exynos4_pmu_init_zero[i]);
+ }
+
+ /* set sw_reset function */
+ s5p_reset_hook = exynos4_sw_reset;
+
+ /* Disable auto wakeup from power off mode */
+ for (i = 0; i < num_possible_cpus(); i++) {
+ tmp = __raw_readl(S5P_ARM_CORE_OPTION(i));
+ tmp &= ~S5P_CORE_OPTION_DIS;
+ __raw_writel(tmp, S5P_ARM_CORE_OPTION(i));
+ }
+
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ value = __raw_readl(S5P_AUTOMATIC_WDT_RESET_DISABLE);
+ value &= ~S5P_SYS_WDTRESET;
+ __raw_writel(value, S5P_AUTOMATIC_WDT_RESET_DISABLE);
+ value = __raw_readl(S5P_MASK_WDT_RESET_REQUEST);
+ value &= ~S5P_SYS_WDTRESET;
+ __raw_writel(value, S5P_MASK_WDT_RESET_REQUEST);
+ }
+
+ return sysdev_register(&exynos4_sysdev);
+}
diff --git a/arch/arm/mach-exynos/cpu-exynos5.c b/arch/arm/mach-exynos/cpu-exynos5.c
new file mode 100644
index 0000000..87f2bbd
--- /dev/null
+++ b/arch/arm/mach-exynos/cpu-exynos5.c
@@ -0,0 +1,381 @@
+/* linux/arch/arm/mach-exynos/cpu-exynos5.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb-core.h>
+#include <plat/exynos5.h>
+#include <plat/sdhci.h>
+#include <plat/pm.h>
+#include <plat/iic-core.h>
+#include <plat/tv-core.h>
+#include <plat/ace-core.h>
+#include <plat/reset.h>
+#include <plat/rtc-core.h>
+#include <plat/adc-core.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu5.h>
+#include <mach/smc.h>
+
+unsigned int gic_bank_offset __read_mostly;
+
+extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
+ unsigned int irq_start);
+extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
+
+/* Initial IO mappings */
+static struct map_desc exynos5_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SYSTIMER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSRAM,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_CMU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
+ .length = 144 * SZ_1K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PMU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PMU),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_COMBINER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO1,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_GPIO1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO2,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_GPIO2),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO3,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_GPIO3),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO4,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_GPIO4),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_AUDSS,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_AUDSS),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_HSPHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SS_PHY,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SS_PHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+#ifdef CONFIG_ARM_TRUSTZONE
+ }, {
+ .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM_NS),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+#endif
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_CPU,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PPMU_CPU),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_DDR_C,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_C),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_DDR_R1,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_R1),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_DDR_L,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PPMU_DDR_L),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_PPMU_RIGHT0_BUS,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_PPMU_RIGHT0_BUS),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_FIMCLITE0,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_FIMC_LITE0),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_FIMCLITE1,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_FIMC_LITE1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_FIMCLITE2,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_FIMC_LITE2),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_MIPICSI0,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_MIPI_CSIS0),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_MIPICSI1,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_MIPI_CSIS1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(EXYNOS5_PA_DMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos5250_rev_0_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_GIC_CPU,
+ .pfn = __phys_to_pfn(EXYNOS5250_REV0_PA_GIC_CPU),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GIC_DIST,
+ .pfn = __phys_to_pfn(EXYNOS5250_REV0_PA_GIC_DIST),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc exynos5250_rev_1_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_GIC_CPU,
+ .pfn = __phys_to_pfn(EXYNOS5250_REV1_PA_GIC_CPU),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GIC_DIST,
+ .pfn = __phys_to_pfn(EXYNOS5250_REV1_PA_GIC_DIST),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void exynos5_idle(void)
+{
+ if (!need_resched())
+ cpu_do_idle();
+
+ local_irq_enable();
+}
+
+/*
+ * exynos5_map_io
+ *
+ * register the standard cpu IO areas
+ */
+void __init exynos5_map_io(void)
+{
+ iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
+
+ if (soc_is_exynos5250()) {
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ iotable_init(exynos5250_rev_1_iodesc,
+ ARRAY_SIZE(exynos5250_rev_1_iodesc));
+ else
+ iotable_init(exynos5250_rev_0_iodesc,
+ ARRAY_SIZE(exynos5250_rev_0_iodesc));
+ }
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ exynos5_default_sdhci0();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ exynos5_default_sdhci1();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ exynos5_default_sdhci2();
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ exynos5_default_sdhci3();
+#endif
+#ifdef CONFIG_S3C_DEV_RTC
+ s3c_rtc_setname("exynos-rtc");
+#endif
+
+ s5p_fb_setname(1, "exynos5-fb"); /* FIMD1 */
+
+ s3c_adc_setname("samsung-adc-v4");
+
+ s5p_hdmi_setname("exynos5-hdmi");
+
+ /* The I2C bus controllers are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+ s3c_i2c2_setname("s3c2440-i2c");
+
+#ifdef CONFIG_S5P_DEV_ACE
+ s5p_ace_setname("exynos4-ace");
+#endif
+}
+
+void __init exynos5_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+
+ s5p_register_clocks(xtal);
+ exynos5_register_clocks();
+ exynos5_setup_clocks();
+}
+
+void __init exynos5_init_irq(void)
+{
+ int irq;
+
+ gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
+ gic_arch_extn.irq_set_wake = s3c_irq_wake;
+
+ for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
+ combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
+ COMBINER_IRQ(irq, 0));
+ combiner_cascade_irq(irq, IRQ_SPI(irq));
+ }
+
+ /* The parameters of s5p_init_irq() are for VIC init.
+ * Theses parameters should be NULL and 0 because EXYNOS5
+ * uses GIC instead of VIC.
+ */
+ s5p_init_irq(NULL, 0);
+}
+
+struct sysdev_class exynos5_sysclass = {
+ .name = "exynos5-core",
+};
+
+static struct sys_device exynos5_sysdev = {
+ .cls = &exynos5_sysclass,
+};
+
+static int __init exynos5_core_init(void)
+{
+ return sysdev_class_register(&exynos5_sysclass);
+}
+
+core_initcall(exynos5_core_init);
+
+#define TAG_RAM_SETUP_SHIFT (9)
+#define DATA_RAM_SETUP_SHIFT (5)
+#define TAG_RAM_LATENCY_SHIFT (6)
+#define DATA_RAM_LATENCY_SHIFT (0)
+
+static int __init exynos5_l2_cache_init(void)
+{
+ unsigned int val;
+
+ if (soc_is_exynos5250()) {
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "bic %0, %0, #(1 << 2)\n" /* cache disable */
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ "mrc p15, 1, %0, c9, c0, 2\n"
+ : "=r"(val));
+
+ val |= (1 << TAG_RAM_SETUP_SHIFT) |
+ (1 << DATA_RAM_SETUP_SHIFT) |
+ (2 << TAG_RAM_LATENCY_SHIFT) |
+ (2 << DATA_RAM_LATENCY_SHIFT);
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_REG, SMC_REG_ID_CP15(9, 1, 0, 2), val, 0);
+#else
+ asm volatile("mcr p15, 1, %0, c9, c0, 2\n": : "r"(val));
+#endif
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "orr %0, %0, #(1 << 2)\n" /* cache enable */
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ : : "r"(val));
+ }
+
+ return 0;
+}
+
+early_initcall(exynos5_l2_cache_init);
+
+static void exynos5_sw_reset(void)
+{
+ int count = 3;
+
+ while (count--) {
+ __raw_writel(0x1, S5P_SWRESET);
+ mdelay(500);
+ }
+}
+
+int __init exynos5_init(void)
+{
+ unsigned int value;
+ printk(KERN_INFO "EXYNOS5: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = exynos5_idle;
+
+ /* set sw_reset function */
+ s5p_reset_hook = exynos5_sw_reset;
+
+ value = __raw_readl(EXYNOS5_AUTOMATIC_WDT_RESET_DISABLE);
+ value &= ~EXYNOS5_SYS_WDTRESET;
+ __raw_writel(value, EXYNOS5_AUTOMATIC_WDT_RESET_DISABLE);
+ value = __raw_readl(EXYNOS5_MASK_WDT_RESET_REQUEST);
+ value &= ~EXYNOS5_SYS_WDTRESET;
+ __raw_writel(value, EXYNOS5_MASK_WDT_RESET_REQUEST);
+
+ if (soc_is_exynos5250() && samsung_rev() >= EXYNOS5250_REV_1_0) {
+ __raw_writel(0x1, EXYNOS5_ADC_PHY_CONTROL);
+ }
+
+ return sysdev_register(&exynos5_sysdev);
+}
diff --git a/arch/arm/mach-exynos/cpufreq-4210.c b/arch/arm/mach-exynos/cpufreq-4210.c
new file mode 100644
index 0000000..7b93045
--- /dev/null
+++ b/arch/arm/mach-exynos/cpufreq-4210.c
@@ -0,0 +1,453 @@
+/* linux/arch/arm/mach-exynos/cpufreq-4210.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4210 - CPU frequency scaling support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/cpufreq.h>
+#include <mach/asv.h>
+#include <mach/sec_debug.h>
+
+#include <plat/clock.h>
+
+#define CPUFREQ_LEVEL_END L6
+
+static int max_support_idx;
+static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
+static struct clk *cpu_clk;
+static struct clk *moutcore;
+static struct clk *mout_mpll;
+static struct clk *mout_apll;
+
+struct cpufreq_clkdiv {
+ unsigned int index;
+ unsigned int clkdiv;
+};
+
+static unsigned int exynos4210_volt_table[CPUFREQ_LEVEL_END];
+
+static struct cpufreq_frequency_table exynos4210_freq_table[] = {
+ {L0, 1400*1000},
+ {L1, 1200*1000},
+ {L2, 1000*1000},
+ {L3, 800*1000},
+ {L4, 500*1000},
+ {L5, 200*1000},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct cpufreq_clkdiv exynos4210_clkdiv_table[] = {
+ {L0, 0},
+ {L1, 0},
+ {L2, 0},
+ {L3, 0},
+ {L4, 0},
+ {L5, 0},
+};
+
+static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
+ /*
+ * Clock divider value for following
+ * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
+ * DIVATB, DIVPCLK_DBG, DIVAPLL }
+ */
+ /* ARM L0: 1400MHz */
+ { 0, 3, 7, 3, 4, 1, 7 },
+
+ /* ARM L1: 1200MHz */
+ { 0, 3, 7, 3, 4, 1, 7 },
+
+ /* ARM L2: 1000MHz */
+ { 0, 3, 7, 3, 4, 1, 7 },
+
+ /* ARM L3: 800MHz */
+ { 0, 3, 7, 3, 3, 1, 7 },
+
+ /* ARM L4: 500MHz */
+ { 0, 3, 7, 3, 3, 1, 7 },
+
+ /* ARM L5: 200MHz */
+ { 0, 1, 3, 1, 3, 1, 0 },
+};
+
+static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
+ /* Clock divider value for following
+ * { DIVCOPY, DIVHPM }
+ */
+ /* ARM L0: 1400MHz */
+ { 5, 0 },
+
+ /* ARM L1: 1200MHz */
+ { 5, 0 },
+
+ /* ARM L2: 1000MHz */
+ { 4, 0 },
+
+ /* ARM L3: 800MHz */
+ { 3, 0 },
+
+ /* ARM L4: 500MHz */
+ { 3, 0 },
+
+ /* ARM L5: 200MHz */
+ { 3, 0 },
+};
+
+static unsigned int exynos4_apll_pms_table[CPUFREQ_LEVEL_END] = {
+ /* APLL FOUT L0: 1400MHz */
+ ((350<<16)|(6<<8)|(0x1)),
+
+ /* APLL FOUT L1: 1200MHz */
+ ((150<<16)|(3<<8)|(0x1)),
+
+ /* APLL FOUT L2: 1000MHz */
+ ((250<<16)|(6<<8)|(0x1)),
+
+ /* APLL FOUT L3: 800MHz */
+ ((200<<16)|(6<<8)|(0x1)),
+
+ /* APLL FOUT L4: 500MHz */
+ ((250<<16)|(6<<8)|(0x2)),
+
+ /* APLL FOUT L5: 200MHz */
+ ((200<<16)|(6<<8)|(0x3)),
+};
+
+/*
+ * ASV group voltage table
+ */
+
+static const unsigned int asv_voltage_A[CPUFREQ_LEVEL_END][8] = {
+ /*
+ * SS, A1, A2, B1, B2, C1, C2, D
+ * @Dummy:
+ * @1200 :
+ * @1000 :
+ * @800 : ASV_VOLTAGE_TABLE
+ * @500 :
+ * @200 :
+ */
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1350000, 1350000, 1300000, 1275000, 1250000, 1225000, 1200000, 1175000 },
+ { 1300000, 1250000, 1200000, 1175000, 1150000, 1125000, 1100000, 1075000 },
+ { 1200000, 1150000, 1100000, 1075000, 1050000, 1025000, 1000000, 975000 },
+ { 1100000, 1050000, 1000000, 975000, 975000, 950000, 925000, 925000 },
+ { 1050000, 1000000, 975000, 950000, 950000, 925000, 925000, 925000 },
+
+};
+
+static const unsigned int asv_voltage_B[CPUFREQ_LEVEL_END][5] = {
+ /*
+ * S, A, B, C, D
+ * @1400 :
+ * @1200 :
+ * @1000 :
+ * @800 : ASV_VOLTAGE_TABLE
+ * @500 :
+ * @200 :
+ */
+ { 1350000, 1350000, 1300000, 1250000, 1225000 },
+ { 1325000, 1275000, 1225000, 1175000, 1150000 },
+ { 1225000, 1175000, 1125000, 1075000, 1050000 },
+ { 1150000, 1100000, 1050000, 1000000, 975000 },
+ { 1050000, 1000000, 950000, 950000, 950000 },
+ { 1025000, 975000, 950000, 950000, 950000 },
+
+};
+
+static void set_clkdiv(unsigned int div_index)
+{
+ unsigned int tmp;
+ /* Change Divider - CPU0 */
+
+ tmp = exynos4210_clkdiv_table[div_index].clkdiv;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU);
+ } while (tmp & 0x1111111);
+
+ /* Change Divider - CPU1 */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1);
+
+ tmp &= ~((0x7 << 4) | (0x7));
+
+ tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
+ (clkdiv_cpu1[div_index][1] << 0));
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1);
+ } while (tmp & 0x11);
+}
+
+static void set_apll(unsigned int new_index,
+ unsigned int old_index)
+{
+ unsigned int tmp;
+
+ /* 1. MUX_CORE_SEL = MPLL,
+ * ARMCLK uses MPLL for lock time */
+ if (clk_set_parent(moutcore, mout_mpll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ mout_mpll->name, moutcore->name);
+
+ do {
+ tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
+ >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
+ tmp &= 0x7;
+ } while (tmp != 0x2);
+
+ /* 2. Set APLL Lock time */
+ __raw_writel(EXYNOS4_APLL_LOCKTIME, EXYNOS4_APLL_LOCK);
+
+ /* 3. Change PLL PMS values */
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
+ tmp |= exynos4_apll_pms_table[new_index];
+ __raw_writel(tmp, EXYNOS4_APLL_CON0);
+
+ /* 4. wait_lock_time */
+ do {
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT)));
+
+ /* 5. MUX_CORE_SEL = APLL */
+ if (clk_set_parent(moutcore, mout_apll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ mout_apll->name, moutcore->name);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
+ tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
+ } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
+
+}
+
+bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index)
+{
+ unsigned int old_pm = (exynos4_apll_pms_table[old_index] >> 8);
+ unsigned int new_pm = (exynos4_apll_pms_table[new_index] >> 8);
+
+ return (old_pm == new_pm) ? 0 : 1;
+}
+
+static void exynos4210_set_frequency(unsigned int old_index,
+ unsigned int new_index)
+{
+ unsigned int tmp;
+
+ sec_debug_aux_log(SEC_DEBUG_AUXLOG_CPU_BUS_CLOCK_CHANGE,
+ "%s: old_index=%d, new_index=%d(%ps)",
+ __func__, old_index, new_index,
+ __builtin_return_address(0));
+
+ if (old_index > new_index) {
+ if (!exynos4210_pms_change(old_index, new_index)) {
+ /* 1. Change the system clock divider values */
+ set_clkdiv(new_index);
+ /* 2. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, EXYNOS4_APLL_CON0);
+
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the system clock divider values */
+ set_clkdiv(new_index);
+ /* 2. Change the apll m,p,s value */
+ set_apll(new_index, old_index);
+ }
+ } else if (old_index < new_index) {
+ if (!exynos4210_pms_change(old_index, new_index)) {
+ /* 1. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, EXYNOS4_APLL_CON0);
+ /* 2. Change the system clock divider values */
+ set_clkdiv(new_index);
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the apll m,p,s value */
+ set_apll(new_index, old_index);
+ /* 2. Change the system clock divider values */
+ set_clkdiv(new_index);
+ }
+ }
+}
+
+static void __init set_volt_table(void)
+{
+ unsigned int asv_group = 0;
+ bool for_1400 = false, for_1200 = false, for_1000 = false;
+ unsigned int tmp;
+ unsigned int i;
+
+ tmp = exynos_result_of_asv;
+
+ asv_group = (tmp & 0xF);
+
+ switch (tmp & (SUPPORT_FREQ_MASK << SUPPORT_FREQ_SHIFT)) {
+ case SUPPORT_1400MHZ:
+#if defined(CONFIG_EXYNOS4210_1200MHZ_SUPPORT)
+ for_1200 = true;
+ max_support_idx = L1;
+#else
+ for_1400 = true;
+ max_support_idx = L0;
+#endif
+ break;
+ case SUPPORT_1200MHZ:
+ for_1200 = true;
+ max_support_idx = L1;
+ break;
+ case SUPPORT_1000MHZ:
+ for_1000 = true;
+ max_support_idx = L2;
+ break;
+ default:
+ for_1000 = true;
+ max_support_idx = L2;
+ break;
+ }
+
+ /*
+ * If ASV group is S, can not support 1.4GHz
+ * Disabling table entry
+ */
+ if ((asv_group == 0) || !for_1400)
+ exynos4210_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
+
+ if (for_1000)
+ exynos4210_freq_table[L1].frequency = CPUFREQ_ENTRY_INVALID;
+
+ printk(KERN_INFO "DVFS : VDD_ARM Voltage table set with %d Group\n", asv_group);
+
+ if (for_1400) {
+ for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) {
+ exynos4210_volt_table[i] =
+ asv_voltage_B[i][asv_group];
+ }
+ } else {
+ for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) {
+ exynos4210_volt_table[i] =
+ asv_voltage_A[i][asv_group];
+ }
+ }
+}
+
+#if defined(CONFIG_REGULATOR_MAX8997)
+extern void max8997_set_arm_voltage_table(int *voltage_table, int arr_size);
+
+static void exynos4210_cpufreq_set_pmic_vol_table(void)
+{
+ int vol_table[CPUFREQ_LEVEL_END];
+ int i;
+
+ for (i = 0; i < CPUFREQ_LEVEL_END; i++)
+ vol_table[i] = exynos4210_volt_table[i];
+
+ max8997_set_arm_voltage_table(vol_table, CPUFREQ_LEVEL_END);
+}
+#else
+static void exynos4210_cpufreq_set_pmic_vol_table(void)
+{
+ /*Do Nothing*/
+}
+#endif /* CONFIG_MACH_U1 */
+
+
+int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
+{
+ int i;
+ unsigned int tmp;
+ unsigned long rate;
+
+ set_volt_table();
+ exynos4210_cpufreq_set_pmic_vol_table();
+
+ cpu_clk = clk_get(NULL, "armclk");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ moutcore = clk_get(NULL, "moutcore");
+ if (IS_ERR(moutcore))
+ goto err_moutcore;
+
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(mout_mpll))
+ goto err_mout_mpll;
+
+ rate = clk_get_rate(mout_mpll) / 1000;
+
+ mout_apll = clk_get(NULL, "mout_apll");
+ if (IS_ERR(mout_apll))
+ goto err_mout_apll;
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU);
+
+ for (i = L0; i < CPUFREQ_LEVEL_END; i++) {
+ tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK |
+ EXYNOS4_CLKDIV_CPU0_COREM0_MASK |
+ EXYNOS4_CLKDIV_CPU0_COREM1_MASK |
+ EXYNOS4_CLKDIV_CPU0_PERIPH_MASK |
+ EXYNOS4_CLKDIV_CPU0_ATB_MASK |
+ EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK |
+ EXYNOS4_CLKDIV_CPU0_APLL_MASK);
+
+ tmp |= ((clkdiv_cpu0[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) |
+ (clkdiv_cpu0[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) |
+ (clkdiv_cpu0[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) |
+ (clkdiv_cpu0[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) |
+ (clkdiv_cpu0[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) |
+ (clkdiv_cpu0[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) |
+ (clkdiv_cpu0[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT));
+
+ exynos4210_clkdiv_table[i].clkdiv = tmp;
+ }
+
+ info->mpll_freq_khz = rate;
+ info->pm_lock_idx = L3;
+ info->pll_safe_idx = L2;
+ info->max_support_idx = max_support_idx;
+ info->min_support_idx = min_support_idx;
+ info->cpu_clk = cpu_clk;
+ info->volt_table = exynos4210_volt_table;
+ info->freq_table = exynos4210_freq_table;
+ info->set_freq = exynos4210_set_frequency;
+ info->need_apll_change = exynos4210_pms_change;
+
+ return 0;
+
+err_mout_apll:
+ if (!IS_ERR(mout_mpll))
+ clk_put(mout_mpll);
+err_mout_mpll:
+ if (!IS_ERR(moutcore))
+ clk_put(moutcore);
+err_moutcore:
+ if (!IS_ERR(cpu_clk))
+ clk_put(cpu_clk);
+
+ pr_debug("%s: failed initialization\n", __func__);
+ return -EINVAL;
+}
+EXPORT_SYMBOL(exynos4210_cpufreq_init);
diff --git a/arch/arm/mach-exynos/cpufreq-4x12.c b/arch/arm/mach-exynos/cpufreq-4x12.c
new file mode 100644
index 0000000..d5dd249
--- /dev/null
+++ b/arch/arm/mach-exynos/cpufreq-4x12.c
@@ -0,0 +1,736 @@
+/* linux/arch/arm/mach-exynos/cpufreq-4x12.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4X12 - CPU frequency scaling support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/pmu.h>
+#include <mach/cpufreq.h>
+#include <mach/asv.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#define CPUFREQ_LEVEL_END (L13 + 1)
+
+#undef PRINT_DIV_VAL
+
+#undef ENABLE_CLKOUT
+
+static int max_support_idx;
+static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
+static struct clk *cpu_clk;
+static struct clk *moutcore;
+static struct clk *mout_mpll;
+static struct clk *mout_apll;
+
+struct cpufreq_clkdiv {
+ unsigned int index;
+ unsigned int clkdiv;
+ unsigned int clkdiv1;
+};
+
+static unsigned int exynos4x12_volt_table[CPUFREQ_LEVEL_END];
+
+static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
+ {L0, 1500*1000},
+ {L1, 1400*1000},
+ {L2, 1300*1000},
+ {L3, 1200*1000},
+ {L4, 1100*1000},
+ {L5, 1000*1000},
+ {L6, 900*1000},
+ {L7, 800*1000},
+ {L8, 700*1000},
+ {L9, 600*1000},
+ {L10, 500*1000},
+ {L11, 400*1000},
+ {L12, 300*1000},
+ {L13, 200*1000},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct cpufreq_clkdiv exynos4x12_clkdiv_table[CPUFREQ_LEVEL_END];
+
+static unsigned int clkdiv_cpu0_4212[CPUFREQ_LEVEL_END][8] = {
+ /*
+ * Clock divider value for following
+ * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
+ * DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 }
+ */
+ /* ARM L0: 1500Mhz */
+ { 0, 3, 7, 0, 6, 1, 2, 0 },
+
+ /* ARM L1: 1400Mhz */
+ { 0, 3, 7, 0, 6, 1, 2, 0 },
+
+ /* ARM L2: 1300Mhz */
+ { 0, 3, 7, 0, 5, 1, 2, 0 },
+
+ /* ARM L3: 1200Mhz */
+ { 0, 3, 7, 0, 5, 1, 2, 0 },
+
+ /* ARM L4: 1100MHz */
+ { 0, 3, 6, 0, 4, 1, 2, 0 },
+
+ /* ARM L5: 1000MHz */
+ { 0, 2, 5, 0, 4, 1, 1, 0 },
+
+ /* ARM L6: 900MHz */
+ { 0, 2, 5, 0, 3, 1, 1, 0 },
+
+ /* ARM L7: 800MHz */
+ { 0, 2, 5, 0, 3, 1, 1, 0 },
+
+ /* ARM L8: 700MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L9: 600MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L10: 500MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L11: 400MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L12: 300MHz */
+ { 0, 2, 4, 0, 2, 1, 1, 0 },
+
+ /* ARM L13: 200MHz */
+ { 0, 1, 3, 0, 1, 1, 1, 0 },
+};
+
+static unsigned int clkdiv_cpu0_4412[CPUFREQ_LEVEL_END][8] = {
+ /*
+ * Clock divider value for following
+ * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
+ * DIVATB, DIVPCLK_DBG, DIVAPLL, DIVCORE2 }
+ */
+ /* ARM L0: 1500Mhz */
+ { 0, 3, 7, 0, 6, 1, 2, 0 },
+
+ /* ARM L1: 1400Mhz */
+ { 0, 3, 7, 0, 6, 1, 2, 0 },
+
+ /* ARM L2: 1300Mhz */
+ { 0, 3, 7, 0, 5, 1, 2, 0 },
+
+ /* ARM L3: 1200Mhz */
+ { 0, 3, 7, 0, 5, 1, 2, 0 },
+
+ /* ARM L4: 1100MHz */
+ { 0, 3, 6, 0, 4, 1, 2, 0 },
+
+ /* ARM L5: 1000MHz */
+ { 0, 2, 5, 0, 4, 1, 1, 0 },
+
+ /* ARM L6: 900MHz */
+ { 0, 2, 5, 0, 3, 1, 1, 0 },
+
+ /* ARM L7: 800MHz */
+ { 0, 2, 5, 0, 3, 1, 1, 0 },
+
+ /* ARM L8: 700MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L9: 600MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L10: 500MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L11: 400MHz */
+ { 0, 2, 4, 0, 3, 1, 1, 0 },
+
+ /* ARM L12: 300MHz */
+ { 0, 2, 4, 0, 2, 1, 1, 0 },
+
+ /* ARM L13: 200MHz */
+ { 0, 1, 3, 0, 1, 1, 1, 0 },
+};
+
+static unsigned int clkdiv_cpu1_4212[CPUFREQ_LEVEL_END][2] = {
+ /* Clock divider value for following
+ * { DIVCOPY, DIVHPM }
+ */
+ /* ARM L0: 1500MHz */
+ { 6, 0 },
+
+ /* ARM L1: 1400MHz */
+ { 6, 0 },
+
+ /* ARM L2: 1300MHz */
+ { 5, 0 },
+
+ /* ARM L3: 1200MHz */
+ { 5, 0 },
+
+ /* ARM L4: 1100MHz */
+ { 4, 0 },
+
+ /* ARM L5: 1000MHz */
+ { 4, 0 },
+
+ /* ARM L6: 900MHz */
+ { 3, 0 },
+
+ /* ARM L7: 800MHz */
+ { 3, 0 },
+
+ /* ARM L8: 700MHz */
+ { 3, 0 },
+
+ /* ARM L9: 600MHz */
+ { 3, 0 },
+
+ /* ARM L10: 500MHz */
+ { 3, 0 },
+
+ /* ARM L11: 400MHz */
+ { 3, 0 },
+
+ /* ARM L12: 300MHz */
+ { 3, 0 },
+
+ /* ARM L13: 200MHz */
+ { 3, 0 },
+};
+
+static unsigned int clkdiv_cpu1_4412[CPUFREQ_LEVEL_END][3] = {
+ /* Clock divider value for following
+ * { DIVCOPY, DIVHPM, DIVCORES }
+ */
+ /* ARM L0: 1500MHz */
+ { 6, 0, 7 },
+
+ /* ARM L1: 1400MHz */
+ { 6, 0, 6 },
+
+ /* ARM L2: 1300MHz */
+ { 5, 0, 6 },
+
+ /* ARM L3: 1200MHz */
+ { 5, 0, 5 },
+
+ /* ARM L4: 1100MHz */
+ { 4, 0, 5 },
+
+ /* ARM L5: 1000MHz */
+ { 4, 0, 4 },
+
+ /* ARM L6: 900MHz */
+ { 3, 0, 4 },
+
+ /* ARM L7: 800MHz */
+ { 3, 0, 3 },
+
+ /* ARM L8: 700MHz */
+ { 3, 0, 3 },
+
+ /* ARM L9: 600MHz */
+ { 3, 0, 2 },
+
+ /* ARM L10: 500MHz */
+ { 3, 0, 2 },
+
+ /* ARM L11: 400MHz */
+ { 3, 0, 1 },
+
+ /* ARM L12: 300MHz */
+ { 3, 0, 1 },
+
+ /* ARM L13: 200MHz */
+ { 3, 0, 0 },
+};
+
+static unsigned int exynos4x12_apll_pms_table[CPUFREQ_LEVEL_END] = {
+ /* APLL FOUT L0: 1500MHz */
+ ((250<<16)|(4<<8)|(0x0)),
+
+ /* APLL FOUT L1: 1400MHz */
+ ((175<<16)|(3<<8)|(0x0)),
+
+ /* APLL FOUT L2: 1300MHz */
+ ((325<<16)|(6<<8)|(0x0)),
+
+ /* APLL FOUT L3: 1200MHz */
+ ((200<<16)|(4<<8)|(0x0)),
+
+ /* APLL FOUT L4: 1100MHz */
+ ((275<<16)|(6<<8)|(0x0)),
+
+ /* APLL FOUT L5: 1000MHz */
+ ((125<<16)|(3<<8)|(0x0)),
+
+ /* APLL FOUT L6: 900MHz */
+ ((150<<16)|(4<<8)|(0x0)),
+
+ /* APLL FOUT L7: 800MHz */
+ ((100<<16)|(3<<8)|(0x0)),
+
+ /* APLL FOUT L8: 700MHz */
+ ((175<<16)|(3<<8)|(0x1)),
+
+ /* APLL FOUT L9: 600MHz */
+ ((200<<16)|(4<<8)|(0x1)),
+
+ /* APLL FOUT L10: 500MHz */
+ ((125<<16)|(3<<8)|(0x1)),
+
+ /* APLL FOUT L11 400MHz */
+ ((100<<16)|(3<<8)|(0x1)),
+
+ /* APLL FOUT L12: 300MHz */
+ ((200<<16)|(4<<8)|(0x2)),
+
+ /* APLL FOUT L13: 200MHz */
+ ((100<<16)|(3<<8)|(0x2)),
+
+};
+
+/*
+ * ASV group voltage table
+ */
+
+#define NO_ABB_LIMIT L8
+
+static const unsigned int asv_voltage_4212[CPUFREQ_LEVEL_END][12] = {
+ /* ASV0, ASV1, ASV2, ASV3, ASV4, ASV5, ASV6, ASV7, ASV8, ASV9, ASV10, ASV11 */
+ { 0, 1300000, 1300000, 1275000, 1300000, 1287500, 1275000, 1250000, 1237500, 1225000, 1225000, 1212500 }, /* L0 */
+ { 1300000, 1287500, 1250000, 1225000, 1237500, 1237500, 1225000, 1200000, 1187500, 1175000, 1175000, 1162500 }, /* L1 */
+ { 1237500, 1225000, 1200000, 1175000, 1187500, 1187500, 1162500, 1150000, 1137500, 1125000, 1125000, 1112500 }, /* L2 */
+ { 1187500, 1175000, 1150000, 1137500, 1150000, 1137500, 1125000, 1100000, 1087500, 1075000, 1075000, 1062500 }, /* L3 */
+ { 1137500, 1125000, 1112500, 1087500, 1112500, 1112500, 1075000, 1062500, 1050000, 1025000, 1025000, 1012500 }, /* L4 */
+ { 1100000, 1087500, 1075000, 1050000, 1075000, 1062500, 1037500, 1025000, 1012500, 1000000, 987500, 975000 }, /* L5 */
+ { 1050000, 1037500, 1025000, 1000000, 1025000, 1025000, 987500, 975000, 962500, 950000, 937500, 925000 }, /* L6 */
+ { 1012500, 1000000, 987500, 962500, 987500, 975000, 962500, 937500, 925000, 912500, 912500, 900000 }, /* L7 */
+ { 962500, 950000, 937500, 912500, 937500, 937500, 925000, 900000, 900000, 900000, 900000, 900000 }, /* L8 */
+ { 925000, 912500, 912500, 900000, 912500, 900000, 900000, 900000, 900000, 900000, 900000, 900000 }, /* L9 */
+ { 912500, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000 }, /* L10 */
+ { 912500, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000 }, /* L11 */
+ { 912500, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000 }, /* L12 */
+ { 912500, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000, 900000 }, /* L13 */
+};
+
+static const unsigned int asv_voltage_s[CPUFREQ_LEVEL_END] = {
+ 1300000, 1300000, 1300000, 1250000, 1200000, 1175000, 1100000,
+ 1050000, 1025000, 1000000, 1000000, 1000000, 950000, 950000
+};
+
+/* ASV table for 12.5mV step */
+#if 0
+/* 20120105 DVFS table version */
+static const unsigned int asv_voltage_step_12_5[CPUFREQ_LEVEL_END][12] = {
+ /* ASV0, ASV1, ASV2, ASV3, ASV4, ASV5, ASV6, ASV7, ASV8, ASV9, ASV10, ASV11 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* L0 - Not used */
+ { 1300000, 1300000, 1300000, 1287500, 1300000, 1287500, 1275000, 1250000, 1250000, 1237500, 1225000, 1212500 },
+ { 1300000, 1300000, 1237500, 1237500, 1250000, 1250000, 1237500, 1212500, 1200000, 1200000, 1187500, 1175000 },
+ { 1225000, 1212500, 1200000, 1187500, 1200000, 1187500, 1175000, 1150000, 1137500, 1125000, 1125000, 1112500 },
+ { 1175000, 1162500, 1150000, 1137500, 1150000, 1137500, 1125000, 1100000, 1100000, 1075000, 1075000, 1062500 },
+ { 1125000, 1112500, 1100000, 1087500, 1100000, 1087500, 1075000, 1050000, 1037500, 1025000, 1025000, 1012500 },
+ { 1075000, 1062500, 1050000, 1050000, 1050000, 1037500, 1025000, 1012500, 1000000, 987500, 987500, 975000 },
+ { 1037500, 1025000, 1012500, 1012500, 1012500, 1000000, 987500, 975000, 975000, 975000, 975000, 962500 },
+ { 1012500, 1000000, 987500, 987500, 987500, 987500, 975000, 975000, 962500, 962500, 962500, 950000 },
+ { 1000000, 987500, 975000, 975000, 975000, 975000, 962500, 962500, 950000, 950000, 950000, 937500 },
+ { 987500, 975000, 962500, 950000, 962500, 950000, 950000, 950000, 925000, 925000, 925000, 912500 },
+ { 975000, 962500, 950000, 925000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 887500 },
+ { 950000, 937500, 925000, 900000, 925000, 900000, 900000, 900000, 900000, 887500, 875000, 862500 },
+ { 925000, 912500, 900000, 900000, 900000, 900000, 900000, 900000, 887500, 875000, 875000, 862500 },
+};
+#else
+/* 20120210 DVFS table version */
+static const unsigned int asv_voltage_step_12_5[CPUFREQ_LEVEL_END][12] = {
+ /* ASV0, ASV1, ASV2, ASV3, ASV4, ASV5, ASV6, ASV7, ASV8, ASV9, ASV10, ASV11 */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* L0 - Not used */
+ { 1325000, 1312500, 1300000, 1287500, 1300000, 1287500, 1275000, 1250000, 1250000, 1237500, 1225000, 1212500 },
+ { 1300000, 1275000, 1237500, 1237500, 1250000, 1250000, 1237500, 1212500, 1200000, 1200000, 1187500, 1175000 },
+ { 1225000, 1212500, 1200000, 1187500, 1200000, 1187500, 1175000, 1150000, 1137500, 1125000, 1125000, 1112500 },
+ { 1175000, 1162500, 1150000, 1137500, 1150000, 1137500, 1125000, 1100000, 1100000, 1075000, 1075000, 1062500 },
+ { 1125000, 1112500, 1100000, 1087500, 1100000, 1087500, 1075000, 1050000, 1037500, 1025000, 1025000, 1012500 },
+ { 1075000, 1062500, 1050000, 1050000, 1050000, 1037500, 1025000, 1012500, 1000000, 987500, 987500, 975000 },
+ { 1037500, 1025000, 1000000, 1000000, 1000000, 987500, 975000, 962500, 962500, 962500, 962500, 950000 },
+ { 1012500, 1000000, 975000, 975000, 975000, 975000, 962500, 962500, 950000, 950000, 950000, 937500 },
+ { 1000000, 987500, 962500, 962500, 962500, 962500, 950000, 950000, 937500, 937500, 937500, 925000 },
+ { 987500, 975000, 950000, 937500, 950000, 937500, 937500, 937500, 912500, 912500, 912500, 900000 },
+ { 975000, 962500, 950000, 925000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 887500 },
+ { 950000, 937500, 925000, 900000, 925000, 900000, 900000, 900000, 900000, 887500, 875000, 862500 },
+ { 925000, 912500, 900000, 900000, 900000, 900000, 900000, 900000, 887500, 875000, 875000, 862500 },
+};
+#endif
+static void set_clkdiv(unsigned int div_index)
+{
+ unsigned int tmp;
+ unsigned int stat_cpu1;
+
+ /* Change Divider - CPU0 */
+
+ tmp = exynos4x12_clkdiv_table[div_index].clkdiv;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU);
+ } while (tmp & 0x11111111);
+
+#ifdef PRINT_DIV_VAL
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU);
+ pr_info("DIV_CPU0[0x%x]\n", tmp);
+
+#endif
+
+ /* Change Divider - CPU1 */
+ tmp = exynos4x12_clkdiv_table[div_index].clkdiv1;
+
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1);
+ if (soc_is_exynos4212())
+ stat_cpu1 = 0x11;
+ else
+ stat_cpu1 = 0x111;
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1);
+ } while (tmp & stat_cpu1);
+#ifdef PRINT_DIV_VAL
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1);
+ pr_info("DIV_CPU1[0x%x]\n", tmp);
+#endif
+}
+
+static void set_apll(unsigned int new_index,
+ unsigned int old_index)
+{
+ unsigned int tmp, pdiv;
+
+ /* 1. MUX_CORE_SEL = MPLL,
+ * ARMCLK uses MPLL for lock time */
+ if (clk_set_parent(moutcore, mout_mpll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ mout_mpll->name, moutcore->name);
+
+ do {
+ tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU)
+ >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
+ tmp &= 0x7;
+ } while (tmp != 0x2);
+
+ /* 2. Set APLL Lock time */
+ pdiv = ((exynos4x12_apll_pms_table[new_index] >> 8) & 0x3f);
+
+ __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK);
+
+ /* 3. Change PLL PMS values */
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
+ tmp |= exynos4x12_apll_pms_table[new_index];
+ __raw_writel(tmp, EXYNOS4_APLL_CON0);
+
+ /* 4. wait_lock_time */
+ do {
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT)));
+
+ /* 5. MUX_CORE_SEL = APLL */
+ if (clk_set_parent(moutcore, mout_apll))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ mout_apll->name, moutcore->name);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU);
+ tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
+ } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
+
+}
+
+bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index)
+{
+ unsigned int old_pm = (exynos4x12_apll_pms_table[old_index] >> 8);
+ unsigned int new_pm = (exynos4x12_apll_pms_table[new_index] >> 8);
+
+ return (old_pm == new_pm) ? 0 : 1;
+}
+
+static void exynos4x12_set_frequency(unsigned int old_index,
+ unsigned int new_index)
+{
+ unsigned int tmp;
+
+ if (old_index > new_index) {
+ if (!exynos4x12_pms_change(old_index, new_index)) {
+ /* 1. Change the system clock divider values */
+ set_clkdiv(new_index);
+ /* 2. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, EXYNOS4_APLL_CON0);
+
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the system clock divider values */
+ set_clkdiv(new_index);
+ /* 2. Change the apll m,p,s value */
+ set_apll(new_index, old_index);
+ }
+ } else if (old_index < new_index) {
+ if (!exynos4x12_pms_change(old_index, new_index)) {
+ /* 1. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(EXYNOS4_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (exynos4x12_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, EXYNOS4_APLL_CON0);
+ /* 2. Change the system clock divider values */
+ set_clkdiv(new_index);
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the apll m,p,s value */
+ set_apll(new_index, old_index);
+ /* 2. Change the system clock divider values */
+ set_clkdiv(new_index);
+ }
+ }
+
+ /* ABB value is changed in below case */
+ if (soc_is_exynos4412() && (exynos_result_of_asv > 3)) {
+ if (new_index == L13)
+ exynos4x12_set_abb_member(ABB_ARM, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_ARM, ABB_MODE_130V);
+ }
+}
+
+static void __init set_volt_table(void)
+{
+ bool for_1500 = false, for_1200 = false, for_1400 = false;
+ unsigned int i;
+
+#ifdef CONFIG_EXYNOS4X12_1500MHZ_SUPPORT
+ for_1500 = true;
+ max_support_idx = L0;
+#elif defined(CONFIG_EXYNOS4X12_1200MHZ_SUPPORT)
+ for_1200 = true;
+ max_support_idx = L3;
+#elif defined(CONFIG_EXYNOS4X12_1400MHZ_SUPPORT)
+ for_1400 = true;
+ max_support_idx = L1;
+
+ /* It doesn't support 1400Mhz under EVT1 or when IDS >= 40 */
+ if (samsung_rev() < EXYNOS4412_REV_1_0 || exynos_result_of_asv > 9) {
+ for_1200 = true;
+ max_support_idx = L3;
+ }
+#else
+ max_support_idx = L5;
+#endif
+ /*
+ * Should be fixed !!!
+ */
+#if 0
+ if ((asv_group == 0) || !for_1400)
+ exynos4212_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
+#else
+ if (!for_1500 && !for_1200 && !for_1400) {
+ exynos4x12_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos4x12_freq_table[L1].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos4x12_freq_table[L2].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos4x12_freq_table[L3].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos4x12_freq_table[L4].frequency = CPUFREQ_ENTRY_INVALID;
+ } else if (for_1200) {
+ exynos4x12_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos4x12_freq_table[L1].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos4x12_freq_table[L2].frequency = CPUFREQ_ENTRY_INVALID;
+ } else if (for_1400) {
+ exynos4x12_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
+ }
+
+#endif
+
+ pr_info("DVFS : VDD_ARM Voltage table set with %d Group\n", exynos_result_of_asv);
+
+ if (exynos_result_of_asv == 0xff) {
+ for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++)
+ exynos4x12_volt_table[i] = asv_voltage_s[i];
+ } else {
+ if (soc_is_exynos4212()) {
+ for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++)
+ exynos4x12_volt_table[i] =
+ asv_voltage_4212[i][exynos_result_of_asv];
+ } else if (soc_is_exynos4412()) {
+ for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++)
+ exynos4x12_volt_table[i] =
+ asv_voltage_step_12_5[i][exynos_result_of_asv];
+ } else {
+ pr_err("%s: Can't find SoC type \n", __func__);
+ }
+ }
+}
+
+/*
+ * The values of the table is not correct.
+ * Copied from C210 as prototype assuming that unmapping 512KiB
+ * requires 128 DMA operations.
+ */
+#ifdef CONFIG_SLP
+static struct dvfs_qos_info exynos4x12_dma_lat_qos[] = {
+ { 118, 200000, L13 },
+ { 40, 500000, L10 },
+ { 24, 800000, L7 },
+ { 16, 1000000, L5 },
+ {},
+};
+#endif
+
+int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+{
+ int i;
+ unsigned int tmp;
+ unsigned long rate;
+
+ set_volt_table();
+
+ cpu_clk = clk_get(NULL, "armclk");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ moutcore = clk_get(NULL, "moutcore");
+ if (IS_ERR(moutcore))
+ goto err_moutcore;
+
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(mout_mpll))
+ goto err_mout_mpll;
+
+ rate = clk_get_rate(mout_mpll) / 1000;
+
+ mout_apll = clk_get(NULL, "mout_apll");
+ if (IS_ERR(mout_apll))
+ goto err_mout_apll;
+
+ for (i = L0; i < CPUFREQ_LEVEL_END; i++) {
+
+ exynos4x12_clkdiv_table[i].index = i;
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU);
+
+ tmp &= ~(EXYNOS4_CLKDIV_CPU0_CORE_MASK |
+ EXYNOS4_CLKDIV_CPU0_COREM0_MASK |
+ EXYNOS4_CLKDIV_CPU0_COREM1_MASK |
+ EXYNOS4_CLKDIV_CPU0_PERIPH_MASK |
+ EXYNOS4_CLKDIV_CPU0_ATB_MASK |
+ EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK |
+ EXYNOS4_CLKDIV_CPU0_APLL_MASK |
+ EXYNOS4_CLKDIV_CPU0_CORE2_MASK);
+
+ if (soc_is_exynos4212()) {
+ tmp |= ((clkdiv_cpu0_4212[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) |
+ (clkdiv_cpu0_4212[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) |
+ (clkdiv_cpu0_4212[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) |
+ (clkdiv_cpu0_4212[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) |
+ (clkdiv_cpu0_4212[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) |
+ (clkdiv_cpu0_4212[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) |
+ (clkdiv_cpu0_4212[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) |
+ (clkdiv_cpu0_4212[i][7] << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT));
+ } else {
+ tmp |= ((clkdiv_cpu0_4412[i][0] << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT) |
+ (clkdiv_cpu0_4412[i][1] << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT) |
+ (clkdiv_cpu0_4412[i][2] << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT) |
+ (clkdiv_cpu0_4412[i][3] << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT) |
+ (clkdiv_cpu0_4412[i][4] << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT) |
+ (clkdiv_cpu0_4412[i][5] << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT) |
+ (clkdiv_cpu0_4412[i][6] << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT) |
+ (clkdiv_cpu0_4412[i][7] << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT));
+ }
+
+ exynos4x12_clkdiv_table[i].clkdiv = tmp;
+
+ tmp = __raw_readl(EXYNOS4_CLKDIV_CPU1);
+
+ if (soc_is_exynos4212()) {
+ tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK |
+ EXYNOS4_CLKDIV_CPU1_HPM_MASK);
+ tmp |= ((clkdiv_cpu1_4212[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) |
+ (clkdiv_cpu1_4212[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT));
+ } else {
+ tmp &= ~(EXYNOS4_CLKDIV_CPU1_COPY_MASK |
+ EXYNOS4_CLKDIV_CPU1_HPM_MASK |
+ EXYNOS4_CLKDIV_CPU1_CORES_MASK);
+ tmp |= ((clkdiv_cpu1_4412[i][0] << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT) |
+ (clkdiv_cpu1_4412[i][1] << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT) |
+ (clkdiv_cpu1_4412[i][2] << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT));
+ }
+ exynos4x12_clkdiv_table[i].clkdiv1 = tmp;
+ }
+
+ info->mpll_freq_khz = rate;
+#ifdef CONFIG_SLP
+ /* S-Boot at 20120406 uses L7 at bootup */
+ info->pm_lock_idx = L7;
+
+ /*
+ * However, the bootup frequency might get changed anytime.
+ * Thus, we'd like to get the value at bootup time.
+ */
+ rate = clk_get_rate(cpu_clk) / 1000;
+ for (i = 0; exynos4x12_freq_table[i].frequency != CPUFREQ_TABLE_END;
+ i++) {
+ if (exynos4x12_freq_table[i].frequency == rate) {
+ info->pm_lock_idx = exynos4x12_freq_table[i].index;
+ break;
+ }
+ }
+ pr_info("Bootup CPU Frequency = [%d] %dMHz\n", info->pm_lock_idx,
+ rate / 1000);
+#else
+ info->pm_lock_idx = L5;
+#endif
+ info->pll_safe_idx = L7;
+ info->max_support_idx = max_support_idx;
+ info->min_support_idx = min_support_idx;
+ info->cpu_clk = cpu_clk;
+ info->volt_table = exynos4x12_volt_table;
+ info->freq_table = exynos4x12_freq_table;
+ info->set_freq = exynos4x12_set_frequency;
+ info->need_apll_change = exynos4x12_pms_change;
+#ifdef CONFIG_SLP
+ info->cpu_dma_latency = exynos4x12_dma_lat_qos;
+#endif
+
+#ifdef ENABLE_CLKOUT
+ tmp = __raw_readl(EXYNOS4_CLKOUT_CMU_CPU);
+ tmp &= ~0xffff;
+ tmp |= 0x1904;
+ __raw_writel(tmp, EXYNOS4_CLKOUT_CMU_CPU);
+
+ exynos4_pmu_xclkout_set(1, XCLKOUT_CMU_CPU);
+#endif
+
+ return 0;
+
+err_mout_apll:
+ if (!IS_ERR(mout_mpll))
+ clk_put(mout_mpll);
+err_mout_mpll:
+ if (!IS_ERR(moutcore))
+ clk_put(moutcore);
+err_moutcore:
+ if (!IS_ERR(cpu_clk))
+ clk_put(cpu_clk);
+
+ pr_debug("%s: failed initialization\n", __func__);
+ return -EINVAL;
+}
+EXPORT_SYMBOL(exynos4x12_cpufreq_init);
diff --git a/arch/arm/mach-exynos/cpufreq-5250.c b/arch/arm/mach-exynos/cpufreq-5250.c
new file mode 100644
index 0000000..cf78c81
--- /dev/null
+++ b/arch/arm/mach-exynos/cpufreq-5250.c
@@ -0,0 +1,526 @@
+/* linux/arch/arm/mach-exynos/cpufreq-5250.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5250 - CPU frequency scaling support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu-5250.h>
+#include <mach/cpufreq.h>
+#include <mach/asv.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#define CPUFREQ_LEVEL_END (L20 + 1)
+
+#undef PRINT_DIV_VAL
+
+#undef ENABLE_CLKOUT
+
+static int max_support_idx;
+static int min_support_idx = (CPUFREQ_LEVEL_END - 1);
+static struct clk *cpu_clk;
+static struct clk *moutcore;
+static struct clk *mout_mpll;
+static struct clk *mout_apll;
+
+struct cpufreq_clkdiv {
+ unsigned int index;
+ unsigned int clkdiv;
+ unsigned int clkdiv1;
+};
+
+static unsigned int exynos5250_volt_table[CPUFREQ_LEVEL_END];
+
+static struct cpufreq_frequency_table exynos5250_freq_table[] = {
+ {L0, 2200*1000},
+ {L1, 2100*1000},
+ {L2, 2000*1000},
+ {L3, 1900*1000},
+ {L4, 1800*1000},
+ {L5, 1700*1000},
+ {L6, 1600*1000},
+ {L7, 1500*1000},
+ {L8, 1400*1000},
+ {L9, 1300*1000},
+ {L10, 1200*1000},
+ {L11, 1100*1000},
+ {L12, 1000*1000},
+ {L13, 900*1000},
+ {L14, 800*1000},
+ {L15, 700*1000},
+ {L16, 600*1000},
+ {L17, 500*1000},
+ {L18, 400*1000},
+ {L19, 300*1000},
+ {L20, 200*1000},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static struct cpufreq_clkdiv exynos5250_clkdiv_table[CPUFREQ_LEVEL_END];
+
+static unsigned int clkdiv_cpu0_5250[CPUFREQ_LEVEL_END][8] = {
+ /*
+ * Clock divider value for following
+ * { ARM, CPUD, ACP, PERIPH, ATB, PCLK_DBG, APLL, ARM2 }
+ */
+ { 0, 5, 7, 7, 7, 1, 5, 0 }, /* L0: 2200Mhz */
+ { 0, 5, 7, 7, 7, 1, 5, 0 }, /* L1: 2100Mhz */
+ { 0, 5, 7, 7, 7, 1, 5, 0 }, /* L2: 2000Mhz */
+ { 0, 4, 7, 7, 7, 1, 5, 0 }, /* L3: 1900Mhz */
+ { 0, 4, 7, 7, 7, 1, 4, 0 }, /* L4: 1800Mhz */
+ { 0, 3, 7, 7, 7, 3, 5, 0 }, /* L5: 1700Mhz */
+ { 0, 3, 7, 7, 7, 1, 4, 0 }, /* L6: 1600MHz */
+ { 0, 2, 7, 7, 7, 1, 4, 0 }, /* L7: 1500Mhz */
+ { 0, 2, 7, 7, 6, 1, 4, 0 }, /* L8: 1400Mhz */
+ { 0, 2, 7, 7, 6, 1, 3, 0 }, /* L9: 1300Mhz */
+ { 0, 2, 7, 7, 5, 1, 3, 0 }, /* L10: 1200Mhz */
+ { 0, 3, 7, 7, 5, 1, 3, 0 }, /* L11: 1100MHz */
+ { 0, 1, 7, 7, 4, 1, 2, 0 }, /* L12: 1000MHz */
+ { 0, 1, 7, 7, 4, 1, 2, 0 }, /* L13: 900MHz */
+ { 0, 1, 7, 7, 4, 1, 2, 0 }, /* L14: 800MHz */
+ { 0, 1, 7, 7, 3, 1, 1, 0 }, /* L15: 700MHz */
+ { 0, 1, 7, 7, 3, 1, 1, 0 }, /* L16: 600MHz */
+ { 0, 1, 7, 7, 2, 1, 1, 0 }, /* L17: 500MHz */
+ { 0, 1, 7, 7, 2, 1, 1, 0 }, /* L18: 400MHz */
+ { 0, 1, 7, 7, 1, 1, 1, 0 }, /* L19: 300MHz */
+ { 0, 1, 7, 7, 1, 1, 1, 0 }, /* L20: 200MHz */
+};
+
+static unsigned int clkdiv_cpu1_5250[CPUFREQ_LEVEL_END][2] = {
+ /* Clock divider value for following
+ * { COPY, HPM }
+ */
+ { 0, 2 }, /* L0: 2200Mhz */
+ { 0, 2 }, /* L1: 2100Mhz */
+ { 0, 2 }, /* L2: 2000Mhz */
+ { 0, 2 }, /* L3: 1900Mhz */
+ { 0, 2 }, /* L4: 1800Mhz */
+ { 0, 2 }, /* L5: 1700Mhz */
+ { 0, 2 }, /* L6: 1600MHz */
+ { 0, 2 }, /* L7: 1500Mhz */
+ { 0, 2 }, /* L8: 1400Mhz */
+ { 0, 2 }, /* L9: 1300Mhz */
+ { 0, 2 }, /* L10: 1200Mhz */
+ { 0, 2 }, /* L11: 1100MHz */
+ { 0, 2 }, /* L12: 1000MHz */
+ { 0, 2 }, /* L13: 900MHz */
+ { 0, 2 }, /* L14: 800MHz */
+ { 0, 2 }, /* L15: 700MHz */
+ { 0, 2 }, /* L16: 600MHz */
+ { 0, 2 }, /* L17: 500MHz */
+ { 0, 2 }, /* L18: 400MHz */
+ { 0, 2 }, /* L19: 300MHz */
+ { 0, 2 }, /* L20: 200MHz */
+};
+
+static unsigned int exynos5_apll_pms_table[CPUFREQ_LEVEL_END] = {
+ ((275<<16)|(3<<8)|(0)), /* L0: 2200Mhz */
+ ((350<<16)|(4<<8)|(0)), /* L1: 2100Mhz */
+ ((250<<16)|(3<<8)|(0)), /* L2: 2000Mhz */
+ ((475<<16)|(6<<8)|(0)), /* L3: 1900Mhz */
+ ((225<<16)|(3<<8)|(0)), /* L4: 1800Mhz */
+ ((425<<16)|(6<<8)|(0)), /* L5: 1700Mhz */
+ ((200<<16)|(3<<8)|(0)), /* L6: 1600MHz */
+ ((250<<16)|(4<<8)|(0)), /* L7: 1500Mhz */
+ ((175<<16)|(3<<8)|(0)), /* L8: 1400Mhz */
+ ((325<<16)|(6<<8)|(0)), /* L9: 1300Mhz */
+ ((200<<16)|(4<<8)|(0)), /* L10: 1200Mhz */
+ ((275<<16)|(6<<8)|(0)), /* L11: 1100MHz */
+ ((125<<16)|(3<<8)|(0)), /* L12: 1000MHz */
+ ((150<<16)|(4<<8)|(0)), /* L13: 900MHz */
+ ((100<<16)|(3<<8)|(0)), /* L14: 800MHz */
+ ((175<<16)|(3<<8)|(1)), /* L15: 700MHz */
+ ((200<<16)|(4<<8)|(1)), /* L16: 600MHz */
+ ((125<<16)|(3<<8)|(1)), /* L17: 500MHz */
+ ((100<<16)|(3<<8)|(1)), /* L18: 400MHz */
+ ((200<<16)|(4<<8)|(2)), /* L19: 300MHz */
+ ((100<<16)|(3<<8)|(2)), /* L20: 200MHz */
+};
+
+/*
+ * ASV group voltage table
+ */
+
+#define NUM_ASV_GROUP L10
+
+
+static const unsigned int asv_voltage[CPUFREQ_LEVEL_END][NUM_ASV_GROUP+1] = {
+ /* ASV0 is not exist */
+ /* ASV0, ASV1, ASV2, ASV3, ASV4, ASV5, ASV6, ASV7, ASV8, ASV9, ASV10 */
+ { 0 }, /* L0 */
+ { 0 }, /* L1 */
+ { 0 }, /* L2 */
+ { 0 }, /* L3 */
+ { 0 }, /* L4 */
+ { 0, 1300000, 1275000, 1287500, 1275000, 1275000, 1262500, 1250000, 1237500, 1225000, 1225000 }, /* L5 */
+ { 0, 1250000, 1237500, 1250000, 1237500, 1250000, 1237500, 1225000, 1212500, 1200000, 1200000 }, /* L6 */
+ { 0, 1225000, 1200000, 1212500, 1200000, 1212500, 1200000, 1187500, 1175000, 1175000, 1150000 }, /* L7 */
+ { 0, 1200000, 1175000, 1200000, 1175000, 1187500, 1175000, 1162500, 1150000, 1137500, 1125000 }, /* L8 */
+ { 0, 1150000, 1125000, 1150000, 1125000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000 }, /* L9 */
+ { 0, 1125000, 1112500, 1125000, 1112500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500 }, /* L10 */
+ { 0, 1100000, 1075000, 1100000, 1087500, 1100000, 1087500, 1075000, 1062500, 1050000, 1037500 }, /* L11 */
+ { 0, 1075000, 1050000, 1062500, 1050000, 1062500, 1050000, 1050000, 1037500, 1025000, 1012500 }, /* L12 */
+ { 0, 1050000, 1025000, 1050000, 1037500, 1050000, 1037500, 1025000, 1012500, 1000000, 987500 }, /* L13 */
+ { 0, 1025000, 1012500, 1025000, 1012500, 1025000, 1012500, 1000000, 1000000, 987500, 975000 }, /* L14 */
+ { 0, 1012500, 1000000, 1012500, 1000000, 1012500, 1000000, 987500, 975000, 975000, 962500 }, /* L15 */
+ { 0, 1000000, 975000, 1000000, 975000, 1000000, 987500, 975000, 962500, 962500, 950000 }, /* L16 */
+ { 0, 975000, 962500, 975000, 962500, 975000, 962500, 950000, 937500, 925000, 925000 }, /* L17 */
+ { 0, 950000, 937500, 950000, 937500, 950000, 937500, 925000, 925000, 925000, 912500 }, /* L18 */
+ { 0, 937500, 925000, 937500, 925000, 937500, 925000, 912500, 912500, 900000, 900000 }, /* L19 */
+ { 0, 925000, 912500, 925000, 912500, 925000, 912500, 900000, 900000, 887500, 887500 }, /* L20 */
+};
+
+static const unsigned int asv_voltage_rev0[CPUFREQ_LEVEL_END][NUM_ASV_GROUP] = {
+ { 0 }, /* L0 */
+ { 0 }, /* L1 */
+ { 0 }, /* L2 */
+ { 0 }, /* L3 */
+ { 0 }, /* L4 */
+ { 1200000 }, /* L5 */
+ { 1200000 }, /* L6 */
+ { 1200000 }, /* L7 */
+ { 1200000 }, /* L8 */
+ { 1200000 }, /* L9 */
+ { 1200000 }, /* L10 */
+ { 1200000 }, /* L11 */
+ { 1175000 }, /* L12 */
+ { 1125000 }, /* L13 */
+ { 1075000 }, /* L14 */
+ { 1050000 }, /* L15 */
+ { 1000000 }, /* L16 */
+ { 950000 }, /* L17 */
+ { 925000 }, /* L18 */
+ { 925000 }, /* L19 */
+ { 900000 }, /* L20 */
+};
+
+#if defined(CONFIG_EXYNOS5250_ABB_WA)
+#define ARM_RBB 6 /* +300mV */
+unsigned int exynos5250_arm_volt;
+
+#define INT_VOLT 1050000
+#endif
+
+static void set_clkdiv(unsigned int div_index)
+{
+ unsigned int tmp;
+
+ /* Change Divider - CPU0 */
+
+ tmp = exynos5250_clkdiv_table[div_index].clkdiv;
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_CPU0);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STATCPU0);
+ } while (tmp & 0x11111111);
+
+#ifdef PRINT_DIV_VAL
+ tmp = __raw_readl(EXYNOS5_CLKDIV_CPU0);
+ pr_info("DIV_CPU0[0x%x]\n", tmp);
+
+#endif
+
+ /* Change Divider - CPU1 */
+ tmp = exynos5250_clkdiv_table[div_index].clkdiv1;
+
+ __raw_writel(tmp, EXYNOS5_CLKDIV_CPU1);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKDIV_STATCPU1);
+ } while (tmp & 0x11);
+#ifdef PRINT_DIV_VAL
+ tmp = __raw_readl(EXYNOS5_CLKDIV_CPU1);
+ pr_info("DIV_CPU1[0x%x]\n", tmp);
+#endif
+}
+
+static void set_apll(unsigned int new_index,
+ unsigned int old_index)
+{
+ unsigned int tmp, pdiv;
+
+ /* 1. MUX_CORE_SEL = MPLL,
+ * ARMCLK uses MPLL for lock time */
+ if (clk_set_parent(moutcore, mout_mpll))
+ pr_err("Unable to set parent %s of clock %s.\n",
+ mout_mpll->name, moutcore->name);
+
+ do {
+ tmp = (__raw_readl(EXYNOS5_CLKMUX_STATCPU) >> 16);
+ tmp &= 0x7;
+ } while (tmp != 0x2);
+
+ /* 2. Set APLL Lock time */
+ pdiv = ((exynos5_apll_pms_table[new_index] >> 8) & 0x3f);
+
+ __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK);
+
+ /* 3. Change PLL PMS values */
+ tmp = __raw_readl(EXYNOS5_APLL_CON0);
+ tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
+ tmp |= exynos5_apll_pms_table[new_index];
+ __raw_writel(tmp, EXYNOS5_APLL_CON0);
+
+ /* 4. wait_lock_time */
+ do {
+ tmp = __raw_readl(EXYNOS5_APLL_CON0);
+ } while (!(tmp & (0x1 << 29)));
+
+ /* 5. MUX_CORE_SEL = APLL */
+ if (clk_set_parent(moutcore, mout_apll))
+ pr_err("Unable to set parent %s of clock %s.\n",
+ mout_apll->name, moutcore->name);
+
+ do {
+ tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU);
+ tmp &= (0x7 << 16);
+ } while (tmp != (0x1 << 16));
+
+}
+
+bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index)
+{
+ unsigned int old_pm = (exynos5_apll_pms_table[old_index] >> 8);
+ unsigned int new_pm = (exynos5_apll_pms_table[new_index] >> 8);
+
+ return (old_pm == new_pm) ? 0 : 1;
+}
+
+#if defined(CONFIG_EXYNOS5250_ABB_WA)
+static DEFINE_SPINLOCK(abb_lock);
+void exynos5250_set_arm_abbg(unsigned int arm_volt, unsigned int int_volt)
+{
+ unsigned int setbits = 8;
+ unsigned int tmp, diff_volt;
+ unsigned long flag;
+
+ spin_lock_irqsave(&abb_lock, flag);
+ if (arm_volt >= int_volt) {
+ diff_volt = arm_volt - int_volt;
+ setbits += diff_volt / 50000;
+ } else {
+ diff_volt = int_volt - arm_volt;
+ setbits -= diff_volt / 50000;
+ }
+ tmp = __raw_readl(EXYNOS5_ABBG_ARM_CONTROL);
+ tmp &= ~(0x1f | (1 << 31) | (1 << 7));
+ tmp |= ((setbits + ARM_RBB) | (1 << 31) | (1 << 7));
+ __raw_writel(tmp, EXYNOS5_ABBG_ARM_CONTROL);
+ spin_unlock_irqrestore(&abb_lock, flag);
+}
+EXPORT_SYMBOL(exynos5250_set_arm_abbg);
+#endif
+
+static void exynos5250_set_frequency(unsigned int old_index,
+ unsigned int new_index)
+{
+ unsigned int tmp;
+#if defined(CONFIG_EXYNOS5250_ABB_WA)
+ unsigned int voltage;
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ voltage = asv_voltage_rev0[new_index][0];
+ exynos5250_set_arm_abbg(voltage, INT_VOLT);
+ }
+#endif
+ if (old_index > new_index) {
+ if (!exynos5250_pms_change(old_index, new_index)) {
+ /* 1. Change the system clock divider values */
+ set_clkdiv(new_index);
+ /* 2. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(EXYNOS5_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (exynos5_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, EXYNOS5_APLL_CON0);
+
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the system clock divider values */
+ set_clkdiv(new_index);
+ /* 2. Change the apll m,p,s value */
+ set_apll(new_index, old_index);
+ }
+ } else if (old_index < new_index) {
+ if (!exynos5250_pms_change(old_index, new_index)) {
+ /* 1. Change just s value in apll m,p,s value */
+ tmp = __raw_readl(EXYNOS5_APLL_CON0);
+ tmp &= ~(0x7 << 0);
+ tmp |= (exynos5_apll_pms_table[new_index] & 0x7);
+ __raw_writel(tmp, EXYNOS5_APLL_CON0);
+ /* 2. Change the system clock divider values */
+ set_clkdiv(new_index);
+ } else {
+ /* Clock Configuration Procedure */
+ /* 1. Change the apll m,p,s value */
+ set_apll(new_index, old_index);
+ /* 2. Change the system clock divider values */
+ set_clkdiv(new_index);
+ }
+ }
+}
+
+static void __init set_volt_table(void)
+{
+ unsigned int asv_group;
+ unsigned int i;
+
+ if (soc_is_exynos5250()) {
+ exynos5250_freq_table[L0].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L1].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L2].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L3].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L4].frequency = CPUFREQ_ENTRY_INVALID;
+
+ switch (samsung_rev() & 0xf0) {
+ case EXYNOS5250_REV_0:
+ exynos5250_freq_table[L5].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L6].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L7].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L8].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L9].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L10].frequency = CPUFREQ_ENTRY_INVALID;
+ exynos5250_freq_table[L11].frequency = CPUFREQ_ENTRY_INVALID;
+
+ max_support_idx = L12;
+ break;
+ case EXYNOS5250_REV_1_0:
+ max_support_idx = L5;
+ break;
+ default:
+ pr_err("%s: Can't find cpu revision(%d) type\n", __func__,
+ samsung_rev());
+ break;
+ }
+ }
+
+ if (soc_is_exynos5250() && samsung_rev() < EXYNOS5250_REV_1_0)
+ asv_group = 0;
+ else
+ asv_group = exynos_result_of_asv;
+
+ pr_info("DVFS : VDD_ARM Voltage table set with %d Group\n", asv_group);
+ pr_info("DVFS : VDD_ARM Voltage of max level is %d\n", asv_voltage[max_support_idx][asv_group]);
+
+ for (i = 0 ; i < CPUFREQ_LEVEL_END ; i++) {
+ if (samsung_rev() < EXYNOS5250_REV_1_0)
+ exynos5250_volt_table[i] = asv_voltage_rev0[i][asv_group];
+ else
+ exynos5250_volt_table[i] = asv_voltage[i][asv_group];
+ }
+}
+
+int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
+{
+ int i;
+ unsigned int tmp;
+ unsigned long rate;
+
+ set_volt_table();
+
+ cpu_clk = clk_get(NULL, "armclk");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ moutcore = clk_get(NULL, "moutcpu");
+ if (IS_ERR(moutcore))
+ goto err_moutcore;
+
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ if (IS_ERR(mout_mpll))
+ goto err_mout_mpll;
+
+ rate = clk_get_rate(mout_mpll) / 1000;
+
+ mout_apll = clk_get(NULL, "mout_apll");
+ if (IS_ERR(mout_apll))
+ goto err_mout_apll;
+
+ for (i = L0; i < CPUFREQ_LEVEL_END; i++) {
+
+ exynos5250_clkdiv_table[i].index = i;
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_CPU0);
+
+ tmp &= ~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) |
+ (0x7 << 12) | (0x7 << 16) | (0x7 << 20) |
+ (0x7 << 24) | (0x7 << 28));
+
+ tmp |= ((clkdiv_cpu0_5250[i][0] << 0) |
+ (clkdiv_cpu0_5250[i][1] << 4) |
+ (clkdiv_cpu0_5250[i][2] << 8) |
+ (clkdiv_cpu0_5250[i][3] << 12) |
+ (clkdiv_cpu0_5250[i][4] << 16) |
+ (clkdiv_cpu0_5250[i][5] << 20) |
+ (clkdiv_cpu0_5250[i][6] << 24) |
+ (clkdiv_cpu0_5250[i][7] << 28));
+
+ exynos5250_clkdiv_table[i].clkdiv = tmp;
+
+ tmp = __raw_readl(EXYNOS5_CLKDIV_CPU1);
+
+ tmp &= ~((0x7 << 0) | (0x7 << 4));
+
+ tmp |= ((clkdiv_cpu1_5250[i][0] << 0) |
+ (clkdiv_cpu1_5250[i][1] << 4));
+
+ exynos5250_clkdiv_table[i].clkdiv1 = tmp;
+ }
+
+ info->mpll_freq_khz = rate;
+ /* 1000Mhz */
+ info->pm_lock_idx = L12;
+ /* 800Mhz */
+ info->pll_safe_idx = L14;
+ info->max_support_idx = max_support_idx;
+ info->min_support_idx = min_support_idx;
+ info->cpu_clk = cpu_clk;
+ info->volt_table = exynos5250_volt_table;
+ info->freq_table = exynos5250_freq_table;
+ info->set_freq = exynos5250_set_frequency;
+ info->need_apll_change = exynos5250_pms_change;
+
+#ifdef ENABLE_CLKOUT
+ tmp = __raw_readl(EXYNOS5_CLKOUT_CMU_CPU);
+ p &= ~0xffff;
+ tmp |= 0x1904;
+ __raw_writel(tmp, EXYNOS5_CLKOUT_CMU_CPU);
+
+ tmp = __raw_readl(S5P_PMU_DEBUG);
+ tmp &= ~0xf00;
+ tmp |= 0x400;
+ __raw_writel(tmp, S5P_PMU_DEBUG);
+
+#endif
+ return 0;
+
+err_mout_apll:
+ if (!IS_ERR(mout_mpll))
+ clk_put(mout_mpll);
+err_mout_mpll:
+ if (!IS_ERR(moutcore))
+ clk_put(moutcore);
+err_moutcore:
+ if (!IS_ERR(cpu_clk))
+ clk_put(cpu_clk);
+
+ pr_err("%s: failed initialization\n", __func__);
+ return -EINVAL;
+}
+EXPORT_SYMBOL(exynos5250_cpufreq_init);
diff --git a/arch/arm/mach-exynos/cpufreq.c b/arch/arm/mach-exynos/cpufreq.c
new file mode 100644
index 0000000..e78dad9
--- /dev/null
+++ b/arch/arm/mach-exynos/cpufreq.c
@@ -0,0 +1,830 @@
+/* linux/arch/arm/mach-exynos/cpufreq.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - CPU frequency scaling support for EXYNOS series
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/cpufreq.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/pm_qos_params.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+#include <mach/cpufreq.h>
+#include <mach/asv.h>
+
+#include <plat/clock.h>
+#include <plat/pm.h>
+#include <plat/cpu.h>
+
+struct exynos_dvfs_info *exynos_info;
+
+static struct regulator *arm_regulator;
+static struct cpufreq_freqs freqs;
+
+static bool exynos_cpufreq_disable;
+static bool exynos_cpufreq_lock_disable;
+static bool exynos_cpufreq_init_done;
+static DEFINE_MUTEX(set_freq_lock);
+static DEFINE_MUTEX(set_cpu_freq_lock);
+
+unsigned int g_cpufreq_limit_id;
+unsigned int g_cpufreq_limit_val[DVFS_LOCK_ID_END];
+unsigned int g_cpufreq_limit_level;
+
+unsigned int g_cpufreq_lock_id;
+unsigned int g_cpufreq_lock_val[DVFS_LOCK_ID_END];
+unsigned int g_cpufreq_lock_level;
+
+int exynos_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ exynos_info->freq_table);
+}
+
+unsigned int exynos_getspeed(unsigned int cpu)
+{
+ return clk_get_rate(exynos_info->cpu_clk) / 1000;
+}
+
+static unsigned int exynos_get_safe_armvolt(unsigned int old_index, unsigned int new_index)
+{
+ unsigned int safe_arm_volt = 0;
+ struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
+ unsigned int *volt_table = exynos_info->volt_table;
+
+ /*
+ * ARM clock source will be changed APLL to MPLL temporary
+ * To support this level, need to control regulator for
+ * reguired voltage level
+ */
+
+ if (exynos_info->need_apll_change != NULL) {
+ if (exynos_info->need_apll_change(old_index, new_index) &&
+ (freq_table[new_index].frequency < exynos_info->mpll_freq_khz) &&
+ (freq_table[old_index].frequency < exynos_info->mpll_freq_khz)) {
+ safe_arm_volt = volt_table[exynos_info->pll_safe_idx];
+ }
+
+ }
+
+ return safe_arm_volt;
+}
+
+static int exynos_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int index, old_index = UINT_MAX;
+ unsigned int arm_volt, safe_arm_volt = 0;
+ int ret = 0, i;
+ struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
+ unsigned int *volt_table = exynos_info->volt_table;
+
+ mutex_lock(&set_freq_lock);
+
+ if (exynos_cpufreq_disable)
+ goto out;
+
+ freqs.old = policy->cur;
+
+ /*
+ * cpufreq_frequency_table_target() cannot be used for freqs.old
+ * because policy->min/max may have been changed. If changed, the
+ * resulting old_index may be inconsistent with freqs.old, which
+ * will lead to inconsistent voltage/frequency configurations later.
+ */
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ if (freq_table[i].frequency == freqs.old)
+ old_index = freq_table[i].index;
+ }
+ if (old_index == UINT_MAX) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (cpufreq_frequency_table_target(policy, freq_table,
+ target_freq, relation, &index)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* Need to set performance limitation */
+ if (!exynos_cpufreq_lock_disable && (index > g_cpufreq_lock_level))
+ index = g_cpufreq_lock_level;
+
+ if (!exynos_cpufreq_lock_disable && (index < g_cpufreq_limit_level))
+ index = g_cpufreq_limit_level;
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+ /* Do NOT step up max arm clock directly to reduce power consumption */
+ if (index == exynos_info->max_support_idx && old_index > 3)
+ index = 3;
+#endif
+
+ freqs.new = freq_table[index].frequency;
+ freqs.cpu = policy->cpu;
+
+ safe_arm_volt = exynos_get_safe_armvolt(old_index, index);
+
+ arm_volt = volt_table[index];
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* When the new frequency is higher than current frequency */
+ if ((freqs.new > freqs.old) && !safe_arm_volt) {
+ /* Firstly, voltage up to increase frequency */
+ regulator_set_voltage(arm_regulator, arm_volt,
+ arm_volt + 25000);
+ }
+
+ if (safe_arm_volt)
+ regulator_set_voltage(arm_regulator, safe_arm_volt,
+ safe_arm_volt + 25000);
+ if (freqs.new != freqs.old)
+ exynos_info->set_freq(old_index, index);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ /* When the new frequency is lower than current frequency */
+ if ((freqs.new < freqs.old) ||
+ ((freqs.new > freqs.old) && safe_arm_volt)) {
+ /* down the voltage after frequency change */
+ regulator_set_voltage(arm_regulator, arm_volt,
+ arm_volt + 25000);
+ }
+
+out:
+ mutex_unlock(&set_freq_lock);
+
+ return ret;
+}
+
+/**
+ * exynos_find_cpufreq_level_by_volt - find cpufreqi_level by requested
+ * arm voltage.
+ *
+ * This function finds the cpufreq_level to set for voltage above req_volt
+ * and return its value.
+ */
+int exynos_find_cpufreq_level_by_volt(unsigned int arm_volt,
+ unsigned int *level)
+{
+ struct cpufreq_frequency_table *table;
+ unsigned int *volt_table = exynos_info->volt_table;
+ int i;
+
+ if (!exynos_cpufreq_init_done)
+ return -EINVAL;
+
+ table = cpufreq_frequency_get_table(0);
+ if (!table) {
+ pr_err("%s: Failed to get the cpufreq table\n", __func__);
+ return -EINVAL;
+ }
+
+ /* check if arm_volt has value or not */
+ if (!arm_volt) {
+ pr_err("%s: req_volt has no value.\n", __func__);
+ return -EINVAL;
+ }
+
+ /* find cpufreq level in volt_table */
+ for (i = exynos_info->min_support_idx;
+ i >= exynos_info->max_support_idx; i--) {
+ if (volt_table[i] >= arm_volt) {
+ *level = (unsigned int)i;
+ return 0;
+ }
+ }
+
+ pr_err("%s: Failed to get level for %u uV\n", __func__, arm_volt);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(exynos_find_cpufreq_level_by_volt);
+
+int exynos_cpufreq_get_level(unsigned int freq, unsigned int *level)
+{
+ struct cpufreq_frequency_table *table;
+ unsigned int i;
+
+ if (!exynos_cpufreq_init_done)
+ return -EINVAL;
+
+ table = cpufreq_frequency_get_table(0);
+ if (!table) {
+ pr_err("%s: Failed to get the cpufreq table\n", __func__);
+ return -EINVAL;
+ }
+
+ for (i = exynos_info->max_support_idx;
+ (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ if (table[i].frequency == freq) {
+ *level = i;
+ return 0;
+ }
+ }
+
+ pr_err("%s: %u KHz is an unsupported cpufreq\n", __func__, freq);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(exynos_cpufreq_get_level);
+
+atomic_t exynos_cpufreq_lock_count;
+
+int exynos_cpufreq_lock(unsigned int nId,
+ enum cpufreq_level_index cpufreq_level)
+{
+ int ret = 0, i, old_idx = -EINVAL;
+ unsigned int freq_old, freq_new, arm_volt, safe_arm_volt;
+ unsigned int *volt_table;
+ struct cpufreq_policy *policy;
+ struct cpufreq_frequency_table *freq_table;
+
+ if (!exynos_cpufreq_init_done)
+ return -EPERM;
+
+ if (!exynos_info)
+ return -EPERM;
+
+ if (exynos_cpufreq_disable && (nId != DVFS_LOCK_ID_TMU)) {
+ pr_info("CPUFreq is already fixed\n");
+ return -EPERM;
+ }
+
+ if (cpufreq_level < exynos_info->max_support_idx
+ || cpufreq_level > exynos_info->min_support_idx) {
+ pr_warn("%s: invalid cpufreq_level(%d:%d)\n", __func__, nId,
+ cpufreq_level);
+ return -EINVAL;
+ }
+
+ policy = cpufreq_cpu_get(0);
+ if (!policy)
+ return -EPERM;
+
+ volt_table = exynos_info->volt_table;
+ freq_table = exynos_info->freq_table;
+
+ mutex_lock(&set_cpu_freq_lock);
+ if (g_cpufreq_lock_id & (1 << nId)) {
+ printk(KERN_ERR "%s:Device [%d] already locked cpufreq\n",
+ __func__, nId);
+ mutex_unlock(&set_cpu_freq_lock);
+ return 0;
+ }
+
+ g_cpufreq_lock_id |= (1 << nId);
+ g_cpufreq_lock_val[nId] = cpufreq_level;
+
+ /* If the requested cpufreq is higher than current min frequency */
+ if (cpufreq_level < g_cpufreq_lock_level)
+ g_cpufreq_lock_level = cpufreq_level;
+
+ mutex_unlock(&set_cpu_freq_lock);
+
+ if ((g_cpufreq_lock_level < g_cpufreq_limit_level)
+ && (nId != DVFS_LOCK_ID_PM))
+ return 0;
+
+ /* Do not setting cpufreq lock frequency
+ * because current governor doesn't support dvfs level lock
+ * except DVFS_LOCK_ID_PM */
+ if (exynos_cpufreq_lock_disable && (nId != DVFS_LOCK_ID_PM))
+ return 0;
+
+ /* If current frequency is lower than requested freq,
+ * it needs to update
+ */
+ mutex_lock(&set_freq_lock);
+ freq_old = policy->cur;
+ freq_new = freq_table[cpufreq_level].frequency;
+ if (freq_old < freq_new) {
+ /* Find out current level index */
+ for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ if (freq_old == freq_table[i].frequency) {
+ old_idx = freq_table[i].index;
+ break;
+ }
+ }
+ if (old_idx == -EINVAL) {
+ printk(KERN_ERR "%s: Level not found\n", __func__);
+ mutex_unlock(&set_freq_lock);
+ return -EINVAL;
+ }
+
+ freqs.old = freq_old;
+ freqs.new = freq_new;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* get the voltage value */
+ safe_arm_volt = exynos_get_safe_armvolt(old_idx, cpufreq_level);
+ if (safe_arm_volt)
+ regulator_set_voltage(arm_regulator, safe_arm_volt,
+ safe_arm_volt + 25000);
+
+ arm_volt = volt_table[cpufreq_level];
+ regulator_set_voltage(arm_regulator, arm_volt,
+ arm_volt + 25000);
+
+ exynos_info->set_freq(old_idx, cpufreq_level);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ mutex_unlock(&set_freq_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(exynos_cpufreq_lock);
+
+void exynos_cpufreq_lock_free(unsigned int nId)
+{
+ unsigned int i;
+
+ if (!exynos_cpufreq_init_done)
+ return;
+
+ mutex_lock(&set_cpu_freq_lock);
+ g_cpufreq_lock_id &= ~(1 << nId);
+ g_cpufreq_lock_val[nId] = exynos_info->min_support_idx;
+ g_cpufreq_lock_level = exynos_info->min_support_idx;
+ if (g_cpufreq_lock_id) {
+ for (i = 0; i < DVFS_LOCK_ID_END; i++) {
+ if (g_cpufreq_lock_val[i] < g_cpufreq_lock_level)
+ g_cpufreq_lock_level = g_cpufreq_lock_val[i];
+ }
+ }
+ mutex_unlock(&set_cpu_freq_lock);
+}
+EXPORT_SYMBOL_GPL(exynos_cpufreq_lock_free);
+
+#ifdef CONFIG_SLP
+static int exynos_cpu_dma_qos_notify(struct notifier_block *nb,
+ unsigned long value, void *data)
+{
+ int i;
+ struct dvfs_qos_info *table;
+ enum cpufreq_level_index last_lvl = L0;
+
+ if (!exynos_info || !exynos_info->cpu_dma_latency)
+ return NOTIFY_DONE;
+
+ if (value == 0 || value == PM_QOS_DEFAULT_VALUE ||
+ value == PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE) {
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_QOS_DMA_LATENCY);
+ return NOTIFY_OK;
+ }
+
+ table = exynos_info->cpu_dma_latency;
+
+ for (i = 0; table[i].qos_value; i++) {
+ if (value >= table[i].qos_value) {
+ exynos_cpufreq_lock(DVFS_LOCK_ID_QOS_DMA_LATENCY,
+ table[i].level);
+ return NOTIFY_OK;
+ }
+ last_lvl = table[i].level;
+ }
+
+ if (last_lvl > L0)
+ last_lvl--;
+
+ exynos_cpufreq_lock(DVFS_LOCK_ID_QOS_DMA_LATENCY, last_lvl);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block pm_qos_cpu_dma_notifier = {
+ .notifier_call = exynos_cpu_dma_qos_notify,
+};
+#endif /* CONFIG_SLP */
+
+int exynos_cpufreq_upper_limit(unsigned int nId,
+ enum cpufreq_level_index cpufreq_level)
+{
+ int ret = 0, old_idx = 0, i;
+ unsigned int freq_old, freq_new, arm_volt, safe_arm_volt;
+ unsigned int *volt_table;
+ struct cpufreq_policy *policy;
+ struct cpufreq_frequency_table *freq_table;
+
+ if (!exynos_cpufreq_init_done)
+ return -EPERM;
+
+ if (!exynos_info)
+ return -EPERM;
+
+ if (exynos_cpufreq_disable) {
+ pr_info("CPUFreq is already fixed\n");
+ return -EPERM;
+ }
+
+ if (cpufreq_level < exynos_info->max_support_idx
+ || cpufreq_level > exynos_info->min_support_idx) {
+ pr_warn("%s: invalid cpufreq_level(%d:%d)\n", __func__, nId,
+ cpufreq_level);
+ return -EINVAL;
+ }
+
+ policy = cpufreq_cpu_get(0);
+ if (!policy)
+ return -EPERM;
+
+ volt_table = exynos_info->volt_table;
+ freq_table = exynos_info->freq_table;
+
+ mutex_lock(&set_cpu_freq_lock);
+ if (g_cpufreq_limit_id & (1 << nId)) {
+ pr_err("[CPUFREQ]This device [%d] already limited cpufreq\n", nId);
+ mutex_unlock(&set_cpu_freq_lock);
+ return 0;
+ }
+
+ g_cpufreq_limit_id |= (1 << nId);
+ g_cpufreq_limit_val[nId] = cpufreq_level;
+
+ /* If the requested limit level is lower than current value */
+ if (cpufreq_level > g_cpufreq_limit_level)
+ g_cpufreq_limit_level = cpufreq_level;
+
+ mutex_unlock(&set_cpu_freq_lock);
+
+ mutex_lock(&set_freq_lock);
+ /* If cur frequency is higher than limit freq, it needs to update */
+ freq_old = policy->cur;
+ freq_new = freq_table[cpufreq_level].frequency;
+ if (freq_old > freq_new) {
+ /* Find out current level index */
+ for (i = 0; i <= exynos_info->min_support_idx; i++) {
+ if (freq_old == freq_table[i].frequency) {
+ old_idx = freq_table[i].index;
+ break;
+ } else if (i == exynos_info->min_support_idx) {
+ printk(KERN_ERR "%s: Level is not found\n", __func__);
+ mutex_unlock(&set_freq_lock);
+
+ return -EINVAL;
+ } else {
+ continue;
+ }
+ }
+ freqs.old = freq_old;
+ freqs.new = freq_new;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ exynos_info->set_freq(old_idx, cpufreq_level);
+
+ safe_arm_volt = exynos_get_safe_armvolt(old_idx, cpufreq_level);
+ if (safe_arm_volt)
+ regulator_set_voltage(arm_regulator, safe_arm_volt,
+ safe_arm_volt + 25000);
+
+ arm_volt = volt_table[cpufreq_level];
+ regulator_set_voltage(arm_regulator, arm_volt, arm_volt + 25000);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+
+ mutex_unlock(&set_freq_lock);
+
+ return ret;
+}
+
+void exynos_cpufreq_upper_limit_free(unsigned int nId)
+{
+ unsigned int i;
+
+ if (!exynos_cpufreq_init_done)
+ return;
+
+ mutex_lock(&set_cpu_freq_lock);
+ g_cpufreq_limit_id &= ~(1 << nId);
+ g_cpufreq_limit_val[nId] = exynos_info->max_support_idx;
+ g_cpufreq_limit_level = exynos_info->max_support_idx;
+
+ if (g_cpufreq_limit_id) {
+ for (i = 0; i < DVFS_LOCK_ID_END; i++) {
+ if (g_cpufreq_limit_val[i] > g_cpufreq_limit_level)
+ g_cpufreq_limit_level = g_cpufreq_limit_val[i];
+ }
+ }
+ mutex_unlock(&set_cpu_freq_lock);
+}
+
+/* This API serve highest priority level locking */
+int exynos_cpufreq_level_fix(unsigned int freq)
+{
+ struct cpufreq_policy *policy;
+ int ret = 0;
+
+ if (!exynos_cpufreq_init_done)
+ return -EPERM;
+
+ policy = cpufreq_cpu_get(0);
+ if (!policy)
+ return -EPERM;
+
+ if (exynos_cpufreq_disable) {
+ pr_info("CPUFreq is already fixed\n");
+ return -EPERM;
+ }
+ ret = exynos_target(policy, freq, CPUFREQ_RELATION_L);
+
+ exynos_cpufreq_disable = true;
+ return ret;
+
+}
+EXPORT_SYMBOL_GPL(exynos_cpufreq_level_fix);
+
+void exynos_cpufreq_level_unfix(void)
+{
+ if (!exynos_cpufreq_init_done)
+ return;
+
+ exynos_cpufreq_disable = false;
+}
+EXPORT_SYMBOL_GPL(exynos_cpufreq_level_unfix);
+
+int exynos_cpufreq_is_fixed(void)
+{
+ return exynos_cpufreq_disable;
+}
+EXPORT_SYMBOL_GPL(exynos_cpufreq_is_fixed);
+
+#ifdef CONFIG_PM
+static int exynos_cpufreq_suspend(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+
+static int exynos_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+#endif
+
+static void exynos_save_gov_freq(void)
+{
+ unsigned int cpu = 0;
+
+ exynos_info->gov_support_freq = exynos_getspeed(cpu);
+ pr_debug("cur_freq[%d] saved to freq[%d]\n", exynos_getspeed(0),
+ exynos_info->gov_support_freq);
+}
+
+static void exynos_restore_gov_freq(struct cpufreq_policy *policy)
+{
+ unsigned int cpu = 0;
+
+ if (exynos_getspeed(cpu) != exynos_info->gov_support_freq)
+ exynos_target(policy, exynos_info->gov_support_freq,
+ CPUFREQ_RELATION_H);
+
+ pr_debug("freq[%d] restored to cur_freq[%d]\n",
+ exynos_info->gov_support_freq, exynos_getspeed(cpu));
+}
+
+static int exynos_cpufreq_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ int ret = 0;
+ unsigned int cpu = 0;
+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ case PM_HIBERNATION_PREPARE:
+ case PM_RESTORE_PREPARE:
+ /* If current governor is userspace or performance or powersave,
+ * save the current cpufreq before sleep.
+ */
+ if (exynos_cpufreq_lock_disable)
+ exynos_save_gov_freq();
+
+ ret = exynos_cpufreq_lock(DVFS_LOCK_ID_PM,
+ exynos_info->pm_lock_idx);
+ if (ret < 0)
+ return NOTIFY_BAD;
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SLP)
+ ret = exynos_cpufreq_upper_limit(DVFS_LOCK_ID_PM,
+ exynos_info->pm_lock_idx);
+ if (ret < 0)
+ return NOTIFY_BAD;
+#endif
+ exynos_cpufreq_disable = true;
+
+#ifdef CONFIG_SLP
+ /*
+ * Safe Voltage for Suspend/Wakeup: Falling back to the
+ * default value of bootloaders.
+ * Note that at suspended state, this 'high' voltage does
+ * not incur higher power consumption because it is OFF.
+ * This is for the stability during suspend/wakeup process.
+ */
+ regulator_set_voltage(arm_regulator, 120000, 120000 + 25000);
+#endif
+
+ pr_debug("PM_SUSPEND_PREPARE for CPUFREQ\n");
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ pr_debug("PM_POST_SUSPEND for CPUFREQ: %d\n", ret);
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_PM);
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SLP)
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_PM);
+#endif
+ exynos_cpufreq_disable = false;
+ /* If current governor is userspace or performance or powersave,
+ * restore the saved cpufreq after waekup.
+ */
+ if (exynos_cpufreq_lock_disable)
+ exynos_restore_gov_freq(policy);
+
+
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos_cpufreq_notifier = {
+ .notifier_call = exynos_cpufreq_notifier_event,
+};
+
+static int exynos_cpufreq_policy_notifier_call(struct notifier_block *this,
+ unsigned long code, void *data)
+{
+ struct cpufreq_policy *policy = data;
+
+ switch (code) {
+ case CPUFREQ_ADJUST:
+ if ((!strnicmp(policy->governor->name, "powersave", CPUFREQ_NAME_LEN))
+ || (!strnicmp(policy->governor->name, "performance", CPUFREQ_NAME_LEN))
+ || (!strnicmp(policy->governor->name, "userspace", CPUFREQ_NAME_LEN))) {
+ printk(KERN_DEBUG "cpufreq governor is changed to %s\n",
+ policy->governor->name);
+ exynos_cpufreq_lock_disable = true;
+ } else
+ exynos_cpufreq_lock_disable = false;
+
+ case CPUFREQ_INCOMPATIBLE:
+ case CPUFREQ_NOTIFY:
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos_cpufreq_policy_notifier = {
+ .notifier_call = exynos_cpufreq_policy_notifier_call,
+};
+
+
+static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ policy->cur = policy->min = policy->max = exynos_getspeed(policy->cpu);
+
+ cpufreq_frequency_table_get_attr(exynos_info->freq_table, policy->cpu);
+
+ /* set the transition latency value */
+ policy->cpuinfo.transition_latency = 100000;
+
+ /*
+ * EXYNOS4 multi-core processors has 2 cores
+ * that the frequency cannot be set independently.
+ * Each cpu is bound to the same speed.
+ * So the affected cpu is all of the cpus.
+ */
+ if (num_online_cpus() == 1) {
+ cpumask_copy(policy->related_cpus, cpu_possible_mask);
+ cpumask_copy(policy->cpus, cpu_online_mask);
+ } else {
+ cpumask_setall(policy->cpus);
+ }
+
+ return cpufreq_frequency_table_cpuinfo(policy, exynos_info->freq_table);
+}
+
+static int exynos_cpufreq_reboot_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ int ret = 0;
+
+ ret = exynos_cpufreq_lock(DVFS_LOCK_ID_PM, exynos_info->pm_lock_idx);
+ if (ret < 0)
+ return NOTIFY_BAD;
+
+ printk(KERN_INFO "REBOOT Notifier for CPUFREQ\n");
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos_cpufreq_reboot_notifier = {
+ .notifier_call = exynos_cpufreq_reboot_notifier_call,
+};
+
+static struct cpufreq_driver exynos_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = exynos_verify_speed,
+ .target = exynos_target,
+ .get = exynos_getspeed,
+ .init = exynos_cpufreq_cpu_init,
+ .name = "exynos_cpufreq",
+#ifdef CONFIG_PM
+ .suspend = exynos_cpufreq_suspend,
+ .resume = exynos_cpufreq_resume,
+#endif
+};
+
+static int __init exynos_cpufreq_init(void)
+{
+ int ret = -EINVAL;
+ int i;
+
+ exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL);
+ if (!exynos_info)
+ return -ENOMEM;
+
+ if (soc_is_exynos4210())
+ ret = exynos4210_cpufreq_init(exynos_info);
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ ret = exynos4x12_cpufreq_init(exynos_info);
+ else if (soc_is_exynos5250())
+ ret = exynos5250_cpufreq_init(exynos_info);
+ else
+ pr_err("%s: CPU type not found\n", __func__);
+
+ if (ret)
+ goto err_vdd_arm;
+
+ if (exynos_info->set_freq == NULL) {
+ printk(KERN_ERR "%s: No set_freq function (ERR)\n",
+ __func__);
+ goto err_vdd_arm;
+ }
+
+ arm_regulator = regulator_get(NULL, "vdd_arm");
+ if (IS_ERR(arm_regulator)) {
+ printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
+ goto err_vdd_arm;
+ }
+
+ exynos_cpufreq_disable = false;
+
+ register_pm_notifier(&exynos_cpufreq_notifier);
+ register_reboot_notifier(&exynos_cpufreq_reboot_notifier);
+ cpufreq_register_notifier(&exynos_cpufreq_policy_notifier,
+ CPUFREQ_POLICY_NOTIFIER);
+
+ exynos_cpufreq_init_done = true;
+
+ for (i = 0; i < DVFS_LOCK_ID_END; i++) {
+ g_cpufreq_lock_val[i] = exynos_info->min_support_idx;
+ g_cpufreq_limit_val[i] = exynos_info->max_support_idx;
+ }
+
+ g_cpufreq_lock_level = exynos_info->min_support_idx;
+ g_cpufreq_limit_level = exynos_info->max_support_idx;
+
+ if (cpufreq_register_driver(&exynos_driver)) {
+ pr_err("failed to register cpufreq driver\n");
+ goto err_cpufreq;
+ }
+
+#ifdef CONFIG_SLP
+ if (exynos_info->cpu_dma_latency)
+ pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
+ &pm_qos_cpu_dma_notifier);
+#endif
+
+ return 0;
+err_cpufreq:
+ unregister_reboot_notifier(&exynos_cpufreq_reboot_notifier);
+ unregister_pm_notifier(&exynos_cpufreq_notifier);
+
+ if (!IS_ERR(arm_regulator))
+ regulator_put(arm_regulator);
+err_vdd_arm:
+ kfree(exynos_info);
+ pr_debug("%s: failed initialization\n", __func__);
+ return -EINVAL;
+}
+late_initcall(exynos_cpufreq_init);
diff --git a/arch/arm/mach-exynos/cpuidle-exynos4.c b/arch/arm/mach-exynos/cpuidle-exynos4.c
new file mode 100644
index 0000000..6afdacd
--- /dev/null
+++ b/arch/arm/mach-exynos/cpuidle-exynos4.c
@@ -0,0 +1,1024 @@
+/* linux/arch/arm/mach-exynos/cpuidle-exynos4.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/proc-fns.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu.h>
+#include <mach/pmu.h>
+#include <mach/gpio.h>
+#include <mach/smc.h>
+#include <mach/clock-domain.h>
+#include <mach/regs-audss.h>
+#include <mach/asv.h>
+#include <mach/regs-usb-phy.h>
+
+#include <plat/regs-otg.h>
+#include <plat/exynos4.h>
+#include <plat/pm.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+#include <plat/regs-watchdog.h>
+#endif
+#include <mach/regs-usb-phy.h>
+#include <plat/usb-phy.h>
+
+
+#ifdef CONFIG_ARM_TRUSTZONE
+#define REG_DIRECTGO_ADDR (S5P_VA_SYSRAM_NS + 0x24)
+#define REG_DIRECTGO_FLAG (S5P_VA_SYSRAM_NS + 0x20)
+#else
+#define REG_DIRECTGO_ADDR (samsung_rev() < EXYNOS4210_REV_1_1 ?\
+ (S5P_VA_SYSRAM + 0x24) : S5P_INFORM7)
+#define REG_DIRECTGO_FLAG (samsung_rev() < EXYNOS4210_REV_1_1 ?\
+ (S5P_VA_SYSRAM + 0x20) : S5P_INFORM6)
+#endif
+
+#include <asm/hardware/gic.h>
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+extern unsigned long sys_pwr_conf_addr;
+extern unsigned int l2x0_save[3];
+extern unsigned int scu_save[2];
+
+enum hc_type {
+ HC_SDHC,
+ HC_MSHC,
+};
+
+enum idle_clock_down {
+ HW_CLK_DWN,
+ SW_CLK_DWN,
+};
+
+unsigned int use_clock_down;
+
+struct check_device_op {
+ void __iomem *base;
+ struct platform_device *pdev;
+ enum hc_type type;
+};
+
+#ifdef CONFIG_MACH_MIDAS
+unsigned int log_en = 1;
+#else
+unsigned int log_en;
+#endif
+module_param_named(log_en, log_en, uint, 0644);
+
+#if defined(CONFIG_MACH_MIDAS) || defined(CONFIG_SLP)
+#define CPUDILE_ENABLE_MASK (ENABLE_LPA)
+#else
+#define CPUDILE_ENABLE_MASK (ENABLE_AFTR | ENABLE_LPA)
+#endif
+
+static enum {
+ ENABLE_IDLE = 0x0,
+ ENABLE_AFTR = 0x1,
+ ENABLE_LPA = 0x2
+} enable_mask = CPUDILE_ENABLE_MASK;
+module_param_named(enable_mask, enable_mask, uint, 0644);
+
+#define ENABLE_LOWPWRMASK (ENABLE_AFTR | ENABLE_LPA)
+
+static struct check_device_op chk_sdhc_op[] = {
+#if defined(CONFIG_EXYNOS4_DEV_DWMCI)
+ {.base = 0, .pdev = &exynos_device_dwmci, .type = HC_MSHC},
+#endif
+#if defined(CONFIG_EXYNOS4_DEV_MSHC)
+ {.base = 0, .pdev = &s3c_device_mshci, .type = HC_MSHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC)
+ {.base = 0, .pdev = &s3c_device_hsmmc0, .type = HC_SDHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC1)
+ {.base = 0, .pdev = &s3c_device_hsmmc1, .type = HC_SDHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC2)
+ {.base = 0, .pdev = &s3c_device_hsmmc2, .type = HC_SDHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC3)
+ {.base = 0, .pdev = &s3c_device_hsmmc3, .type = HC_SDHC},
+#endif
+};
+
+#if defined(CONFIG_USB_S3C_OTGD) && !defined(CONFIG_USB_EXYNOS_SWITCH)
+static struct check_device_op chk_usbotg_op = {
+ .base = 0, .pdev = &s3c_device_usbgadget, .type = 0
+};
+#endif
+
+#define S3C_HSMMC_PRNSTS (0x24)
+#define S3C_HSMMC_CLKCON (0x2c)
+#define S3C_HSMMC_CMD_INHIBIT 0x00000001
+#define S3C_HSMMC_DATA_INHIBIT 0x00000002
+#define S3C_HSMMC_CLOCK_CARD_EN 0x0004
+
+#define MSHCI_CLKENA (0x10) /* Clock enable */
+#define MSHCI_STATUS (0x48) /* Status */
+#define MSHCI_DATA_BUSY (0x1<<9)
+#define MSHCI_DATA_STAT_BUSY (0x1<<10)
+#define MSHCI_ENCLK (0x1)
+
+#define GPIO_OFFSET 0x20
+#define GPIO_PUD_OFFSET 0x08
+#define GPIO_CON_PDN_OFFSET 0x10
+#define GPIO_PUD_PDN_OFFSET 0x14
+#define GPIO_END_OFFSET 0x200
+
+/* GPIO_END_OFFSET value of exynos4212 */
+#define GPIO1_END_OFFSET 0x280
+#define GPIO2_END_OFFSET 0x200
+#define GPIO4_END_OFFSET 0xE0
+
+static void exynos4_gpio_conpdn_reg(void)
+{
+ void __iomem *gpio_base = S5P_VA_GPIO;
+ unsigned int val;
+
+ do {
+ /* Keep the previous state in didle mode */
+ __raw_writel(0xffff, gpio_base + GPIO_CON_PDN_OFFSET);
+
+ /* Pull up-down state in didle is same as normal */
+ val = __raw_readl(gpio_base + GPIO_PUD_OFFSET);
+ __raw_writel(val, gpio_base + GPIO_PUD_PDN_OFFSET);
+
+ gpio_base += GPIO_OFFSET;
+
+ if (gpio_base == S5P_VA_GPIO + GPIO_END_OFFSET)
+ gpio_base = S5P_VA_GPIO2;
+
+ } while (gpio_base <= S5P_VA_GPIO2 + GPIO_END_OFFSET);
+
+ /* set the GPZ */
+ gpio_base = S5P_VA_GPIO3;
+ __raw_writel(0xffff, gpio_base + GPIO_CON_PDN_OFFSET);
+
+ val = __raw_readl(gpio_base + GPIO_PUD_OFFSET);
+ __raw_writel(val, gpio_base + GPIO_PUD_PDN_OFFSET);
+}
+
+static void exynos4212_gpio_conpdn_reg(void)
+{
+ void __iomem *gpio_base = S5P_VA_GPIO;
+ unsigned int val;
+
+ do {
+ /* Keep the previous state in didle mode */
+ __raw_writel(0xffff, gpio_base + GPIO_CON_PDN_OFFSET);
+
+ /* Pull up-down state in didle is same as normal */
+ val = __raw_readl(gpio_base + GPIO_PUD_OFFSET);
+ __raw_writel(val, gpio_base + GPIO_PUD_PDN_OFFSET);
+
+ gpio_base += GPIO_OFFSET;
+
+ /* Skip gpio_base there aren't gpios in part1 & part4 of exynos4212 */
+ if (gpio_base == (S5P_VA_GPIO + 0xE0))
+ gpio_base = S5P_VA_GPIO + 0x180;
+ else if (gpio_base == (S5P_VA_GPIO + 0x200))
+ gpio_base = S5P_VA_GPIO + 0x240;
+ else if (gpio_base == (S5P_VA_GPIO4 + 0x40))
+ gpio_base = S5P_VA_GPIO4 + 0x60;
+ else if (gpio_base == (S5P_VA_GPIO4 + 0xA0))
+ gpio_base = S5P_VA_GPIO4 + 0xC0;
+
+ if (gpio_base == S5P_VA_GPIO + GPIO1_END_OFFSET)
+ gpio_base = S5P_VA_GPIO2 + 0x40; /* GPK0CON */
+
+ if (gpio_base == S5P_VA_GPIO2 + GPIO2_END_OFFSET)
+ gpio_base = S5P_VA_GPIO4;
+
+ } while (gpio_base <= S5P_VA_GPIO4 + GPIO4_END_OFFSET);
+
+ /* set the GPZ */
+ gpio_base = S5P_VA_GPIO3;
+ __raw_writel(0xffff, gpio_base + GPIO_CON_PDN_OFFSET);
+
+ val = __raw_readl(gpio_base + GPIO_PUD_OFFSET);
+ __raw_writel(val, gpio_base + GPIO_PUD_PDN_OFFSET);
+}
+
+static int check_power_domain(void)
+{
+ unsigned long tmp;
+
+ tmp = __raw_readl(S5P_PMU_LCD0_CONF);
+ if ((tmp & S5P_INT_LOCAL_PWR_EN) == S5P_INT_LOCAL_PWR_EN)
+ return 1;
+
+ tmp = __raw_readl(S5P_PMU_MFC_CONF);
+ if ((tmp & S5P_INT_LOCAL_PWR_EN) == S5P_INT_LOCAL_PWR_EN)
+ return 1;
+
+ tmp = __raw_readl(S5P_PMU_G3D_CONF);
+ if ((tmp & S5P_INT_LOCAL_PWR_EN) == S5P_INT_LOCAL_PWR_EN)
+ return 1;
+
+ tmp = __raw_readl(S5P_PMU_CAM_CONF);
+ if ((tmp & S5P_INT_LOCAL_PWR_EN) == S5P_INT_LOCAL_PWR_EN)
+ return 1;
+
+ tmp = __raw_readl(S5P_PMU_TV_CONF);
+ if ((tmp & S5P_INT_LOCAL_PWR_EN) == S5P_INT_LOCAL_PWR_EN)
+ return 1;
+
+ tmp = __raw_readl(S5P_PMU_GPS_CONF);
+ if ((tmp & S5P_INT_LOCAL_PWR_EN) == S5P_INT_LOCAL_PWR_EN)
+ return 1;
+
+ return 0;
+}
+
+static int __maybe_unused check_clock_gating(void)
+{
+ unsigned long tmp;
+
+ tmp = __raw_readl(EXYNOS4_CLKGATE_IP_IMAGE);
+ if (tmp & (EXYNOS4_CLKGATE_IP_IMAGE_MDMA | EXYNOS4_CLKGATE_IP_IMAGE_SMMUMDMA
+ | EXYNOS4_CLKGATE_IP_IMAGE_QEMDMA))
+ return 1;
+
+ tmp = __raw_readl(EXYNOS4_CLKGATE_IP_FSYS);
+ if (tmp & (EXYNOS4_CLKGATE_IP_FSYS_PDMA0 | EXYNOS4_CLKGATE_IP_FSYS_PDMA1))
+ return 1;
+
+ tmp = __raw_readl(EXYNOS4_CLKGATE_IP_PERIL);
+ if (tmp & EXYNOS4_CLKGATE_IP_PERIL_I2C0_7)
+ return 1;
+
+ return 0;
+}
+
+static int sdmmc_dev_num;
+/* If SD/MMC interface is working: return = 1 or not 0 */
+static int check_sdmmc_op(unsigned int ch)
+{
+ unsigned int reg1, reg2;
+ void __iomem *base_addr;
+
+ if (unlikely(ch >= sdmmc_dev_num)) {
+ printk(KERN_ERR "Invalid ch[%d] for SD/MMC\n", ch);
+ return 0;
+ }
+
+ if (chk_sdhc_op[ch].type == HC_SDHC) {
+ base_addr = chk_sdhc_op[ch].base;
+ /* Check CLKCON [2]: ENSDCLK */
+ reg2 = readl(base_addr + S3C_HSMMC_CLKCON);
+ return !!(reg2 & (S3C_HSMMC_CLOCK_CARD_EN));
+ } else if (chk_sdhc_op[ch].type == HC_MSHC) {
+ base_addr = chk_sdhc_op[ch].base;
+ /* Check STATUS [9] for data busy */
+ reg1 = readl(base_addr + MSHCI_STATUS);
+ return (reg1 & (MSHCI_DATA_BUSY)) ||
+ (reg1 & (MSHCI_DATA_STAT_BUSY));
+
+ }
+ /* should not be here */
+ return 0;
+}
+
+/* Check all sdmmc controller */
+static int loop_sdmmc_check(void)
+{
+ unsigned int iter;
+
+ for (iter = 0; iter < sdmmc_dev_num; iter++) {
+ if (check_sdmmc_op(iter))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Check USB Device and Host is working or not
+ * USB_S3C-OTGD can check GOTGCTL register
+ * GOTGCTL(0xEC000000)
+ * BSesVld (Indicates the Device mode transceiver status)
+ * BSesVld = 1b : B-session is valid
+ * 0b : B-session is not valiid
+ * USB_EXYNOS_SWITCH can check Both Host and Device status.
+ */
+static int check_usb_op(void)
+{
+#if defined(CONFIG_USB_S3C_OTGD) && !defined(CONFIG_USB_EXYNOS_SWITCH)
+ void __iomem *base_addr;
+ unsigned int val;
+
+ base_addr = chk_usbotg_op.base;
+ val = __raw_readl(base_addr + S3C_UDC_OTG_GOTGCTL);
+
+ return val & (A_SESSION_VALID | B_SESSION_VALID);
+#elif defined(CONFIG_USB_EXYNOS_SWITCH)
+ return exynos_check_usb_op();
+#else
+ return 0;
+#endif
+}
+
+#ifdef CONFIG_SND_SAMSUNG_RP
+extern int srp_get_op_level(void); /* By srp driver */
+#endif
+
+#if defined(CONFIG_BT)
+static inline int check_bt_op(void)
+{
+ extern int bt_is_running;
+
+ return bt_is_running;
+}
+#endif
+
+static int gps_is_running;
+
+void set_gps_uart_op(int onoff)
+{
+ pr_info("%s: %s\n", __func__, onoff ? "on" : "off");
+ gps_is_running = onoff;
+}
+
+static inline int check_gps_uart_op(void)
+{
+ return gps_is_running;
+}
+
+static int exynos4_check_operation(void)
+{
+ if (check_power_domain())
+ return 1;
+
+ if (clock_domain_enabled(LPA_DOMAIN))
+ return 1;
+
+ if (loop_sdmmc_check())
+ return 1;
+#ifdef CONFIG_SND_SAMSUNG_RP
+ if (srp_get_op_level())
+ return 1;
+#endif
+ if (check_usb_op())
+ return 1;
+
+#if defined(CONFIG_BT)
+ if (check_bt_op())
+ return 1;
+#endif
+
+ if (check_gps_uart_op())
+ return 1;
+
+ if (exynos4_check_usb_op())
+ return 1;
+
+ return 0;
+}
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+static struct sleep_save exynos4_aftr_save[] = {
+ SAVE_ITEM(S3C2410_WTDAT),
+ SAVE_ITEM(S3C2410_WTCNT),
+ SAVE_ITEM(S3C2410_WTCON),
+};
+#endif
+
+static struct sleep_save exynos4_lpa_save[] = {
+ /* CMU side */
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
+ SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ SAVE_ITEM(S3C2410_WTDAT),
+ SAVE_ITEM(S3C2410_WTCNT),
+ SAVE_ITEM(S3C2410_WTCON),
+#endif
+};
+
+static struct sleep_save exynos4_set_clksrc[] = {
+ { .reg = EXYNOS4_CLKSRC_MASK_TOP , .val = 0x00000001, },
+ { .reg = EXYNOS4_CLKSRC_MASK_CAM , .val = 0x11111111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_TV , .val = 0x00000111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_LCD0 , .val = 0x00001111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO , .val = 0x00000001, },
+ { .reg = EXYNOS4_CLKSRC_MASK_FSYS , .val = 0x01011111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_PERIL0 , .val = 0x01111111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_PERIL1 , .val = 0x01110111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_DMC , .val = 0x00010000, },
+};
+
+static struct sleep_save exynos4210_set_clksrc[] = {
+ { .reg = EXYNOS4_CLKSRC_MASK_LCD1 , .val = 0x00001111, },
+};
+
+static int exynos4_check_enter(void)
+{
+ unsigned int ret;
+ unsigned int check_val;
+
+ ret = 0;
+
+ /* Check UART for console is empty */
+ check_val = __raw_readl(S5P_VA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT) +
+ 0x18);
+
+ ret = ((check_val >> 16) & 0xff);
+
+ return ret;
+}
+
+void exynos4_flush_cache(void *addr, phys_addr_t phy_ttb_base)
+{
+ outer_clean_range(virt_to_phys(addr - 0x40),
+ virt_to_phys(addr + 0x40));
+ outer_clean_range(virt_to_phys(cpu_resume),
+ virt_to_phys(cpu_resume + 0x40));
+ outer_clean_range(phy_ttb_base, phy_ttb_base + 0xffff);
+ flush_cache_all();
+}
+
+static void exynos4_set_wakeupmask(void)
+{
+ __raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
+}
+
+static void vfp_enable(void *unused)
+{
+ u32 access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+}
+
+static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+ unsigned long tmp, abb_val;
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ s3c_pm_do_save(exynos4_aftr_save, ARRAY_SIZE(exynos4_aftr_save));
+#endif
+
+ local_irq_disable();
+
+ if (log_en)
+ pr_info("+++aftr\n");
+
+ do_gettimeofday(&before);
+
+ exynos4_set_wakeupmask();
+
+ __raw_writel(virt_to_phys(exynos4_idle_resume), REG_DIRECTGO_ADDR);
+ __raw_writel(0xfcba0d10, REG_DIRECTGO_FLAG);
+
+ /* Set value of power down register for aftr mode */
+ exynos4_sys_powerdown_conf(SYS_AFTR);
+
+ if (!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(0);
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+ if (!soc_is_exynos4210()) {
+ abb_val = exynos4x12_get_abb_member(ABB_ARM);
+ exynos4x12_set_abb_member(ABB_ARM, ABB_MODE_075V);
+ }
+#endif
+
+ if (exynos4_enter_lp(0, PLAT_PHYS_OFFSET - PAGE_OFFSET) == 0) {
+
+ /*
+ * Clear Central Sequence Register in exiting early wakeup
+ */
+ tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+ tmp |= (S5P_CENTRAL_LOWPWR_CFG);
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+
+ goto early_wakeup;
+ }
+ flush_tlb_all();
+
+ cpu_init();
+
+ vfp_enable(NULL);
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ s3c_pm_do_restore_core(exynos4_aftr_save,
+ ARRAY_SIZE(exynos4_aftr_save));
+#endif
+
+early_wakeup:
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+ if ((exynos_result_of_asv > 1) && !soc_is_exynos4210())
+ exynos4x12_set_abb_member(ABB_ARM, abb_val);
+#endif
+
+ if (!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(1);
+
+ /* Clear wakeup state register */
+ __raw_writel(0x0, S5P_WAKEUP_STAT);
+
+ do_gettimeofday(&after);
+
+ if (log_en)
+ pr_info("---aftr\n");
+
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+ return idle_time;
+}
+
+extern void bt_uart_rts_ctrl(int flag);
+
+static int exynos4_enter_core0_lpa(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+ unsigned long tmp, abb_val, abb_val_int;
+
+ s3c_pm_do_save(exynos4_lpa_save, ARRAY_SIZE(exynos4_lpa_save));
+
+ /*
+ * Before enter central sequence mode, clock src register have to set
+ */
+ s3c_pm_do_restore_core(exynos4_set_clksrc,
+ ARRAY_SIZE(exynos4_set_clksrc));
+
+ if (soc_is_exynos4210())
+ s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
+
+#if defined(CONFIG_BT)
+ /* BT-UART RTS Control (RTS High) */
+ bt_uart_rts_ctrl(1);
+#endif
+ local_irq_disable();
+
+ if (log_en)
+ pr_info("+++lpa\n");
+
+ do_gettimeofday(&before);
+
+ /*
+ * Unmasking all wakeup source.
+ */
+ __raw_writel(0x3ff0000, S5P_WAKEUP_MASK);
+
+ /* Configure GPIO Power down control register */
+#ifdef CONFIG_MIDAS_COMMON
+ if (exynos4_sleep_gpio_table_set)
+ exynos4_sleep_gpio_table_set();
+ else
+#endif
+ exynos4_gpio_conpdn_reg();
+
+ /* ensure at least INFORM0 has the resume address */
+ __raw_writel(virt_to_phys(exynos4_idle_resume), S5P_INFORM0);
+
+ __raw_writel(virt_to_phys(exynos4_idle_resume), REG_DIRECTGO_ADDR);
+ __raw_writel(0xfcba0d10, REG_DIRECTGO_FLAG);
+
+ __raw_writel(S5P_CHECK_LPA, S5P_INFORM1);
+ exynos4_sys_powerdown_conf(SYS_LPA);
+
+ /* Should be fixed on EVT1 */
+ if (!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(0);
+
+ do {
+ /* Waiting for flushing UART fifo */
+ } while (exynos4_check_enter());
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+ if (!soc_is_exynos4210()) {
+ abb_val = exynos4x12_get_abb_member(ABB_ARM);
+ abb_val_int = exynos4x12_get_abb_member(ABB_INT);
+ exynos4x12_set_abb_member(ABB_ARM, ABB_MODE_075V);
+ exynos4x12_set_abb_member(ABB_INT, ABB_MODE_075V);
+ }
+#endif
+
+ if (exynos4_enter_lp(0, PLAT_PHYS_OFFSET - PAGE_OFFSET) == 0) {
+
+ /*
+ * Clear Central Sequence Register in exiting early wakeup
+ */
+ tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+ tmp |= (S5P_CENTRAL_LOWPWR_CFG);
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+
+ goto early_wakeup;
+ }
+ flush_tlb_all();
+
+ cpu_init();
+
+ vfp_enable(NULL);
+
+ /* For release retention */
+ __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
+
+early_wakeup:
+ s3c_pm_do_restore_core(exynos4_lpa_save,
+ ARRAY_SIZE(exynos4_lpa_save));
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+ if ((exynos_result_of_asv > 1) && !soc_is_exynos4210()) {
+ exynos4x12_set_abb_member(ABB_ARM, abb_val);
+ exynos4x12_set_abb_member(ABB_INT, abb_val_int);
+ }
+#endif
+
+ if (!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(1);
+
+ /* Clear wakeup state register */
+ __raw_writel(0x0, S5P_WAKEUP_STAT);
+
+ __raw_writel(0x0, S5P_WAKEUP_MASK);
+
+ do_gettimeofday(&after);
+
+ if (log_en)
+ pr_info("---lpa\n");
+
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+#if defined(CONFIG_BT)
+ /* BT-UART RTS Control (RTS Low) */
+ bt_uart_rts_ctrl(0);
+#endif
+
+ return idle_time;
+}
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+
+static int exynos4_enter_lowpower(struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+
+static struct cpuidle_state exynos4_cpuidle_set[] = {
+ [0] = {
+ .enter = exynos4_enter_idle,
+ .exit_latency = 1,
+ .target_residency = 10000,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "IDLE",
+ .desc = "ARM clock gating(WFI)",
+ },
+#ifdef CONFIG_EXYNOS4_LOWPWR_IDLE
+ [1] = {
+ .enter = exynos4_enter_lowpower,
+ .exit_latency = 300,
+ .target_residency = 10000,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "LOW_POWER",
+ .desc = "ARM power down",
+ },
+#endif
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
+
+static struct cpuidle_driver exynos4_idle_driver = {
+ .name = "exynos4_idle",
+ .owner = THIS_MODULE,
+};
+
+static unsigned int cpu_core;
+static unsigned int old_div;
+static DEFINE_SPINLOCK(idle_lock);
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+ int cpu;
+ unsigned int tmp;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ if (use_clock_down == SW_CLK_DWN) {
+ /* USE SW Clock Down */
+ cpu = get_cpu();
+
+ spin_lock(&idle_lock);
+ cpu_core |= (1 << cpu);
+
+ if ((cpu_core == 0x3) || (cpu_online(1) == 0)) {
+ old_div = __raw_readl(EXYNOS4_CLKDIV_CPU);
+ tmp = old_div;
+ tmp |= ((0x7 << 28) | (0x7 << 0));
+ __raw_writel(tmp, EXYNOS4_CLKDIV_CPU);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU);
+ } while (tmp & 0x10000001);
+
+ }
+
+ spin_unlock(&idle_lock);
+
+ cpu_do_idle();
+
+ spin_lock(&idle_lock);
+
+ if ((cpu_core == 0x3) || (cpu_online(1) == 0)) {
+ __raw_writel(old_div, EXYNOS4_CLKDIV_CPU);
+
+ do {
+ tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU);
+ } while (tmp & 0x10000001);
+
+ }
+
+ cpu_core &= ~(1 << cpu);
+ spin_unlock(&idle_lock);
+
+ put_cpu();
+ } else
+ cpu_do_idle();
+
+ do_gettimeofday(&after);
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+ return idle_time;
+}
+
+static int exynos4_check_entermode(void)
+{
+ unsigned int ret;
+ unsigned int mask = (enable_mask & ENABLE_LOWPWRMASK);
+
+ if (!mask)
+ return 0;
+
+ if ((mask & ENABLE_LPA) && !exynos4_check_operation())
+ ret = S5P_CHECK_LPA;
+ else if (mask & ENABLE_AFTR)
+ ret = S5P_CHECK_DIDLE;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static int exynos4_enter_lowpower(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct cpuidle_state *new_state = state;
+ unsigned int enter_mode;
+ unsigned int tmp;
+
+ /* This mode only can be entered when only Core0 is online */
+ if (num_online_cpus() != 1) {
+ BUG_ON(!dev->safe_state);
+ new_state = dev->safe_state;
+ }
+ dev->last_state = new_state;
+
+ if (!soc_is_exynos4210()) {
+ tmp = S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0;
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
+ }
+
+ if (new_state == &dev->states[0])
+ return exynos4_enter_idle(dev, new_state);
+
+ enter_mode = exynos4_check_entermode();
+ if (!enter_mode)
+ return exynos4_enter_idle(dev, new_state);
+ else if (enter_mode == S5P_CHECK_DIDLE)
+ return exynos4_enter_core0_aftr(dev, new_state);
+ else
+ return exynos4_enter_core0_lpa(dev, new_state);
+}
+
+static int exynos4_cpuidle_notifier_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ disable_hlt();
+ pr_debug("PM_SUSPEND_PREPARE for CPUIDLE\n");
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ enable_hlt();
+ pr_debug("PM_POST_SUSPEND for CPUIDLE\n");
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos4_cpuidle_notifier = {
+ .notifier_call = exynos4_cpuidle_notifier_event,
+};
+
+#ifdef CONFIG_EXYNOS4_ENABLE_CLOCK_DOWN
+static void __init exynos4_core_down_clk(void)
+{
+ unsigned int tmp;
+
+ tmp = __raw_readl(EXYNOS4_PWR_CTRL1);
+
+ tmp &= ~(PWR_CTRL1_CORE2_DOWN_MASK | PWR_CTRL1_CORE1_DOWN_MASK);
+
+ /* set arm clock divider value on idle state */
+ tmp |= ((0x7 << PWR_CTRL1_CORE2_DOWN_RATIO) |
+ (0x7 << PWR_CTRL1_CORE1_DOWN_RATIO));
+
+ if (soc_is_exynos4212()) {
+ /* Set PWR_CTRL1 register to use clock down feature */
+ tmp |= (PWR_CTRL1_DIV2_DOWN_EN |
+ PWR_CTRL1_DIV1_DOWN_EN |
+ PWR_CTRL1_USE_CORE1_WFE |
+ PWR_CTRL1_USE_CORE0_WFE |
+ PWR_CTRL1_USE_CORE1_WFI |
+ PWR_CTRL1_USE_CORE0_WFI);
+ } else if (soc_is_exynos4412()) {
+ tmp |= (PWR_CTRL1_DIV2_DOWN_EN |
+ PWR_CTRL1_DIV1_DOWN_EN |
+ PWR_CTRL1_USE_CORE3_WFE |
+ PWR_CTRL1_USE_CORE2_WFE |
+ PWR_CTRL1_USE_CORE1_WFE |
+ PWR_CTRL1_USE_CORE0_WFE |
+ PWR_CTRL1_USE_CORE3_WFI |
+ PWR_CTRL1_USE_CORE2_WFI |
+ PWR_CTRL1_USE_CORE1_WFI |
+ PWR_CTRL1_USE_CORE0_WFI);
+ }
+
+ __raw_writel(tmp, EXYNOS4_PWR_CTRL1);
+
+ tmp = __raw_readl(EXYNOS4_PWR_CTRL2);
+
+ tmp &= ~(PWR_CTRL2_DUR_STANDBY2_MASK | PWR_CTRL2_DUR_STANDBY1_MASK |
+ PWR_CTRL2_CORE2_UP_MASK | PWR_CTRL2_CORE1_UP_MASK);
+
+ /* set duration value on middle wakeup step */
+ tmp |= ((0x1 << PWR_CTRL2_DUR_STANDBY2) |
+ (0x1 << PWR_CTRL2_DUR_STANDBY1));
+
+ /* set arm clock divier value on middle wakeup step */
+ tmp |= ((0x1 << PWR_CTRL2_CORE2_UP_RATIO) |
+ (0x1 << PWR_CTRL2_CORE1_UP_RATIO));
+
+ /* Set PWR_CTRL2 register to use step up for arm clock */
+ tmp |= (PWR_CTRL2_DIV2_UP_EN | PWR_CTRL2_DIV1_UP_EN);
+
+ __raw_writel(tmp, EXYNOS4_PWR_CTRL2);
+
+ printk(KERN_INFO "Exynos4 : ARM Clock down on idle mode is enabled\n");
+}
+#else
+#define exynos4_core_down_clk() do { } while (0)
+#endif
+
+static int __init exynos4_init_cpuidle(void)
+{
+ int i, max_cpuidle_state, cpu_id, ret;
+ struct cpuidle_device *device;
+ struct platform_device *pdev;
+ struct resource *res;
+
+ if (soc_is_exynos4210())
+ use_clock_down = SW_CLK_DWN;
+ else
+ use_clock_down = HW_CLK_DWN;
+
+ /* Clock down feature can use only EXYNOS4212 */
+ if (use_clock_down == HW_CLK_DWN)
+ exynos4_core_down_clk();
+
+ ret = cpuidle_register_driver(&exynos4_idle_driver);
+
+ if(ret < 0){
+ printk(KERN_ERR "exynos4 idle register driver failed\n");
+ return ret;
+ }
+
+ for_each_cpu(cpu_id, cpu_online_mask) {
+ device = &per_cpu(exynos4_cpuidle_device, cpu_id);
+ device->cpu = cpu_id;
+
+ if (cpu_id == 0)
+ device->state_count = ARRAY_SIZE(exynos4_cpuidle_set);
+ else
+ device->state_count = 1; /* Support IDLE only */
+
+ max_cpuidle_state = device->state_count;
+
+ for (i = 0; i < max_cpuidle_state; i++) {
+ memcpy(&device->states[i], &exynos4_cpuidle_set[i],
+ sizeof(struct cpuidle_state));
+ }
+
+ device->safe_state = &device->states[0];
+
+ if (cpuidle_register_device(device)) {
+ cpuidle_unregister_driver(&exynos4_idle_driver);
+ printk(KERN_ERR "CPUidle register device failed\n,");
+ return -EIO;
+ }
+ }
+
+ sdmmc_dev_num = ARRAY_SIZE(chk_sdhc_op);
+
+ for (i = 0; i < sdmmc_dev_num; i++) {
+
+ pdev = chk_sdhc_op[i].pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ printk(KERN_ERR "failed to get iomem region\n");
+ return -EINVAL;
+ }
+
+ chk_sdhc_op[i].base = ioremap(res->start, resource_size(res));
+
+ if (!chk_sdhc_op[i].base) {
+ printk(KERN_ERR "failed to map io region\n");
+ return -EINVAL;
+ }
+ }
+
+#if defined(CONFIG_USB_S3C_OTGD) && !defined(CONFIG_USB_EXYNOS_SWITCH)
+ pdev = chk_usbotg_op.pdev;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ printk(KERN_ERR "failed to get iomem region\n");
+ return -EINVAL;
+ }
+
+ chk_usbotg_op.base = ioremap(res->start, resource_size(res));
+
+ if (!chk_usbotg_op.base) {
+ printk(KERN_ERR "failed to map io region\n");
+ return -EINVAL;
+ }
+#endif
+ register_pm_notifier(&exynos4_cpuidle_notifier);
+ sys_pwr_conf_addr = (unsigned long)S5P_CENTRAL_SEQ_CONFIGURATION;
+
+ /* Save register value for SCU */
+ scu_save[0] = __raw_readl(S5P_VA_SCU + 0x30);
+ scu_save[1] = __raw_readl(S5P_VA_SCU + 0x0);
+
+ /* Save register value for L2X0 */
+ l2x0_save[0] = __raw_readl(S5P_VA_L2CC + 0x108);
+ l2x0_save[1] = __raw_readl(S5P_VA_L2CC + 0x10C);
+ l2x0_save[2] = __raw_readl(S5P_VA_L2CC + 0xF60);
+
+ flush_cache_all();
+ outer_clean_range(virt_to_phys(l2x0_save), ARRAY_SIZE(l2x0_save));
+ outer_clean_range(virt_to_phys(scu_save), ARRAY_SIZE(scu_save));
+
+ return 0;
+}
+device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos/cpuidle-exynos5.c b/arch/arm/mach-exynos/cpuidle-exynos5.c
new file mode 100644
index 0000000..fbe063d
--- /dev/null
+++ b/arch/arm/mach-exynos/cpuidle-exynos5.c
@@ -0,0 +1,674 @@
+/* linux/arch/arm/mach-exynos/cpuidle-exynos5.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/proc-fns.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+#include <plat/pm.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-core.h>
+#include <plat/regs-otg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <mach/regs-pmu5.h>
+#include <mach/pm-core.h>
+#include <mach/pmu.h>
+#include <mach/regs-clock.h>
+#include <mach/smc.h>
+#include <mach/clock-domain.h>
+#include <mach/regs-usb-phy.h>
+
+#ifdef CONFIG_ARM_TRUSTZONE
+#define REG_DIRECTGO_ADDR (S5P_VA_SYSRAM_NS + 0x24)
+#define REG_DIRECTGO_FLAG (S5P_VA_SYSRAM_NS + 0x20)
+#else
+#define REG_DIRECTGO_ADDR (S5P_VA_SYSRAM + 0x24)
+#define REG_DIRECTGO_FLAG (S5P_VA_SYSRAM + 0x20)
+#endif
+
+extern unsigned long sys_pwr_conf_addr;
+
+static int exynos5_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+
+static int __maybe_unused exynos5_enter_lowpower(struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+
+struct check_reg_lpa {
+ void __iomem *check_reg;
+ unsigned int check_bit;
+};
+
+/*
+ * List of check power domain list for LPA mode
+ * These register are have to power off to enter LPA mode
+ */
+static struct check_reg_lpa exynos5_power_domain[] = {
+ {.check_reg = EXYNOS5_GSCL_STATUS, .check_bit = 0x7},
+ {.check_reg = EXYNOS5_G3D_STATUS, .check_bit = 0x7},
+};
+
+/*
+ * List of check clock gating list for LPA mode
+ * If clock of list is not gated, system can not enter LPA mode.
+ */
+static struct check_reg_lpa exynos5_clock_gating[] = {
+ {.check_reg = EXYNOS5_CLKSRC_MASK_DISP1_0, .check_bit = 0x00000001},
+ {.check_reg = EXYNOS5_CLKGATE_IP_DISP1, .check_bit = 0x00000010},
+ {.check_reg = EXYNOS5_CLKGATE_IP_MFC, .check_bit = 0x00000001},
+ {.check_reg = EXYNOS5_CLKGATE_IP_GEN, .check_bit = 0x00004016},
+ {.check_reg = EXYNOS5_CLKGATE_IP_FSYS, .check_bit = 0x00000002},
+ {.check_reg = EXYNOS5_CLKGATE_IP_PERIC, .check_bit = 0x00377FC0},
+};
+
+enum hc_type {
+ HC_SDHC,
+ HC_MSHC,
+};
+
+struct check_device_op {
+ void __iomem *base;
+ struct platform_device *pdev;
+ enum hc_type type;
+};
+
+static struct check_device_op chk_sdhc_op[] = {
+#if defined(CONFIG_EXYNOS4_DEV_DWMCI)
+ {.base = 0, .pdev = &exynos_device_dwmci, .type = HC_MSHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC)
+ {.base = 0, .pdev = &s3c_device_hsmmc0, .type = HC_SDHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC1)
+ {.base = 0, .pdev = &s3c_device_hsmmc1, .type = HC_SDHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC2)
+ {.base = 0, .pdev = &s3c_device_hsmmc2, .type = HC_SDHC},
+#endif
+#if defined(CONFIG_S3C_DEV_HSMMC3)
+ {.base = 0, .pdev = &s3c_device_hsmmc3, .type = HC_SDHC},
+#endif
+};
+
+static struct check_device_op chk_sdhc_op_exynos5250_rev1[] = {
+#if defined(CONFIG_EXYNOS4_DEV_DWMCI)
+ {.base = 0, .pdev = &exynos_device_dwmci0, .type = HC_MSHC},
+ {.base = 0, .pdev = &exynos_device_dwmci1, .type = HC_MSHC},
+ {.base = 0, .pdev = &exynos_device_dwmci2, .type = HC_MSHC},
+ {.base = 0, .pdev = &exynos_device_dwmci3, .type = HC_MSHC},
+#endif
+};
+
+#define S3C_HSMMC_PRNSTS (0x24)
+#define S3C_HSMMC_CLKCON (0x2c)
+#define S3C_HSMMC_CMD_INHIBIT 0x00000001
+#define S3C_HSMMC_DATA_INHIBIT 0x00000002
+#define S3C_HSMMC_CLOCK_CARD_EN 0x0004
+
+#define MSHCI_CLKENA (0x10) /* Clock enable */
+#define MSHCI_STATUS (0x48) /* Status */
+#define MSHCI_DATA_BUSY (0x1<<9)
+#define MSHCI_DATA_STAT_BUSY (0x1<<10)
+#define MSHCI_ENCLK (0x1)
+
+static int sdmmc_dev_num;
+/* If SD/MMC interface is working: return = 1 or not 0 */
+static int check_sdmmc_op(unsigned int ch)
+{
+ unsigned int reg1, reg2;
+ void __iomem *base_addr;
+
+ if (unlikely(ch >= sdmmc_dev_num)) {
+ printk(KERN_ERR "Invalid ch[%d] for SD/MMC\n", ch);
+ return 0;
+ }
+
+ if (soc_is_exynos5250() && (samsung_rev() >= EXYNOS5250_REV_1_0)) {
+ if (chk_sdhc_op_exynos5250_rev1[ch].type == HC_MSHC) {
+ base_addr = chk_sdhc_op_exynos5250_rev1[ch].base;
+ /* Check STATUS [9] for data busy */
+ reg1 = readl(base_addr + MSHCI_STATUS);
+ return (reg1 & (MSHCI_DATA_BUSY)) ||
+ (reg1 & (MSHCI_DATA_STAT_BUSY));
+ }
+ } else {
+ if (chk_sdhc_op[ch].type == HC_SDHC) {
+ base_addr = chk_sdhc_op[ch].base;
+ /* Check CLKCON [2]: ENSDCLK */
+ reg2 = readl(base_addr + S3C_HSMMC_CLKCON);
+ return !!(reg2 & (S3C_HSMMC_CLOCK_CARD_EN));
+ } else if (chk_sdhc_op[ch].type == HC_MSHC) {
+ base_addr = chk_sdhc_op[ch].base;
+ /* Check STATUS [9] for data busy */
+ reg1 = readl(base_addr + MSHCI_STATUS);
+ return (reg1 & (MSHCI_DATA_BUSY)) ||
+ (reg1 & (MSHCI_DATA_STAT_BUSY));
+ }
+ }
+ /* should not be here */
+ return 0;
+}
+
+/* Check all sdmmc controller */
+static int loop_sdmmc_check(void)
+{
+ unsigned int iter;
+
+ for (iter = 0; iter < sdmmc_dev_num; iter++) {
+ if (check_sdmmc_op(iter)) {
+ printk(KERN_DEBUG "SDMMC [%d] working\n", iter);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int exynos5_check_reg_status(struct check_reg_lpa *reg_list,
+ unsigned int list_cnt)
+{
+ unsigned int i;
+ unsigned int tmp;
+
+ for (i = 0; i < list_cnt; i++) {
+ tmp = __raw_readl(reg_list[i].check_reg);
+ if (tmp & reg_list[i].check_bit)
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int exynos5_uart_fifo_check(void)
+{
+ unsigned int ret;
+ unsigned int check_val;
+
+ ret = 0;
+
+ /* Check UART for console is empty */
+ check_val = __raw_readl(S5P_VA_UART(CONFIG_S3C_LOWLEVEL_UART_PORT) +
+ 0x18);
+
+ ret = ((check_val >> 16) & 0xff);
+
+ return ret;
+}
+
+static struct cpuidle_state exynos5_cpuidle_set[] = {
+ [0] = {
+ .enter = exynos5_enter_idle,
+ .exit_latency = 1,
+ .target_residency = 10000,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "IDLE",
+ .desc = "ARM clock gating(WFI)",
+ },
+#ifdef CONFIG_EXYNOS5_LOWPWR_IDLE
+ [1] = {
+ .enter = exynos5_enter_lowpower,
+ .exit_latency = 300,
+ .target_residency = 10000,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "LOW_POWER",
+ .desc = "ARM power down",
+ },
+#endif
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, exynos5_cpuidle_device);
+
+static struct cpuidle_driver exynos5_idle_driver = {
+ .name = "exynos5_idle",
+ .owner = THIS_MODULE,
+};
+
+/*
+ * To keep value of gpio on power down mode
+ * set Power down register of gpio
+ */
+static void exynos5_gpio_set_pd_reg(void)
+{
+ struct s3c_gpio_chip *target_chip;
+ unsigned int gpio_nr;
+ unsigned int tmp;
+
+ for (gpio_nr = 0; gpio_nr < EXYNOS5_GPIO_END; gpio_nr++) {
+ target_chip = s3c_gpiolib_getchip(gpio_nr);
+
+ if (!target_chip)
+ continue;
+
+ if (!target_chip->pm)
+ continue;
+
+ /* Keep the previous state in LPA mode */
+ s5p_gpio_set_pd_cfg(gpio_nr, 0x3);
+
+ /* Pull up-down state in LPA mode is same as normal */
+ tmp = s3c_gpio_getpull(gpio_nr);
+ s5p_gpio_set_pd_pull(gpio_nr, tmp);
+ }
+}
+
+static int exynos5_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ cpu_do_idle();
+
+ do_gettimeofday(&after);
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+ return idle_time;
+}
+
+static void exynos5_set_wakeupmask(void)
+{
+ __raw_writel(0x0000ff3e, EXYNOS5_WAKEUP_MASK);
+}
+
+static inline void vfp_enable(void *unused)
+{
+ u32 access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+}
+
+static struct sleep_save exynos5_lpa_save[] = {
+ /* CMU side */
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_TOP),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_GSCL),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_DISP1_0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_MAUDIO),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_FSYS),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC0),
+ SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC1),
+ SAVE_ITEM(EXYNOS5_CLKSRC_TOP3),
+};
+
+static struct sleep_save exynos5_set_clksrc[] = {
+ { .reg = EXYNOS5_CLKSRC_MASK_TOP , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_GSCL , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_DISP1_0 , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_MAUDIO , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_FSYS , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_PERIC0 , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_PERIC1 , .val = 0xffffffff, },
+};
+
+static int exynos5_enter_core0_lpa(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+
+ unsigned long tmp;
+
+ s3c_pm_do_save(exynos5_lpa_save, ARRAY_SIZE(exynos5_lpa_save));
+ /*
+ * Before enter central sequence mode, clock src register have to set
+ */
+ s3c_pm_do_restore_core(exynos5_set_clksrc,
+ ARRAY_SIZE(exynos5_set_clksrc));
+
+ local_irq_disable();
+
+ do_gettimeofday(&before);
+
+ /*
+ * Unmasking all wakeup source.
+ */
+ __raw_writel(0x0, S5P_WAKEUP_MASK);
+
+ /* Configure GPIO Power down control register */
+ exynos5_gpio_set_pd_reg();
+
+ /* ensure at least INFORM0 has the resume address */
+ __raw_writel(virt_to_phys(exynos5_idle_resume), REG_DIRECTGO_ADDR);
+ __raw_writel(0xfcba0d10, REG_DIRECTGO_FLAG);
+
+ __raw_writel(S5P_CHECK_LPA, EXYNOS5_INFORM1);
+
+ exynos5_sys_powerdown_conf(SYS_LPA);
+
+ /* Disable USE_RETENTION of JPEG_MEM_OPTION */
+ tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION);
+ tmp |= EXYNOS5_OPTION_USE_RETENTION;
+ __raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION);
+
+ do {
+ /* Waiting for flushing UART fifo */
+ } while (exynos5_uart_fifo_check());
+
+ /*
+ * GPS can not turn off.
+ */
+ if (samsung_rev() < EXYNOS5250_REV_1_0)
+ __raw_writel(0x10000, EXYNOS5_GPS_LPI);
+
+ if (exynos5_enter_lp(0, PLAT_PHYS_OFFSET - PAGE_OFFSET) == 0) {
+ /*
+ * Clear Central Sequence Register in exiting early wakeup
+ */
+ tmp = __raw_readl(EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+ tmp |= (EXYNOS5_CENTRAL_LOWPWR_CFG);
+ __raw_writel(tmp, EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+
+ goto early_wakeup;
+ }
+
+ flush_tlb_all();
+
+ cpu_init();
+
+ vfp_enable(NULL);
+
+ /* For release retention */
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_MAU_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_GPIO_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_UART_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_MMCA_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_MMCB_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_EBIA_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_EBIB_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_SPI_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_OPTION);
+
+early_wakeup:
+ s3c_pm_do_restore_core(exynos5_lpa_save,
+ ARRAY_SIZE(exynos5_lpa_save));
+
+ /* Clear wakeup state register */
+ __raw_writel(0x0, EXYNOS5_WAKEUP_STAT);
+
+ __raw_writel(0x0, EXYNOS5_WAKEUP_MASK);
+
+ do_gettimeofday(&after);
+
+ local_irq_enable();
+
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+ return idle_time;
+}
+
+static int exynos5_enter_core0_aftr(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+ unsigned long tmp;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ exynos5_set_wakeupmask();
+
+ __raw_writel(virt_to_phys(exynos5_idle_resume), REG_DIRECTGO_ADDR);
+ __raw_writel(0xfcba0d10, REG_DIRECTGO_FLAG);
+
+ /* Set value of power down register for aftr mode */
+ exynos5_sys_powerdown_conf(SYS_AFTR);
+
+ if (exynos5_enter_lp(0, PLAT_PHYS_OFFSET - PAGE_OFFSET) == 0) {
+ /*
+ * Clear Central Sequence Register in exiting early wakeup
+ */
+ tmp = __raw_readl(EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+ tmp |= EXYNOS5_CENTRAL_LOWPWR_CFG;
+ __raw_writel(tmp, EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+
+ goto early_wakeup;
+ }
+
+ flush_tlb_all();
+
+ cpu_init();
+
+ vfp_enable(NULL);
+
+early_wakeup:
+ /* Clear wakeup state register */
+ __raw_writel(0x0, EXYNOS5_WAKEUP_STAT);
+
+ do_gettimeofday(&after);
+
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+ return idle_time;
+}
+
+static int __maybe_unused exynos5_check_enter_mode(void)
+{
+ /* Check power domain */
+ if (exynos5_check_reg_status(exynos5_power_domain,
+ ARRAY_SIZE(exynos5_power_domain)))
+ return S5P_CHECK_DIDLE;
+
+ /* Check clock gating */
+ if (exynos5_check_reg_status(exynos5_clock_gating,
+ ARRAY_SIZE(exynos5_clock_gating)))
+ return S5P_CHECK_DIDLE;
+
+ if (clock_domain_enabled(LPA_DOMAIN))
+ return S5P_CHECK_DIDLE;
+
+ if (loop_sdmmc_check())
+ return S5P_CHECK_DIDLE;
+
+ if (exynos_check_usb_op())
+ return S5P_CHECK_DIDLE;
+
+ return S5P_CHECK_LPA;
+}
+
+static int __maybe_unused exynos5_enter_lowpower(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct cpuidle_state *new_state = state;
+ unsigned int tmp;
+
+ /* This mode only can be entered when only Core0 is online */
+ if (num_online_cpus() != 1) {
+ BUG_ON(!dev->safe_state);
+ new_state = dev->safe_state;
+ }
+ dev->last_state = new_state;
+
+ if (new_state == &dev->states[0])
+ return exynos5_enter_idle(dev, new_state);
+
+ tmp = __raw_readl(EXYNOS5_CENTRAL_SEQ_OPTION);
+ tmp = (EXYNOS5_USE_STANDBYWFI_ARM_CORE0 |
+ EXYNOS5_USE_STANDBYWFE_ARM_CORE0);
+ __raw_writel(tmp, EXYNOS5_CENTRAL_SEQ_OPTION);
+
+ if (exynos5_check_enter_mode() == S5P_CHECK_DIDLE)
+ return exynos5_enter_core0_aftr(dev, new_state);
+ else
+ return exynos5_enter_core0_aftr(dev, new_state);
+ //return exynos5_enter_core0_lpa(dev, new_state);
+}
+
+static int exynos5_cpuidle_notifier_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ disable_hlt();
+ pr_debug("PM_SUSPEND_PREPARE for CPUIDLE\n");
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ enable_hlt();
+ pr_debug("PM_POST_SUSPEND for CPUIDLE\n");
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos5_cpuidle_notifier = {
+ .notifier_call = exynos5_cpuidle_notifier_event,
+};
+
+#ifdef CONFIG_EXYNOS5_ENABLE_CLOCK_DOWN
+static void __init exynos5_core_down_clk(void)
+{
+ unsigned int tmp;
+
+ tmp = __raw_readl(EXYNOS5_PWR_CTRL1);
+
+ tmp &= ~(PWR_CTRL1_CORE2_DOWN_MASK | PWR_CTRL1_CORE1_DOWN_MASK);
+
+ /* set arm clock divider value on idle state */
+ tmp |= ((0x7 << PWR_CTRL1_CORE2_DOWN_RATIO) |
+ (0x7 << PWR_CTRL1_CORE1_DOWN_RATIO));
+
+ tmp |= (PWR_CTRL1_DIV2_DOWN_EN |
+ PWR_CTRL1_DIV1_DOWN_EN |
+ PWR_CTRL1_USE_CORE1_WFE |
+ PWR_CTRL1_USE_CORE0_WFE |
+ PWR_CTRL1_USE_CORE1_WFI |
+ PWR_CTRL1_USE_CORE0_WFI);
+
+ __raw_writel(tmp, EXYNOS5_PWR_CTRL1);
+
+ tmp = __raw_readl(EXYNOS5_PWR_CTRL2);
+
+ tmp &= ~(PWR_CTRL2_DUR_STANDBY2_MASK | PWR_CTRL2_DUR_STANDBY1_MASK |
+ PWR_CTRL2_CORE2_UP_MASK | PWR_CTRL2_CORE1_UP_MASK);
+
+ /* set duration value on middle wakeup step */
+ tmp |= ((0x1 << PWR_CTRL2_DUR_STANDBY2) |
+ (0x1 << PWR_CTRL2_DUR_STANDBY1));
+
+ /* set arm clock divier value on middle wakeup step */
+ tmp |= ((0x1 << PWR_CTRL2_CORE2_UP_RATIO) |
+ (0x1 << PWR_CTRL2_CORE1_UP_RATIO));
+
+ /* Set PWR_CTRL2 register to use step up for arm clock */
+ tmp |= (PWR_CTRL2_DIV2_UP_EN | PWR_CTRL2_DIV1_UP_EN);
+
+ __raw_writel(tmp, EXYNOS5_PWR_CTRL2);
+ printk(KERN_INFO "Exynos5 : ARM Clock down on idle mode is enabled\n");
+}
+#else
+#define exynos5_core_down_clk() do { } while (0)
+#endif
+
+static int __init exynos5_init_cpuidle(void)
+{
+ int i, max_cpuidle_state, cpu_id, ret;
+ struct cpuidle_device *device;
+ struct platform_device *pdev;
+ struct resource *res;
+ void __iomem *base;
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ exynos4_reset_assert_ctrl(1);
+
+ exynos5_core_down_clk();
+
+ ret = cpuidle_register_driver(&exynos5_idle_driver);
+
+ if(ret < 0){
+ printk(KERN_ERR "exynos5 idle register driver failed\n");
+ return ret;
+ }
+
+
+ for_each_cpu(cpu_id, cpu_online_mask) {
+ device = &per_cpu(exynos5_cpuidle_device, cpu_id);
+ device->cpu = cpu_id;
+
+ if (cpu_id == 0)
+ device->state_count = ARRAY_SIZE(exynos5_cpuidle_set);
+ else
+ device->state_count = 1; /* Support IDLE only */
+
+ max_cpuidle_state = device->state_count;
+
+ for (i = 0; i < max_cpuidle_state; i++) {
+ memcpy(&device->states[i], &exynos5_cpuidle_set[i],
+ sizeof(struct cpuidle_state));
+ }
+
+ device->safe_state = &device->states[0];
+
+ if (cpuidle_register_device(device)) {
+ cpuidle_unregister_driver(&exynos5_idle_driver);
+ printk(KERN_ERR "CPUidle register device failed\n,");
+ return -EIO;
+ }
+ }
+
+ if (soc_is_exynos5250() && (samsung_rev() >= EXYNOS5250_REV_1_0))
+ sdmmc_dev_num = ARRAY_SIZE(chk_sdhc_op_exynos5250_rev1);
+ else
+ sdmmc_dev_num = ARRAY_SIZE(chk_sdhc_op);
+
+ for (i = 0; i < sdmmc_dev_num; i++) {
+
+ if (soc_is_exynos5250() && (samsung_rev() >= EXYNOS5250_REV_1_0))
+ pdev = chk_sdhc_op_exynos5250_rev1[i].pdev;
+ else
+ pdev = chk_sdhc_op[i].pdev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ printk(KERN_ERR "failed to get iomem region\n");
+ return -EINVAL;
+ }
+
+ if (soc_is_exynos5250() && (samsung_rev() >= EXYNOS5250_REV_1_0)) {
+ chk_sdhc_op_exynos5250_rev1[i].base = ioremap(res->start, resource_size(res));
+ base = chk_sdhc_op_exynos5250_rev1[i].base;
+ } else {
+ chk_sdhc_op[i].base = ioremap(res->start, resource_size(res));
+ base = chk_sdhc_op[i].base;
+ }
+
+
+ if (!base) {
+ printk(KERN_ERR "failed to map io region\n");
+ return -EINVAL;
+ }
+ }
+
+ register_pm_notifier(&exynos5_cpuidle_notifier);
+ sys_pwr_conf_addr = (unsigned long)EXYNOS5_CENTRAL_SEQ_CONFIGURATION;
+
+ return 0;
+}
+device_initcall(exynos5_init_cpuidle);
diff --git a/arch/arm/mach-exynos/dev-ahci-exynos5.c b/arch/arm/mach-exynos/dev-ahci-exynos5.c
new file mode 100644
index 0000000..7163446
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-ahci-exynos5.c
@@ -0,0 +1,486 @@
+/* linux/arch/arm/mach-exynos/dev-ahci-exynos5.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Srikanth TS <ts.srikanth@samsung.com> for Samsung
+ *
+ * EXYNOS5 - AHCI SATA3.0 support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/ahci_platform.h>
+
+#include <plat/cpu.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu5.h>
+#include <mach/map-exynos5.h>
+
+#define SATA_TIME_LIMIT 10000
+#define PMU_BASE_ADDRS 0x10040000
+#define PMU_SATA_PHY_CTRL 0x724
+#define SATA_PHY_I2C_SLAVE_ADDRS 0x70
+
+#define SATA_RESET 0x4
+#define RESET_CMN_RST_N (1 << 1)
+#define LINK_RESET 0xF0000
+
+#define SATA_MODE0 0x10
+
+#define SATA_CTRL0 0x14
+#define CTRL0_P0_PHY_CALIBRATED_SEL (1 << 9)
+#define CTRL0_P0_PHY_CALIBRATED (1 << 8)
+
+#define SATA_STAT0 0x18
+
+#define SATA_TBD 0x9C
+#define SATA_PHSATA_CTRLM 0xE0
+#define PHCTRLM_REF_RATE (1 << 1)
+#define PHCTRLM_HIGH_SPEED (1 << 0)
+
+#define SATA_PHSATA_CTRL0 0xE4
+
+#define SATA_PHSATA_STATM 0xF0
+#define PHSTATM_PLL_LOCKED (1 << 0)
+
+#define SATA_PHSATA_STAT0 0xF4
+
+/********************** I2C**************/
+#define SATA_I2C_PHY_ADDR 0x70
+#define SATA_I2C_CON 0x00
+#define SATA_I2C_STAT 0x04
+#define SATA_I2C_ADDR 0x08
+#define SATA_I2C_DS 0x0C
+#define SATA_I2C_LC 0x10
+
+/* I2CCON reg */
+#define CON_ACKEN (1 << 7)
+#define CON_CLK512 (1 << 6)
+#define CON_CLK16 (~CON_CLK512)
+#define CON_INTEN (1 << 5)
+#define CON_INTPND (1 << 4)
+#define CON_TXCLK_PS (0xF)
+
+/* I2CSTAT reg */
+#define STAT_MSTR (0x2 << 6)
+#define STAT_MSTT (0x3 << 6)
+#define STAT_BSYST (1 << 5)
+#define STAT_RTEN (1 << 4)
+#define STAT_LAST (1 << 0)
+
+#define LC_FLTR_EN (1 << 2)
+
+#define SATA_PHY_CON_RESET 0xF003F
+
+#define HOST_PORTS_IMPL 0xC
+#define SCLK_SATA_FREQ (66 * MHZ)
+
+enum {
+ GEN1 = 0,
+ GEN2 = 1,
+ GEN3 = 2,
+};
+
+static void __iomem *phy_i2c_base, *phy_ctrl;
+u32 time_limit_cnt;
+
+static bool sata_is_reg(void __iomem *base, u32 reg, u32 checkbit, u32 Status)
+{
+ if ((__raw_readl(base + reg) & checkbit) == Status)
+ return true;
+ else
+ return false;
+}
+
+static bool wait_for_reg_status(void __iomem *base, u32 reg, u32 checkbit,
+ u32 Status)
+{
+ time_limit_cnt = 0;
+ while (!sata_is_reg(base, reg, checkbit, Status)) {
+ if (time_limit_cnt == SATA_TIME_LIMIT) {
+ printk(KERN_ERR " Register Status wait FAIL\n");
+ return false;
+ }
+ udelay(1000);
+ time_limit_cnt++;
+ }
+ return true;
+}
+
+
+static void sata_set_gen(u8 gen)
+{
+ __raw_writel(gen, phy_ctrl + SATA_MODE0);
+}
+
+/* Address :I2C Address */
+static void sata_i2c_write_addrs(u8 data)
+{
+ __raw_writeb((data & 0xFE), phy_i2c_base + SATA_I2C_DS);
+}
+
+static void sata_i2c_write_data(u8 data)
+{
+ __raw_writeb((data), phy_i2c_base + SATA_I2C_DS);
+}
+
+static void sata_i2c_start(void)
+{
+ u32 val;
+ val = __raw_readl(phy_i2c_base + SATA_I2C_STAT);
+ val |= STAT_BSYST;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_STAT);
+}
+
+static void sata_i2c_stop(void)
+{
+ u32 val;
+ val = __raw_readl(phy_i2c_base + SATA_I2C_STAT);
+ val &= ~STAT_BSYST;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_STAT);
+}
+
+static bool sata_i2c_get_int_status(void)
+{
+ if ((__raw_readl(phy_i2c_base + SATA_I2C_CON)) & CON_INTPND)
+ return true;
+ else
+ return false;
+}
+
+static bool sata_i2c_is_tx_ack(void)
+{
+ if ((__raw_readl(phy_i2c_base + SATA_I2C_STAT)) & STAT_LAST)
+ return false;
+ else
+ return true;
+}
+
+static bool sata_i2c_is_bus_ready(void)
+{
+ if ((__raw_readl(phy_i2c_base + SATA_I2C_STAT)) & STAT_BSYST)
+ return false;
+ else
+ return true;
+}
+
+static bool sata_i2c_wait_for_busready(u32 time_out)
+{
+ while (--time_out) {
+ if (sata_i2c_is_bus_ready())
+ return true;
+ udelay(100);
+ }
+ printk(KERN_ERR "SATA I2C wait fail for bus ready...\n");
+ return false;
+}
+
+static bool sata_i2c_wait_for_tx_ack(u32 time_out)
+{
+ while (--time_out) {
+ if (sata_i2c_get_int_status()) {
+ if (sata_i2c_is_tx_ack())
+ return true;
+ }
+ udelay(100);
+ }
+ return false;
+}
+
+static void sata_i2c_clear_int_status(void)
+{
+ u32 val;
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val &= ~CON_INTPND;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+}
+
+
+static void sata_i2c_set_ack_gen(bool enable)
+{
+ u32 val;
+ if (enable) {
+ val = (__raw_readl(phy_i2c_base + SATA_I2C_CON)) | CON_ACKEN;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+ } else {
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val &= ~CON_ACKEN;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+ }
+
+}
+
+static void sata_i2c_set_master_tx(void)
+{
+ u32 val;
+ /* Disable I2C */
+ val = __raw_readl(phy_i2c_base + SATA_I2C_STAT);
+ val &= ~STAT_RTEN;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_STAT);
+ /* Clear Mode */
+ val = __raw_readl(phy_i2c_base + SATA_I2C_STAT);
+ val &= ~STAT_MSTT;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_STAT);
+
+ sata_i2c_clear_int_status();
+ /* interrupt disable */
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val &= ~CON_INTEN;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+
+ /* Master, Send mode */
+ val = __raw_readl(phy_i2c_base + SATA_I2C_STAT);
+ val |= STAT_MSTT;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_STAT);
+
+ /* interrupt enable */
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val |= CON_INTEN;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+
+ /* Enable I2C */
+ val = __raw_readl(phy_i2c_base + SATA_I2C_STAT);
+ val |= STAT_RTEN;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_STAT);
+}
+
+static void sata_i2c_init(void)
+{
+ u32 val;
+
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val &= CON_CLK16;
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val &= ~(CON_TXCLK_PS);
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+
+ val = __raw_readl(phy_i2c_base + SATA_I2C_CON);
+ val |= (2 & CON_TXCLK_PS);
+ __raw_writel(val, phy_i2c_base + SATA_I2C_CON);
+
+ val = __raw_readl(phy_i2c_base + SATA_I2C_LC);
+ val &= ~(LC_FLTR_EN);
+ __raw_writel(val, phy_i2c_base + SATA_I2C_LC);
+
+ sata_i2c_set_ack_gen(false);
+}
+static bool sata_i2c_send(u8 slave_addrs, u8 addrs, u8 ucData)
+{
+ s32 ret = 0;
+ if (!sata_i2c_wait_for_busready(SATA_TIME_LIMIT))
+ return false;
+
+ sata_i2c_init();
+ sata_i2c_set_master_tx();
+
+ __raw_writel(SATA_PHY_CON_RESET, phy_ctrl + SATA_RESET);
+ sata_i2c_write_addrs(slave_addrs);
+ sata_i2c_start();
+ if (!sata_i2c_wait_for_tx_ack(SATA_TIME_LIMIT)) {
+ ret = false;
+ goto STOP;
+ }
+ sata_i2c_write_data(addrs);
+ sata_i2c_clear_int_status();
+ if (!sata_i2c_wait_for_tx_ack(SATA_TIME_LIMIT)) {
+ ret = false;
+ goto STOP;
+ }
+ sata_i2c_write_data(ucData);
+ sata_i2c_clear_int_status();
+ if (!sata_i2c_wait_for_tx_ack(SATA_TIME_LIMIT)) {
+ ret = false;
+ goto STOP;
+ }
+ ret = true;
+
+STOP:
+ sata_i2c_stop();
+ sata_i2c_clear_int_status();
+ sata_i2c_wait_for_busready(SATA_TIME_LIMIT);
+
+ return ret;
+}
+
+static int ahci_phy_init(void __iomem *mmio)
+{
+ u8 uCount, i = 0;
+ /* 0x3A for 40bit I/F */
+ u8 reg_addrs[] = {0x22, 0x21, 0x3A};
+ /* 0x0B for 40bit I/F */
+ u8 default_setting_value[] = {0x30, 0x4f, 0x0B};
+
+ uCount = sizeof(reg_addrs)/sizeof(u8);
+ while (i < uCount) {
+ if (!sata_i2c_send(SATA_PHY_I2C_SLAVE_ADDRS, reg_addrs[i],
+ default_setting_value[i]))
+ return false;
+ i++;
+ }
+ return 0;
+}
+
+static int exynos5_ahci_init(struct device *dev, void __iomem *mmio)
+{
+ struct clk *clk_sata, *clk_sataphy, *clk_sata_i2c, *clk_sclk_sata;
+ int val, ret;
+
+ phy_i2c_base = ioremap(EXYNOS5_PA_SATA_PHY_I2C, SZ_4K);
+ if (!phy_i2c_base) {
+ dev_err(dev, "failed to allocate memory for SATA PHY\n");
+ return -ENOMEM;
+ }
+
+ phy_ctrl = ioremap(EXYNOS5_PA_SATA_PHY_CTRL, SZ_64K);
+ if (!phy_ctrl) {
+ dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n");
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, EXYNOS5_SATA_PHY_CONTROL);
+
+ val = 0;
+ __raw_writel(val, phy_ctrl + SATA_RESET);
+ val = __raw_readl(phy_ctrl + SATA_RESET);
+ val |= 0x3D;
+ __raw_writel(val, phy_ctrl + SATA_RESET);
+
+ clk_sata = clk_get(dev, "sata");
+ if (IS_ERR(clk_sata)) {
+ dev_err(dev, "failed to get sata clock\n");
+ ret = PTR_ERR(clk_sata);
+ clk_sata = NULL;
+ goto err2;
+
+ }
+ clk_enable(clk_sata);
+
+ clk_sataphy = clk_get(dev, "sata_phy");
+ if (IS_ERR(clk_sataphy)) {
+ dev_err(dev, "failed to get sataphy clock\n");
+ ret = PTR_ERR(clk_sataphy);
+ clk_sataphy = NULL;
+ goto err3;
+ }
+ clk_enable(clk_sataphy);
+
+ clk_sata_i2c = clk_get(dev, "sata_phy_i2c");
+ if (IS_ERR(clk_sata_i2c)) {
+ dev_err(dev, "failed to get sclk_sata\n");
+ ret = PTR_ERR(clk_sata_i2c);
+ clk_sata_i2c = NULL;
+ goto err4;
+ }
+ clk_enable(clk_sata_i2c);
+
+ clk_sclk_sata = clk_get(dev, "sclk_sata");
+ clk_enable(clk_sclk_sata);
+ if (IS_ERR(clk_sclk_sata)) {
+ dev_err(dev, "failed to get sclk_sata\n");
+ ret = PTR_ERR(clk_sclk_sata);
+ clk_sclk_sata = NULL;
+ goto err5;
+ }
+ clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ);
+
+ val = __raw_readl(phy_ctrl + SATA_RESET);
+ val |= LINK_RESET;
+ __raw_writel(val, phy_ctrl + SATA_RESET);
+
+ val = __raw_readl(phy_ctrl + SATA_RESET);
+ val |= RESET_CMN_RST_N;
+ __raw_writel(val, phy_ctrl + SATA_RESET);
+
+ val = __raw_readl(phy_ctrl + SATA_PHSATA_CTRLM);
+ val &= ~PHCTRLM_REF_RATE;
+ __raw_writel(val, phy_ctrl + SATA_PHSATA_CTRLM);
+
+ /* High speed enable for Gen3 */
+ val = __raw_readl(phy_ctrl + SATA_PHSATA_CTRLM);
+ val |= PHCTRLM_HIGH_SPEED;
+ __raw_writel(val, phy_ctrl + SATA_PHSATA_CTRLM);
+
+ /* Port0 is available */
+ __raw_writel(0x1, mmio + HOST_PORTS_IMPL);
+
+ ret = ahci_phy_init(mmio);
+
+ val = __raw_readl(phy_ctrl + SATA_CTRL0);
+ val |= CTRL0_P0_PHY_CALIBRATED_SEL|CTRL0_P0_PHY_CALIBRATED;
+ __raw_writel(val, phy_ctrl + SATA_CTRL0);
+ sata_set_gen(GEN3);
+
+ /* release cmu reset */
+ val = __raw_readl(phy_ctrl + SATA_RESET);
+ val &= ~RESET_CMN_RST_N;
+ __raw_writel(val, phy_ctrl + SATA_RESET);
+
+ val = __raw_readl(phy_ctrl + SATA_RESET);
+ val |= RESET_CMN_RST_N;
+ __raw_writel(val, phy_ctrl + SATA_RESET);
+
+ if (wait_for_reg_status(phy_ctrl, SATA_PHSATA_STATM,
+ PHSTATM_PLL_LOCKED, 1)) {
+ return ret;
+ }
+ dev_err(dev, " ahci_phy_init FAIL\n");
+
+err5:
+ clk_disable(clk_sata_i2c);
+ clk_put(clk_sata_i2c);
+err4:
+ clk_disable(clk_sataphy);
+ clk_put(clk_sataphy);
+err3:
+ clk_disable(clk_sata);
+ clk_put(clk_sata);
+err2:
+ iounmap(phy_ctrl);
+err1:
+ iounmap(phy_i2c_base);
+
+ return false;
+}
+
+static struct ahci_platform_data exynos5_ahci_pdata = {
+ .init = exynos5_ahci_init,
+};
+
+static struct resource exynos5_ahci_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_SATA_BASE,
+ .end = EXYNOS5_PA_SATA_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SATA,
+ .end = IRQ_SATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 exynos5_ahci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos5_device_ahci = {
+ .name = "ahci",
+ .id = -1,
+ .resource = exynos5_ahci_resource,
+ .num_resources = ARRAY_SIZE(exynos5_ahci_resource),
+ .dev = {
+ .platform_data = &exynos5_ahci_pdata,
+ .dma_mask = &exynos5_ahci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/mach-exynos4/dev-ahci.c b/arch/arm/mach-exynos/dev-ahci.c
index f57a3de..21b0f4f 100644
--- a/arch/arm/mach-exynos4/dev-ahci.c
+++ b/arch/arm/mach-exynos/dev-ahci.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/dev-ahci.c
+/* linux/arch/arm/mach-exynos/dev-ahci.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/dev-audio.c b/arch/arm/mach-exynos/dev-audio.c
new file mode 100644
index 0000000..054a26d
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-audio.c
@@ -0,0 +1,438 @@
+/* linux/arch/arm/mach-exynos/dev-audio.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+#include <plat/cpu.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static const char *rclksrc[] = {
+ [0] = "busclk",
+ [1] = "i2sclk",
+};
+
+struct exynos_gpio_cfg {
+ unsigned int addr;
+ unsigned int num;
+ unsigned int bit;
+};
+
+static int exynos_cfg_i2s_gpio(struct platform_device *pdev)
+{
+ /* configure GPIO for i2s port */
+ struct exynos_gpio_cfg exynos4_cfg[3] = {
+ { EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2) },
+ { EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2) },
+ { EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(2) }
+ };
+ struct exynos_gpio_cfg exynos5_cfg[3] = {
+ { EXYNOS5_GPZ(0), 7, S3C_GPIO_SFN(2) },
+ { EXYNOS5_GPB0(0), 5, S3C_GPIO_SFN(2) },
+ { EXYNOS5_GPB1(0), 5, S3C_GPIO_SFN(2) }
+ };
+
+ if (pdev->id < 0 || pdev->id > 2) {
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ s3c_gpio_cfgpin_range(exynos4_cfg[pdev->id].addr,
+ exynos4_cfg[pdev->id].num, exynos4_cfg[pdev->id].bit);
+ else if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgpin_range(exynos5_cfg[pdev->id].addr,
+ exynos5_cfg[pdev->id].num, exynos5_cfg[pdev->id].bit);
+
+ return 0;
+}
+
+static struct s3c_audio_pdata i2sv5_pdata = {
+ .cfg_gpio = exynos_cfg_i2s_gpio,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN
+#ifdef CONFIG_SND_SOC_SAMSUNG_I2S_SEC
+ | QUIRK_SEC_DAI
+#endif
+#ifdef CONFIG_SND_SAMSUNG_RP
+ | QUIRK_ENABLED_SRP
+#endif
+ | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+static struct resource exynos_i2s0_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_I2S0,
+ .end = EXYNOS_PA_I2S0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_TX,
+ .end = DMACH_I2S0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_RX,
+ .end = DMACH_I2S0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DMACH_I2S0S_TX,
+ .end = DMACH_I2S0S_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device exynos_device_i2s0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos_i2s0_resource),
+ .resource = exynos_i2s0_resource,
+ .dev = {
+ .platform_data = &i2sv5_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "sclk_i2s",
+ [1] = "no_such_clock",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = exynos_cfg_i2s_gpio,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_NO_MUXPSR,
+ .src_clk = rclksrc_v3,
+ },
+ },
+};
+
+static struct resource exynos_i2s1_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_I2S1,
+ .end = EXYNOS_PA_I2S1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S1_TX,
+ .end = DMACH_I2S1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S1_RX,
+ .end = DMACH_I2S1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device exynos_device_i2s1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos_i2s1_resource),
+ .resource = exynos_i2s1_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+static struct resource exynos_i2s2_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_I2S2,
+ .end = EXYNOS_PA_I2S2 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S2_TX,
+ .end = DMACH_I2S2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S2_RX,
+ .end = DMACH_I2S2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device exynos_device_i2s2 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos_i2s2_resource),
+ .resource = exynos_i2s2_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+/* PCM Controller platform_devices */
+
+static int exynos_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ /* configure GPIO for pcm port */
+ struct exynos_gpio_cfg exynos4_cfg[3] = {
+ { EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3) },
+ { EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3) },
+ { EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3) }
+ };
+ struct exynos_gpio_cfg exynos5_cfg[3] = {
+ { EXYNOS5_GPZ(0), 5, S3C_GPIO_SFN(3) },
+ { EXYNOS5_GPB0(0), 5, S3C_GPIO_SFN(3) },
+ { EXYNOS5_GPB1(0), 5, S3C_GPIO_SFN(3) }
+ };
+
+ if (pdev->id < 0 || pdev->id > 2) {
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ s3c_gpio_cfgpin_range(exynos4_cfg[pdev->id].addr,
+ exynos4_cfg[pdev->id].num, exynos4_cfg[pdev->id].bit);
+ else if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgpin_range(exynos5_cfg[pdev->id].addr,
+ exynos5_cfg[pdev->id].num, exynos5_cfg[pdev->id].bit);
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+ .cfg_gpio = exynos_pcm_cfg_gpio,
+};
+
+static struct resource exynos_pcm0_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_PCM0,
+ .end = EXYNOS_PA_PCM0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM0_TX,
+ .end = DMACH_PCM0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM0_RX,
+ .end = DMACH_PCM0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device exynos_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos_pcm0_resource),
+ .resource = exynos_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource exynos_pcm1_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_PCM1,
+ .end = EXYNOS_PA_PCM1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM1_TX,
+ .end = DMACH_PCM1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM1_RX,
+ .end = DMACH_PCM1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device exynos_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos_pcm1_resource),
+ .resource = exynos_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource exynos_pcm2_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_PCM2,
+ .end = EXYNOS_PA_PCM2 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM2_TX,
+ .end = DMACH_PCM2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM2_RX,
+ .end = DMACH_PCM2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device exynos_device_pcm2 = {
+ .name = "samsung-pcm",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos_pcm2_resource),
+ .resource = exynos_pcm2_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+/* AC97 Controller platform devices */
+
+static int exynos_ac97_cfg_gpio(struct platform_device *pdev)
+{
+ /* configure GPIO for ac97 port */
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
+ else if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgpin_range(EXYNOS5_GPB0(0), 5, S3C_GPIO_SFN(4));
+
+ return 0;
+}
+
+static struct resource exynos_ac97_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_AC97,
+ .end = EXYNOS_PA_AC97 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_AC97_PCMOUT,
+ .end = DMACH_AC97_PCMOUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_AC97_PCMIN,
+ .end = DMACH_AC97_PCMIN,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DMACH_AC97_MICIN,
+ .end = DMACH_AC97_MICIN,
+ .flags = IORESOURCE_DMA,
+ },
+ [4] = {
+ .start = IRQ_AC97,
+ .end = IRQ_AC97,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+ .cfg_gpio = exynos_ac97_cfg_gpio,
+};
+
+static u64 exynos_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_ac97_resource),
+ .resource = exynos_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &exynos_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/* S/PDIF Controller platform_device */
+
+static int exynos_spdif_cfg_gpio(struct platform_device *pdev)
+{
+ /* configure GPIO for SPDIF port */
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
+ else if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgpin_range(EXYNOS5_GPB1(0), 2, S3C_GPIO_SFN(4));
+
+ return 0;
+}
+
+static struct resource exynos_spdif_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_SPDIF,
+ .end = EXYNOS_PA_SPDIF + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPDIF,
+ .end = DMACH_SPDIF,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata samsung_spdif_pdata = {
+ .cfg_gpio = exynos_spdif_cfg_gpio,
+};
+
+static u64 exynos_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_spdif = {
+ .name = "samsung-spdif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_spdif_resource),
+ .resource = exynos_spdif_resource,
+ .dev = {
+ .platform_data = &samsung_spdif_pdata,
+ .dma_mask = &exynos_spdif_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+static struct resource exynos_srp_resource[] = {
+};
+
+static u64 exynos_srp_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_srp = {
+ .name = "samsung-rp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_srp_resource),
+ .resource = exynos_srp_resource,
+ .dev = {
+ .dma_mask = &exynos_srp_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+EXPORT_SYMBOL(exynos_device_srp);
+#endif
+
+#ifdef CONFIG_ARCH_EXYNOS4
+void __init exynos4_i2sv3_setup_resource(void)
+{
+ if (!soc_is_exynos4210()) {
+ exynos_i2s1_resource[0].start = EXYNOS4212_PA_I2S1;
+ exynos_i2s1_resource[0].end = EXYNOS4212_PA_I2S1 + 0x100 - 1;
+ exynos_i2s2_resource[0].start = EXYNOS4212_PA_I2S2;
+ exynos_i2s2_resource[0].end = EXYNOS4212_PA_I2S2 + 0x100 - 1;
+ }
+}
+#endif
diff --git a/arch/arm/mach-exynos/dev-c2c.c b/arch/arm/mach-exynos/dev-c2c.c
new file mode 100644
index 0000000..1b77a8e
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-c2c.c
@@ -0,0 +1,85 @@
+/* linux/arch/arm/mach-exynos/dev-c2c.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Base EXYNOS C2C resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/map.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu5.h>
+#include <mach/c2c.h>
+#include <plat/irqs.h>
+#include <plat/cpu.h>
+
+static struct resource exynos_c2c_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_C2C,
+ .end = EXYNOS_PA_C2C + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EXYNOS_PA_C2C_CP,
+ .end = EXYNOS_PA_C2C_CP + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_C2C_SSCM0,
+ .end = IRQ_C2C_SSCM0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_C2C_SSCM1,
+ .end = IRQ_C2C_SSCM1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 exynos_c2c_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_c2c = {
+ .name = "samsung-c2c",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_c2c_resource),
+ .resource = exynos_c2c_resource,
+ .dev = {
+ .dma_mask = &exynos_c2c_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init exynos_c2c_set_platdata(struct exynos_c2c_platdata *pd)
+{
+ struct exynos_c2c_platdata *npd = pd;
+
+ if (!npd->setup_gpio)
+ npd->setup_gpio = exynos_c2c_cfg_gpio;
+ if (!npd->set_cprst)
+ npd->set_cprst = exynos_c2c_set_cprst;
+ if (!npd->clear_cprst)
+ npd->clear_cprst = exynos_c2c_clear_cprst;
+
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ /* Set C2C_CTRL Register */
+ writel(0x1, S5P_C2C_CTRL);
+ if (samsung_rev() < EXYNOS4412_REV_1_0)
+ npd->c2c_sysreg = S3C_VA_SYS + 0x010C;
+ } else if (soc_is_exynos5250()) {
+ /* Set C2C_CTRL Register */
+ writel(0x1, EXYNOS5_C2C_CTRL);
+ if (samsung_rev() < EXYNOS5250_REV_1_0)
+ npd->c2c_sysreg = S3C_VA_SYS + 0x0360;
+ }
+
+ exynos_device_c2c.dev.platform_data = npd;
+}
diff --git a/arch/arm/mach-exynos/dev-dwmci.c b/arch/arm/mach-exynos/dev-dwmci.c
new file mode 100644
index 0000000..8db1907
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-dwmci.c
@@ -0,0 +1,239 @@
+/*
+ * linux/arch/arm/mach-exynos/dev-dwmci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Platform device for Synopsys DesignWare Mobile Storage IP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/mmc/host.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <mach/map.h>
+
+#define DWMCI_CLKSEL 0x09c
+
+static int exynos_dwmci_get_bus_wd(u32 slot_id)
+{
+ return 4;
+}
+
+static int exynos_dwmci_init(u32 slot_id, irq_handler_t handler, void *data)
+{
+ struct dw_mci *host = (struct dw_mci *)data;
+
+ /* Set Phase Shift Register */
+ if (soc_is_exynos4210()) {
+ host->pdata->sdr_timing = 0x00010001;
+ host->pdata->ddr_timing = 0x00020002;
+ } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ host->pdata->sdr_timing = 0x00010001;
+ host->pdata->ddr_timing = 0x00010002;
+ } else if (soc_is_exynos5250()) {
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ switch (host->pdev->id) {
+ case 0:
+ host->pdata->sdr_timing = 0x03020001;
+ host->pdata->ddr_timing = 0x03030002;
+ break;
+ case 1:
+ host->pdata->sdr_timing = 0x03020001;
+ host->pdata->ddr_timing = 0x03030002;
+ break;
+ case 2:
+ host->pdata->sdr_timing = 0x03020001;
+ host->pdata->ddr_timing = 0x03030002;
+ break;
+ case 3:
+ host->pdata->sdr_timing = 0x03020001;
+ host->pdata->ddr_timing = 0x03030002;
+ break;
+ default:
+ host->pdata->sdr_timing = 0x03020001;
+ host->pdata->ddr_timing = 0x03030002;
+ break;
+ }
+ } else {
+ host->pdata->sdr_timing = 0x00010000;
+ host->pdata->ddr_timing = 0x00010000;
+ }
+ }
+#ifdef CONFIG_SLP
+ host->pdata->sdr_timing = 0x00020001;
+ host->pdata->ddr_timing = 0x00020002;
+#endif
+
+ return 0;
+}
+
+static void exynos_dwmci_set_io_timing(void *data, unsigned char timing)
+{
+ struct dw_mci *host = (struct dw_mci *)data;
+
+ if (timing == MMC_TIMING_UHS_DDR50)
+ __raw_writel(host->pdata->ddr_timing,
+ host->regs + DWMCI_CLKSEL);
+ else
+ __raw_writel(host->pdata->sdr_timing,
+ host->regs + DWMCI_CLKSEL);
+}
+
+static struct resource exynos_dwmci_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_DWMCI,
+ .end = EXYNOS_PA_DWMCI + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DWMCI,
+ .end = IRQ_DWMCI,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct dw_mci_board exynos_dwmci_def_platdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+ .bus_hz = 80 * 1000 * 1000,
+ .detect_delay_ms = 200,
+ .init = exynos_dwmci_init,
+ .get_bus_wd = exynos_dwmci_get_bus_wd,
+ .set_io_timing = exynos_dwmci_set_io_timing,
+};
+
+static u64 exynos_dwmci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_dwmci = {
+ .name = "dw_mmc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_dwmci_resource),
+ .resource = exynos_dwmci_resource,
+ .dev = {
+ .dma_mask = &exynos_dwmci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &exynos_dwmci_def_platdata,
+ },
+};
+
+#define EXYNOS5_DWMCI_RESOURCE(_channel) \
+static struct resource exynos5_dwmci##_channel##_resource[] = { \
+ [0] = { \
+ .start = S3C_PA_HSMMC##_channel, \
+ .end = S3C_PA_HSMMC##_channel + SZ_4K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ [1] = { \
+ .start = IRQ_HSMMC##_channel, \
+ .end = IRQ_HSMMC##_channel, \
+ .flags = IORESOURCE_IRQ, \
+ } \
+};
+
+EXYNOS5_DWMCI_RESOURCE(0)
+EXYNOS5_DWMCI_RESOURCE(1)
+EXYNOS5_DWMCI_RESOURCE(2)
+EXYNOS5_DWMCI_RESOURCE(3)
+
+#define EXYNOS_DWMCI_DEF_PLATDATA(_channel) \
+struct dw_mci_board exynos_dwmci##_channel##_def_platdata = { \
+ .num_slots = 1, \
+ .quirks = \
+ DW_MCI_QUIRK_BROKEN_CARD_DETECTION, \
+ .bus_hz = 200 * 1000 * 1000, \
+ .detect_delay_ms = 200, \
+ .init = exynos_dwmci_init, \
+ .get_bus_wd = exynos_dwmci_get_bus_wd, \
+ .set_io_timing = exynos_dwmci_set_io_timing, \
+ .cd_type = DW_MCI_CD_INTERNAL \
+};
+
+EXYNOS_DWMCI_DEF_PLATDATA(0)
+EXYNOS_DWMCI_DEF_PLATDATA(1)
+EXYNOS_DWMCI_DEF_PLATDATA(2)
+EXYNOS_DWMCI_DEF_PLATDATA(3)
+
+#define EXYNOS_DWMCI_PLATFORM_DEVICE(_channel) \
+struct platform_device exynos_device_dwmci##_channel = \
+{ \
+ .name = "dw_mmc", \
+ .id = _channel, \
+ .num_resources = \
+ ARRAY_SIZE(exynos5_dwmci##_channel##_resource), \
+ .resource = exynos5_dwmci##_channel##_resource, \
+ .dev = { \
+ .dma_mask = &exynos_dwmci_dmamask,\
+ .coherent_dma_mask = DMA_BIT_MASK(32), \
+ .platform_data = \
+ &exynos_dwmci##_channel##_def_platdata, \
+ }, \
+};
+
+EXYNOS_DWMCI_PLATFORM_DEVICE(0)
+EXYNOS_DWMCI_PLATFORM_DEVICE(1)
+EXYNOS_DWMCI_PLATFORM_DEVICE(2)
+EXYNOS_DWMCI_PLATFORM_DEVICE(3)
+
+void __init exynos_dwmci_set_platdata(struct dw_mci_board *pd, u32 slot_id)
+{
+ struct dw_mci_board *npd = NULL;
+
+ if ((soc_is_exynos4210()) ||
+ soc_is_exynos4212() || soc_is_exynos4412()) {
+ npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+ &exynos_device_dwmci);
+ } else if (soc_is_exynos5250()) {
+ if (slot_id == 0) {
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ exynos_device_dwmci0.resource[0].start =
+ EXYNOS_PA_DWMCI;
+ exynos_device_dwmci0.resource[0].end =
+ EXYNOS_PA_DWMCI + SZ_4K - 1;
+ exynos_device_dwmci0.resource[1].start =
+ IRQ_DWMCI;
+ exynos_device_dwmci0.resource[1].end =
+ IRQ_DWMCI;
+ }
+ npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+ &exynos_device_dwmci0);
+ } else if (slot_id == 1) {
+ npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+ &exynos_device_dwmci1);
+ } else if (slot_id == 2) {
+ npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+ &exynos_device_dwmci2);
+ } else if (slot_id == 3) {
+ npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+ &exynos_device_dwmci3);
+ } else {
+ pr_err("This channel %d Cannot support.\n", slot_id);
+ }
+ } else {
+ printk("dwmci platform data support only exynos4/5!\n");
+#ifdef CONFIG_SLP
+ npd = s3c_set_platdata(pd, sizeof(struct dw_mci_board),
+ &exynos_device_dwmci);
+#endif
+ }
+
+ if (npd) {
+ if (!npd->init)
+ npd->init = exynos_dwmci_init;
+ if (!npd->get_bus_wd)
+ npd->get_bus_wd = exynos_dwmci_get_bus_wd;
+ if (!npd->set_io_timing)
+ npd->set_io_timing = exynos_dwmci_set_io_timing;
+ }
+}
diff --git a/arch/arm/mach-exynos/dev-fimc-is.c b/arch/arm/mach-exynos/dev-fimc-is.c
new file mode 100644
index 0000000..bc531e3
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-fimc-is.c
@@ -0,0 +1,136 @@
+/* linux/arch/arm/plat-s5p/dev-fimc_is.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Base FIMC-IS resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <media/exynos_fimc_is.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+static struct resource exynos4_fimc_is_resource[] = {
+ [0] = {
+ .start = EXYNOS4_PA_FIMC_IS,
+ .end = EXYNOS4_PA_FIMC_IS + SZ_2M + SZ_256K + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC_IS0,
+ .end = IRQ_FIMC_IS0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_FIMC_IS1,
+ .end = IRQ_FIMC_IS1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos4_device_fimc_is = {
+ .name = "exynos4-fimc-is",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos4_fimc_is_resource),
+ .resource = exynos4_fimc_is_resource,
+};
+#endif
+
+#if defined(CONFIG_ARCH_EXYNOS5)
+static struct resource exynos5_fimc_is_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_FIMC_IS,
+ .end = EXYNOS5_PA_FIMC_IS + SZ_2M + SZ_256K + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ARMISP_GIC,
+ .end = IRQ_ARMISP_GIC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_ISP_GIC,
+ .end = IRQ_ISP_GIC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos5_device_fimc_is = {
+ .name = "exynos5-fimc-is",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos5_fimc_is_resource),
+ .resource = exynos5_fimc_is_resource,
+};
+#endif
+
+struct exynos4_platform_fimc_is exynos4_fimc_is_default_data __initdata = {
+ .hw_ver = 15,
+};
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+void __init exynos4_fimc_is_set_platdata(struct exynos4_platform_fimc_is *pd)
+{
+ struct exynos4_platform_fimc_is *npd;
+
+ if (!pd)
+ pd = &exynos4_fimc_is_default_data;
+
+ npd = kmemdup(pd, sizeof(struct exynos4_platform_fimc_is), GFP_KERNEL);
+
+ if (!npd) {
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ } else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = exynos_fimc_is_cfg_gpio;
+ if (!npd->clk_cfg)
+ npd->clk_cfg = exynos_fimc_is_cfg_clk;
+ if (!npd->clk_on)
+ npd->clk_on = exynos_fimc_is_clk_on;
+ if (!npd->clk_off)
+ npd->clk_off = exynos_fimc_is_clk_off;
+ if (!npd->clk_get)
+ npd->clk_get = exynos_fimc_is_clk_get;
+ if (!npd->clk_put)
+ npd->clk_put = exynos_fimc_is_clk_put;
+
+ exynos4_device_fimc_is.dev.platform_data = npd;
+ }
+}
+#endif
+
+#if defined(CONFIG_ARCH_EXYNOS5)
+void __init exynos5_fimc_is_set_platdata(struct exynos5_platform_fimc_is *pd)
+{
+ struct exynos5_platform_fimc_is *npd;
+
+ if (!pd)
+ pd = (struct exynos5_platform_fimc_is *)&exynos4_fimc_is_default_data;
+
+ npd = kmemdup(pd, sizeof(struct exynos5_platform_fimc_is), GFP_KERNEL);
+
+ if (!npd) {
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ } else {
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = exynos5_fimc_is_cfg_gpio;
+ if (!npd->clk_cfg)
+ npd->clk_cfg = exynos5_fimc_is_cfg_clk;
+ if (!npd->clk_on)
+ npd->clk_on = exynos5_fimc_is_clk_on;
+ if (!npd->clk_off)
+ npd->clk_off = exynos5_fimc_is_clk_off;
+
+ exynos5_device_fimc_is.dev.platform_data = npd;
+ }
+}
+#endif
diff --git a/arch/arm/mach-exynos/dev-fimc-lite.c b/arch/arm/mach-exynos/dev-fimc-lite.c
new file mode 100644
index 0000000..9187566
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-fimc-lite.c
@@ -0,0 +1,85 @@
+/* linux/arch/arm/plat-s5p/dev-fimc-lite.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Base S5P FIMC-Lite resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <mach/map.h>
+#include <media/exynos_flite.h>
+
+static struct resource exynos_flite0_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_FIMC_LITE0,
+ .end = EXYNOS_PA_FIMC_LITE0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC_LITE0,
+ .end = IRQ_FIMC_LITE0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos_device_flite0 = {
+ .name = "exynos-fimc-lite",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos_flite0_resource),
+ .resource = exynos_flite0_resource,
+};
+
+static struct resource exynos_flite1_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_FIMC_LITE1,
+ .end = EXYNOS_PA_FIMC_LITE1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC_LITE1,
+ .end = IRQ_FIMC_LITE1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos_device_flite1 = {
+ .name = "exynos-fimc-lite",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos_flite1_resource),
+ .resource = exynos_flite1_resource,
+};
+
+#ifdef CONFIG_ARCH_EXYNOS5
+static struct resource exynos_flite2_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_FIMC_LITE2,
+ .end = EXYNOS_PA_FIMC_LITE2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC_LITE2,
+ .end = IRQ_FIMC_LITE2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos_device_flite2 = {
+ .name = "exynos-fimc-lite",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos_flite2_resource),
+ .resource = exynos_flite2_resource,
+};
+#endif
+
+struct exynos_platform_flite exynos_flite0_default_data __initdata;
+struct exynos_platform_flite exynos_flite1_default_data __initdata;
+#ifdef CONFIG_ARCH_EXYNOS5
+struct exynos_platform_flite exynos_flite2_default_data __initdata;
+#endif
diff --git a/arch/arm/mach-exynos/dev-gsc.c b/arch/arm/mach-exynos/dev-gsc.c
new file mode 100644
index 0000000..bb6403d
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-gsc.c
@@ -0,0 +1,123 @@
+/* linux/arch/arm/mach-exynos/dev-gsc.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base G-Scaler resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <media/exynos_gscaler.h>
+#include <plat/devs.h>
+#include <mach/map.h>
+
+static u64 exynos5_gsc_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource exynos5_gsc0_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_GSC0,
+ .end = EXYNOS5_PA_GSC0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GSC0,
+ .end = IRQ_GSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos5_device_gsc0 = {
+ .name = "exynos-gsc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos5_gsc0_resource),
+ .resource = exynos5_gsc0_resource,
+ .dev = {
+ .dma_mask = &exynos5_gsc_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource exynos5_gsc1_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_GSC1,
+ .end = EXYNOS5_PA_GSC1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GSC1,
+ .end = IRQ_GSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos5_device_gsc1 = {
+ .name = "exynos-gsc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos5_gsc1_resource),
+ .resource = exynos5_gsc1_resource,
+ .dev = {
+ .dma_mask = &exynos5_gsc_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource exynos5_gsc2_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_GSC2,
+ .end = EXYNOS5_PA_GSC2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GSC2,
+ .end = IRQ_GSC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos5_device_gsc2 = {
+ .name = "exynos-gsc",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos5_gsc2_resource),
+ .resource = exynos5_gsc2_resource,
+ .dev = {
+ .dma_mask = &exynos5_gsc_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource exynos5_gsc3_resource[] = {
+ [0] = {
+ .start = EXYNOS5_PA_GSC3,
+ .end = EXYNOS5_PA_GSC3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GSC3,
+ .end = IRQ_GSC3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device exynos5_device_gsc3 = {
+ .name = "exynos-gsc",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(exynos5_gsc3_resource),
+ .resource = exynos5_gsc3_resource,
+ .dev = {
+ .dma_mask = &exynos5_gsc_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct exynos_platform_gscaler exynos_gsc0_default_data __initdata;
+struct exynos_platform_gscaler exynos_gsc1_default_data __initdata;
+struct exynos_platform_gscaler exynos_gsc2_default_data __initdata;
+struct exynos_platform_gscaler exynos_gsc3_default_data __initdata;
diff --git a/arch/arm/mach-exynos/dev-ion.c b/arch/arm/mach-exynos/dev-ion.c
new file mode 100644
index 0000000..8d84b33
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-ion.c
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-exynos/dev-ion.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/ion.h>
+#include <linux/slab.h>
+#include <mach/exynos-ion.h>
+
+struct platform_device exynos_device_ion = {
+ .name = "ion-exynos",
+ .id = -1,
+};
+
+void __init exynos_ion_set_platdata(void)
+{
+ struct ion_platform_data *pdata;
+ pdata = kzalloc(sizeof(struct ion_platform_data)
+ + 5 * sizeof(struct ion_platform_heap), GFP_KERNEL);
+ if (pdata) {
+ pdata->nr = 5;
+ pdata->heaps[0].type = ION_HEAP_TYPE_SYSTEM;
+ pdata->heaps[0].name = "ion_noncontig_heap";
+ pdata->heaps[0].id = ION_HEAP_TYPE_SYSTEM;
+ pdata->heaps[1].type = ION_HEAP_TYPE_SYSTEM_CONTIG;
+ pdata->heaps[1].name = "ion_contig_heap";
+ pdata->heaps[1].id = ION_HEAP_TYPE_SYSTEM_CONTIG;
+ pdata->heaps[2].type = ION_HEAP_TYPE_EXYNOS;
+ pdata->heaps[2].name = "exynos_noncontig_heap";
+ pdata->heaps[2].id = ION_HEAP_TYPE_EXYNOS;
+ pdata->heaps[3].type = ION_HEAP_TYPE_EXYNOS_CONTIG;
+ pdata->heaps[3].name = "exynos_contig_heap";
+ pdata->heaps[3].id = ION_HEAP_TYPE_EXYNOS_CONTIG;
+ pdata->heaps[4].type = ION_HEAP_TYPE_EXYNOS_USER;
+ pdata->heaps[4].name = "exynos_user_heap";
+ pdata->heaps[4].id = ION_HEAP_TYPE_EXYNOS_USER;
+ exynos_device_ion.dev.platform_data = pdata;
+ }
+}
diff --git a/arch/arm/mach-exynos/dev-pd-exynos4.c b/arch/arm/mach-exynos/dev-pd-exynos4.c
new file mode 100644
index 0000000..670d425
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-pd-exynos4.c
@@ -0,0 +1,255 @@
+/* linux/arch/arm/mach-exynos/dev-pd-exynos4.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Power Domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/regs-pmu.h>
+#include <mach/regs-clock.h>
+
+#include <plat/pd.h>
+
+static u32 exynos_pd_status[8];
+
+static int exynos_pd_save(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ struct platform_device *pdev = to_platform_device(dev);
+ int ret = 0;
+
+ exynos_pd_status[pdev->id] = __raw_readl(pdata->base + 0x4);
+ exynos_pd_status[pdev->id] &= S5P_INT_LOCAL_PWR_EN;
+
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("%s: %s(%d) exynos4_pd_status = 0x%08x\n",
+ __func__, pdev->name, pdev->id, exynos_pd_status[pdev->id]);
+#endif
+
+ if (exynos_pd_status[pdev->id] == S5P_INT_LOCAL_PWR_EN)
+ ret = exynos_pd_disable(dev);
+
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("%s: %s(%d) exynos4 pd status reg = 0x%08x\n",
+ __func__, pdev->name, pdev->id, __raw_readl(pdata->base + 0x4));
+#endif
+
+ return ret;
+}
+
+static int exynos_pd_restore(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ struct platform_device *pdev = to_platform_device(dev);
+ int ret = 0;
+
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("%s: %s(%d) exynos4_pd_status = 0x%08x\n",
+ __func__, pdev->name, pdev->id, exynos_pd_status[pdev->id]);
+#endif
+
+ if (exynos_pd_status[pdev->id] == S5P_INT_LOCAL_PWR_EN)
+ ret = exynos_pd_enable(dev);
+
+ exynos_pd_status[pdev->id] = 0;
+
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("%s: %s(%d) exynos4 pd status reg = 0x%08x\n",
+ __func__, pdev->name, pdev->id, __raw_readl(pdata->base + 0x4));
+#endif
+
+ return ret;
+}
+
+struct platform_device exynos4_device_pd[] = {
+ [PD_MFC] = {
+ .name = "samsung-pd",
+ .id = PD_MFC,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_MFC_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_MFC,
+ .read_phy_addr = EXYNOS4_PA_MFC,
+ },
+ },
+ },
+ },
+ [PD_G3D] = {
+ .name = "samsung-pd",
+ .id = PD_G3D,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_G3D_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_G3D,
+ .read_phy_addr = EXYNOS4_PA_G3D,
+ },
+ },
+ },
+ },
+ [PD_LCD0] = {
+ .name = "samsung-pd",
+ .id = PD_LCD0,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_LCD0_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_LCD0,
+ .read_phy_addr = EXYNOS4_PA_FIMD0,
+ },
+ },
+ },
+ },
+ [PD_LCD1] = {
+ .name = "samsung-pd",
+ .id = PD_LCD1,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_LCD1_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_LCD1,
+ .read_phy_addr = EXYNOS4_PA_FIMD1,
+ },
+ },
+ },
+ },
+ [PD_TV] = {
+ .name = "samsung-pd",
+ .id = PD_TV,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_TV_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_TV,
+ .read_phy_addr = EXYNOS4_PA_VP,
+ },
+ },
+ },
+ },
+ [PD_CAM] = {
+ .name = "samsung-pd",
+ .id = PD_CAM,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_CAM_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_CAM,
+ .read_phy_addr = EXYNOS4_PA_FIMC0,
+ },
+ },
+ },
+ },
+ [PD_GPS] = {
+ .name = "samsung-pd",
+ .id = PD_GPS,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_GPS_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_GPS,
+ .read_phy_addr = EXYNOS4_PA_GPS,
+ },
+ },
+ },
+ },
+ [PD_GPS_ALIVE] = {
+ .name = "samsung-pd",
+ .id = PD_GPS_ALIVE,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_GPS_ALIVE_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = (void __iomem *)NULL,
+ .read_phy_addr = (unsigned long)NULL,
+ },
+ },
+ },
+ },
+ [PD_ISP] = {
+ .name = "samsung-pd",
+ .id = PD_ISP,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_ISP_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_ISP,
+ .read_phy_addr = EXYNOS4_PA_FIMC_IS,
+ },
+ },
+ },
+ },
+ [PD_MAUDIO] = {
+ .name = "samsung-pd",
+ .id = PD_MAUDIO,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .save = exynos_pd_save,
+ .restore = exynos_pd_restore,
+ .base = S5P_PMU_MAUDIO_CONF,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS4_CLKGATE_IP_MAUDIO,
+ .read_phy_addr = EXYNOS4_PA_AUDSS,
+ },
+ },
+ },
+ },
+};
diff --git a/arch/arm/mach-exynos/dev-pd-exynos5.c b/arch/arm/mach-exynos/dev-pd-exynos5.c
new file mode 100644
index 0000000..ee3768c
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-pd-exynos5.c
@@ -0,0 +1,120 @@
+/* linux/arch/arm/mach-exynos/dev-pd-exynos5.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - Power Domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/regs-pmu5.h>
+#include <mach/regs-clock.h>
+
+#include <plat/pd.h>
+
+struct platform_device exynos5_device_pd[] = {
+ [PD_MFC] = {
+ .name = "samsung-pd",
+ .id = PD_MFC,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .base = EXYNOS5_MFC_CONFIGURATION,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS5_CLKGATE_IP_MFC,
+ .clksrc_base = EXYNOS5_CLKSRC_TOP3,
+ },
+ },
+ },
+ },
+ [PD_G3D] = {
+ .name = "samsung-pd",
+ .id = PD_G3D,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .base = EXYNOS5_G3D_CONFIGURATION,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS5_CLKGATE_IP_G3D,
+ .clksrc_base = EXYNOS5_CLKSRC_TOP3,
+ },
+ },
+ },
+ },
+ [PD_GPS] = {
+ .name = "samsung-pd",
+ .id = PD_GPS,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .base = EXYNOS5_GPS_CONFIGURATION,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS5_CLKGATE_IP_GPS,
+ .clksrc_base = EXYNOS5_CLKSRC_TOP3,
+ },
+ },
+ },
+ },
+ [PD_ISP] = {
+ .name = "samsung-pd",
+ .id = PD_ISP,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .base = EXYNOS5_ISP_CONFIGURATION,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = NULL,
+ .clksrc_base = EXYNOS5_CLKSRC_TOP3,
+ },
+ },
+ },
+ },
+ [PD_GSCL] = {
+ .name = "samsung-pd",
+ .id = PD_GSCL,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .base = EXYNOS5_GSCL_CONFIGURATION,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS5_CLKGATE_IP_GSCL,
+ .clksrc_base = EXYNOS5_CLKSRC_TOP3,
+ },
+ },
+ },
+ },
+ [PD_DISP1] = {
+ .name = "samsung-pd",
+ .id = PD_DISP1,
+ .dev = {
+ .platform_data = &(struct samsung_pd_info) {
+ .init = exynos_pd_init,
+ .enable = exynos_pd_enable,
+ .disable = exynos_pd_disable,
+ .base = EXYNOS5_DISP1_CONFIGURATION,
+ .data = &(struct exynos_pd_data) {
+ .clk_base = EXYNOS5_CLKGATE_IP_DISP1,
+ .clksrc_base = EXYNOS5_CLKSRC_TOP3,
+ },
+ },
+ },
+ },
+};
diff --git a/arch/arm/mach-exynos/dev-pd.c b/arch/arm/mach-exynos/dev-pd.c
new file mode 100644
index 0000000..2441fe6
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-pd.c
@@ -0,0 +1,167 @@
+/* linux/arch/arm/mach-exynos/dev-pd.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Power Domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu5.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pd.h>
+#include <plat/bts.h>
+
+int exynos_pd_init(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ struct exynos_pd_data *data = (struct exynos_pd_data *) pdata->data;
+
+ if (soc_is_exynos4210() && data->read_phy_addr) {
+ data->read_base = ioremap(data->read_phy_addr, SZ_4K);
+ if (!data->read_base)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+int exynos_pd_enable(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ struct exynos_pd_data *data = (struct exynos_pd_data *) pdata->data;
+ u32 timeout;
+ u32 tmp = 0;
+
+ /* save IP clock gating register */
+ if (data->clk_base) {
+ tmp = __raw_readl(data->clk_base);
+
+ /* enable all the clocks of IPs in the power domain */
+ __raw_writel(0xffffffff, data->clk_base);
+ }
+
+ __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
+
+ /* Wait max 1ms */
+ timeout = 1000;
+ while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
+ != S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ printk(KERN_ERR "Power domain %s enable failed.\n",
+ dev_name(dev));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ udelay(1);
+ }
+
+ if (data->read_base)
+ /* dummy read to check the completion of power-on sequence */
+ __raw_readl(data->read_base);
+
+ /* restore IP clock gating register */
+ if (data->clk_base)
+ __raw_writel(tmp, data->clk_base);
+
+ bts_enable(pdata->id);
+ return 0;
+}
+
+int exynos_pd_disable(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ struct exynos_pd_data *data = (struct exynos_pd_data *) pdata->data;
+ u32 timeout;
+ u32 tmp = 0;
+
+ static int boot_lcd0 = 1;
+ if (boot_lcd0) {
+ struct platform_device *pdev = to_platform_device(dev);
+ /*
+ * Currently,in exynos4x12, FIMD parent power domain
+ * is PD_LCD0,
+ * but in exynos5x12, it is changed to PD_DISP1.
+ * so i add PD_DISP1 for exynos5
+ */
+ if ((pdev->id == PD_LCD0) || (pdev->id == PD_DISP1)) {
+ printk(KERN_INFO "lcd0 disable skip only one time");
+ boot_lcd0--;
+ return 0;
+ }
+ }
+
+ /* save clock source register */
+ if (data->clksrc_base)
+ tmp = __raw_readl(data->clksrc_base);
+#ifdef CONFIG_EXYNOS5_LOWPWR_IDLE
+ if (soc_is_exynos5250() &&
+ (pdata->base == EXYNOS5_ISP_CONFIGURATION))
+ return 0;
+#endif
+ /* Do not disable MFC power domain for EXYNOS5250 EVT0 */
+ if (soc_is_exynos5250() &&
+ (samsung_rev() < EXYNOS5250_REV_1_0) &&
+ (pdata->base == EXYNOS5_MFC_CONFIGURATION))
+ return 0;
+
+ /*
+ * To ISP power domain off,
+ * first, ISP_ARM power domain be off.
+ */
+ if (soc_is_exynos5250() &&
+ (pdata->base == EXYNOS5_ISP_CONFIGURATION)) {
+ if (!(__raw_readl(EXYNOS5_ISP_ARM_STATUS) & 0x1)) {
+ /* Disable ISP_ARM */
+ timeout = __raw_readl(EXYNOS5_ISP_ARM_OPTION);
+ timeout &= ~EXYNOS5_ISP_ARM_ENABLE;
+ __raw_writel(timeout, EXYNOS5_ISP_ARM_OPTION);
+
+ /* ISP_ARM power off */
+ __raw_writel(0x0, EXYNOS5_ISP_ARM_CONFIGURATION);
+
+ timeout = 1000;
+
+ while (__raw_readl(EXYNOS5_ISP_ARM_STATUS) & 0x1) {
+ if (timeout == 0) {
+ printk(KERN_ERR "ISP_ARM power domain can not off\n");
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ udelay(1);
+ }
+ /* CMU_RESET_ISP_ARM off */
+ __raw_writel(0x0, EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG);
+ }
+ }
+
+ __raw_writel(0, pdata->base);
+
+ /* Wait max 1ms */
+ timeout = 1000;
+ while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ printk(KERN_ERR "Power domain %s disable failed.\n",
+ dev_name(dev));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ udelay(1);
+ }
+
+ /* restore clock source register */
+ if (data->clksrc_base)
+ __raw_writel(tmp, data->clksrc_base);
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/dev-spi.c b/arch/arm/mach-exynos/dev-spi.c
new file mode 100644
index 0000000..0807d3d
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-spi.c
@@ -0,0 +1,308 @@
+/* linux/arch/arm/mach-exynos/dev-spi.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+
+#include <mach/irqs.h>
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/spi-clocks.h>
+#include <mach/regs-clock.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irqs.h>
+
+static char *spi_src_clks[] = {
+ [EXYNOS_SPI_SRCCLK_SCLK] = "sclk_spi",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the CS.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+#if defined(CONFIG_ARCH_EXYNOS5)
+static int exynos_spi_cfg_gpio(struct platform_device *pdev)
+{
+ int gpio;
+
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(0), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(2), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(3), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPA2(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS5_GPA2(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS5_GPA2(3), S3C_GPIO_PULL_UP);
+
+ for (gpio = EXYNOS5_GPA2(0); gpio < EXYNOS5_GPA2(4); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ break;
+
+ case 1:
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(6), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS5_GPA2(7), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPA2(4), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS5_GPA2(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS5_GPA2(7), S3C_GPIO_PULL_UP);
+
+ for (gpio = EXYNOS5_GPA2(4); gpio < EXYNOS5_GPA2(8); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ break;
+
+ case 2:
+ s3c_gpio_cfgpin(EXYNOS5_GPB1(1), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(EXYNOS5_GPB1(3), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(EXYNOS5_GPB1(4), S3C_GPIO_SFN(5));
+ s3c_gpio_setpull(EXYNOS5_GPB1(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS5_GPB1(3), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS5_GPB1(4), S3C_GPIO_PULL_UP);
+
+ for (gpio = EXYNOS5_GPB1(1); gpio < EXYNOS5_GPB1(5); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#else
+static int exynos_spi_cfg_gpio(struct platform_device *pdev)
+{
+ int gpio;
+
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin(EXYNOS4_GPB(0), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS4_GPB(2), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS4_GPB(3), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPB(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS4_GPB(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS4_GPB(3), S3C_GPIO_PULL_UP);
+
+ for (gpio = EXYNOS4_GPB(0); gpio < EXYNOS4_GPB(4); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ break;
+
+ case 1:
+ s3c_gpio_cfgpin(EXYNOS4_GPB(4), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS4_GPB(6), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(EXYNOS4_GPB(7), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPB(4), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS4_GPB(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS4_GPB(7), S3C_GPIO_PULL_UP);
+
+ for (gpio = EXYNOS4_GPB(4); gpio < EXYNOS4_GPB(8); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ break;
+
+ case 2:
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(1), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(3), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(4), S3C_GPIO_SFN(5));
+ s3c_gpio_setpull(EXYNOS4_GPC1(1), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS4_GPC1(3), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(EXYNOS4_GPC1(4), S3C_GPIO_PULL_UP);
+
+ for (gpio = EXYNOS4_GPC1(1); gpio < EXYNOS4_GPC1(5); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
+static struct resource exynos_spi0_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_SPI0,
+ .end = EXYNOS_PA_SPI0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI0_TX,
+ .end = DMACH_SPI0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI0_RX,
+ .end = DMACH_SPI0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info exynos_spi0_pdata = {
+ .cfg_gpio = exynos_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+ .high_speed = 1,
+ .clk_from_cmu = true,
+ .tx_st_done = 25,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos_spi0_resource),
+ .resource = exynos_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &exynos_spi0_pdata,
+ },
+};
+
+static struct resource exynos_spi1_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_SPI1,
+ .end = EXYNOS_PA_SPI1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI1_TX,
+ .end = DMACH_SPI1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI1_RX,
+ .end = DMACH_SPI1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info exynos_spi1_pdata = {
+ .cfg_gpio = exynos_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+ .high_speed = 1,
+ .clk_from_cmu = true,
+ .tx_st_done = 25,
+};
+
+struct platform_device exynos_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos_spi1_resource),
+ .resource = exynos_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &exynos_spi1_pdata,
+ },
+};
+
+static struct resource exynos_spi2_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_SPI2,
+ .end = EXYNOS_PA_SPI2 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI2_TX,
+ .end = DMACH_SPI2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI2_RX,
+ .end = DMACH_SPI2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI2,
+ .end = IRQ_SPI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info exynos_spi2_pdata = {
+ .cfg_gpio = exynos_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+ .high_speed = 1,
+ .clk_from_cmu = true,
+ .tx_st_done = 25,
+};
+
+struct platform_device exynos_device_spi2 = {
+ .name = "s3c64xx-spi",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos_spi2_resource),
+ .resource = exynos_spi2_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &exynos_spi2_pdata,
+ },
+};
+
+void __init exynos_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
+{
+ struct s3c64xx_spi_info *pd;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0
+ || src_clk_nr > EXYNOS_SPI_SRCCLK_SCLK) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ pd = &exynos_spi0_pdata;
+ break;
+ case 1:
+ pd = &exynos_spi1_pdata;
+ break;
+ case 2:
+ pd = &exynos_spi2_pdata;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+ __func__, cntrlr);
+ return;
+ }
+
+ pd->num_cs = num_cs;
+ pd->src_clk_nr = src_clk_nr;
+ pd->src_clk_name = spi_src_clks[src_clk_nr];
+}
diff --git a/arch/arm/mach-exynos/dev-sysmmu-exynos4.c b/arch/arm/mach-exynos/dev-sysmmu-exynos4.c
new file mode 100644
index 0000000..bb14b74
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-sysmmu-exynos4.c
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-exynos/dev-sysmmu.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - System MMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/dev-sysmmu.h>
+#include <plat/s5p-clock.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#define EXYNOS_PA_SYSMMU(ipbase) EXYNOS4_PA_SYSMMU_##ipbase
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#define EXYNOS_PA_SYSMMU(ipbase) EXYNOS5_PA_SYSMMU_##ipbase
+#endif
+
+#define SYSMMU_RESOURCE(ipname, base, irq) \
+static struct resource sysmmu_resource_##ipname[] =\
+{\
+ {\
+ .start = EXYNOS_PA_SYSMMU(base),\
+ .end = EXYNOS_PA_SYSMMU(base) + SZ_4K - 1,\
+ .flags = IORESOURCE_MEM,\
+ }, {\
+ .start = IRQ_SYSMMU_##irq##_0,\
+ .end = IRQ_SYSMMU_##irq##_0,\
+ .flags = IORESOURCE_IRQ,\
+ },\
+}
+
+#define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
+struct platform_device SYSMMU_PLATDEV(ipname) =\
+{\
+ .name = SYSMMU_DEVNAME_BASE,\
+ .id = devid,\
+ .num_resources = ARRAY_SIZE(sysmmu_resource_##ipname),\
+ .resource = sysmmu_resource_##ipname,\
+ .dev = {\
+ .dma_mask = &exynos_sysmmu_dma_mask,\
+ .coherent_dma_mask = DMA_BIT_MASK(32),\
+ },\
+}
+
+static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
+
+SYSMMU_RESOURCE(sss, SSS, SSS);
+SYSMMU_RESOURCE(jpeg, JPEG, JPEG);
+SYSMMU_RESOURCE(fimd1, FIMD1, FIMD1);
+SYSMMU_RESOURCE(2d, 2D, 2D);
+SYSMMU_RESOURCE(rot, ROTATOR, ROTATOR);
+SYSMMU_RESOURCE(mdma, MDMA2, MDMA1);
+SYSMMU_RESOURCE(tv, TV, TV);
+SYSMMU_RESOURCE(mfc_l, MFC_L, MFC_L);
+SYSMMU_RESOURCE(mfc_r, MFC_R, MFC_R);
+SYSMMU_RESOURCE(is_isp, ISP, ISP);
+SYSMMU_RESOURCE(is_drc, DRC, DRC);
+SYSMMU_RESOURCE(is_fd, FD, FD);
+SYSMMU_RESOURCE(is_cpu, ISPCPU, MCUISP);
+SYSMMU_RESOURCE(flite0, LITE0, LITE0);
+SYSMMU_RESOURCE(flite1, LITE1, LITE1);
+
+SYSMMU_PLATFORM_DEVICE(sss, 0);
+SYSMMU_PLATFORM_DEVICE(jpeg, 5);
+SYSMMU_PLATFORM_DEVICE(fimd1, 7);
+SYSMMU_PLATFORM_DEVICE(2d, 9);
+SYSMMU_PLATFORM_DEVICE(rot, 10);
+SYSMMU_PLATFORM_DEVICE(mdma, 11);
+SYSMMU_PLATFORM_DEVICE(tv, 12);
+SYSMMU_PLATFORM_DEVICE(mfc_l, 13);
+SYSMMU_PLATFORM_DEVICE(mfc_r, 14);
+SYSMMU_PLATFORM_DEVICE(is_isp, 16);
+SYSMMU_PLATFORM_DEVICE(is_drc, 17);
+SYSMMU_PLATFORM_DEVICE(is_fd, 18);
+SYSMMU_PLATFORM_DEVICE(is_cpu, 19);
+SYSMMU_PLATFORM_DEVICE(flite0, 30);
+SYSMMU_PLATFORM_DEVICE(flite1, 31);
+
+#ifdef CONFIG_ARCH_EXYNOS4
+SYSMMU_RESOURCE(fimc0, FIMC0, FIMC0);
+SYSMMU_RESOURCE(fimc1, FIMC1, FIMC1);
+SYSMMU_RESOURCE(fimc2, FIMC2, FIMC2);
+SYSMMU_RESOURCE(fimc3, FIMC3, FIMC3);
+SYSMMU_RESOURCE(fimd0, FIMD0, FIMD0);
+SYSMMU_RESOURCE(pcie, PCIe, PCIE);
+SYSMMU_RESOURCE(g2d_acp, G2D_ACP, 2D);
+
+SYSMMU_PLATFORM_DEVICE(fimc0, 1);
+SYSMMU_PLATFORM_DEVICE(fimc1, 2);
+SYSMMU_PLATFORM_DEVICE(fimc2, 3);
+SYSMMU_PLATFORM_DEVICE(fimc3, 4);
+SYSMMU_PLATFORM_DEVICE(fimd0, 6);
+SYSMMU_PLATFORM_DEVICE(pcie, 8);
+SYSMMU_PLATFORM_DEVICE(g2d_acp, 15);
+#endif
+
+#ifdef CONFIG_ARCH_EXYNOS5
+SYSMMU_RESOURCE(gsc0, GSC0, GSC0);
+SYSMMU_RESOURCE(gsc1, GSC1, GSC1);
+SYSMMU_RESOURCE(gsc2, GSC2, GSC2);
+SYSMMU_RESOURCE(gsc3, GSC3, GSC3);
+SYSMMU_RESOURCE(is_sclrc, SCALERC, SCALERCISP);
+SYSMMU_RESOURCE(is_sclrp, SCALERP, SCALERPISP);
+SYSMMU_RESOURCE(is_odc, ODC, ODC);
+SYSMMU_RESOURCE(is_dis0, DIS0, DIS0);
+SYSMMU_RESOURCE(is_dis1, DIS1, DIS1);
+SYSMMU_RESOURCE(is_3dnr, 3DNR, 3DNR);
+SYSMMU_RESOURCE(flite2, LITE2, LITE2);
+
+SYSMMU_PLATFORM_DEVICE(gsc0, 20);
+SYSMMU_PLATFORM_DEVICE(gsc1, 21);
+SYSMMU_PLATFORM_DEVICE(gsc2, 22);
+SYSMMU_PLATFORM_DEVICE(gsc3, 23);
+SYSMMU_PLATFORM_DEVICE(is_sclrc, 24);
+SYSMMU_PLATFORM_DEVICE(is_sclrp, 25);
+SYSMMU_PLATFORM_DEVICE(is_odc, 26);
+SYSMMU_PLATFORM_DEVICE(is_dis0, 27);
+SYSMMU_PLATFORM_DEVICE(is_dis1, 28);
+SYSMMU_PLATFORM_DEVICE(is_3dnr, 29);
+SYSMMU_PLATFORM_DEVICE(flite2, 32);
+#endif
diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c
new file mode 100644
index 0000000..0981fba
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-sysmmu.c
@@ -0,0 +1,301 @@
+/* linux/arch/arm/mach-exynos/dev-sysmmu.c
+ *
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - System MMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/cpu.h>
+#include <plat/pd.h>
+#include <plat/devs.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/sysmmu.h>
+
+static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
+
+/* DEFINE_RES_XXXX is defined in 3.3 kernel */
+#ifndef DEFINE_RES_NAMED
+#define DEFINE_RES_NAMED(_start, _size, _name, _flags) \
+ { \
+ .start = (_start), \
+ .end = (_start) + (_size) - 1, \
+ .name = (_name), \
+ .flags = (_flags), \
+ }
+
+#define DEFINE_RES_MEM_NAMED(_start, _size, _name) \
+ DEFINE_RES_NAMED((_start), (_size), (_name), IORESOURCE_MEM)
+#define DEFINE_RES_MEM(_start, _size) \
+ DEFINE_RES_MEM_NAMED((_start), (_size), NULL)
+
+#define DEFINE_RES_IRQ_NAMED(_irq, _name) \
+ DEFINE_RES_NAMED((_irq), 1, (_name), IORESOURCE_IRQ)
+#define DEFINE_RES_IRQ(_irq) \
+ DEFINE_RES_IRQ_NAMED((_irq), NULL)
+#endif /* DEFINE_RES_NAMED */
+
+#define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
+static struct sysmmu_platform_data platdata_##ipname = { \
+ .dbgname = #ipname, \
+}; \
+struct platform_device SYSMMU_PLATDEV(ipname) = \
+{ \
+ .name = SYSMMU_DEVNAME_BASE, \
+ .id = devid, \
+ .dev = { \
+ .dma_mask = &exynos_sysmmu_dma_mask, \
+ .coherent_dma_mask = DMA_BIT_MASK(32), \
+ .platform_data = &platdata_##ipname, \
+ }, \
+}
+
+SYSMMU_PLATFORM_DEVICE(mfc_lr, 0);
+SYSMMU_PLATFORM_DEVICE(tv, 2);
+SYSMMU_PLATFORM_DEVICE(jpeg, 3);
+SYSMMU_PLATFORM_DEVICE(rot, 4);
+SYSMMU_PLATFORM_DEVICE(fimc0, 5); /* fimc* and gsc* exist exclusively */
+SYSMMU_PLATFORM_DEVICE(fimc1, 6);
+SYSMMU_PLATFORM_DEVICE(fimc2, 7);
+SYSMMU_PLATFORM_DEVICE(fimc3, 8);
+SYSMMU_PLATFORM_DEVICE(gsc0, 5);
+SYSMMU_PLATFORM_DEVICE(gsc1, 6);
+SYSMMU_PLATFORM_DEVICE(gsc2, 7);
+SYSMMU_PLATFORM_DEVICE(gsc3, 8);
+SYSMMU_PLATFORM_DEVICE(isp, 9);
+SYSMMU_PLATFORM_DEVICE(fimd0, 10);
+SYSMMU_PLATFORM_DEVICE(fimd1, 11);
+SYSMMU_PLATFORM_DEVICE(camif0, 12);
+SYSMMU_PLATFORM_DEVICE(camif1, 13);
+SYSMMU_PLATFORM_DEVICE(camif2, 14);
+SYSMMU_PLATFORM_DEVICE(2d, 15);
+
+#define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname
+
+#define SYSMMU_RESOURCE(core, ipname) \
+ static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata =
+
+#define DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
+ DEFINE_RES_MEM_NAMED(core##_PA_SYSMMU_##mem, SZ_4K, #mem), \
+ DEFINE_RES_IRQ_NAMED(core##_IRQ_SYSMMU_##irq##_0, #mem)
+
+#define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \
+ SYSMMU_RESOURCE(core, ipname) { \
+ DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
+ }
+
+struct sysmmu_resource_map {
+ struct platform_device *pdev;
+ struct resource *res;
+ u32 rnum;
+ struct device *pdd;
+ char *clocknames;
+};
+
+#define SYSMMU_RESOURCE_MAPPING(core, ipname, resname) { \
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME, \
+}
+
+#define SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) { \
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
+}
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) { \
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME, \
+ .pdd = &exynos##core##_device_pd[pd].dev, \
+}
+
+#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) {\
+ .pdev = &SYSMMU_PLATDEV(ipname), \
+ .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
+ .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
+ .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
+ .pdd = &exynos##core##_device_pd[pd].dev, \
+}
+#else
+#define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) \
+ SYSMMU_RESOURCE_MAPPING(core, ipname, resname)
+#define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) \
+ SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata)
+
+#endif /* CONFIG_EXYNOS_DEV_PD */
+
+#ifdef CONFIG_ARCH_EXYNOS4
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0, FIMC0, FIMC0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1, FIMC1, FIMC1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2, FIMC2, FIMC2);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3, FIMC3, FIMC3);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg, JPEG, JPEG);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d, G2D, 2D);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv, TV, TV_M0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp, G2D_ACP, 2D);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot, ROTATOR, ROTATOR);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0, FIMD0, LCD0_M0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1, FIMD1, LCD1_M1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0, FIMC_LITE0, FIMC_LITE0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1, FIMC_LITE1, FIMC_LITE1);
+SYSMMU_RESOURCE(EXYNOS4, mfc_lr) {
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, MFC_R, MFC_M0),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, MFC_L, MFC_M1),
+};
+SYSMMU_RESOURCE(EXYNOS4, isp) {
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISP, FIMC_ISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, DRC, FIMC_DRC),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, FD, FIMC_FD),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISPCPU, FIMC_CX),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap4[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc0, fimc0, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc1, fimc1, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc2, fimc2, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimc3, fimc3, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, tv, tv, PD_TV),
+ SYSMMU_RESOURCE_MAPPING_PD(4, mfc_lr, mfc_lr, PD_MFC),
+ SYSMMU_RESOURCE_MAPPING_PD(4, rot, rot, PD_LCD0),
+ SYSMMU_RESOURCE_MAPPING_PD(4, jpeg, jpeg, PD_CAM),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimd0, fimd0, PD_LCD0),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap4210[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING_PD(4, 2d, 2d, PD_LCD0),
+ SYSMMU_RESOURCE_MAPPING_PD(4, fimd1, fimd1, PD_LCD1),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap4212[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING(4, 2d, 2d_acp),
+ SYSMMU_RESOURCE_MAPPING_PD(4, camif0, flite0, PD_ISP),
+ SYSMMU_RESOURCE_MAPPING_PD(4, camif1, flite1, PD_ISP),
+ SYSMMU_RESOURCE_MAPPING_PD(4, isp, isp, PD_ISP),
+};
+#endif /* CONFIG_ARCH_EXYNOS4 */
+
+#ifdef CONFIG_ARCH_EXYNOS5
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg, JPEG, JPEG);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1, FIMD1, FIMD1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d, 2D, 2D);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot, ROTATOR, ROTATOR);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv, TV, TV);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0, LITE0, LITE0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1, LITE1, LITE1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite2, LITE2, LITE2);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0, GSC0, GSC0);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1, GSC1, GSC1);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2, GSC2, GSC2);
+SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3, GSC3, GSC3);
+SYSMMU_RESOURCE(EXYNOS5, mfc_lr) {
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, MFC_R, MFC_R),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, MFC_L, MFC_L),
+};
+SYSMMU_RESOURCE(EXYNOS5, isp) {
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISP, ISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, DRC, DRC),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, FD, FD),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISPCPU, MCUISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERC, SCALERCISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERP, SCALERPISP),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, ODC, ODC),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS0, DIS0),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS1, DIS1),
+ DEFINE_SYSMMU_RESOURCE(EXYNOS5, 3DNR, 3DNR),
+};
+
+static struct sysmmu_resource_map sysmmu_resmap5[] __initdata = {
+ SYSMMU_RESOURCE_MAPPING(5, jpeg, jpeg),
+ SYSMMU_RESOURCE_MAPPING(5, fimd1, fimd1),
+ SYSMMU_RESOURCE_MAPPING(5, 2d, 2d),
+ SYSMMU_RESOURCE_MAPPING(5, rot, rot),
+ SYSMMU_RESOURCE_MAPPING_PD(5, tv, tv, PD_DISP1),
+ SYSMMU_RESOURCE_MAPPING_PD(5, camif0, flite0, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, camif1, flite1, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, camif2, flite2, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc0, gsc0, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc1, gsc1, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc2, gsc2, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, gsc3, gsc3, PD_GSCL),
+ SYSMMU_RESOURCE_MAPPING_PD(5, mfc_lr, mfc_lr, PD_MFC),
+ SYSMMU_RESOURCE_MAPPING_MCPD(5, isp, isp, PD_ISP, mc_platdata),
+};
+#endif /* CONFIG_ARCH_EXYNOS5 */
+
+static int __init init_sysmmu_platform_device(void)
+{
+ int i, j;
+ struct sysmmu_resource_map *resmap[2] = {NULL, NULL};
+ int nmap[2] = {0, 0};
+
+#ifdef CONFIG_ARCH_EXYNOS5
+ if (soc_is_exynos5250()) {
+ resmap[0] = sysmmu_resmap5;
+ nmap[0] = ARRAY_SIZE(sysmmu_resmap5);
+ nmap[1] = 0;
+ }
+#endif
+
+#ifdef CONFIG_ARCH_EXYNOS4
+ if (resmap[0] == NULL) {
+ resmap[0] = sysmmu_resmap4;
+ nmap[0] = ARRAY_SIZE(sysmmu_resmap4);
+ }
+
+ if (soc_is_exynos4210()) {
+ resmap[1] = sysmmu_resmap4210;
+ nmap[1] = ARRAY_SIZE(sysmmu_resmap4210);
+ }
+
+ if (soc_is_exynos4412() || soc_is_exynos4212()) {
+ resmap[1] = sysmmu_resmap4212;
+ nmap[1] = ARRAY_SIZE(sysmmu_resmap4212);
+ }
+#endif
+
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < nmap[j]; i++) {
+ struct sysmmu_resource_map *map;
+ struct sysmmu_platform_data *platdata;
+
+ map = &resmap[j][i];
+
+ map->pdev->dev.parent = map->pdd;
+
+ platdata = map->pdev->dev.platform_data;
+ platdata->clockname = map->clocknames;
+
+ if (platform_device_add_resources(map->pdev, map->res,
+ map->rnum)) {
+ pr_err("%s: Failed to add device resources for "
+ "%s.%d\n", __func__,
+ map->pdev->name, map->pdev->id);
+ continue;
+ }
+
+ if (platform_device_register(map->pdev)) {
+ pr_err("%s: Failed to register %s.%d\n",
+ __func__, map->pdev->name,
+ map->pdev->id);
+ }
+ }
+ }
+
+ return 0;
+}
+subsys_initcall(init_sysmmu_platform_device);
diff --git a/arch/arm/mach-exynos/dev.c b/arch/arm/mach-exynos/dev.c
new file mode 100644
index 0000000..a866a9a
--- /dev/null
+++ b/arch/arm/mach-exynos/dev.c
@@ -0,0 +1,188 @@
+/* linux/arch/arm/mach-exynos/dev.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 Device List support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <mach/dev.h>
+#ifdef CONFIG_ARCH_EXYNOS4
+#include <mach/busfreq_exynos4.h>
+#else
+#include <mach/busfreq_exynos5.h>
+#endif
+
+static LIST_HEAD(domains_list);
+static DEFINE_MUTEX(domains_mutex);
+
+static struct device_domain *find_device_domain(struct device *dev)
+{
+ struct device_domain *tmp_domain, *domain = ERR_PTR(-ENODEV);
+
+ mutex_lock(&domains_mutex);
+ list_for_each_entry(tmp_domain, &domains_list, node) {
+ if (tmp_domain->device == dev) {
+ domain = tmp_domain;
+ break;
+ }
+ }
+
+ mutex_unlock(&domains_mutex);
+ return domain;
+}
+
+int dev_add(struct device_domain *dev, struct device *device)
+{
+ if (!dev || !device)
+ return -EINVAL;
+
+ mutex_lock(&domains_mutex);
+ INIT_LIST_HEAD(&dev->domain_list);
+ dev->device = device;
+ list_add(&dev->node, &domains_list);
+ mutex_unlock(&domains_mutex);
+
+ return 0;
+}
+
+struct device *dev_get(const char *name)
+{
+ struct device_domain *domain;
+
+ mutex_lock(&domains_mutex);
+ list_for_each_entry(domain, &domains_list, node)
+ if (strcmp(name, dev_name(domain->device)) == 0)
+ goto found;
+
+ mutex_unlock(&domains_mutex);
+ return ERR_PTR(-ENODEV);
+found:
+ mutex_unlock(&domains_mutex);
+ return domain->device;
+}
+
+void dev_put(const char *name)
+{
+ return;
+}
+
+int dev_lock(struct device *device, struct device *dev,
+ unsigned long freq)
+{
+ struct device_domain *domain;
+ struct domain_lock *lock;
+ int ret = 0;
+
+ domain = find_device_domain(device);
+
+ if (IS_ERR(domain)) {
+ dev_err(dev, "Can't find device domain.\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&domains_mutex);
+ list_for_each_entry(lock, &domain->domain_list, node) {
+ if (lock->device == dev) {
+ /* If the lock already exist, only update the freq */
+ lock->freq = freq;
+ goto out;
+ }
+ }
+
+ lock = kzalloc(sizeof(struct domain_lock), GFP_KERNEL);
+ if (!lock) {
+ dev_err(device, "Unable to create domain_lock");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ lock->device = dev;
+ lock->freq = freq;
+ list_add(&lock->node, &domain->domain_list);
+
+out:
+ mutex_unlock(&domains_mutex);
+ exynos_request_apply(freq);
+ return ret;
+}
+
+int dev_unlock(struct device *device, struct device *dev)
+{
+ struct device_domain *domain;
+ struct domain_lock *lock;
+
+ domain = find_device_domain(device);
+
+ if (IS_ERR(domain)) {
+ dev_err(dev, "Can't find device domain.\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&domains_mutex);
+ list_for_each_entry(lock, &domain->domain_list, node) {
+ if (lock->device == dev) {
+ list_del(&lock->node);
+ kfree(lock);
+ break;
+ }
+ }
+
+ mutex_unlock(&domains_mutex);
+
+ return 0;
+}
+
+unsigned long dev_max_freq(struct device *device)
+{
+ struct device_domain *domain;
+ struct domain_lock *lock;
+ unsigned long freq = 0;
+
+ domain = find_device_domain(device);
+ if (IS_ERR(domain)) {
+ dev_dbg(device, "Can't find device domain.\n");
+ return freq;
+ }
+
+ mutex_lock(&domains_mutex);
+ list_for_each_entry(lock, &domain->domain_list, node)
+ if (lock->freq > freq)
+ freq = lock->freq;
+
+ mutex_unlock(&domains_mutex);
+
+ return freq;
+}
+
+int dev_lock_list(struct device *device, char *buf)
+{
+ struct device_domain *domain;
+ struct domain_lock *lock;
+ int count = 0;
+
+ domain = find_device_domain(device);
+ if (IS_ERR(domain)) {
+ dev_dbg(device, "Can't find device domain.\n");
+ return 0;
+ }
+
+ mutex_lock(&domains_mutex);
+ count = sprintf(buf, "Lock List\n");
+ list_for_each_entry(lock, &domain->domain_list, node)
+ count += sprintf(buf + count, "%s : %lu\n", dev_name(lock->device), lock->freq);
+
+ mutex_unlock(&domains_mutex);
+
+ return count;
+}
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
new file mode 100644
index 0000000..2de356e
--- /dev/null
+++ b/arch/arm/mach-exynos/dma.c
@@ -0,0 +1,404 @@
+/* linux/arch/arm/mach-exynos/dma.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <plat/devs.h>
+#include <plat/irqs.h>
+#ifdef CONFIG_EXYNOS_DEV_PD
+#include <plat/pd.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/cpu.h>
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource exynos_mdma_resource[] = {
+ [0] = {
+ .start = S5P_PA_MDMA1,
+ .end = S5P_PA_MDMA1 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MDMA1,
+ .end = IRQ_MDMA1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct s3c_pl330_platdata exynos_mdma_pdata = {
+ .peri = {
+ /*
+ * The DMAC can have max 8 channel so there
+ * can be MAX 8 M<->M requests served at any time.
+ *
+ * Always keep the first 8 M->M channels on the
+ * DMAC dedicated for M->M transfers.
+ */
+ [0] = DMACH_MTOM_0,
+ [1] = DMACH_MTOM_1,
+ [2] = DMACH_MTOM_2,
+ [3] = DMACH_MTOM_3,
+ [4] = DMACH_MTOM_4,
+ [5] = DMACH_MTOM_5,
+ [6] = DMACH_MTOM_6,
+ [7] = DMACH_MTOM_7,
+ [8] = DMACH_MAX,
+ [9] = DMACH_MAX,
+ [10] = DMACH_MAX,
+ [11] = DMACH_MAX,
+ [12] = DMACH_MAX,
+ [13] = DMACH_MAX,
+ [14] = DMACH_MAX,
+ [15] = DMACH_MAX,
+ [16] = DMACH_MAX,
+ [17] = DMACH_MAX,
+ [18] = DMACH_MAX,
+ [19] = DMACH_MAX,
+ [20] = DMACH_MAX,
+ [21] = DMACH_MAX,
+ [22] = DMACH_MAX,
+ [23] = DMACH_MAX,
+ [24] = DMACH_MAX,
+ [25] = DMACH_MAX,
+ [26] = DMACH_MAX,
+ [27] = DMACH_MAX,
+ [28] = DMACH_MAX,
+ [29] = DMACH_MAX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+struct platform_device exynos_device_mdma = {
+ .name = "s3c-pl330",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(exynos_mdma_resource),
+ .resource = exynos_mdma_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &exynos_mdma_pdata,
+#if 0 /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_EXYNOS_DEV_PD) */
+ .parent = &exynos4_device_pd[PD_LCD0].dev,
+#endif
+ },
+};
+
+static struct resource exynos_pdma0_resource[] = {
+ [0] = {
+ .start = S5P_PA_PDMA0,
+ .end = S5P_PA_PDMA0 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA0,
+ .end = IRQ_PDMA0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata exynos4210_pdma0_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM2_RX,
+ [3] = DMACH_PCM2_TX,
+ [4] = DMACH_MSM_REQ0,
+ [5] = DMACH_MSM_REQ2,
+ [6] = DMACH_SPI0_RX,
+ [7] = DMACH_SPI0_TX,
+ [8] = DMACH_SPI2_RX,
+ [9] = DMACH_SPI2_TX,
+ [10] = DMACH_I2S0S_TX,
+ [11] = DMACH_I2S0_RX,
+ [12] = DMACH_I2S0_TX,
+ [13] = DMACH_I2S2_RX,
+ [14] = DMACH_I2S2_TX,
+ [15] = DMACH_UART0_RX,
+ [16] = DMACH_UART0_TX,
+ [17] = DMACH_UART2_RX,
+ [18] = DMACH_UART2_TX,
+ [19] = DMACH_UART4_RX,
+ [20] = DMACH_UART4_TX,
+ [21] = DMACH_SLIMBUS0_RX,
+ [22] = DMACH_SLIMBUS0_TX,
+ [23] = DMACH_SLIMBUS2_RX,
+ [24] = DMACH_SLIMBUS2_TX,
+ [25] = DMACH_SLIMBUS4_RX,
+ [26] = DMACH_SLIMBUS4_TX,
+ [27] = DMACH_AC97_MICIN,
+ [28] = DMACH_AC97_PCMIN,
+ [29] = DMACH_AC97_PCMOUT,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct s3c_pl330_platdata exynos4212_pdma0_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM2_RX,
+ [3] = DMACH_PCM2_TX,
+ [4] = DMACH_MIPI_HSI0,
+ [5] = DMACH_MIPI_HSI1,
+ [6] = DMACH_SPI0_RX,
+ [7] = DMACH_SPI0_TX,
+ [8] = DMACH_SPI2_RX,
+ [9] = DMACH_SPI2_TX,
+ [10] = DMACH_I2S0S_TX,
+ [11] = DMACH_I2S0_RX,
+ [12] = DMACH_I2S0_TX,
+ [13] = DMACH_I2S2_RX,
+ [14] = DMACH_I2S2_TX,
+ [15] = DMACH_UART0_RX,
+ [16] = DMACH_UART0_TX,
+ [17] = DMACH_UART2_RX,
+ [18] = DMACH_UART2_TX,
+ [19] = DMACH_UART4_RX,
+ [20] = DMACH_UART4_TX,
+ [21] = DMACH_SLIMBUS0_RX,
+ [22] = DMACH_SLIMBUS0_TX,
+ [23] = DMACH_SLIMBUS2_RX,
+ [24] = DMACH_SLIMBUS2_TX,
+ [25] = DMACH_SLIMBUS4_RX,
+ [26] = DMACH_SLIMBUS4_TX,
+ [27] = DMACH_AC97_MICIN,
+ [28] = DMACH_AC97_PCMIN,
+ [29] = DMACH_AC97_PCMOUT,
+ [30] = DMACH_MIPI_HSI4,
+ [31] = DMACH_MIPI_HSI5,
+ },
+};
+
+static struct s3c_pl330_platdata exynos5210_pdma0_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM2_RX,
+ [3] = DMACH_PCM2_TX,
+ [4] = DMACH_SPI0_RX,
+ [5] = DMACH_SPI0_TX,
+ [6] = DMACH_SPI2_RX,
+ [7] = DMACH_SPI2_TX,
+ [8] = DMACH_I2S0S_TX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S2_RX,
+ [12] = DMACH_I2S2_TX,
+ [13] = DMACH_UART0_RX,
+ [14] = DMACH_UART0_TX,
+ [15] = DMACH_UART2_RX,
+ [16] = DMACH_UART2_TX,
+ [17] = DMACH_UART4_RX,
+ [18] = DMACH_UART4_TX,
+ [19] = DMACH_SLIMBUS0_RX,
+ [20] = DMACH_SLIMBUS0_TX,
+ [21] = DMACH_SLIMBUS2_RX,
+ [22] = DMACH_SLIMBUS2_TX,
+ [23] = DMACH_SLIMBUS4_RX,
+ [24] = DMACH_SLIMBUS4_TX,
+ [25] = DMACH_AC97_MICIN,
+ [26] = DMACH_AC97_PCMIN,
+ [27] = DMACH_AC97_PCMOUT,
+ [28] = DMACH_MIPI_HSI0,
+ [29] = DMACH_MIPI_HSI2,
+ [30] = DMACH_MIPI_HSI4,
+ [31] = DMACH_MIPI_HSI6,
+ },
+};
+
+struct platform_device exynos_device_pdma0 = {
+ .name = "s3c-pl330",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(exynos_pdma0_resource),
+ .resource = exynos_pdma0_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource exynos_pdma1_resource[] = {
+ [0] = {
+ .start = S5P_PA_PDMA1,
+ .end = S5P_PA_PDMA1 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA1,
+ .end = IRQ_PDMA1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata exynos4210_pdma1_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM1_RX,
+ [3] = DMACH_PCM1_TX,
+ [4] = DMACH_MSM_REQ1,
+ [5] = DMACH_MSM_REQ3,
+ [6] = DMACH_SPI1_RX,
+ [7] = DMACH_SPI1_TX,
+ [8] = DMACH_I2S0S_TX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S1_RX,
+ [12] = DMACH_I2S1_TX,
+ [13] = DMACH_UART0_RX,
+ [14] = DMACH_UART0_TX,
+ [15] = DMACH_UART1_RX,
+ [16] = DMACH_UART1_TX,
+ [17] = DMACH_UART3_RX,
+ [18] = DMACH_UART3_TX,
+ [19] = DMACH_SLIMBUS1_RX,
+ [20] = DMACH_SLIMBUS1_TX,
+ [21] = DMACH_SLIMBUS3_RX,
+ [22] = DMACH_SLIMBUS3_TX,
+ [23] = DMACH_SLIMBUS5_RX,
+ [24] = DMACH_SLIMBUS5_TX,
+ [25] = DMACH_SLIMBUS0AUX_RX,
+ [26] = DMACH_SLIMBUS0AUX_TX,
+ [27] = DMACH_SPDIF,
+ [28] = DMACH_MAX,
+ [29] = DMACH_MAX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct s3c_pl330_platdata exynos4212_pdma1_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM1_RX,
+ [3] = DMACH_PCM1_TX,
+ [4] = DMACH_MIPI_HSI2,
+ [5] = DMACH_MIPI_HSI3,
+ [6] = DMACH_SPI1_RX,
+ [7] = DMACH_SPI1_TX,
+ [8] = DMACH_I2S0S_TX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S1_RX,
+ [12] = DMACH_I2S1_TX,
+ [13] = DMACH_UART0_RX,
+ [14] = DMACH_UART0_TX,
+ [15] = DMACH_UART1_RX,
+ [16] = DMACH_UART1_TX,
+ [17] = DMACH_UART3_RX,
+ [18] = DMACH_UART3_TX,
+ [19] = DMACH_SLIMBUS1_RX,
+ [20] = DMACH_SLIMBUS1_TX,
+ [21] = DMACH_SLIMBUS3_RX,
+ [22] = DMACH_SLIMBUS3_TX,
+ [23] = DMACH_SLIMBUS5_RX,
+ [24] = DMACH_SLIMBUS5_TX,
+ [25] = DMACH_SLIMBUS0AUX_RX,
+ [26] = DMACH_SLIMBUS0AUX_TX,
+ [27] = DMACH_SPDIF,
+ [28] = DMACH_MIPI_HSI6,
+ [29] = DMACH_MIPI_HSI7,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct s3c_pl330_platdata exynos5210_pdma1_pdata = {
+ .peri = {
+ [0] = DMACH_PCM0_RX,
+ [1] = DMACH_PCM0_TX,
+ [2] = DMACH_PCM1_RX,
+ [3] = DMACH_PCM1_TX,
+ [4] = DMACH_SPI1_RX,
+ [5] = DMACH_SPI1_TX,
+ [6] = DMACH_PWM,
+ [7] = DMACH_SPDIF,
+ [8] = DMACH_I2S0S_TX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S1_RX,
+ [12] = DMACH_I2S1_TX,
+ [13] = DMACH_UART0_RX,
+ [14] = DMACH_UART0_TX,
+ [15] = DMACH_UART1_RX,
+ [16] = DMACH_UART1_TX,
+ [17] = DMACH_UART3_RX,
+ [18] = DMACH_UART3_TX,
+ [19] = DMACH_SLIMBUS1_RX,
+ [20] = DMACH_SLIMBUS1_TX,
+ [21] = DMACH_SLIMBUS3_RX,
+ [22] = DMACH_SLIMBUS3_TX,
+ [23] = DMACH_SLIMBUS5_RX,
+ [24] = DMACH_SLIMBUS5_TX,
+ [25] = DMACH_SLIMBUS0AUX_RX,
+ [26] = DMACH_SLIMBUS0AUX_TX,
+ [27] = DMACH_DISP1,
+ [28] = DMACH_MIPI_HSI1,
+ [29] = DMACH_MIPI_HSI3,
+ [30] = DMACH_MIPI_HSI5,
+ [31] = DMACH_MIPI_HSI7,
+ },
+};
+
+struct platform_device exynos_device_pdma1 = {
+ .name = "s3c-pl330",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(exynos_pdma1_resource),
+ .resource = exynos_pdma1_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct platform_device *exynos_dmacs[] __initdata = {
+ &exynos_device_mdma,
+ &exynos_device_pdma0,
+ &exynos_device_pdma1,
+};
+
+static int __init exynos_dma_init(void)
+{
+ if (soc_is_exynos4210()) {
+ exynos_device_pdma0.dev.platform_data = &exynos4210_pdma0_pdata;
+ exynos_device_pdma1.dev.platform_data = &exynos4210_pdma1_pdata;
+ } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ exynos_device_pdma0.dev.platform_data = &exynos4212_pdma0_pdata;
+ exynos_device_pdma1.dev.platform_data = &exynos4212_pdma1_pdata;
+ } else if (soc_is_exynos5210() || soc_is_exynos5250()) {
+ exynos_device_pdma0.dev.platform_data = &exynos5210_pdma0_pdata;
+ exynos_device_pdma1.dev.platform_data = &exynos5210_pdma1_pdata;
+ }
+
+ return platform_add_devices(exynos_dmacs, ARRAY_SIZE(exynos_dmacs));
+}
+arch_initcall(exynos_dma_init);
diff --git a/arch/arm/mach-exynos/dvfs-hotplug.c b/arch/arm/mach-exynos/dvfs-hotplug.c
new file mode 100644
index 0000000..519e9f3
--- /dev/null
+++ b/arch/arm/mach-exynos/dvfs-hotplug.c
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-exynos/dvfs-hotplug.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Integrated DVFS CPU hotplug
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+
+static unsigned int total_num_target_freq;
+static unsigned int consecutv_highestlevel_cnt;
+static unsigned int consecutv_lowestlevel_cnt;
+
+static unsigned int freq_max;
+static unsigned int freq_in_trg;
+static unsigned int freq_min = -1UL;
+
+static unsigned int can_hotplug;
+
+static void exynos4_integrated_dvfs_hotplug(unsigned int freq_old,
+ unsigned int freq_new)
+{
+ total_num_target_freq++;
+ freq_in_trg = 800000;
+
+ if ((freq_old >= freq_in_trg) && (freq_new >= freq_in_trg)) {
+ if (soc_is_exynos4412()) {
+ if (cpu_online(3) == 0) {
+ if (consecutv_highestlevel_cnt >= 5) {
+ cpu_up(3);
+ consecutv_highestlevel_cnt = 0;
+ }
+ } else if (cpu_online(2) == 0) {
+ if (consecutv_highestlevel_cnt >= 5) {
+ cpu_up(2);
+ consecutv_highestlevel_cnt = 0;
+ }
+ } else if (cpu_online(1) == 0) {
+ if (consecutv_highestlevel_cnt >= 5) {
+ cpu_up(1);
+ consecutv_highestlevel_cnt = 0;
+ }
+ }
+ consecutv_highestlevel_cnt++;
+ } else {
+ if (cpu_online(1) == 0) {
+ if (consecutv_highestlevel_cnt >= 5) {
+ cpu_up(1);
+ consecutv_highestlevel_cnt = 0;
+ }
+ }
+ consecutv_highestlevel_cnt++;
+ }
+ } else if ((freq_old <= freq_min) && (freq_new <= freq_min)) {
+ if (soc_is_exynos4412()) {
+ if (cpu_online(1) == 1) {
+ if (consecutv_lowestlevel_cnt >= 5) {
+ cpu_down(1);
+ consecutv_lowestlevel_cnt = 0;
+ } else
+ consecutv_lowestlevel_cnt++;
+ } else if (cpu_online(2) == 1) {
+ if (consecutv_lowestlevel_cnt >= 5) {
+ cpu_down(2);
+ consecutv_lowestlevel_cnt = 0;
+ } else
+ consecutv_lowestlevel_cnt++;
+ } else if (cpu_online(3) == 1) {
+ if (consecutv_lowestlevel_cnt >= 5) {
+ cpu_down(3);
+ consecutv_lowestlevel_cnt = 0;
+ } else
+ consecutv_lowestlevel_cnt++;
+ }
+ } else {
+ if (cpu_online(1) == 1) {
+ if (consecutv_lowestlevel_cnt >= 5) {
+ cpu_down(1);
+ consecutv_lowestlevel_cnt = 0;
+ } else
+ consecutv_lowestlevel_cnt++;
+ }
+ }
+ } else {
+ consecutv_highestlevel_cnt = 0;
+ consecutv_lowestlevel_cnt = 0;
+ }
+}
+
+static int hotplug_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
+
+ if ((val == CPUFREQ_POSTCHANGE) && can_hotplug)
+ exynos4_integrated_dvfs_hotplug(freqs->old, freqs->new);
+
+ return 0;
+}
+
+static struct notifier_block dvfs_hotplug = {
+ .notifier_call = hotplug_cpufreq_transition,
+};
+
+static int hotplug_pm_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ switch (val) {
+ case PM_SUSPEND_PREPARE:
+ can_hotplug = 0;
+ consecutv_highestlevel_cnt = 0;
+ consecutv_lowestlevel_cnt = 0;
+ break;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ can_hotplug = 1;
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block pm_hotplug = {
+ .notifier_call = hotplug_pm_transition,
+};
+
+/*
+ * Note : This function should be called after intialization of CPUFreq
+ * driver for exynos4. The cpufreq_frequency_table for exynos4 should be
+ * established before calling this function.
+ */
+static int __init exynos4_integrated_dvfs_hotplug_init(void)
+{
+ int i;
+ struct cpufreq_frequency_table *table;
+ unsigned int freq;
+
+ total_num_target_freq = 0;
+ consecutv_highestlevel_cnt = 0;
+ consecutv_lowestlevel_cnt = 0;
+ can_hotplug = 1;
+
+ table = cpufreq_frequency_get_table(0);
+ if (IS_ERR(table)) {
+ printk(KERN_ERR "%s: Check loading cpufreq before\n", __func__);
+ return PTR_ERR(table);
+ }
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq != CPUFREQ_ENTRY_INVALID && freq > freq_max)
+ freq_max = freq;
+ else if (freq != CPUFREQ_ENTRY_INVALID && freq_min > freq)
+ freq_min = freq;
+ }
+
+ printk(KERN_INFO "%s, max(%d),min(%d)\n", __func__, freq_max, freq_min);
+
+ register_pm_notifier(&pm_hotplug);
+
+ return cpufreq_register_notifier(&dvfs_hotplug,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+late_initcall(exynos4_integrated_dvfs_hotplug_init);
diff --git a/arch/arm/mach-exynos/dynamic-dvfs-nr_running-hotplug.c b/arch/arm/mach-exynos/dynamic-dvfs-nr_running-hotplug.c
new file mode 100644
index 0000000..7c380ae
--- /dev/null
+++ b/arch/arm/mach-exynos/dynamic-dvfs-nr_running-hotplug.c
@@ -0,0 +1,322 @@
+/* linux/arch/arm/mach-exynos/dynamic-dvfs-nr_running-hotplug.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Integrated DVFS CPU hotplug
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+
+#ifdef CONFIG_SLP
+#include <linux/platform_device.h>
+#endif
+
+#include <plat/cpu.h>
+
+static unsigned int total_num_target_freq;
+static unsigned int ctn_freq_in_trg_cnt; /* continuous frequency hotplug in trigger count */
+static unsigned int ctn_freq_out_trg_cnt; /* continuous frequency hotplug out trigger count */
+static unsigned int ctn_nr_running_over2;
+static unsigned int ctn_nr_running_over3;
+static unsigned int ctn_nr_running_over4;
+static unsigned int ctn_nr_running_under2;
+static unsigned int ctn_nr_running_under3;
+static unsigned int ctn_nr_running_under4;
+static unsigned int freq_max; /* max frequency of the dedicated dvfs table */
+static unsigned int freq_min = -1UL; /* min frequency of the dedicated dvfs table */
+static unsigned int freq_in_trg; /* frequency hotplug in trigger */
+static unsigned int freq_out_trg; /* frequency hotplug out trigger */
+static unsigned int can_hotplug;
+#ifdef CONFIG_SLP
+static unsigned int user_lock; /* Enable/Disable hotplug */
+#endif
+
+static void exynos4_integrated_dvfs_hotplug(unsigned int freq_old,
+ unsigned int freq_new)
+{
+
+ total_num_target_freq++;
+ freq_in_trg = 800000; /* tunnable */
+ freq_out_trg = freq_min; /* tunnable */
+
+ if (nr_running() <= 1) {
+ ctn_nr_running_over2 = 0;
+ ctn_nr_running_over3 = 0;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2++;
+ ctn_nr_running_under3++;
+ ctn_nr_running_under4++;
+ } else if ((nr_running() > 1) && (nr_running() <= 2)) {
+ ctn_nr_running_over2++;
+ ctn_nr_running_over3 = 0;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3++;
+ ctn_nr_running_under4++;
+ } else if ((nr_running() > 2) && (nr_running() <= 3)) {
+ ctn_nr_running_over2++;
+ ctn_nr_running_over3++;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3 = 0;
+ ctn_nr_running_under4++;
+ } else if (nr_running() > 3) {
+ ctn_nr_running_over2++;
+ ctn_nr_running_over3++;
+ ctn_nr_running_over4++;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3 = 0;
+ ctn_nr_running_under4 = 0;
+ }
+
+ if ((freq_old >= freq_in_trg) && (freq_new >= freq_in_trg))
+ ctn_freq_in_trg_cnt++;
+ else
+ ctn_freq_in_trg_cnt = 0;
+ if ((freq_old <= freq_out_trg) && (freq_new <= freq_out_trg))
+ ctn_freq_out_trg_cnt++;
+ else
+ ctn_freq_out_trg_cnt = 0;
+
+ if (soc_is_exynos4412()) {
+ if ((cpu_online(3) == 0) && (nr_running() >= 2) &&
+ ((freq_old >= freq_in_trg) && (freq_new >= freq_in_trg))) {
+ if ((ctn_nr_running_over2 >= 4) &&
+ (ctn_freq_in_trg_cnt >= 5)) {
+ /* over 400ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_up(3);
+ ctn_freq_in_trg_cnt = 0;
+ }
+ } else if ((cpu_online(2) == 0) && (nr_running() >= 3) &&
+ ((freq_old >= freq_in_trg) && (freq_new >= freq_in_trg))) {
+ if ((ctn_nr_running_over3 >= 4) &&
+ (ctn_freq_in_trg_cnt >= 5)) {
+ /* over 400ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_up(2);
+ ctn_freq_in_trg_cnt = 0;
+ }
+ } else if ((cpu_online(1) == 0) && (nr_running() >= 4) &&
+ ((freq_old >= freq_in_trg) && (freq_new >= freq_in_trg))) {
+ if ((ctn_nr_running_over4 >= 8) &&
+ (ctn_freq_in_trg_cnt >= 5)) {
+ /* over 800ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_up(1);
+ ctn_freq_in_trg_cnt = 0;
+ }
+ }
+ } else {
+ if ((cpu_online(1) == 0) && ((freq_old >= freq_in_trg) &&
+ (freq_new >= freq_in_trg))) {
+ if ((ctn_nr_running_over2 >= 8) &&
+ (ctn_freq_in_trg_cnt >= 5)) {
+ /* over 800ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_up(1);
+ ctn_nr_running_over2 = 0;
+ ctn_freq_in_trg_cnt = 0;
+ }
+ }
+ }
+
+ if (soc_is_exynos4412()) {
+ if ((cpu_online(1) == 1) && (nr_running() < 4) &&
+ ((freq_old <= freq_out_trg) && (freq_new <= freq_out_trg))) {
+ if ((ctn_nr_running_under4 >= 8) &&
+ (ctn_freq_out_trg_cnt >= 5)) {
+ /* over 800ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_down(1);
+ ctn_freq_out_trg_cnt = 0;
+ }
+ } else if ((cpu_online(2) == 1) && (nr_running() < 3) &&
+ ((freq_old <= freq_out_trg) && (freq_new <= freq_out_trg))) {
+ if ((ctn_nr_running_under3 >= 8) &&
+ (ctn_freq_out_trg_cnt >= 5)) {
+ /* over 800ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_down(2);
+ ctn_freq_out_trg_cnt = 0;
+ }
+ } else if ((cpu_online(3) == 1) && (nr_running() < 2) &&
+ ((freq_old <= freq_out_trg) && (freq_new <= freq_out_trg))) {
+ if ((ctn_nr_running_under2 >= 8) &&
+ (ctn_freq_out_trg_cnt >= 5)) {
+ /* over 800ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_down(3);
+ ctn_freq_out_trg_cnt = 0;
+ }
+ }
+ } else {
+ if ((cpu_online(1) == 1) &&
+ ((freq_old <= freq_out_trg) && (freq_new <= freq_out_trg))) {
+ if ((ctn_nr_running_under2 >= 8) &&
+ (ctn_freq_out_trg_cnt >= 5)) {
+ /* over 800ms for nr_running(), over 500ms for frequency, tunnable */
+ cpu_down(1);
+ ctn_nr_running_under2 = 0;
+ ctn_freq_out_trg_cnt = 0;
+ }
+ }
+ }
+}
+
+static int hotplug_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
+
+ if ((val == CPUFREQ_POSTCHANGE) && can_hotplug)
+ exynos4_integrated_dvfs_hotplug(freqs->old, freqs->new);
+
+ return 0;
+}
+
+static struct notifier_block dvfs_hotplug = {
+ .notifier_call = hotplug_cpufreq_transition,
+};
+
+static int hotplug_pm_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ switch (val) {
+ case PM_SUSPEND_PREPARE:
+ can_hotplug = 0;
+ ctn_freq_in_trg_cnt = 0;
+ ctn_freq_out_trg_cnt = 0;
+ break;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+#ifdef CONFIG_SLP
+ if (!user_lock)
+#endif
+ can_hotplug = 1;
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block pm_hotplug = {
+ .notifier_call = hotplug_pm_transition,
+};
+
+#ifdef CONFIG_SLP
+static ssize_t user_lock_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", user_lock);
+}
+
+static ssize_t user_lock_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+
+ ret = sscanf(buf, "%u", &user_lock);
+ if (ret != 1)
+ return -EINVAL;
+
+ if (user_lock)
+ can_hotplug = 0;
+ else
+ can_hotplug = 1;
+
+ return count;
+}
+static DEVICE_ATTR(user_lock, 0644, user_lock_show, user_lock_store);
+
+static int sysfs_pm_hotplug_create(struct device *dev)
+{
+ int ret;
+
+ ret = device_create_file(dev, &dev_attr_user_lock);
+
+ if (ret)
+ device_remove_file(dev, &dev_attr_user_lock);
+
+ return ret;
+}
+
+static void sysfs_pm_hotplug_remove(struct device *dev)
+{
+ device_remove_file(dev, &dev_attr_user_lock);
+}
+
+static struct platform_device exynos_pm_hotplug_device = {
+ .name = "exynos-dynamic-cpu-hotplug",
+ .id = -1,
+};
+#endif
+
+/*
+ * Note : This function should be called after intialization of CPUFreq
+ * driver for exynos4. The cpufreq_frequency_table for exynos4 should be
+ * established before calling this function.
+ */
+static int __init exynos4_integrated_dvfs_hotplug_init(void)
+{
+ int i;
+ struct cpufreq_frequency_table *table;
+ unsigned int freq;
+
+#ifdef CONFIG_SLP
+ int ret;
+#endif
+
+ total_num_target_freq = 0;
+ ctn_freq_in_trg_cnt = 0;
+ ctn_freq_out_trg_cnt = 0;
+ ctn_nr_running_over2 = 0;
+ ctn_nr_running_over3 = 0;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3 = 0;
+ ctn_nr_running_under4 = 0;
+
+ can_hotplug = 1;
+
+ table = cpufreq_frequency_get_table(0);
+ if (IS_ERR(table)) {
+ printk(KERN_ERR "%s: Check loading cpufreq before\n", __func__);
+ return PTR_ERR(table);
+ }
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq != CPUFREQ_ENTRY_INVALID && freq > freq_max)
+ freq_max = freq;
+ else if (freq != CPUFREQ_ENTRY_INVALID && freq_min > freq)
+ freq_min = freq;
+ }
+
+ printk(KERN_INFO "%s, max(%d),min(%d)\n", __func__, freq_max, freq_min);
+
+#ifdef CONFIG_SLP
+ ret = platform_device_register(&exynos_pm_hotplug_device);
+ if (ret) {
+ printk(KERN_ERR "failed register pd\n");
+ return ret;
+ }
+
+ ret = sysfs_pm_hotplug_create(&exynos_pm_hotplug_device.dev);
+ if (ret)
+ printk(KERN_ERR "failed at(%d)\n", __LINE__);
+#endif
+
+ register_pm_notifier(&pm_hotplug);
+
+ return cpufreq_register_notifier(&dvfs_hotplug,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+late_initcall(exynos4_integrated_dvfs_hotplug_init);
diff --git a/arch/arm/mach-exynos/dynamic-nr_running-hotplug.c b/arch/arm/mach-exynos/dynamic-nr_running-hotplug.c
new file mode 100644
index 0000000..233a104
--- /dev/null
+++ b/arch/arm/mach-exynos/dynamic-nr_running-hotplug.c
@@ -0,0 +1,199 @@
+/* linux/arch/arm/mach-exynos/dynamic-nr_running-hotplug.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - nr_running based dynamic CPU hotplug
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/suspend.h>
+#include <plat/cpu.h>
+
+static unsigned int total_num_target_freq;
+static unsigned int ctn_highestlevel_cnt; /* continuous the highest level count */
+static unsigned int ctn_lowestlevel_cnt;
+static unsigned int ctn_nr_running_over2;
+static unsigned int ctn_nr_running_over3;
+static unsigned int ctn_nr_running_over4;
+static unsigned int ctn_nr_running_under2;
+static unsigned int ctn_nr_running_under3;
+static unsigned int ctn_nr_running_under4;
+static unsigned int freq_max;
+static unsigned int freq_in_trg;
+static unsigned int freq_min;
+static unsigned int can_hotplug;
+
+static void exynos4_integrated_dvfs_hotplug(unsigned int freq_old,
+ unsigned int freq_new)
+{
+ total_num_target_freq++;
+ freq_in_trg = 800000;
+
+ if (nr_running() <= 1) {
+ ctn_nr_running_over2 = 0;
+ ctn_nr_running_over3 = 0;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2++;
+ ctn_nr_running_under3++;
+ ctn_nr_running_under4++;
+ } else if ((nr_running() > 1) && (nr_running() <= 2)) {
+ ctn_nr_running_over2++;
+ ctn_nr_running_over3 = 0;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3++;
+ ctn_nr_running_under4++;
+ } else if ((nr_running() > 2) && (nr_running() <= 3)) {
+ ctn_nr_running_over2++;
+ ctn_nr_running_over3++;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3 = 0;
+ ctn_nr_running_under4++;
+ } else if (nr_running() > 3) {
+ ctn_nr_running_over2++;
+ ctn_nr_running_over3++;
+ ctn_nr_running_over4++;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3 = 0;
+ ctn_nr_running_under4 = 0;
+ }
+
+ if (soc_is_exynos4412()) {
+ if ((cpu_online(3) == 0) && (nr_running() >= 2)) {
+ if (ctn_nr_running_over2 >= 4) { /* over 400ms, tunnable */
+ cpu_up(3);
+ }
+ } else if ((cpu_online(2) == 0) && (nr_running() >= 3)) {
+ if (ctn_nr_running_over3 >= 4) { /* over 400ms, tunnable */
+ cpu_up(2);
+ }
+ } else if ((cpu_online(1) == 0) && (nr_running() >= 4)) {
+ if (ctn_nr_running_over4 >= 8) { /* over 800ms, tunnable */
+ cpu_up(1);
+ }
+ }
+ } else {
+ if (cpu_online(1) == 0) {
+ if (ctn_nr_running_over2 >= 8) { /* over 800ms, tunnable */
+ cpu_up(1);
+ ctn_nr_running_over2 = 0;
+ }
+ }
+ } /* end of else */
+ if (soc_is_exynos4412()) {
+ if ((cpu_online(1) == 1) && (nr_running() < 4)) {
+ if (ctn_nr_running_under4 >= 8) { /* over 800ms, tunnable */
+ cpu_down(1);
+ }
+ } else if ((cpu_online(2) == 1) && (nr_running() < 3)) {
+ if (ctn_nr_running_under3 >= 8) { /* over 800ms, tunnable */
+ cpu_down(2);
+ }
+ } else if ((cpu_online(3) == 1) && (nr_running() < 2)) {
+ if (ctn_nr_running_under2 >= 8) { /* over 800ms, tunnable */
+ cpu_down(3);
+ }
+ }
+ } else {
+ if (cpu_online(1) == 1) {
+ if (ctn_nr_running_under2 >= 8) { /* over 800ms, tunnable */
+ cpu_down(1);
+ ctn_nr_running_under2 = 0;
+ }
+ }
+ } /* end of else */
+}
+
+static int hotplug_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
+
+ if ((val == CPUFREQ_POSTCHANGE) && can_hotplug)
+ exynos4_integrated_dvfs_hotplug(freqs->old, freqs->new);
+
+ return 0;
+}
+
+static struct notifier_block dvfs_hotplug = {
+ .notifier_call = hotplug_cpufreq_transition,
+};
+
+static int hotplug_pm_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ switch (val) {
+ case PM_SUSPEND_PREPARE:
+ can_hotplug = 0;
+ ctn_highestlevel_cnt = 0;
+ ctn_lowestlevel_cnt = 0;
+ break;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ can_hotplug = 1;
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block pm_hotplug = {
+ .notifier_call = hotplug_pm_transition,
+};
+
+/*
+ * Note : This function should be called after intialization of CPUFreq
+ * driver for exynos4. The cpufreq_frequency_table for exynos4 should be
+ * established before calling this function.
+ */
+static int __init exynos4_integrated_dvfs_hotplug_init(void)
+{
+ int i;
+ struct cpufreq_frequency_table *table;
+ unsigned int freq;
+
+ total_num_target_freq = 0;
+ ctn_highestlevel_cnt = 0;
+ ctn_lowestlevel_cnt = 0;
+ ctn_nr_running_over2 = 0;
+ ctn_nr_running_over3 = 0;
+ ctn_nr_running_over4 = 0;
+ ctn_nr_running_under2 = 0;
+ ctn_nr_running_under3 = 0;
+ ctn_nr_running_under4 = 0;
+
+ can_hotplug = 1;
+
+ table = cpufreq_frequency_get_table(0);
+ if (IS_ERR(table)) {
+ printk(KERN_ERR "%s: Check loading cpufreq before\n", __func__);
+ return PTR_ERR(table);
+ }
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq != CPUFREQ_ENTRY_INVALID && freq > freq_max)
+ freq_max = freq;
+ else if (freq != CPUFREQ_ENTRY_INVALID && freq_min > freq)
+ freq_min = freq;
+ }
+
+ register_pm_notifier(&pm_hotplug);
+
+ return cpufreq_register_notifier(&dvfs_hotplug,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+late_initcall(exynos4_integrated_dvfs_hotplug_init);
diff --git a/arch/arm/mach-exynos/exynos4-smc.c b/arch/arm/mach-exynos/exynos4-smc.c
new file mode 100644
index 0000000..08795fa
--- /dev/null
+++ b/arch/arm/mach-exynos/exynos4-smc.c
@@ -0,0 +1,52 @@
+#include <linux/types.h>
+#include <mach/smc.h>
+
+#ifndef __ASSEMBLY__
+u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
+{
+ register u32 reg0 __asm__("r0") = cmd;
+ register u32 reg1 __asm__("r1") = arg1;
+ register u32 reg2 __asm__("r2") = arg2;
+ register u32 reg3 __asm__("r3") = arg3;
+
+ __asm__ volatile (
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ "smc 0\n"
+ : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+ );
+
+ return reg0;
+}
+
+u32 exynos_smc_readsfr(u32 addr, u32 *val)
+{
+ register u32 reg0 __asm__("r0") = SMC_CMD_REG;
+ register u32 reg1 __asm__("r1") = SMC_REG_ID_SFR_R(addr);
+ register u32 reg2 __asm__("r2") = 0;
+ register u32 reg3 __asm__("r3") = 0;
+
+ __asm__ volatile (
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
+ "smc 0\n"
+ : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+ );
+
+ if (reg0 == SMC_CMD_REG) {
+ if (!reg1)
+ *val = reg2;
+ return reg1;
+ }
+
+ if (!reg0)
+ *val = reg2;
+
+ return reg0;
+}
+
+#endif
+
+
diff --git a/arch/arm/mach-exynos/gc1-gpio.c b/arch/arm/mach-exynos/gc1-gpio.c
new file mode 100644
index 0000000..674d293
--- /dev/null
+++ b/arch/arm/mach-exynos/gc1-gpio.c
@@ -0,0 +1,528 @@
+/*
+ * linux/arch/arm/mach-exynos/midas-gpio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - GPIO setting in set board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio-midas.h>
+#include <plat/cpu.h>
+#include <mach/pmu.h>
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+/*
+ * GC1 GPIO Init Table
+ */
+static struct gpio_init_data m0_init_gpios[] = {
+
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_INT */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPX0(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPX0(7), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS4_GPX1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPX1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* TELE_KEY_F */
+
+ {EXYNOS4_GPX2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* KEY_S1 */
+ {EXYNOS4_GPX2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* KEY_S2 */
+ {EXYNOS4_GPX2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* TELE_KEY */
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* FUEL_ALERT */
+ {EXYNOS4_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKEUP */
+
+ {EXYNOS4_GPX3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_WAKE */
+ {EXYNOS4_GPX3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WIDE_KEY */
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* T_FLASH_DETECT */
+
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV4}, /* WLAN_EN */
+
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV3}, /* CAM_MCLK */
+
+ {EXYNOS4212_GPM2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV3}, /* VTCAM_MCLK */
+};
+
+/*
+ * GC1 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(IPC_RXD) */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(IPC_TXD) */
+#else
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_FLM_RXD */
+ /*
+ * UART3-TXD : It should be pulled up during sleep, if this uart is
+ * used for PC connection like a factory command program.
+ * Otherwise, a PC might get null characters like noise.
+ * In addition, LPA mode is also applied to this comment, because
+ * LPA mode invokes this GPIO sleep configuration.
+ */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* AP_FLM_TXD */
+#endif
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*HWREV*/
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*HWREV*/
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*HWREV*/
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*HWREV*/
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+}; /* GC1_sleep_gpio_table */
+
+/*
+ * GC1 Rev0.1 (HW EMUL REV0.4) GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev01[][3] = {
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*GYRO_INT*/
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*POWER_LED*/
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*GYRO_DE*/
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*MOT_EN*/
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*SAMBAZ*/
+};
+
+/*
+ * GC1 Rev0.2 (HW MAIN REV0.0) GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev02[][3] = {
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*NC*/
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*NC*/
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*NC*/
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*NC*/
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /*NC*/
+};
+
+struct m0_sleep_table {
+ unsigned int (*ptr)[3];
+ int size;
+};
+
+#define GPIO_TABLE(_ptr) \
+ {.ptr = _ptr, \
+ .size = ARRAY_SIZE(_ptr)} \
+
+#define GPIO_TABLE_NULL \
+ {.ptr = NULL, \
+ .size = 0} \
+
+/* in order to distinguish SLEEP GPIO of HW version */
+static struct m0_sleep_table m0_sleep_table[] = {
+ GPIO_TABLE(m0_sleep_gpio_table), /* HWID(0x0) - GC1 HWREV0.3 */
+ GPIO_TABLE(m0_sleep_gpio_table_rev01), /* HWID(0x1) - GC1 HWREV0.4 */
+ GPIO_TABLE(m0_sleep_gpio_table_rev02), /* HWID(0x2) - GC1 MAIN 0.0 */
+};
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void m0_config_sleep_gpio_table(void)
+{
+ int i;
+ int index = min(ARRAY_SIZE(m0_sleep_table), system_rev + 1);
+
+ for (i = 0; i < index; i++) {
+ if (m0_sleep_table[i].ptr == NULL)
+ continue;
+
+ config_sleep_gpio_table(m0_sleep_table[i].size,
+ m0_sleep_table[i].ptr);
+ }
+}
+
+/* To save power consumption, gpio pin set before enterling sleep */
+void midas_config_sleep_gpio_table(void)
+{
+ m0_config_sleep_gpio_table();
+}
+
+/* Intialize gpio set in midas board */
+void midas_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(m0_init_gpios); i++) {
+ gpio = m0_init_gpios[i].num;
+ if (gpio <= EXYNOS4212_GPV4(1)) {
+ s3c_gpio_cfgpin(gpio, m0_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, m0_init_gpios[i].pud);
+
+ if (m0_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, m0_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, m0_init_gpios[i].drv);
+ }
+ }
+}
diff --git a/arch/arm/mach-exynos/gc1-power.c b/arch/arm/mach-exynos/gc1-power.c
new file mode 100644
index 0000000..175a579
--- /dev/null
+++ b/arch/arm/mach-exynos/gc1-power.c
@@ -0,0 +1,791 @@
+/*
+ * midas-power.c - Power Management of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Chiwoong Byun <woong.byun@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-midas.h>
+#include <mach/irqs.h>
+
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max77686.h>
+#include <linux/mfd/max77693.h>
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#endif
+
+
+#ifdef CONFIG_REGULATOR_MAX77686
+/* max77686 */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo3_supply[] = {};
+#endif
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+ REGULATOR_SUPPLY("touchkey", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
+ REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.95v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("ois_1.5v", NULL),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb2_1.95v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("touch_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_2.8v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("mot_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply max77686_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynoss4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply max77686_buck9 =
+ REGULATOR_SUPPLY("cam_isp_1.2v", NULL);
+
+static struct regulator_consumer_supply max77686_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo5, "VCC_1.8V_IO", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo10, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo11, "VABB1_1.95V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo13, "OIS_1.5V", 1500000, 1500000, 0,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo14, "VABB2_1.95V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "TSP_VDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "CAM_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo25, "CAM_SENSOR_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "MOT_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+ .max_uV = 1050000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck1),
+ .consumer_supplies = max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck3),
+ .consumer_supplies = max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1075000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck4),
+ .consumer_supplies = max77686_buck4,
+};
+
+static struct regulator_init_data max77686_buck9_data = {
+ .constraints = {
+ .name = "CAM_ISP_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck9,
+};
+
+static struct regulator_init_data max77686_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_enp32khz),
+ .consumer_supplies = max77686_enp32khz,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_BUCK9, &max77686_buck9_data,},
+ {MAX77686_LDO3, &ldo3_init_data,},
+ {MAX77686_LDO5, &ldo5_init_data,},
+ {MAX77686_LDO8, &ldo8_init_data,},
+ {MAX77686_LDO10, &ldo10_init_data,},
+ {MAX77686_LDO11, &ldo11_init_data,},
+ {MAX77686_LDO12, &ldo12_init_data,},
+ {MAX77686_LDO13, &ldo13_init_data,},
+ {MAX77686_LDO14, &ldo14_init_data,},
+ {MAX77686_LDO17, &ldo17_init_data,},
+ {MAX77686_LDO18, &ldo18_init_data,},
+ {MAX77686_LDO19, &ldo19_init_data,},
+ {MAX77686_LDO21, &ldo21_init_data,},
+ {MAX77686_LDO23, &ldo23_init_data,},
+ {MAX77686_LDO24, &ldo24_init_data,},
+ {MAX77686_LDO25, &ldo25_init_data,},
+ {MAX77686_LDO26, &ldo26_init_data,},
+ {MAX77686_P32KH, &max77686_enp32khz_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO3] = {MAX77686_LDO3, MAX77686_OPMODE_NORMAL},
+ [MAX77686_LDO8] = {MAX77686_LDO8, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO10] = {MAX77686_LDO10, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO12] = {MAX77686_LDO12, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+struct max77686_platform_data exynos4_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+ .wtsr_smpl = MAX77686_WTSR_ENABLE | MAX77686_SMPL_ENABLE,
+
+ .buck234_gpio_dvs = {
+ /* Use DVS2 register of each bucks to supply stable power
+ * after sudden reset */
+ {GPIO_PMIC_DVS1, 1},
+ {GPIO_PMIC_DVS2, 0},
+ {GPIO_PMIC_DVS3, 0},
+ },
+ .buck234_gpio_selb = {
+ GPIO_BUCK2_SEL,
+ GPIO_BUCK3_SEL,
+ GPIO_BUCK4_SEL,
+ },
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1000000, /* 1.0V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1000000, /* 1.0V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+};
+
+#endif /* CONFIG_REGULATOR_MAX77686 */
+
+void midas_power_set_muic_pdata(void *pdata, int gpio)
+{
+ gpio_request(gpio, "AP_PMIC_IRQ");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+}
+
+void midas_power_gpio_init(void)
+{
+}
+
+#ifdef CONFIG_MFD_MAX77693
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+static struct regulator_consumer_supply charger_supply[] = {
+ REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
+ REGULATOR_SUPPLY("vinchg1", NULL),
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 0,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct regulator_init_data charger_init_data = {
+ .constraints = {
+ .name = "CHARGER",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_CURRENT,
+ .boot_on = 1,
+ .min_uA = 60000,
+ .max_uA = 2580000,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(charger_supply),
+ .consumer_supplies = charger_supply,
+};
+
+struct max77693_regulator_data max77693_regulators[] = {
+ {MAX77693_ESAFEOUT1, &safeout1_init_data,},
+ {MAX77693_ESAFEOUT2, &safeout2_init_data,},
+ {MAX77693_CHARGER, &charger_init_data,},
+};
+
+#endif /* CONFIG_MFD_MAX77693 */
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+/* S5M8767 Regulator */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply s5m_ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#else
+static struct regulator_consumer_supply s5m_ldo3_supply[] = {};
+#endif
+
+static struct regulator_consumer_supply s5m_ldo4_supply[] = {
+ REGULATOR_SUPPLY("vddq_pre_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
+ REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply s5m_ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo10_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply s5m_ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.95v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb2_1.95v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo20_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo21_supply[] = {
+ REGULATOR_SUPPLY("mot_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo22_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_2.8v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply s5m_ldo23_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo24_supply[] = {
+ REGULATOR_SUPPLY("led_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo25_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo26_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo27_supply[] = {
+ REGULATOR_SUPPLY("ois_1.5v", NULL),
+};
+
+static struct regulator_consumer_supply s5m_ldo28_supply[] = {
+ REGULATOR_SUPPLY("touch_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m8767_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck6 =
+ REGULATOR_SUPPLY("cam_isp_1.2v", NULL);
+
+static struct regulator_consumer_supply s5m8767_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define S5M_REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, \
+ _ops_mask, _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+S5M_REGULATOR_INIT(s5m_ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+S5M_REGULATOR_INIT(s5m_ldo8, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+S5M_REGULATOR_INIT(s5m_ldo9, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo10, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+S5M_REGULATOR_INIT(s5m_ldo11, "VABB1_1.95V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+S5M_REGULATOR_INIT(s5m_ldo14, "VABB2_1.95V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo20, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo21, "MOT_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo22, "CAM_SENSOR_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo23, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo24, "LED_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo25, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo26, "CAM_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo27, "OIS_1.5V", 1500000, 1500000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+S5M_REGULATOR_INIT(s5m_ldo28, "TSP_VDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+
+static struct regulator_init_data s5m8767_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck1),
+ .consumer_supplies = s5m8767_buck1,
+};
+
+static struct regulator_init_data s5m8767_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .always_on = 1,
+ .apply_uV = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck2,
+};
+
+static struct regulator_init_data s5m8767_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck3),
+ .consumer_supplies = s5m8767_buck3,
+};
+
+static struct regulator_init_data s5m8767_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1075000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck4),
+ .consumer_supplies = s5m8767_buck4,
+};
+
+static struct regulator_init_data s5m8767_buck6_data = {
+ .constraints = {
+ .name = "CAM_ISP_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck6,
+};
+
+static struct regulator_init_data s5m8767_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_enp32khz),
+ .consumer_supplies = s5m8767_enp32khz,
+};
+
+static struct s5m_regulator_data s5m8767_regulators[] = {
+ {S5M8767_BUCK1, &s5m8767_buck1_data,},
+ {S5M8767_BUCK2, &s5m8767_buck2_data,},
+ {S5M8767_BUCK3, &s5m8767_buck3_data,},
+ {S5M8767_BUCK4, &s5m8767_buck4_data,},
+ {S5M8767_BUCK6, &s5m8767_buck6_data,},
+ {S5M8767_LDO3, &s5m_ldo3_init_data,},
+ {S5M8767_LDO8, &s5m_ldo8_init_data,},
+ {S5M8767_LDO9, &s5m_ldo9_init_data,},
+ {S5M8767_LDO10, &s5m_ldo10_init_data,},
+ {S5M8767_LDO11, &s5m_ldo11_init_data,},
+ {S5M8767_LDO12, &s5m_ldo12_init_data,},
+ {S5M8767_LDO14, &s5m_ldo14_init_data,},
+ {S5M8767_LDO20, &s5m_ldo20_init_data,},
+ {S5M8767_LDO21, &s5m_ldo21_init_data,},
+ {S5M8767_LDO22, &s5m_ldo22_init_data,},
+ {S5M8767_LDO23, &s5m_ldo23_init_data,},
+ {S5M8767_LDO24, &s5m_ldo24_init_data,},
+ {S5M8767_LDO25, &s5m_ldo25_init_data,},
+ {S5M8767_LDO26, &s5m_ldo26_init_data,},
+ {S5M8767_LDO27, &s5m_ldo27_init_data,},
+ {S5M8767_LDO28, &s5m_ldo28_init_data,},
+};
+
+struct s5m_opmode_data s5m8767_opmode_data[S5M8767_REG_MAX] = {
+ [S5M8767_BUCK1] = {S5M8767_BUCK1, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK2] = {S5M8767_BUCK2, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK3] = {S5M8767_BUCK3, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK4] = {S5M8767_BUCK4, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO3] = {S5M8767_LDO3, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO8] = {S5M8767_LDO8, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO10] = {S5M8767_LDO10, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO11] = {S5M8767_LDO11, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO12] = {S5M8767_LDO12, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO14] = {S5M8767_LDO14, S5M_OPMODE_STANDBY},
+};
+
+struct s5m_platform_data exynos4_s5m8767_info = {
+ .device_type = S5M8767X,
+ .num_regulators = ARRAY_SIZE(s5m8767_regulators),
+ .regulators = s5m8767_regulators,
+ .buck2_ramp_enable = true,
+ .buck3_ramp_enable = true,
+ .buck4_ramp_enable = true,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = s5m8767_opmode_data,
+ .wtsr_smpl = 1,
+
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1100000, /* 1.1V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1100000, /* 1.1V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+
+ .buck_ramp_delay = 25,
+ .buck_default_idx = 1,
+
+ .buck_gpios[0] = EXYNOS4212_GPM3(0),
+ .buck_gpios[1] = EXYNOS4212_GPM3(1),
+ .buck_gpios[2] = EXYNOS4212_GPM3(2),
+
+ .buck_ds[0] = EXYNOS4_GPF3(1),
+ .buck_ds[1] = EXYNOS4_GPF3(2),
+ .buck_ds[2] = EXYNOS4_GPF3(3),
+
+ .buck2_init = 1100000,
+ .buck3_init = 1000000,
+ .buck4_init = 1000000,
+};
+
+/* End of S5M8767 */
+#endif
+
+void midas_power_init(void)
+{
+ printk(KERN_INFO "%s\n", __func__);
+}
diff --git a/arch/arm/mach-exynos4/headsmp.S b/arch/arm/mach-exynos/headsmp.S
index 3cdeb36..617509e 100644
--- a/arch/arm/mach-exynos4/headsmp.S
+++ b/arch/arm/mach-exynos/headsmp.S
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/headsmp.S
+ * linux/arch/arm/mach-exynos/headsmp.S
*
* Cloned from linux/arch/arm/mach-realview/headsmp.S
*
@@ -20,7 +20,7 @@
* a "holding pen" into which all secondary cores are held until we're
* ready for them to initialise.
*/
-ENTRY(exynos4_secondary_startup)
+ENTRY(exynos_secondary_startup)
mrc p15, 0, r0, c0, c0, 5
and r0, r0, #15
adr r4, 1f
diff --git a/arch/arm/mach-exynos4/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index 2b5909e..d16df01 100644
--- a/arch/arm/mach-exynos4/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
@@ -1,4 +1,4 @@
-/* linux arch/arm/mach-exynos4/hotplug.c
+/* linux arch/arm/mach-exynos/hotplug.c
*
* Cloned from linux/arch/arm/mach-realview/hotplug.c
*
@@ -13,12 +13,17 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/completion.h>
+#include <linux/io.h>
#include <asm/cacheflush.h>
+#include <plat/cpu.h>
+#include <mach/regs-pmu.h>
+
extern volatile int pen_release;
-static inline void cpu_enter_lowpower(void)
+static inline void cpu_enter_lowpower_a9(void)
{
unsigned int v;
@@ -40,6 +45,35 @@ static inline void cpu_enter_lowpower(void)
: "cc");
}
+static inline void cpu_enter_lowpower_a15(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "Ir" (CR_C)
+ : "cc");
+
+ flush_cache_all();
+
+ asm volatile(
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (0x40)
+ : "cc");
+
+ isb();
+ dsb();
+}
+
static inline void cpu_leave_lowpower(void)
{
unsigned int v;
@@ -58,12 +92,11 @@ static inline void cpu_leave_lowpower(void)
static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
{
- /*
- * there is no power-control hardware on this platform, so all
- * we can do is put the core into WFI; this is safe as the calling
- * code will have already disabled interrupts
- */
for (;;) {
+ /* make cpu1 to be turned off at next WFI command */
+ if ((cpu >= 1) && (cpu < NR_CPUS))
+ __raw_writel(0, S5P_ARM_CORE_CONFIGURATION(cpu));
+
/*
* here's the WFI
*/
@@ -107,7 +140,10 @@ void platform_cpu_die(unsigned int cpu)
/*
* we're ready for shutdown now, so do it
*/
- cpu_enter_lowpower();
+ if (soc_is_exynos5250())
+ cpu_enter_lowpower_a15();
+ else
+ cpu_enter_lowpower_a9();
platform_do_lowpower(cpu, &spurious);
/*
diff --git a/arch/arm/mach-exynos/idle-exynos4.S b/arch/arm/mach-exynos/idle-exynos4.S
new file mode 100644
index 0000000..a8038e3
--- /dev/null
+++ b/arch/arm/mach-exynos/idle-exynos4.S
@@ -0,0 +1,241 @@
+/* linux/arch/arm/mach-exynos/idle-exynos4.S
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4210 AFTR/LPA idle support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+#include <mach/smc.h>
+#include <mach/map-exynos4.h>
+
+ .text
+
+ /*
+ * exynos4_enter_lp
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(exynos4_enter_lp)
+ stmfd sp!, { r3 - r12, lr }
+
+ adr r0, sleep_save_misc
+
+ mrc p15, 0, r2, c15, c0, 0 @ read power control register
+ str r2, [r0], #4
+
+ mrc p15, 0, r2, c15, c0, 1 @ read diagnostic register
+ str r2, [r0], #4
+
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ mov r0, sp
+
+ mrc p15, 0, r1, c2, c0, 0 @ TTB 0
+ mov r2, r1, lsr #14 @ get TTB0 base
+ mov r1, r2, lsl #14
+ bl exynos4_flush_cache
+
+ adr r0, sys_pwr_conf_addr
+ ldr r1, [r0]
+ ldr r2, [r1]
+ bic r2, r2, #(1<<16)
+ str r2, [r1]
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldr r0, =SMC_CMD_CPU0AFTR
+ mov r1, #0
+ mov r2, #0
+ mov r3, #0
+#ifdef REQUIRES_SEC
+ .arch_extension sec
+#endif
+ smc 0
+#else
+ dsb
+ wfi
+#endif
+
+ /* Restore original sp */
+ mov r0, sp
+ add r0, r0, #4
+ ldr sp, [r0]
+
+ mov r0, #0
+ b early_wakeup
+
+resume_with_mmu:
+#ifdef CONFIG_CACHE_L2X0
+ /* Enable L2 cache */
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldr r0, =SMC_CMD_L2X0CTRL
+ mov r1, #1
+ mov r2, #0
+ mov r3, #0
+#ifdef REQUIRES_SEC
+ .arch_extension sec
+#endif
+ smc 0
+#else
+ mov r0, #1
+ ldr r1, =S5P_VA_L2CC
+ str r0, [r1, #0x100]
+#endif
+#endif
+ adr r0, sleep_save_misc
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldr r1, [r0], #4
+ ldr r2, [r0], #4
+ ldr r0, =SMC_CMD_C15RESUME
+ mov r3, #0
+#ifdef REQUIRES_SEC
+ .arch_extension sec
+#endif
+ smc 0
+#else
+ ldr r1, [r0], #4
+ mcr p15, 0, r1, c15, c0, 0 @ write power control register
+
+ ldr r1, [r0], #4
+ mcr p15, 0, r1, c15, c0, 1 @ write diagnostic register
+#endif
+
+ mov r0, #1
+early_wakeup:
+
+ ldmfd sp!, { r3 - r12, pc }
+
+ .ltorg
+
+ /*
+ * sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+sleep_save_misc:
+ .long 0
+ .long 0
+
+ .global sys_pwr_conf_addr
+sys_pwr_conf_addr:
+ .long 0
+
+ .global l2x0_save
+l2x0_save:
+ .word 0
+ .word 0
+ .word 0
+
+ .global scu_save
+scu_save:
+ .word 0
+ .word 0
+
+ /*
+ * exynos4_idle_resume
+ *
+ * resume code entry for IROM to call
+ *
+ * we must put this code here in the data segment as we have no
+ * other way of restoring the stack pointer after sleep, and we
+ * must not write to the code segment (code is read-only)
+ */
+
+ENTRY(exynos4_idle_resume)
+ /* SCU enable */
+ ldr r1, =0x10500000
+ adr r0, scu_save
+
+ ldr r5, [r0]
+ ldr r6, [r0, #4]
+
+ str r5, [r1, #0x30]
+ str r6, [r1]
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Restore register value for L2X0 */
+ adr r0, l2x0_save
+
+ ldr r5, [r0], #4 @ Data latency
+ ldr r6, [r0], #4 @ Tag latency
+ ldr r7, [r0], #4 @ prepatch
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ mov r1, r5
+ mov r2, r6
+ mov r3, r7
+
+ ldr r0, =SMC_CMD_L2X0SETUP1
+
+#ifdef REQUIRES_SEC
+ .arch_extension sec
+#endif
+ smc 0
+
+ ldr r0, =SMC_CMD_L2X0SETUP2
+ ldr r1, =0x3
+ ldr r2, =0x7C470001
+ ldr r3, =0xC200FFFF
+
+#ifdef REQUIRES_SEC
+ .arch_extension sec
+#endif
+ smc 0
+#else
+ ldr r0, =EXYNOS4_PA_L2CC
+
+ str r5, [r0, #L2X0_TAG_LATENCY_CTRL]
+ str r6, [r0, #L2X0_DATA_LATENCY_CTRL]
+ str r7, [r0, #L2X0_PREFETCH_CTRL]
+
+ /*
+ * Set Power ctrl register for L2X0
+ */
+ mov r1, #0x3
+ str r1, [r0, #L2X0_POWER_CTRL]
+
+ ldr r1, [r0, #L2X0_AUX_CTRL]
+ ldr r2, =0x7C470001
+ ldr r3, =0xC200FFFF
+
+ and r1, r1, r3
+ orr r1, r1, r2
+
+ str r1, [r0, #L2X0_AUX_CTRL]
+
+#endif
+#endif
+ b cpu_resume
diff --git a/arch/arm/mach-exynos/idle-exynos5.S b/arch/arm/mach-exynos/idle-exynos5.S
new file mode 100644
index 0000000..a3575ca
--- /dev/null
+++ b/arch/arm/mach-exynos/idle-exynos5.S
@@ -0,0 +1,210 @@
+/* linux/arch/arm/mach-exynos/idle-exynos5.S
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 AFTR/LPA idle support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+#include <mach/smc.h>
+
+ .text
+
+ /*
+ * exynos5_enter_lp
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(exynos5_enter_lp)
+ stmfd sp!, { r3 - r12, lr }
+
+ adr r0, sleep_save_misc
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ mrc p15, 0, r2, c1, c0, 1 @ read aux control register
+ str r2, [r0], #4
+#endif
+ mrc p15, 1, r2, c9, c0, 2 @ read l2 control register
+ str r2, [r0], #4
+ mrc p15, 1, r2, c15, c0, 3 @ read l2 prefetch register
+ str r2, [r0], #4
+
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ bl exynos5_L1_dcache_flush
+
+ adr r0, sys_pwr_conf_addr
+ ldr r1, [r0]
+ ldr r2, [r1]
+ bic r2, r2, #(1<<16)
+ str r2, [r1]
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldr r0, =SMC_CMD_CPU0AFTR
+ mov r1, #0
+ mov r2, #0
+ mov r3, #0
+ smc 0
+#else
+ dsb
+ wfi
+#endif
+
+ /* Restore original sp */
+ mov r0, sp
+ add r0, r0, #4
+ ldr sp, [r0]
+
+ mov r0, #0
+ b early_wakeup
+
+resume_with_mmu:
+ adr r4, sleep_save_misc
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ mov r3, #0
+
+ ldr r0, =SMC_CMD_REG
+ ldr r1, =SMC_REG_ID_CP15(1, 0, 0, 1) @ aux control register
+ ldr r2, [r4], #4
+ smc 0
+ ldr r0, =SMC_CMD_REG
+ ldr r1, =SMC_REG_ID_CP15(9, 1, 0, 2) @ L2 control register
+ ldr r2, [r4], #4
+ smc 0
+ ldr r0, =SMC_CMD_REG
+ ldr r1, =SMC_REG_ID_CP15(15, 1, 0, 3) @ L2 prefetch register
+ ldr r2, [r4], #4
+ smc 0
+#else
+ ldr r2, [r4], #4
+ mcr p15, 1, r2, c9, c0, 2 @ L2 control register
+ ldr r2, [r4], #4
+ mcr p15, 1, r2, c15, c0, 3 @ L2 prefetch register
+#endif
+ mov r0, #1
+early_wakeup:
+
+ ldmfd sp!, { r3 - r12, pc }
+
+ .ltorg
+
+ /*
+ * sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+sleep_save_misc:
+ .long 0
+ .long 0
+ .long 0
+
+ .global sys_pwr_conf_addr
+sys_pwr_conf_addr:
+ .long 0
+
+ /*
+ * exynos5_L1_dcache_flush
+ *
+ * L1 only dcache flush function
+ *
+ * When enter lowpower cpuidle mode, It is need to L1 only flush function.
+ */
+ENTRY(exynos5_L1_dcache_flush)
+ dmb @ ensure ordering with previous memory accesses
+ mrc p15, 1, r0, c0, c0, 1 @ read clidr
+ ands r3, r0, #0x7000000 @ extract loc from clidr
+ mov r3, r3, lsr #23 @ left align loc bit field
+ beq skip @ if loc is 0, then no need to clean
+ mov r10, #0 @ start clean at cache level 0
+loop1:
+ add r2, r10, r10, lsr #1 @ work out 3x current cache level
+ mov r1, r0, lsr r2 @ extract cache type bits from clidr
+ and r1, r1, #7 @ mask of the bits for current cache only
+ cmp r1, #2 @ see what cache we have at this level
+ blt skip @ skip if no cache, or just i-cache
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ isb @ isb to sych the new cssr&csidr
+ mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
+ and r2, r1, #7 @ extract the length of the cache lines
+ add r2, r2, #4 @ add 4 (line length offset)
+ ldr r4, =0x3ff
+ ands r4, r4, r1, lsr #3 @ find maximum number on the way size
+ clz r5, r4 @ find bit position of way size increment
+ ldr r7, =0x7fff
+ ands r7, r7, r1, lsr #13 @ extract max number of the index size
+loop2:
+ mov r9, r4 @ create working copy of max way size
+loop3:
+ ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
+ THUMB( lsl r6, r9, r5 )
+ THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
+ ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
+ THUMB( lsl r6, r7, r2 )
+ THUMB( orr r11, r11, r6 ) @ factor index number into r11
+ mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
+ subs r9, r9, #1 @ decrement the way
+ bge loop3
+ subs r7, r7, #1 @ decrement the index
+ bge loop2
+skip:
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+ dsb
+ isb
+ mov pc, lr
+ENDPROC(exynos5_L1_dcache_flush)
+
+ /*
+ * exynos5_idle_resume
+ *
+ * resume code entry for IROM to call
+ *
+ * we must put this code here in the data segment as we have no
+ * other way of restoring the stack pointer after sleep, and we
+ * must not write to the code segment (code is read-only)
+ */
+
+ENTRY(exynos5_idle_resume)
+ /*
+ * To use JTEG after wakeup from power mode
+ * Set DBGEN, NIDEN, SPIDEN, SPNIDEN on TZPC1
+ */
+ ldr r0, =0x10110810
+ mov r1, #0xf
+ str r1, [r0]
+ dsb
+ isb
+
+ b cpu_resume
diff --git a/arch/arm/mach-exynos/include/mach/asv.h b/arch/arm/mach-exynos/include/mach/asv.h
new file mode 100644
index 0000000..6fda670
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/asv.h
@@ -0,0 +1,124 @@
+/* linux/arch/arm/mach-exynos/include/mach/asv.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Adoptive Support Voltage Header file
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_ASV_H
+#define __ASM_ARCH_ASV_H __FILE__
+
+#ifdef CONFIG_EXYNOS4_CPUFREQ
+
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu5.h>
+
+#include <plat/cpu.h>
+
+#define JUDGE_TABLE_END NULL
+
+#define LOOP_CNT 10
+
+extern unsigned int exynos_result_of_asv;
+
+enum exynos4x12_abb_member {
+ ABB_INT,
+ ABB_MIF,
+ ABB_G3D,
+ ABB_ARM,
+};
+
+static inline void exynos4x12_set_abb_member(enum exynos4x12_abb_member abb_target,
+ unsigned int abb_mode_value)
+{
+ unsigned int tmp;
+
+ if (abb_mode_value != ABB_MODE_BYPASS)
+ tmp = S5P_ABB_INIT;
+ else
+ tmp = S5P_ABB_INIT_BYPASS;
+
+ tmp |= abb_mode_value;
+
+ if (!soc_is_exynos5250())
+ __raw_writel(tmp, S5P_ABB_MEMBER(abb_target));
+ else if (abb_target == ABB_INT)
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_INT));
+ else if (abb_target == ABB_MIF)
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_MIF));
+ else if (abb_target == ABB_G3D)
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_G3D));
+ else if (abb_target == ABB_ARM)
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_ARM));
+}
+
+static inline void exynos4x12_set_abb(unsigned int abb_mode_value)
+{
+ unsigned int tmp;
+
+ pr_debug("EXYNOS4X12 ABB MODE : %d(mV)\n", 600 + (abb_mode_value * 50));
+
+ if (abb_mode_value != ABB_MODE_BYPASS)
+ tmp = S5P_ABB_INIT;
+ else
+ tmp = S5P_ABB_INIT_BYPASS;
+
+ tmp |= abb_mode_value;
+
+ if (!soc_is_exynos5250()) {
+ __raw_writel(tmp, S5P_ABB_INT);
+ __raw_writel(tmp, S5P_ABB_MIF);
+ __raw_writel(tmp, S5P_ABB_G3D);
+ __raw_writel(tmp, S5P_ABB_ARM);
+ } else {
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_INT));
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_MIF));
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_G3D));
+ __raw_writel(tmp, EXYNOS5_ABB_MEMBER(ABB_ARM));
+ }
+}
+
+static inline int exynos4x12_get_abb_member(enum exynos4x12_abb_member abb_target)
+{
+ return (__raw_readl(S5P_ABB_MEMBER(abb_target)) & 0x1f);
+}
+
+struct asv_judge_table {
+ unsigned int hpm_limit; /* HPM value to decide group of target */
+ unsigned int ids_limit; /* IDS value to decide group of target */
+};
+
+struct samsung_asv {
+ unsigned int pkg_id; /* fused value for pakage */
+ unsigned int ids_offset; /* ids_offset of chip */
+ unsigned int ids_mask; /* ids_mask of chip */
+ unsigned int hpm_result; /* hpm value of chip */
+ unsigned int ids_result; /* ids value of chip */
+ int (*check_vdd_arm)(void); /* check vdd_arm value, this function is selectable */
+ int (*pre_clock_init)(void); /* clock init function to get hpm */
+ int (*pre_clock_setup)(void); /* clock setup function to get hpm */
+ /* specific get ids function */
+ int (*get_ids)(struct samsung_asv *asv_info);
+ /* specific get hpm function */
+ int (*get_hpm)(struct samsung_asv *asv_info);
+ /* store into some repository to send result of asv */
+ int (*store_result)(struct samsung_asv *asv_info);
+};
+
+extern int exynos4210_asv_init(struct samsung_asv *asv_info);
+extern int exynos4x12_asv_init(struct samsung_asv *asv_info);
+extern int exynos5250_asv_init(struct samsung_asv *asv_info);
+void exynos4x12_set_abb_member(enum exynos4x12_abb_member abb_target, unsigned int abb_mode_value);
+
+#else
+
+/* left empty to invoke build errors */
+
+#endif
+
+#endif /* __ASM_ARCH_ASV_H */
diff --git a/arch/arm/mach-exynos/include/mach/bcm47511.h b/arch/arm/mach-exynos/include/mach/bcm47511.h
new file mode 100644
index 0000000..b2648eb
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/bcm47511.h
@@ -0,0 +1,27 @@
+/* linux/arm/arch/mach-exynos/include/mach/bcm47511.h
+ *
+ * Platform data Header for BCM47511(GPS) driver.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ * Minho Ban <mhban@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _BCM47511_H
+#define _BCM47511_H
+
+struct bcm47511_platform_data {
+ unsigned int regpu; /* Power */
+ unsigned int nrst; /* Reset */
+ unsigned int uart_rxd; /* Start gpio number of uart */
+ /* Below are machine dependant */
+ unsigned int gps_cntl; /* Request 26MHz CP clock */
+ const char *reg32khz; /* regulator id for 32KHz clk */
+};
+
+#endif /* _BCM47511_H */
+
+
diff --git a/arch/arm/mach-exynos/include/mach/board-bluetooth-bcm.h b/arch/arm/mach-exynos/include/mach/board-bluetooth-bcm.h
new file mode 100644
index 0000000..125d7f2
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/board-bluetooth-bcm.h
@@ -0,0 +1,30 @@
+/*
+ * Bluetooth Broadcom GPIO and Low Power Mode control
+ *
+ * Copyright (C) 2011 Samsung, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __BOARD_BLUETOOTH_BCM4334_H__
+#define __BOARD_BLUETOOTH_BCM4334_H__
+
+#include <linux/serial_core.h>
+
+extern void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport);
+
+#endif /* __BOARD_BLUETOOTH_BCM4334_H__ */
diff --git a/arch/arm/mach-exynos/include/mach/board-bluetooth-csr.h b/arch/arm/mach-exynos/include/mach/board-bluetooth-csr.h
new file mode 100644
index 0000000..11514b1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/board-bluetooth-csr.h
@@ -0,0 +1,30 @@
+/*
+ * Bluetooth CSR GPIO and Low Power Mode control
+ *
+ * Copyright (C) 2011 Samsung, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __BOARD_BLUETOOTH_CSR8811_H__
+#define __BOARD_BLUETOOTH_CSR8811_H__
+
+#include <linux/serial_core.h>
+
+extern void csr_bt_lpm_exit_lpm_locked(struct uart_port *uport);
+
+#endif /* __BOARD_BLUETOOTH_BCM4334_H__ */
diff --git a/arch/arm/mach-exynos/include/mach/board-gps.h b/arch/arm/mach-exynos/include/mach/board-gps.h
new file mode 100644
index 0000000..6b7e42a
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/board-gps.h
@@ -0,0 +1,29 @@
+/*
+ * GPS GPIO control
+ *
+ * Copyright (C) 2012 Samsung, Inc.
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#ifndef __BOARD_GPS_H__
+#define __BOARD_GPS_H__
+
+extern struct class *sec_class;
+
+#endif /* __BOARD_GPS_H__ */
diff --git a/arch/arm/mach-exynos/include/mach/board_rev.h b/arch/arm/mach-exynos/include/mach/board_rev.h
new file mode 100644
index 0000000..a5e37a1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/board_rev.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-exynos/include/mach/board_rev.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - board revision support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BOARD_REV_H
+#define __ASM_ARCH_BOARD_REV_H __FILE__
+
+enum {
+ SAMSUNG_BOARD_REV_0_0 = 0x0000,
+ SAMSUNG_BOARD_REV_0_1 = 0x0001
+};
+
+extern int samsung_board_rev;
+
+#define samsung_board_rev_is_0_0() (samsung_board_rev == SAMSUNG_BOARD_REV_0_0)
+#define samsung_board_rev_is_0_1() (samsung_board_rev == SAMSUNG_BOARD_REV_0_1)
+
+#endif /* __ASM_ARCH_BOARD_REV_H */
diff --git a/arch/arm/mach-exynos/include/mach/busfreq.h b/arch/arm/mach-exynos/include/mach/busfreq.h
new file mode 100644
index 0000000..1be7145
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/busfreq.h
@@ -0,0 +1,120 @@
+/* linux/arch/arm/mach-exynos/include/mach/busfreq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - BUSFreq support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BUSFREQ_H
+#define __ASM_ARCH_BUSFREQ_H __FILE__
+
+#include <linux/notifier.h>
+#include <linux/earlysuspend.h>
+
+#include <mach/ppmu.h>
+
+#define MAX_LOAD 100
+#define LOAD_HISTORY_SIZE 5
+#define DIVIDING_FACTOR 10000
+
+#define TIMINGROW_OFFSET 0x34
+
+struct opp;
+struct device;
+struct busfreq_table;
+
+struct busfreq_data {
+ bool use;
+ struct device *dev;
+ struct delayed_work worker;
+ struct opp *curr_opp;
+ struct opp *max_opp;
+ struct opp *min_opp;
+ struct regulator *vdd_int;
+ struct regulator *vdd_mif;
+ unsigned int sampling_rate;
+ struct kobject *busfreq_kobject;
+ int table_size;
+ struct busfreq_table *table;
+ unsigned long long *time_in_state;
+ unsigned long long last_time;
+ unsigned int load_history[PPMU_END][LOAD_HISTORY_SIZE];
+ int index;
+
+ struct notifier_block exynos_buspm_notifier;
+ struct notifier_block exynos_reboot_notifier;
+ struct notifier_block exynos_request_notifier;
+ struct early_suspend busfreq_early_suspend_handler;
+ struct attribute_group busfreq_attr_group;
+ int (*init) (struct device *dev, struct busfreq_data *data);
+ struct opp *(*monitor)(struct busfreq_data *data);
+ void (*target) (int mif_index, int int_index);
+ unsigned int (*get_int_volt) (unsigned long freq);
+ unsigned int (*get_table_index) (struct opp *opp);
+ void (*busfreq_prepare) (unsigned int index);
+ void (*busfreq_post) (unsigned int index);
+ void (*set_qos) (unsigned int index);
+ void (*busfreq_suspend) (void);
+ void (*busfreq_resume) (void);
+};
+
+struct busfreq_table {
+ unsigned int idx;
+ unsigned int mem_clk;
+ unsigned int volt;
+ unsigned int clk_topdiv;
+ unsigned int clk_dmc0div;
+ unsigned int clk_dmc1div;
+};
+
+void exynos_request_apply(unsigned long freq, struct device *dev);
+struct opp *step_down(struct busfreq_data *data, int step);
+
+#if defined(CONFIG_ARCH_EXYNOS5)
+int exynos5250_init(struct device *dev, struct busfreq_data *data);
+void exynos5250_target(int mif_index, int int_index);
+unsigned int exynos5250_get_int_volt(unsigned long freq);
+unsigned int exynos5250_get_table_index(struct opp *opp);
+struct opp *exynos5250_monitor(struct busfreq_data *data);
+void exynos5250_prepare(unsigned int index);
+void exynos5250_post(unsigned int index);
+void exynos5250_suspend(void);
+void exynos5250_resume(void);
+
+#define exynos4x12_init NULL
+#define exynos4x12_target NULL
+#define exynos4x12_get_int_volt NULL
+#define exynos4x12_get_table_index NULL
+#define exynos4x12_monitor NULL
+#define exynos4x12_prepare NULL
+#define exynos4x12_post NULL
+#define exynos4x12_suspend NULL
+#define exynos4x12_resume NULL
+#elif defined(CONFIG_ARCH_EXYNOS4)
+#define exynos5250_init NULL
+#define exynos5250_target NULL
+#define exynos5250_get_int_volt NULL
+#define exynos5250_get_table_index NULL
+#define exynos5250_monitor NULL
+#define exynos5250_prepare NULL
+#define exynos5250_post NULL
+#define exynos5250_suspend NULL
+#define exynos5250_resume NULL
+
+int exynos4x12_init(struct device *dev, struct busfreq_data *data);
+void exynos4x12_target(int mif_index, int int_index);
+unsigned int exynos4x12_get_int_volt(unsigned long freq);
+unsigned int exynos4x12_get_table_index(struct opp *opp);
+struct opp *exynos4x12_monitor(struct busfreq_data *data);
+void exynos4x12_prepare(unsigned int index);
+void exynos4x12_post(unsigned int index);
+void exynos4x12_set_qos(unsigned int index);
+void exynos4x12_suspend(void);
+void exynos4x12_resume(void);
+#endif
+#endif /* __ASM_ARCH_BUSFREQ_H */
diff --git a/arch/arm/mach-exynos/include/mach/busfreq_exynos4.h b/arch/arm/mach-exynos/include/mach/busfreq_exynos4.h
new file mode 100644
index 0000000..fabd1e8
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/busfreq_exynos4.h
@@ -0,0 +1,103 @@
+/* linux/arch/arm/mach-exynos/include/mach/busfreq_exynos4.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - BUSFreq support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BUSFREQ_H
+#define __ASM_ARCH_BUSFREQ_H __FILE__
+
+#include <linux/notifier.h>
+#include <linux/earlysuspend.h>
+
+#include <mach/ppmu.h>
+
+#define MAX_LOAD 100
+#define LOAD_HISTORY_SIZE 5
+#define DIVIDING_FACTOR 10000
+
+#define TIMINGROW_OFFSET 0x34
+
+#define EXYNOS4412_DMC_MAX_THRESHOLD 30
+#define EXYNOS4212_DMC_MAX_THRESHOLD 30
+
+extern unsigned int up_threshold;
+extern unsigned int ppmu_threshold;
+extern unsigned int idle_threshold;
+extern unsigned int up_cpu_threshold;
+extern unsigned int max_cpu_threshold;
+extern unsigned int cpu_slope_size;
+extern unsigned int dmc_max_threshold;
+extern unsigned int load_history_size;
+
+struct opp;
+struct device;
+struct busfreq_table;
+
+struct busfreq_data {
+ bool use;
+ struct device *dev;
+ struct delayed_work worker;
+ struct opp *curr_opp;
+ struct opp *max_opp;
+ struct opp *min_opp;
+ struct regulator *vdd_int;
+ struct regulator *vdd_mif;
+ unsigned int sampling_rate;
+ struct kobject *busfreq_kobject;
+ int table_size;
+ struct busfreq_table *table;
+ unsigned long long *time_in_state;
+ unsigned long long last_time;
+ unsigned int load_history[PPMU_END][LOAD_HISTORY_SIZE];
+ int index;
+
+ struct notifier_block exynos_buspm_notifier;
+ struct notifier_block exynos_reboot_notifier;
+ struct notifier_block exynos_request_notifier;
+ struct notifier_block exynos_cpufreq_notifier;
+ struct notifier_block exynos_busqos_notifier;
+ struct early_suspend busfreq_early_suspend_handler;
+ struct attribute_group busfreq_attr_group;
+ int (*init) (struct device *dev, struct busfreq_data *data);
+ struct opp *(*monitor)(struct busfreq_data *data);
+ void (*target) (int index);
+ unsigned int (*get_int_volt) (unsigned long index);
+ unsigned int (*get_table_index) (struct opp *opp);
+ void (*busfreq_prepare) (unsigned int index);
+ void (*busfreq_post) (unsigned int index);
+ void (*set_qos) (unsigned int index);
+ void (*busfreq_suspend) (void);
+ void (*busfreq_resume) (void);
+};
+
+struct busfreq_table {
+ unsigned int idx;
+ unsigned int mem_clk;
+ unsigned int volt;
+ unsigned int clk_topdiv;
+ unsigned int clk_dmc0div;
+ unsigned int clk_dmc1div;
+};
+
+void exynos_request_apply(unsigned long freq);
+struct opp *step_down(struct busfreq_data *data, int step);
+
+int exynos4x12_init(struct device *dev, struct busfreq_data *data);
+void exynos4x12_target(int index);
+unsigned int exynos4x12_get_int_volt(unsigned long freq);
+unsigned int exynos4x12_get_table_index(struct opp *opp);
+struct opp *exynos4x12_monitor(struct busfreq_data *data);
+void exynos4x12_prepare(unsigned int index);
+void exynos4x12_post(unsigned int index);
+void exynos4x12_set_qos(unsigned int index);
+void exynos4x12_suspend(void);
+void exynos4x12_resume(void);
+int exynos4x12_find_busfreq_by_volt(unsigned int req_volt, unsigned int *freq);
+#endif /* __ASM_ARCH_BUSFREQ_H */
diff --git a/arch/arm/mach-exynos/include/mach/busfreq_exynos5.h b/arch/arm/mach-exynos/include/mach/busfreq_exynos5.h
new file mode 100644
index 0000000..fe00bd1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/busfreq_exynos5.h
@@ -0,0 +1,93 @@
+/* linux/arch/arm/mach-exynos/include/mach/busfreq_exynos5.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - BUSFreq support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_BUSFREQ_H
+#define __ASM_ARCH_BUSFREQ_H __FILE__
+
+#include <linux/notifier.h>
+#include <linux/earlysuspend.h>
+
+#include <mach/ppmu.h>
+
+#define MAX_LOAD 100
+#define LOAD_HISTORY_SIZE 5
+#define DIVIDING_FACTOR 10000
+
+#define TIMINGROW_OFFSET 0x34
+
+enum busfreq_level_idx {
+ LV_0,
+ LV_1,
+ LV_2,
+ LV_3,
+ LV_INT_END,
+ LV_MIF_END = LV_3,
+};
+
+struct opp;
+struct device;
+struct busfreq_table;
+
+struct busfreq_data {
+ bool use;
+ struct device *dev[PPMU_TYPE_END];
+ struct delayed_work worker;
+ unsigned long curr_freq[PPMU_TYPE_END];
+ unsigned long max_freq[PPMU_TYPE_END];
+ unsigned long min_freq[PPMU_TYPE_END];
+ struct regulator *vdd_reg[PPMU_TYPE_END];
+ unsigned int sampling_rate;
+ struct kobject *busfreq_kobject;
+ struct busfreq_table *table[PPMU_TYPE_END];
+ unsigned long long time_in_state[PPMU_TYPE_END][LV_INT_END];
+ unsigned long long last_time[PPMU_TYPE_END];
+ unsigned int load_history[PPMU_END][LOAD_HISTORY_SIZE];
+ int index;
+
+ struct notifier_block exynos_buspm_notifier;
+ struct notifier_block exynos_reboot_notifier;
+ struct notifier_block exynos_request_notifier;
+ struct early_suspend busfreq_early_suspend_handler;
+ struct attribute_group busfreq_attr_group;
+ int (*init) (struct device *dev, struct busfreq_data *data);
+ void (*monitor) (struct busfreq_data *data, struct opp **mif_opp,
+ struct opp **int_opp);
+ void (*target) (struct busfreq_data *data, enum ppmu_type type, int index);
+ unsigned int (*get_int_volt) (unsigned long freq);
+ int (*get_table_index) (unsigned long freq, enum ppmu_type type);
+ void (*busfreq_prepare) (int index);
+ void (*busfreq_post) (int index);
+ void (*busfreq_suspend) (void);
+ void (*busfreq_resume) (void);
+
+ /* Dividers calculated at boot/probe-time */
+ unsigned int lex_divtable[LV_INT_END];
+ unsigned int r0x_divtable[LV_INT_END];
+ unsigned int r1x_divtable[LV_INT_END];
+ unsigned int cdrex_divtable[LV_MIF_END];
+ unsigned int cdrex2_divtable[LV_MIF_END];
+};
+
+struct busfreq_table {
+ unsigned int idx;
+ unsigned int mem_clk;
+ unsigned int volt;
+ unsigned int clk_topdiv;
+ unsigned int clk_dmc0div;
+ unsigned int clk_dmc1div;
+};
+
+void exynos_request_apply(unsigned long freq);
+unsigned long step_down(struct busfreq_data *data, enum ppmu_type type, int step);
+
+int exynos5250_init(struct device *dev, struct busfreq_data *data);
+#endif /* __ASM_ARCH_BUSFREQ_H */
diff --git a/arch/arm/mach-exynos/include/mach/c2c.h b/arch/arm/mach-exynos/include/mach/c2c.h
new file mode 100644
index 0000000..a422bde
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/c2c.h
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-exynos/include/mach/c2c.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform header file for Samsung C2C Interface driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __ASM_PLAT_C2C_H
+#define __ASM_PLAT_C2C_H __FILE__
+
+#define C2C_SHAREDMEM_BASE 0x60000000
+
+enum c2c_opp_mode {
+ C2C_OPP0 = 0,
+ C2C_OPP25 = 1,
+ C2C_OPP50 = 2,
+ C2C_OPP100 = 3,
+};
+
+enum c2c_buswidth {
+ C2C_BUSWIDTH_8 = 0,
+ C2C_BUSWIDTH_10 = 1,
+ C2C_BUSWIDTH_16 = 2,
+};
+
+enum c2c_shrdmem_size {
+ C2C_MEMSIZE_4 = 0,
+ C2C_MEMSIZE_8 = 1,
+ C2C_MEMSIZE_16 = 2,
+ C2C_MEMSIZE_32 = 3,
+ C2C_MEMSIZE_64 = 4,
+ C2C_MEMSIZE_128 = 5,
+ C2C_MEMSIZE_256 = 6,
+ C2C_MEMSIZE_512 = 7,
+};
+
+struct exynos_c2c_platdata {
+ void (*setup_gpio)(enum c2c_buswidth rx_width, enum c2c_buswidth tx_width);
+ void (*set_cprst)(void);
+ void (*clear_cprst)(void);
+ u32 (*get_c2c_state)(void);
+
+ u32 shdmem_addr;
+ enum c2c_shrdmem_size shdmem_size;
+
+ void __iomem *ap_sscm_addr;
+ void __iomem *cp_sscm_addr;
+
+ enum c2c_buswidth rx_width;
+ enum c2c_buswidth tx_width;
+ u32 clk_opp100; /* clock of OPP100 mode */
+ u32 clk_opp50; /* clock of OPP50 mode */
+ u32 clk_opp25; /* clock of OPP25 */
+ enum c2c_opp_mode default_opp_mode;
+
+ void __iomem *c2c_sysreg; /* System Register address for C2C */
+ char *c2c_clk;
+};
+
+void exynos_c2c_set_platdata(struct exynos_c2c_platdata *pd);
+extern void exynos_c2c_cfg_gpio(enum c2c_buswidth rx_width, enum c2c_buswidth tx_width);
+extern void exynos_c2c_set_cprst(void);
+extern void exynos_c2c_clear_cprst(void);
+#endif /*__ASM_PLAT_C2C_H */
diff --git a/arch/arm/mach-exynos/include/mach/clkdev.h b/arch/arm/mach-exynos/include/mach/clkdev.h
new file mode 100644
index 0000000..7dffa83
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_CLKDEV_H__
+#define __MACH_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do {} while (0)
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/clock-domain.h b/arch/arm/mach-exynos/include/mach/clock-domain.h
new file mode 100644
index 0000000..91013d1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/clock-domain.h
@@ -0,0 +1,33 @@
+/* linux/arch/arm/mach-exynos/include/mach/clock-domain.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - Clock Domain support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_DOMAIN_H
+#define __ASM_ARCH_CLOCK_DOMAIN_H __FILE__
+
+#define LPA_DOMAIN 0x00000001
+
+struct clock {
+ struct list_head node;
+
+ struct clk *clk;
+};
+
+struct clock_domain {
+ struct list_head node;
+
+ unsigned int flag;
+ struct list_head domain_list;
+};
+
+int clock_add_domain(unsigned int flag, struct clk *clk);
+int clock_domain_enabled(unsigned int flag);
+#endif /* __ASM_ARCH_CLOCK_DOMAIN_H */
diff --git a/arch/arm/mach-exynos/include/mach/cpufreq.h b/arch/arm/mach-exynos/include/mach/cpufreq.h
new file mode 100644
index 0000000..9ef27df
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/cpufreq.h
@@ -0,0 +1,152 @@
+/* linux/arch/arm/mach-exynos/include/mach/cpufreq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - CPUFreq support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* CPU frequency level index for using cpufreq lock API
+ * This should be same with cpufreq_frequency_table
+*/
+
+enum cpufreq_level_index {
+ L0, L1, L2, L3, L4,
+ L5, L6, L7, L8, L9,
+ L10, L11, L12, L13, L14,
+ L15, L16, L17, L18, L19,
+ L20,
+};
+
+enum busfreq_level_request {
+ BUS_L0, /* MEM 400MHz BUS 200MHz */
+ BUS_L1, /* MEM 267MHz BUS 160MHz */
+ BUS_L2, /* MEM 133MHz BUS 133MHz */
+ BUS_LEVEL_END,
+};
+
+enum cpufreq_lock_ID {
+ DVFS_LOCK_ID_G2D, /* G2D */
+ DVFS_LOCK_ID_TV, /* TV */
+ DVFS_LOCK_ID_MFC, /* MFC */
+ DVFS_LOCK_ID_USB, /* USB */
+ DVFS_LOCK_ID_USB_IF, /* USB_IF */
+ DVFS_LOCK_ID_CAM, /* CAM */
+ DVFS_LOCK_ID_PM, /* PM */
+ DVFS_LOCK_ID_USER, /* USER */
+ DVFS_LOCK_ID_TMU, /* TMU */
+ DVFS_LOCK_ID_LPA, /* LPA */
+ DVFS_LOCK_ID_TSP, /* TSP */
+ DVFS_LOCK_ID_PEN, /* E-PEN */
+ DVFS_LOCK_ID_G3D, /* G3D */
+ DVFS_LOCK_ID_IR_LED, /* IR_LED */
+ DVFS_LOCK_ID_LCD, /* LCD */
+ DVFS_LOCK_ID_DRM, /* DRM */
+ DVFS_LOCK_ID_ROTATION_BOOSTER, /* ROTATION_BOOSTER */
+
+ /*
+ * QoS Request on DMA Latency.
+ *
+ * dvfs_lock is a non standard implementation that can be
+ * replaced with PM QoS framework.
+ * However, in this implementation, in order to provide
+ * a prototype and test of PM QoS on CPU (DMA Latency),
+ * PM QoS uses dvfs_lock on CPU until we have a full
+ * implementation in CPUFREQ framework of QoS.
+ */
+ DVFS_LOCK_ID_QOS_DMA_LATENCY,
+ DVFS_LOCK_ID_END,
+};
+
+int exynos_cpufreq_get_level(unsigned int freq,
+ unsigned int *level);
+int exynos_find_cpufreq_level_by_volt(unsigned int arm_volt,
+ unsigned int *level);
+int exynos_cpufreq_lock(unsigned int nId,
+ enum cpufreq_level_index cpufreq_level);
+void exynos_cpufreq_lock_free(unsigned int nId);
+
+int exynos4_busfreq_lock(unsigned int nId,
+ enum busfreq_level_request busfreq_level);
+void exynos4_busfreq_lock_free(unsigned int nId);
+
+int exynos_cpufreq_upper_limit(unsigned int nId,
+ enum cpufreq_level_index cpufreq_level);
+void exynos_cpufreq_upper_limit_free(unsigned int nId);
+
+/*
+ * This level fix API set highset priority level lock.
+ * Please use this carefully, with other lock API
+ */
+int exynos_cpufreq_level_fix(unsigned int freq);
+void exynos_cpufreq_level_unfix(void);
+int exynos_cpufreq_is_fixed(void);
+
+#define MAX_INDEX 10
+
+#ifdef CONFIG_SLP
+struct dvfs_qos_info {
+ unsigned int qos_value;
+ unsigned int min_freq;
+ enum cpufreq_level_index level;
+};
+#endif
+
+struct exynos_dvfs_info {
+ unsigned long mpll_freq_khz;
+ unsigned int pll_safe_idx;
+ unsigned int pm_lock_idx;
+ unsigned int max_support_idx;
+ unsigned int min_support_idx;
+ unsigned int gov_support_freq;
+ struct clk *cpu_clk;
+ unsigned int *volt_table;
+ struct cpufreq_frequency_table *freq_table;
+ void (*set_freq)(unsigned int, unsigned int);
+ bool (*need_apll_change)(unsigned int, unsigned int);
+
+#ifdef CONFIG_SLP
+ struct dvfs_qos_info *cpu_dma_latency;
+#endif
+};
+
+extern struct exynos_dvfs_info *exynos_info;
+
+#define SUPPORT_1400MHZ (1<<31)
+#define SUPPORT_1200MHZ (1<<30)
+#define SUPPORT_1000MHZ (1<<29)
+#define SUPPORT_FREQ_SHIFT 29
+#define SUPPORT_FREQ_MASK 7
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
+extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
+static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
+{
+ return 0;
+}
+
+#elif defined(CONFIG_ARCH_EXYNOS5)
+static inline int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
+{
+ return 0;
+}
+
+static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+{
+ return 0;
+}
+
+extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
+#else
+ #warning "Should define CONFIG_ARCH_EXYNOS4(5)\n"
+#endif
+
+#if defined(CONFIG_EXYNOS5250_ABB_WA)
+/* These function and variables should be removed in EVT1 */
+void exynos5250_set_arm_abbg(unsigned int arm_volt, unsigned int int_volt);
+#endif
diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos/include/mach/debug-macro.S
index a442ef8..26ee8b5 100644
--- a/arch/arm/mach-exynos4/include/mach/debug-macro.S
+++ b/arch/arm/mach-exynos/include/mach/debug-macro.S
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/debug-macro.S
+/* linux/arch/arm/mach-exynos/include/mach/debug-macro.S
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/dev-sysmmu.h b/arch/arm/mach-exynos/include/mach/dev-sysmmu.h
new file mode 100644
index 0000000..ed5fc92
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/dev-sysmmu.h
@@ -0,0 +1,87 @@
+/* linux/arch/arm/mach-exynos/include/mach/dev-sysmmu.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - System MMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ARM_MACH_EXYNOS_SYSMMU_H_
+#define _ARM_MACH_EXYNOS_SYSMMU_H_
+
+#define SYSMMU_DEVNAME_BASE "s5p-sysmmu"
+
+#ifdef CONFIG_S5P_SYSTEM_MMU
+#include <linux/device.h>
+
+#define SYSMMU_PLATDEV(ipname) exynos_device_sysmmu_##ipname
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#define ASSIGN_SYSMMU_POWERDOMAIN(ipname, powerdomain) \
+ SYSMMU_PLATDEV(ipname).dev.parent = powerdomain
+#else
+#define ASSIGN_SYSMMU_POWERDOMAIN(ipname, powerdomain) do { } while (0)
+#endif
+
+extern struct platform_device SYSMMU_PLATDEV(sss);
+extern struct platform_device SYSMMU_PLATDEV(jpeg);
+extern struct platform_device SYSMMU_PLATDEV(fimd1);
+extern struct platform_device SYSMMU_PLATDEV(pcie);
+extern struct platform_device SYSMMU_PLATDEV(2d);
+extern struct platform_device SYSMMU_PLATDEV(rot);
+extern struct platform_device SYSMMU_PLATDEV(mdma);
+extern struct platform_device SYSMMU_PLATDEV(tv);
+extern struct platform_device SYSMMU_PLATDEV(mfc_l);
+extern struct platform_device SYSMMU_PLATDEV(mfc_r);
+extern struct platform_device SYSMMU_PLATDEV(is_isp);
+extern struct platform_device SYSMMU_PLATDEV(is_drc);
+extern struct platform_device SYSMMU_PLATDEV(is_fd);
+extern struct platform_device SYSMMU_PLATDEV(is_cpu);
+extern struct platform_device SYSMMU_PLATDEV(flite0);
+extern struct platform_device SYSMMU_PLATDEV(flite1);
+extern struct platform_device SYSMMU_PLATDEV(flite2);
+
+#ifdef CONFIG_ARCH_EXYNOS4
+extern struct platform_device SYSMMU_PLATDEV(fimc0);
+extern struct platform_device SYSMMU_PLATDEV(fimc1);
+extern struct platform_device SYSMMU_PLATDEV(fimc2);
+extern struct platform_device SYSMMU_PLATDEV(fimc3);
+extern struct platform_device SYSMMU_PLATDEV(g2d_acp);
+extern struct platform_device SYSMMU_PLATDEV(gps);
+extern struct platform_device SYSMMU_PLATDEV(lite0);
+extern struct platform_device SYSMMU_PLATDEV(lite1);
+extern struct platform_device SYSMMU_PLATDEV(ispcx);
+extern struct platform_device SYSMMU_PLATDEV(fimd0);
+#endif
+
+#ifdef CONFIG_ARCH_EXYNOS5
+extern struct platform_device SYSMMU_PLATDEV(gsc0);
+extern struct platform_device SYSMMU_PLATDEV(gsc1);
+extern struct platform_device SYSMMU_PLATDEV(gsc2);
+extern struct platform_device SYSMMU_PLATDEV(gsc3);
+
+extern struct platform_device SYSMMU_PLATDEV(is_sclrc);
+extern struct platform_device SYSMMU_PLATDEV(is_sclrp);
+extern struct platform_device SYSMMU_PLATDEV(is_odc);
+extern struct platform_device SYSMMU_PLATDEV(is_dis0);
+extern struct platform_device SYSMMU_PLATDEV(is_dis1);
+extern struct platform_device SYSMMU_PLATDEV(is_3dnr);
+#endif
+
+static inline void sysmmu_set_owner(struct device *sysmmu, struct device *owner)
+{
+ sysmmu->platform_data = owner;
+}
+
+#else /* !CONFIG_S5P_SYSTEM_MMU */
+#define sysmmu_set_owner(sysmmu, owner) do { } while (0)
+#define ASSIGN_SYSMMU_POWERDOMAIN(ipname, powerdomain) do { } while (0)
+#endif
+
+#define SYSMMU_CLOCK_NAME(ipname, id) SYSMMU_DEVNAME_BASE "." #id
+
+#endif /* _ARM_MACH_EXYNOS_SYSMMU_H_ */
diff --git a/arch/arm/mach-exynos/include/mach/dev.h b/arch/arm/mach-exynos/include/mach/dev.h
new file mode 100644
index 0000000..c3dcb71
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/dev.h
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-exynos/include/mach/dev.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Device List support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_DEV_H
+#define __ASM_ARCH_DEV_H __FILE__
+
+struct device;
+
+struct domain_lock {
+ struct list_head node;
+
+ struct device_domain *domain;
+ struct device *device;
+ unsigned long freq;
+};
+
+struct device_domain {
+ struct list_head node;
+
+ struct device *device;
+ struct list_head domain_list;
+};
+
+int dev_add(struct device_domain *domain, struct device *device);
+struct device *dev_get(const char *name);
+void dev_put(const char *name);
+int dev_lock(struct device *device, struct device *dev, unsigned long freq);
+int dev_lock_fix(struct device *device, struct device *dev, unsigned long freq);
+int dev_unlock(struct device *device, struct device *dev);
+void dev_unlock_fix(struct device *device, struct device *dev);
+unsigned long dev_max_freq(struct device *device);
+int dev_lock_list(struct device *dev, char *buf);
+
+#endif /* __ASM_ARCH_DEV_H */
diff --git a/arch/arm/mach-exynos/include/mach/diag_bridge.h b/arch/arm/mach-exynos/include/mach/diag_bridge.h
new file mode 100644
index 0000000..b06f020
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/diag_bridge.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_USB_DIAG_BRIDGE_H__
+#define __LINUX_USB_DIAG_BRIDGE_H__
+
+struct diag_bridge_ops {
+ void *ctxt;
+ void (*read_complete_cb)(void *ctxt, char *buf,
+ int buf_size, int actual);
+ void (*write_complete_cb)(void *ctxt, char *buf,
+ int buf_size, int actual);
+ int (*suspend)(void *ctxt);
+ void (*resume)(void *ctxt);
+};
+
+#if defined(CONFIG_USB_QCOM_DIAG_BRIDGE) \
+ || defined(CONFIG_USB_QCOM_DIAG_BRIDGE_MODULE)
+
+extern int diag_bridge_read(char *data, int size);
+extern int diag_bridge_write(char *data, int size);
+extern int diag_bridge_open(struct diag_bridge_ops *ops);
+extern void diag_bridge_close(void);
+
+#else
+
+static int __maybe_unused diag_bridge_read(char *data, int size)
+{
+ return -ENODEV;
+}
+
+static int __maybe_unused diag_bridge_write(char *data, int size)
+{
+ return -ENODEV;
+}
+
+static int __maybe_unused diag_bridge_open(struct diag_bridge_ops *ops)
+{
+ return -ENODEV;
+}
+
+static void __maybe_unused diag_bridge_close(void) { }
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos/include/mach/dma.h
index 81209eb..81209eb 100644
--- a/arch/arm/mach-exynos4/include/mach/dma.h
+++ b/arch/arm/mach-exynos/include/mach/dma.h
diff --git a/arch/arm/mach-exynos/include/mach/dsim.h b/arch/arm/mach-exynos/include/mach/dsim.h
new file mode 100644
index 0000000..de60369
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/dsim.h
@@ -0,0 +1,259 @@
+/* linux/arm/arch/mach-exynos/include/mach/dsim.h
+ *
+ * Platform data header for Samsung MIPI-DSIM.
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _DSIM_H
+#define _DSIM_H
+
+/* h/w configuration */
+#define MIPI_FIN 24000000
+#define DSIM_HEADER_FIFO_SZ 16
+#define DSIM_TIMEOUT_MS 5000
+#define DSIM_NO_OF_INTERRUPT 26
+#define DSIM_PM_STABLE_TIME 10
+
+#define DSIM_TRUE 1
+#define DSIM_FALSE 0
+
+#define CMD_LENGTH 0xf
+
+enum dsim_interface_type {
+ DSIM_COMMAND = 0,
+ DSIM_VIDEO = 1,
+};
+
+enum dsim_state {
+ DSIM_STATE_RESET = 0,
+ DSIM_STATE_INIT = 1,
+ DSIM_STATE_STOP = 2,
+ DSIM_STATE_HSCLKEN = 3,
+ DSIM_STATE_ULPS = 4,
+};
+
+enum {
+ DSIM_NONE_STATE = 0,
+ DSIM_RESUME_COMPLETE = 1,
+ DSIM_FRAME_DONE = 2,
+};
+
+enum dsim_virtual_ch_no {
+ DSIM_VIRTUAL_CH_0 = 0,
+ DSIM_VIRTUAL_CH_1 = 1,
+ DSIM_VIRTUAL_CH_2 = 2,
+ DSIM_VIRTUAL_CH_3 = 3,
+};
+
+enum dsim_video_mode_type {
+ DSIM_NON_BURST_SYNC_EVENT = 0,
+ DSIM_BURST_SYNC_EVENT = 1,
+ DSIM_NON_BURST_SYNC_PULSE = 2,
+ DSIM_BURST = 3,
+ DSIM_NON_VIDEO_MODE = 4,
+};
+
+enum dsim_fifo_state {
+ DSIM_RX_DATA_FULL = (1 << 25),
+ DSIM_RX_DATA_EMPTY = (1 << 24),
+ SFR_HEADER_FULL = (1 << 23),
+ SFR_HEADER_EMPTY = (1 << 22),
+ SFR_PAYLOAD_FULL = (1 << 21),
+ SFR_PAYLOAD_EMPTY = (1 << 20),
+ I80_HEADER_FULL = (1 << 19),
+ I80_HEADER_EMPTY = (1 << 18),
+ I80_PALOAD_FULL = (1 << 17),
+ I80_PALOAD_EMPTY = (1 << 16),
+ SUB_DISP_HEADER_FULL = (1 << 15),
+ SUB_DISP_HEADER_EMPTY = (1 << 14),
+ SUB_DISP_PAYLOAD_FULL = (1 << 13),
+ SUB_DISP_PAYLOAD_EMPTY = (1 << 12),
+ MAIN_DISP_HEADER_FULL = (1 << 11),
+ MAIN_DISP_HEADER_EMPTY = (1 << 10),
+ MAIN_DISP_PAYLOAD_FULL = (1 << 9),
+ MAIN_DISP_PAYLOAD_EMPTY = (1 << 8),
+};
+
+enum dsim_no_of_data_lane {
+ DSIM_DATA_LANE_1 = 0,
+ DSIM_DATA_LANE_2 = 1,
+ DSIM_DATA_LANE_3 = 2,
+ DSIM_DATA_LANE_4 = 3,
+};
+
+enum dsim_byte_clk_src {
+ DSIM_PLL_OUT_DIV8 = 0,
+ DSIM_EXT_CLK_DIV8 = 1,
+ DSIM_EXT_CLK_BYPASS = 2,
+};
+
+enum dsim_lane {
+ DSIM_LANE_DATA0 = (1 << 0),
+ DSIM_LANE_DATA1 = (1 << 1),
+ DSIM_LANE_DATA2 = (1 << 2),
+ DSIM_LANE_DATA3 = (1 << 3),
+ DSIM_LANE_DATA_ALL = 0xf,
+ DSIM_LANE_CLOCK = (1 << 4),
+ DSIM_LANE_ALL = DSIM_LANE_CLOCK | DSIM_LANE_DATA_ALL,
+};
+
+enum dsim_pixel_format {
+ DSIM_CMD_3BPP = 0,
+ DSIM_CMD_8BPP = 1,
+ DSIM_CMD_12BPP = 2,
+ DSIM_CMD_16BPP = 3,
+ DSIM_VID_16BPP_565 = 4,
+ DSIM_VID_18BPP_666PACKED = 5,
+ DSIM_18BPP_666LOOSELYPACKED = 6,
+ DSIM_24BPP_888 = 7,
+};
+
+enum dsim_lane_state {
+ DSIM_LANE_STATE_HS_READY,
+ DSIM_LANE_STATE_ULPS,
+ DSIM_LANE_STATE_STOP,
+ DSIM_LANE_STATE_LPDT,
+};
+
+enum dsim_transfer {
+ DSIM_TRANSFER_NEITHER = 0,
+ DSIM_TRANSFER_BYCPU = (1 << 7),
+ DSIM_TRANSFER_BYLCDC = (1 << 6),
+ DSIM_TRANSFER_BOTH = (0x3 << 6)
+};
+
+enum dsim_lane_change {
+ DSIM_NO_CHANGE = 0,
+ DSIM_DATA_LANE_CHANGE = 1,
+ DSIM_CLOCK_NALE_CHANGE = 2,
+ DSIM_ALL_LANE_CHANGE = 3,
+};
+
+enum dsim_int_src {
+ DSIM_ALL_OF_INTR = 0xffffffff,
+ DSIM_PLL_STABLE = (1 << 31),
+ DSIM_REL_SWRST = (1 << 30),
+ DSIM_FIFO_EMPTY = (1 << 29),
+};
+
+enum dsim_data_id {
+ /* short packet types of packet types for command */
+ GEN_SHORT_WR_NO_PARA = 0x03,
+ GEN_SHORT_WR_1_PARA = 0x13,
+ GEN_SHORT_WR_2_PARA = 0x23,
+ GEN_RD_NO_PARA = 0x04,
+ GEN_RD_1_PARA = 0x14,
+ GEN_RD_2_PARA = 0x24,
+ DCS_WR_NO_PARA = 0x05,
+ DCS_WR_1_PARA = 0x15,
+ DCS_RD_NO_PARA = 0x06,
+ SET_MAX_RTN_PKT_SIZE = 0x37,
+
+ /* long packet types of packet types for command */
+ NULL_PKT = 0x09,
+ BLANKING_PKT = 0x19,
+ GEN_LONG_WR = 0x29,
+ DCS_LONG_WR = 0x39,
+
+ /* short packet types of generic command */
+ CMD_OFF = 0x02,
+ CMD_ON = 0x12,
+ SHUT_DOWN = 0x22,
+ TURN_ON = 0x32,
+
+ /* short packet types for video data */
+ VSYNC_START = 0x01,
+ VSYNC_END = 0x11,
+ HSYNC_START = 0x21,
+ HSYNC_END = 0x31,
+ EOT_PKT = 0x08,
+
+ /* long packet types for video data */
+ RGB565_PACKED = 0x0e,
+ RGB666_PACKED = 0x1e,
+ RGB666_LOOSLY = 0x2e,
+ RGB888_PACKED = 0x3e,
+};
+
+struct dsim_config {
+ /* only DSIM_1_03 */
+ unsigned char auto_flush;
+
+ /* only DSIM_1.02 or DSIM_1_03 */
+ unsigned char eot_disable;
+
+ /* porch option */
+ unsigned char auto_vertical_cnt; /* auto vertical cnt mode */
+ unsigned char hse; /* horizontal sync event mode */
+ unsigned char hfp; /* discard horizontal front porch time */
+ unsigned char hbp; /* discard horizontal back porch time */
+ unsigned char hsa; /* discard horizontal sync area timing */
+
+ /* data lane */
+ enum dsim_no_of_data_lane e_no_data_lane; /* number of data lane using DSI Master */
+
+ /* byte clock and escape clock */
+ enum dsim_byte_clk_src e_byte_clk;
+
+ /* pll pms value */
+ unsigned char p;
+ unsigned short m;
+ unsigned char s;
+
+ /* pll stable time */
+ unsigned int pll_stable_time;
+
+ unsigned long esc_clk;
+
+ /* BTA sequence */
+ unsigned short stop_holding_cnt;
+ unsigned char bta_timeout;
+ unsigned short rx_timeout;
+ enum dsim_video_mode_type e_lane_swap;
+
+ unsigned long hs_toggle;
+};
+
+struct dsim_lcd_config {
+ enum dsim_interface_type e_interface;
+ unsigned int parameter[3];
+
+ /* lcd panel info */
+ void *lcd_panel_info;
+
+ /* platform data for lcd panel based on MIPI-DSI. */
+ void *mipi_ddi_pd;
+
+ unsigned int lcd_enabled;
+};
+
+struct s5p_platform_dsim {
+ char *clk_name;
+ char lcd_panel_name[64];
+ unsigned int te_irq;
+ unsigned int platform_rev;
+
+ struct dsim_config *dsim_info;
+ struct dsim_lcd_config *dsim_lcd_info;
+
+ void (*mipi_power) (int enable);
+ void (*enable_clk) (void *d_clk, unsigned char enable);
+ void (*part_reset) (void);
+ void (*init_d_phy) (unsigned int dsim_base);
+ void (*exit_d_phy) (unsigned int dsim_base);
+ void (*cfg_gpio) (void);
+};
+
+extern void s5p_dsim_enable_clk(void *d_clk, unsigned char enable);
+extern void s5p_dsim_part_reset(void);
+extern void s5p_dsim_init_d_phy(unsigned int dsim_base);
+extern void s5p_dsim_exit_d_phy(unsigned int dsim_base);
+extern void exynos4_dsim_gpio_setup_24bpp(void);
+
+#endif /* _DSIM_H */
diff --git a/arch/arm/mach-exynos/include/mach/dwmci.h b/arch/arm/mach-exynos/include/mach/dwmci.h
new file mode 100644
index 0000000..fc14dc0
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/dwmci.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-exynos/include/mach/dwmci.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Synopsys DesignWare Mobile Storage for EXYNOS4210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_DWMCI_H
+#define __ASM_ARM_ARCH_DWMCI_H __FILE__
+
+#include <linux/mmc/dw_mmc.h>
+
+extern void exynos_dwmci_set_platdata(struct dw_mci_board *pd, u32 slot_id);
+
+#endif /* __ASM_ARM_ARCH_DWMCI_H */
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S
index d8f38c2..c6b2b7c 100644
--- a/arch/arm/mach-exynos4/include/mach/entry-macro.S
+++ b/arch/arm/mach-exynos/include/mach/entry-macro.S
@@ -1,4 +1,4 @@
-/* arch/arm/mach-exynos4/include/mach/entry-macro.S
+/* arch/arm/mach-exynos/include/mach/entry-macro.S
*
* Cloned from arch/arm/mach-realview/include/mach/entry-macro.S
*
@@ -11,13 +11,32 @@
#include <mach/hardware.h>
#include <asm/hardware/gic.h>
+#include <mach/map.h>
.macro disable_fiq
.endm
.macro get_irqnr_preamble, base, tmp
- ldr \base, =gic_cpu_base_addr
+#ifdef CONFIG_ARCH_EXYNOS4
+ mov \tmp, #0
+ mrc p15, 0, \base, c0, c0, 5
+ and \base, \base, #3
+ cmp \base, #0
+ beq 1f
+ ldr \tmp, =gic_bank_offset
+ ldr \tmp, [\tmp]
+ cmp \base, #1
+ beq 1f
+ cmp \base, #2
+ addeq \tmp, \tmp, \tmp
+ addne \tmp, \tmp, \tmp, LSL #1
+#endif
+1: ldr \base, =gic_cpu_base_addr
ldr \base, [\base]
+
+#ifdef CONFIG_ARCH_EXYNOS4
+ add \base, \base, \tmp
+#endif
.endm
.macro arch_ret_to_user, tmp1, tmp2
@@ -46,6 +65,13 @@
ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+#if defined (CONFIG_ARCH_EXYNOS4)
+ /* workaround for gic lockup */
+ add \base, \base, #0x10000
+ ldr \tmp, [\base, #GIC_DIST_PRI]
+ str \tmp, [\base, #GIC_DIST_PRI]
+ sub \base, \base, #0x10000
+#endif
ldr \tmp, =1021
bic \irqnr, \irqstat, #0x1c00
@@ -55,6 +81,22 @@
cmpne \irqnr, \tmp
cmpcs \irqnr, \irqnr
addne \irqnr, \irqnr, #32
+#if defined(CONFIG_ARM_TRUSTZONE)
+ bne 101f
+
+ mrc p15, 0, \tmp, c0, c0, 5
+ and \tmp, \tmp, #0x3
+ cmp \tmp, #1
+ cmpcs \tmp, \tmp
+ beq 101f
+
+ cmp \irqnr, #7
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, #16
+ cmpcs \irqnr, \irqnr
+ addne \irqnr, \irqnr, #32
+101:
+#endif
.endm
@@ -75,10 +117,10 @@
/* As above, this assumes that irqstat and base are preserved.. */
.macro test_for_ltirq, irqnr, irqstat, base, tmp
- bic \irqnr, \irqstat, #0x1c00
- mov \tmp, #0
- cmp \irqnr, #29
- moveq \tmp, #1
- streq \irqstat, [\base, #GIC_CPU_EOI]
- cmp \tmp, #0
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #28
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
.endm
diff --git a/arch/arm/mach-exynos/include/mach/exynos-clock.h b/arch/arm/mach-exynos/include/mach/exynos-clock.h
new file mode 100644
index 0000000..823d548
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/exynos-clock.h
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-exynos/include/mach/exynos-clock.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for exynos4 clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clk exynos4_clk_sclk_hdmi27m;
+extern struct clk exynos4_clk_sclk_usbphy0;
+extern struct clk exynos4_clk_sclk_usbphy1;
+extern struct clk exynos4_clk_sclk_hdmiphy;
+extern struct clk exynos4_clk_fimg2d;
+
+extern struct clksrc_clk exynos4_clk_sclk_apll;
+extern struct clksrc_clk exynos4_clk_mout_mpll;
+extern struct clksrc_clk exynos4_clk_aclk_160;
+extern struct clksrc_clk exynos4_clk_aclk_133;
+extern struct clksrc_clk exynos4_clk_aclk_200;
+#ifdef CONFIG_CPU_EXYNOS4212
+extern struct clksrc_clk exynos4212_clk_aclk_266;
+extern struct clksrc_clk exynos4212_clk_aclk_400_mcuisp;
+#endif
+extern struct clksrc_clk exynos4_clk_mout_epll;
+extern struct clksrc_clk exynos4_clk_sclk_vpll;
+extern struct clksrc_clk exynos4_clk_mout_g2d0;
+extern struct clksrc_clk exynos4_clk_mout_g2d1;
+extern struct clksrc_clk exynos4_clk_sclk_fimg2d;
+
+extern struct clk *exynos4_clkset_corebus_list[];
+extern struct clksrc_sources exynos4_clkset_mout_corebus;
+
+extern struct clk *exynos4_clkset_aclk_top_list[];
+extern struct clksrc_sources exynos4_clkset_aclk;
+
+extern struct clk *exynos4_clkset_group_list[];
+extern struct clksrc_sources exynos4_clkset_group;
+
+extern struct clk *exynos4_clkset_mout_mfc0_list[];
+
+extern struct clk exynos4_init_dmaclocks[];
+
+/* For vpll */
+struct vpll_div_data {
+ u32 rate;
+ u32 pdiv;
+ u32 mdiv;
+ u32 sdiv;
+ u32 k;
+ u32 mfr;
+ u32 mrr;
+ u32 vsel;
+};
+
+extern struct clk_ops exynos4_vpll_ops;
+extern struct clk_ops exynos4_epll_ops;
+
+extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_leftbus_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_rightbus_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_gps_ctrl(struct clk *clk, int enable);
+extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/include/mach/exynos-ion.h b/arch/arm/mach-exynos/include/mach/exynos-ion.h
new file mode 100644
index 0000000..cca859a
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/exynos-ion.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-exynos/include/mach/exynos-ion.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_EXYNOS_ION_H_
+
+struct platform_device;
+
+#ifdef CONFIG_ION_EXYNOS
+extern struct platform_device exynos_device_ion;
+void exynos_ion_set_platdata(void);
+#endif
+
+#endif /* __MACH_S5PV310_ION_H_ */
diff --git a/arch/arm/mach-exynos/include/mach/gc1-power.h b/arch/arm/mach-exynos/include/mach/gc1-power.h
new file mode 100644
index 0000000..ffebeae
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gc1-power.h
@@ -0,0 +1,37 @@
+/*
+ * midas-power.h - Power Management of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Chiwoong Byun <woong.byun@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MIDAS_POWER_H
+#define __MIDAS_POWER_H __FILE__
+
+#if defined(CONFIG_MFD_S5M_CORE) && defined(CONFIG_MFD_MAX77686)
+extern struct s5m_platform_data exynos4_s5m8767_info;
+extern struct max77686_platform_data exynos4_max77686_info;
+#elif defined(CONFIG_MFD_S5M_CORE)
+extern struct s5m_platform_data exynos4_s5m8767_info;
+#else
+extern struct max77686_platform_data exynos4_max77686_info;
+#endif
+
+void midas_power_init(void);
+void midas_power_set_muic_pdata(void *, int);
+void midas_power_gpio_init(void);
+#endif /* __MIDAS_POWER_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-exynos4.h b/arch/arm/mach-exynos/include/mach/gpio-exynos4.h
new file mode 100644
index 0000000..93b5b7b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-exynos4.h
@@ -0,0 +1,241 @@
+/* linux/arch/arm/mach-exynos/include/mach/gpio-exynos4.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - GPIO common lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_EXYNOS4_H
+#define __ASM_ARCH_GPIO_EXYNOS4_H __FILE__
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
+
+/* Common GPIO bank sizes */
+#define EXYNOS4_GPIO_A0_NR (8)
+#define EXYNOS4_GPIO_A1_NR (6)
+#define EXYNOS4_GPIO_B_NR (8)
+#define EXYNOS4_GPIO_C0_NR (5)
+#define EXYNOS4_GPIO_C1_NR (5)
+#define EXYNOS4_GPIO_D0_NR (4)
+#define EXYNOS4_GPIO_D1_NR (4)
+#define EXYNOS4_GPIO_F0_NR (8)
+#define EXYNOS4_GPIO_F1_NR (8)
+#define EXYNOS4_GPIO_F2_NR (8)
+#define EXYNOS4_GPIO_F3_NR (6)
+#define EXYNOS4_GPIO_K0_NR (7)
+#define EXYNOS4_GPIO_K1_NR (7)
+#define EXYNOS4_GPIO_K2_NR (7)
+#define EXYNOS4_GPIO_K3_NR (7)
+#define EXYNOS4_GPIO_L0_NR (8)
+#define EXYNOS4_GPIO_L1_NR (3)
+#define EXYNOS4_GPIO_L2_NR (8)
+#define EXYNOS4_GPIO_Y0_NR (6)
+#define EXYNOS4_GPIO_Y1_NR (4)
+#define EXYNOS4_GPIO_Y2_NR (6)
+#define EXYNOS4_GPIO_Y3_NR (8)
+#define EXYNOS4_GPIO_Y4_NR (8)
+#define EXYNOS4_GPIO_Y5_NR (8)
+#define EXYNOS4_GPIO_Y6_NR (8)
+#define EXYNOS4_GPIO_X0_NR (8)
+#define EXYNOS4_GPIO_X1_NR (8)
+#define EXYNOS4_GPIO_X2_NR (8)
+#define EXYNOS4_GPIO_X3_NR (8)
+#define EXYNOS4_GPIO_Z_NR (7)
+
+/* Only EXYNOS4210 GPIO bank sizes */
+#define EXYNOS4210_GPIO_E0_NR (5)
+#define EXYNOS4210_GPIO_E1_NR (8)
+#define EXYNOS4210_GPIO_E2_NR (6)
+#define EXYNOS4210_GPIO_E3_NR (8)
+#define EXYNOS4210_GPIO_E4_NR (8)
+#define EXYNOS4210_GPIO_J0_NR (8)
+#define EXYNOS4210_GPIO_J1_NR (5)
+
+/* Only EXYNOS4212 GPIO bank sizes */
+#define EXYNOS4212_GPIO_J0_NR (8)
+#define EXYNOS4212_GPIO_J1_NR (5)
+#define EXYNOS4212_GPIO_M0_NR (8)
+#define EXYNOS4212_GPIO_M1_NR (7)
+#define EXYNOS4212_GPIO_M2_NR (5)
+#define EXYNOS4212_GPIO_M3_NR (8)
+#define EXYNOS4212_GPIO_M4_NR (8)
+#define EXYNOS4212_GPIO_V0_NR (8)
+#define EXYNOS4212_GPIO_V1_NR (8)
+#define EXYNOS4212_GPIO_V2_NR (8)
+#define EXYNOS4212_GPIO_V3_NR (8)
+#define EXYNOS4212_GPIO_V4_NR (2)
+
+/* GPIO bank numbers */
+
+#define EXYNOS4_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum exynos4_gpio_number {
+ EXYNOS4_GPIO_A0_START = 0,
+ EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
+ EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
+ EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
+ EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
+ EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
+ EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
+ EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
+ EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
+ EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
+ EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
+ EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
+ EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
+ EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
+ EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
+ EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
+ EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
+ EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
+ EXYNOS4_GPIO_Y0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
+ EXYNOS4_GPIO_Y1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
+ EXYNOS4_GPIO_Y2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
+ EXYNOS4_GPIO_Y3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
+ EXYNOS4_GPIO_Y4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
+ EXYNOS4_GPIO_Y5_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
+ EXYNOS4_GPIO_Y6_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
+ EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
+ EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
+ EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
+ EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
+ EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
+};
+
+enum exynos4210_gpio_number {
+ EXYNOS4210_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Z),
+ EXYNOS4210_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4210_GPIO_E0),
+ EXYNOS4210_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4210_GPIO_E1),
+ EXYNOS4210_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4210_GPIO_E2),
+ EXYNOS4210_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4210_GPIO_E3),
+ EXYNOS4210_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4210_GPIO_E4),
+ EXYNOS4210_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4210_GPIO_J0),
+};
+
+enum exynos4212_gpio_number {
+ EXYNOS4212_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Z),
+ EXYNOS4212_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_J0),
+ EXYNOS4212_GPIO_M0_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_J1),
+ EXYNOS4212_GPIO_M1_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_M0),
+ EXYNOS4212_GPIO_M2_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_M1),
+ EXYNOS4212_GPIO_M3_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_M2),
+ EXYNOS4212_GPIO_M4_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_M3),
+ EXYNOS4212_GPIO_V0_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_M4),
+ EXYNOS4212_GPIO_V1_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_V0),
+ EXYNOS4212_GPIO_V2_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_V1),
+ EXYNOS4212_GPIO_V3_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_V2),
+ EXYNOS4212_GPIO_V4_START = EXYNOS4_GPIO_NEXT(EXYNOS4212_GPIO_V3),
+};
+
+/* EXYNOS4 GPIO number definitions */
+#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr))
+#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr))
+#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr))
+#define EXYNOS4_GPC0(_nr) (EXYNOS4_GPIO_C0_START + (_nr))
+#define EXYNOS4_GPC1(_nr) (EXYNOS4_GPIO_C1_START + (_nr))
+#define EXYNOS4_GPD0(_nr) (EXYNOS4_GPIO_D0_START + (_nr))
+#define EXYNOS4_GPD1(_nr) (EXYNOS4_GPIO_D1_START + (_nr))
+#define EXYNOS4_GPF0(_nr) (EXYNOS4_GPIO_F0_START + (_nr))
+#define EXYNOS4_GPF1(_nr) (EXYNOS4_GPIO_F1_START + (_nr))
+#define EXYNOS4_GPF2(_nr) (EXYNOS4_GPIO_F2_START + (_nr))
+#define EXYNOS4_GPF3(_nr) (EXYNOS4_GPIO_F3_START + (_nr))
+#define EXYNOS4_GPK0(_nr) (EXYNOS4_GPIO_K0_START + (_nr))
+#define EXYNOS4_GPK1(_nr) (EXYNOS4_GPIO_K1_START + (_nr))
+#define EXYNOS4_GPK2(_nr) (EXYNOS4_GPIO_K2_START + (_nr))
+#define EXYNOS4_GPK3(_nr) (EXYNOS4_GPIO_K3_START + (_nr))
+#define EXYNOS4_GPL0(_nr) (EXYNOS4_GPIO_L0_START + (_nr))
+#define EXYNOS4_GPL1(_nr) (EXYNOS4_GPIO_L1_START + (_nr))
+#define EXYNOS4_GPL2(_nr) (EXYNOS4_GPIO_L2_START + (_nr))
+#define EXYNOS4_GPY0(_nr) (EXYNOS4_GPIO_Y0_START + (_nr))
+#define EXYNOS4_GPY1(_nr) (EXYNOS4_GPIO_Y1_START + (_nr))
+#define EXYNOS4_GPY2(_nr) (EXYNOS4_GPIO_Y2_START + (_nr))
+#define EXYNOS4_GPY3(_nr) (EXYNOS4_GPIO_Y3_START + (_nr))
+#define EXYNOS4_GPY4(_nr) (EXYNOS4_GPIO_Y4_START + (_nr))
+#define EXYNOS4_GPY5(_nr) (EXYNOS4_GPIO_Y5_START + (_nr))
+#define EXYNOS4_GPY6(_nr) (EXYNOS4_GPIO_Y6_START + (_nr))
+#define EXYNOS4_GPX0(_nr) (EXYNOS4_GPIO_X0_START + (_nr))
+#define EXYNOS4_GPX1(_nr) (EXYNOS4_GPIO_X1_START + (_nr))
+#define EXYNOS4_GPX2(_nr) (EXYNOS4_GPIO_X2_START + (_nr))
+#define EXYNOS4_GPX3(_nr) (EXYNOS4_GPIO_X3_START + (_nr))
+#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr))
+
+#define EXYNOS4210_GPE0(_nr) (EXYNOS4210_GPIO_E0_START + (_nr))
+#define EXYNOS4210_GPE1(_nr) (EXYNOS4210_GPIO_E1_START + (_nr))
+#define EXYNOS4210_GPE2(_nr) (EXYNOS4210_GPIO_E2_START + (_nr))
+#define EXYNOS4210_GPE3(_nr) (EXYNOS4210_GPIO_E3_START + (_nr))
+#define EXYNOS4210_GPE4(_nr) (EXYNOS4210_GPIO_E4_START + (_nr))
+#define EXYNOS4210_GPJ0(_nr) (EXYNOS4210_GPIO_J0_START + (_nr))
+#define EXYNOS4210_GPJ1(_nr) (EXYNOS4210_GPIO_J1_START + (_nr))
+
+#define EXYNOS4212_GPJ0(_nr) (EXYNOS4212_GPIO_J0_START + (_nr))
+#define EXYNOS4212_GPJ1(_nr) (EXYNOS4212_GPIO_J1_START + (_nr))
+#define EXYNOS4212_GPM0(_nr) (EXYNOS4212_GPIO_M0_START + (_nr))
+#define EXYNOS4212_GPM1(_nr) (EXYNOS4212_GPIO_M1_START + (_nr))
+#define EXYNOS4212_GPM2(_nr) (EXYNOS4212_GPIO_M2_START + (_nr))
+#define EXYNOS4212_GPM3(_nr) (EXYNOS4212_GPIO_M3_START + (_nr))
+#define EXYNOS4212_GPM4(_nr) (EXYNOS4212_GPIO_M4_START + (_nr))
+#define EXYNOS4212_GPV0(_nr) (EXYNOS4212_GPIO_V0_START + (_nr))
+#define EXYNOS4212_GPV1(_nr) (EXYNOS4212_GPIO_V1_START + (_nr))
+#define EXYNOS4212_GPV2(_nr) (EXYNOS4212_GPIO_V2_START + (_nr))
+#define EXYNOS4212_GPV3(_nr) (EXYNOS4212_GPIO_V3_START + (_nr))
+#define EXYNOS4212_GPV4(_nr) (EXYNOS4212_GPIO_V4_START + (_nr))
+
+/* the end of the EXYNOS4 specific gpios */
+#define EXYNOS4210_GPIO_END (EXYNOS4212_GPV4(EXYNOS4212_GPIO_V4_NR) + 1)
+#define EXYNOS4212_GPIO_END (EXYNOS4210_GPJ1(EXYNOS4210_GPIO_J1_NR) + 1)
+
+#define EXYNOS4XXX_GPIO_END (EXYNOS4212_GPIO_END > EXYNOS4210_GPIO_END ? \
+ EXYNOS4212_GPIO_END : EXYNOS4210_GPIO_END)
+#define EXYNOS4_GPIO_END EXYNOS4XXX_GPIO_END
+
+/* define the number of gpios we need to the one after the GPZ() range */
+#define ARCH_NR_GPIOS (EXYNOS4XXX_GPIO_END + \
+ CONFIG_SAMSUNG_GPIO_EXTRA)
+
+#include <asm-generic/gpio.h>
+#if defined(CONFIG_MACH_MIDAS) || defined(CONFIG_MACH_SLP_MIDAS) \
+ || defined(CONFIG_MACH_SLP_PQ) \
+ || defined(CONFIG_MACH_SLP_PQ_LTE)
+#include "gpio-midas.h"
+#endif
+
+#if defined(CONFIG_MACH_SLP_NAPLES)
+#include "gpio-naples.h"
+#endif
+
+#if defined(CONFIG_MACH_U1)
+#include "gpio-u1.h"
+#endif
+
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+#include "gpio-u1camera.h"
+#endif
+
+#if defined(CONFIG_MACH_Q1_BD)
+#include "gpio-q1.h"
+#endif
+
+#if defined(CONFIG_MACH_P2)
+#include "gpio-p2.h"
+#endif
+
+#if defined(CONFIG_MACH_P4)
+#include "gpio-p4.h"
+#endif
+
+#if defined(CONFIG_MACH_P8)
+#include "gpio-p8.h"
+#endif
+
+#endif /* __ASM_ARCH_GPIO_EXYNOS4_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-exynos5.h b/arch/arm/mach-exynos/include/mach/gpio-exynos5.h
new file mode 100644
index 0000000..65aff87
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-exynos5.h
@@ -0,0 +1,201 @@
+/* linux/arch/arm/mach-exynos/include/mach/gpio-exynos5.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - GPIO common lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_EXYNOS5_H
+#define __ASM_ARCH_GPIO_EXYNOS5_H __FILE__
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
+
+/* Common GPIO bank sizes */
+#define EXYNOS5_GPIO_A0_NR (8)
+#define EXYNOS5_GPIO_A1_NR (6)
+#define EXYNOS5_GPIO_A2_NR (8)
+#define EXYNOS5_GPIO_B0_NR (5)
+#define EXYNOS5_GPIO_B1_NR (5)
+#define EXYNOS5_GPIO_B2_NR (4)
+#define EXYNOS5_GPIO_B3_NR (4)
+#define EXYNOS5_GPIO_C0_NR (7)
+#define EXYNOS5_GPIO_C1_NR (7)
+#define EXYNOS5_GPIO_C2_NR (7)
+#define EXYNOS5_GPIO_C3_NR (7)
+#define EXYNOS5_GPIO_C4_NR (8)
+#define EXYNOS5_GPIO_D0_NR (8)
+#define EXYNOS5_GPIO_D1_NR (8)
+#define EXYNOS5_GPIO_Y0_NR (6)
+#define EXYNOS5_GPIO_Y1_NR (4)
+#define EXYNOS5_GPIO_Y2_NR (6)
+#define EXYNOS5_GPIO_Y3_NR (8)
+#define EXYNOS5_GPIO_Y4_NR (8)
+#define EXYNOS5_GPIO_Y5_NR (8)
+#define EXYNOS5_GPIO_Y6_NR (8)
+#define EXYNOS5_GPIO_X0_NR (8)
+#define EXYNOS5_GPIO_X1_NR (8)
+#define EXYNOS5_GPIO_X2_NR (8)
+#define EXYNOS5_GPIO_X3_NR (8)
+#define EXYNOS5_GPIO_E0_NR (8)
+#define EXYNOS5_GPIO_E1_NR (2)
+#define EXYNOS5_GPIO_F0_NR (4)
+#define EXYNOS5_GPIO_F1_NR (4)
+#define EXYNOS5_GPIO_G0_NR (8)
+#define EXYNOS5_GPIO_G1_NR (8)
+#define EXYNOS5_GPIO_G2_NR (2)
+#define EXYNOS5_GPIO_H0_NR (4)
+#define EXYNOS5_GPIO_H1_NR (8)
+#define EXYNOS5_GPIO_V0_NR (8)
+#define EXYNOS5_GPIO_V1_NR (8)
+#define EXYNOS5_GPIO_V2_NR (8)
+#define EXYNOS5_GPIO_V3_NR (8)
+#define EXYNOS5_GPIO_V4_NR (2)
+#define EXYNOS5_GPIO_Z_NR (7)
+
+/* Only EXYNOS5210 GPIO bank sizes */
+#define EXYNOS5210_GPIO_J0_NR (5)
+#define EXYNOS5210_GPIO_J1_NR (8)
+#define EXYNOS5210_GPIO_J2_NR (8)
+#define EXYNOS5210_GPIO_J3_NR (8)
+#define EXYNOS5210_GPIO_J4_NR (2)
+#define EXYNOS5210_GPIO_K0_NR (8)
+#define EXYNOS5210_GPIO_K1_NR (8)
+#define EXYNOS5210_GPIO_K2_NR (8)
+#define EXYNOS5210_GPIO_K3_NR (7)
+
+/* GPIO bank numbers */
+
+#define EXYNOS5_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum exynos5_gpio_number {
+ EXYNOS5_GPIO_A0_START = 0,
+ EXYNOS5_GPIO_A1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_A0),
+ EXYNOS5_GPIO_A2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_A1),
+ EXYNOS5_GPIO_B0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_A2),
+ EXYNOS5_GPIO_B1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_B0),
+ EXYNOS5_GPIO_B2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_B1),
+ EXYNOS5_GPIO_B3_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_B2),
+ EXYNOS5_GPIO_C0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_B3),
+ EXYNOS5_GPIO_C1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_C0),
+ EXYNOS5_GPIO_C2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_C1),
+ EXYNOS5_GPIO_C3_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_C2),
+ EXYNOS5_GPIO_C4_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_C3),
+ EXYNOS5_GPIO_D0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_C4),
+ EXYNOS5_GPIO_D1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_D0),
+ EXYNOS5_GPIO_Y0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_D1),
+ EXYNOS5_GPIO_Y1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y0),
+ EXYNOS5_GPIO_Y2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y1),
+ EXYNOS5_GPIO_Y3_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y2),
+ EXYNOS5_GPIO_Y4_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y3),
+ EXYNOS5_GPIO_Y5_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y4),
+ EXYNOS5_GPIO_Y6_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y5),
+ EXYNOS5_GPIO_X0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Y6),
+ EXYNOS5_GPIO_X1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_X0),
+ EXYNOS5_GPIO_X2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_X1),
+ EXYNOS5_GPIO_X3_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_X2),
+ EXYNOS5_GPIO_E0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_X3),
+ EXYNOS5_GPIO_E1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_E0),
+ EXYNOS5_GPIO_F0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_E1),
+ EXYNOS5_GPIO_F1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_F0),
+ EXYNOS5_GPIO_G0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_F1),
+ EXYNOS5_GPIO_G1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_G0),
+ EXYNOS5_GPIO_G2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_G1),
+ EXYNOS5_GPIO_H0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_G2),
+ EXYNOS5_GPIO_H1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_H0),
+ EXYNOS5_GPIO_V0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_H1),
+ EXYNOS5_GPIO_V1_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_V0),
+ EXYNOS5_GPIO_V2_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_V1),
+ EXYNOS5_GPIO_V3_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_V2),
+ EXYNOS5_GPIO_V4_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_V3),
+ EXYNOS5_GPIO_Z_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_V4),
+};
+
+enum exynos5210_gpio_number {
+ EXYNOS5210_GPIO_J0_START = EXYNOS5_GPIO_NEXT(EXYNOS5_GPIO_Z),
+ EXYNOS5210_GPIO_J1_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_J0),
+ EXYNOS5210_GPIO_J2_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_J1),
+ EXYNOS5210_GPIO_J3_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_J2),
+ EXYNOS5210_GPIO_J4_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_J3),
+ EXYNOS5210_GPIO_K0_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_J4),
+ EXYNOS5210_GPIO_K1_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_K0),
+ EXYNOS5210_GPIO_K2_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_K1),
+ EXYNOS5210_GPIO_K3_START = EXYNOS5_GPIO_NEXT(EXYNOS5210_GPIO_K2),
+};
+
+/* EXYNOS5 GPIO number definitions */
+#define EXYNOS5_GPA0(_nr) (EXYNOS5_GPIO_A0_START + (_nr))
+#define EXYNOS5_GPA1(_nr) (EXYNOS5_GPIO_A1_START + (_nr))
+#define EXYNOS5_GPA2(_nr) (EXYNOS5_GPIO_A2_START + (_nr))
+#define EXYNOS5_GPB0(_nr) (EXYNOS5_GPIO_B0_START + (_nr))
+#define EXYNOS5_GPB1(_nr) (EXYNOS5_GPIO_B1_START + (_nr))
+#define EXYNOS5_GPB2(_nr) (EXYNOS5_GPIO_B2_START + (_nr))
+#define EXYNOS5_GPB3(_nr) (EXYNOS5_GPIO_B3_START + (_nr))
+#define EXYNOS5_GPC0(_nr) (EXYNOS5_GPIO_C0_START + (_nr))
+#define EXYNOS5_GPC1(_nr) (EXYNOS5_GPIO_C1_START + (_nr))
+#define EXYNOS5_GPC2(_nr) (EXYNOS5_GPIO_C2_START + (_nr))
+#define EXYNOS5_GPC3(_nr) (EXYNOS5_GPIO_C3_START + (_nr))
+#define EXYNOS5_GPC4(_nr) (EXYNOS5_GPIO_C4_START + (_nr))
+#define EXYNOS5_GPD0(_nr) (EXYNOS5_GPIO_D0_START + (_nr))
+#define EXYNOS5_GPD1(_nr) (EXYNOS5_GPIO_D1_START + (_nr))
+#define EXYNOS5_GPY0(_nr) (EXYNOS5_GPIO_Y0_START + (_nr))
+#define EXYNOS5_GPY1(_nr) (EXYNOS5_GPIO_Y1_START + (_nr))
+#define EXYNOS5_GPY2(_nr) (EXYNOS5_GPIO_Y2_START + (_nr))
+#define EXYNOS5_GPY3(_nr) (EXYNOS5_GPIO_Y3_START + (_nr))
+#define EXYNOS5_GPY4(_nr) (EXYNOS5_GPIO_Y4_START + (_nr))
+#define EXYNOS5_GPY5(_nr) (EXYNOS5_GPIO_Y5_START + (_nr))
+#define EXYNOS5_GPY6(_nr) (EXYNOS5_GPIO_Y6_START + (_nr))
+#define EXYNOS5_GPX0(_nr) (EXYNOS5_GPIO_X0_START + (_nr))
+#define EXYNOS5_GPX1(_nr) (EXYNOS5_GPIO_X1_START + (_nr))
+#define EXYNOS5_GPX2(_nr) (EXYNOS5_GPIO_X2_START + (_nr))
+#define EXYNOS5_GPX3(_nr) (EXYNOS5_GPIO_X3_START + (_nr))
+#define EXYNOS5_GPE0(_nr) (EXYNOS5_GPIO_E0_START + (_nr))
+#define EXYNOS5_GPE1(_nr) (EXYNOS5_GPIO_E1_START + (_nr))
+#define EXYNOS5_GPF0(_nr) (EXYNOS5_GPIO_F0_START + (_nr))
+#define EXYNOS5_GPF1(_nr) (EXYNOS5_GPIO_F1_START + (_nr))
+#define EXYNOS5_GPG0(_nr) (EXYNOS5_GPIO_G0_START + (_nr))
+#define EXYNOS5_GPG1(_nr) (EXYNOS5_GPIO_G1_START + (_nr))
+#define EXYNOS5_GPG2(_nr) (EXYNOS5_GPIO_G2_START + (_nr))
+#define EXYNOS5_GPH0(_nr) (EXYNOS5_GPIO_H0_START + (_nr))
+#define EXYNOS5_GPH1(_nr) (EXYNOS5_GPIO_H1_START + (_nr))
+#define EXYNOS5_GPV0(_nr) (EXYNOS5_GPIO_V0_START + (_nr))
+#define EXYNOS5_GPV1(_nr) (EXYNOS5_GPIO_V1_START + (_nr))
+#define EXYNOS5_GPV2(_nr) (EXYNOS5_GPIO_V2_START + (_nr))
+#define EXYNOS5_GPV3(_nr) (EXYNOS5_GPIO_V3_START + (_nr))
+#define EXYNOS5_GPV4(_nr) (EXYNOS5_GPIO_V4_START + (_nr))
+#define EXYNOS5_GPZ(_nr) (EXYNOS5_GPIO_Z_START + (_nr))
+
+/* EXYNOS5210 GPIO number definitions */
+#define EXYNOS5210_GPJ0(_nr) (EXYNOS5210_GPIO_J0_START + (_nr))
+#define EXYNOS5210_GPJ1(_nr) (EXYNOS5210_GPIO_J1_START + (_nr))
+#define EXYNOS5210_GPJ2(_nr) (EXYNOS5210_GPIO_J2_START + (_nr))
+#define EXYNOS5210_GPJ3(_nr) (EXYNOS5210_GPIO_J3_START + (_nr))
+#define EXYNOS5210_GPJ4(_nr) (EXYNOS5210_GPIO_J4_START + (_nr))
+#define EXYNOS5210_GPK0(_nr) (EXYNOS5210_GPIO_K0_START + (_nr))
+#define EXYNOS5210_GPK1(_nr) (EXYNOS5210_GPIO_K1_START + (_nr))
+#define EXYNOS5210_GPK2(_nr) (EXYNOS5210_GPIO_K2_START + (_nr))
+#define EXYNOS5210_GPK3(_nr) (EXYNOS5210_GPIO_K3_START + (_nr))
+
+/* the end of the EXYNOS5 specific gpios */
+#define EXYNOS5210_GPIO_END (EXYNOS5210_GPK3(EXYNOS5210_GPIO_K3_NR) + 1)
+#define EXYNOS5250_GPIO_END (EXYNOS5_GPZ(EXYNOS5_GPIO_Z_NR) + 1)
+
+#define EXYNOS5XXX_GPIO_END (EXYNOS5210_GPIO_END > EXYNOS5250_GPIO_END ? \
+ EXYNOS5210_GPIO_END : EXYNOS5250_GPIO_END)
+#define EXYNOS5_GPIO_END EXYNOS5XXX_GPIO_END
+
+#if defined(CONFIG_MACH_P10)
+#include "gpio-p10.h"
+#endif
+
+#endif /* __ASM_ARCH_GPIO_EXYNOS5_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-midas.h b/arch/arm/mach-exynos/include/mach/gpio-midas.h
new file mode 100644
index 0000000..894c1cf
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-midas.h
@@ -0,0 +1,52 @@
+/* linux/arch/arm/mach-exynos/include/mach/gpio-midas.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - MIDAS GPIO lib
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_MIDAS_H
+#define __ASM_ARCH_GPIO_MIDAS_H __FILE__
+
+#if defined(CONFIG_MACH_MIDAS_01_BD) || defined(CONFIG_GPIO_MIDAS_01_BD)
+#include "gpio-rev01-midas.h"
+#elif defined(CONFIG_MACH_MIDAS_02_BD) || defined(CONFIG_GPIO_MIDAS_02_BD)
+#include "gpio-rev02-midas.h"
+#elif defined(CONFIG_MACH_M0_GRANDECTC)
+#include "gpio-rev00-m0grandectc.h"
+#elif defined(CONFIG_MACH_M0_CTC)
+#include "gpio-rev00-m0ctc.h"
+#elif defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ)
+#include "gpio-rev00-m0.h"
+#elif defined(CONFIG_MACH_M3)
+#include "gpio-rev00-m3.h"
+#elif defined(CONFIG_MACH_C1) && !defined(CONFIG_TARGET_LOCALE_KOR)
+#include "gpio-rev00-c1.h"
+#elif defined(CONFIG_MACH_C1CTC)
+#include "gpio-rev00-c1ctc.h"
+#elif (defined(CONFIG_MACH_C1VZW) || defined(CONFIG_MACH_SLP_PQ_LTE)) && \
+ !defined(CONFIG_TARGET_LOCALE_KOR)
+#include "gpio-rev00-c1vzw.h"
+#elif defined(CONFIG_MACH_JENGA)
+#include "gpio-rev00-jenga.h"
+#elif defined(CONFIG_MACH_S2PLUS)
+#include "gpio-rev00-s2plus.h"
+#elif defined(CONFIG_GPIO_NAPLES_00_BD)
+#include "gpio-rev00-naples.h"
+#elif (defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)) && \
+ defined(CONFIG_TARGET_LOCALE_KOR)
+#include "gpio-rev03-c1kor.h"
+#elif defined(CONFIG_MACH_P4NOTE)
+#include "gpio-rev00-p4notepq.h"
+#elif defined(CONFIG_MACH_GC1)
+#include "gpio-rev00-gc1.h"
+#elif defined(CONFIG_MACH_T0)
+#include "gpio-rev00-t0.h"
+#endif
+
+#endif /* __ASM_ARCH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-naples.h b/arch/arm/mach-exynos/include/mach/gpio-naples.h
new file mode 100644
index 0000000..bed9ee9
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-naples.h
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-exynos/include/mach/gpio-naples.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - MIDAS GPIO lib
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_NAPLES_H
+#define __ASM_ARCH_GPIO_NAPLES_H __FILE__
+
+#if defined(CONFIG_GPIO_NAPLES_00_BD)
+#include "gpio-rev00-naples.h"
+#endif
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+#endif /* __ASM_ARCH_GPIO_NAPLES_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-p10.h b/arch/arm/mach-exynos/include/mach/gpio-p10.h
new file mode 100644
index 0000000..3674faa
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-p10.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-exynos/include/mach/gpio-midas.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - MIDAS GPIO lib
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_P10_H
+#define __ASM_ARCH_GPIO_P10_H __FILE__
+
+#if defined(CONFIG_MACH_P10_00_BD)
+#include "gpio-rev00-p10.h"
+#elif defined(CONFIG_MACH_P10_LTE_00_BD)
+#include "gpio-rev00-p10-lte.h"
+#elif defined(CONFIG_MACH_P10_WIFI_00_BD)
+#include "gpio-rev00-p10-wifi.h"
+#elif defined(CONFIG_MACH_P10_LUNGO_01_BD)
+#include "gpio-rev01-p10-lungo.h"
+#elif defined(CONFIG_MACH_P10_LUNGO_WIFI_01_BD)
+#include "gpio-rev01-p10-lungo-wifi.h"
+#endif
+
+#endif /* __ASM_ARCH_GPIO_P10_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-p2.h b/arch/arm/mach-exynos/include/mach/gpio-p2.h
new file mode 100644
index 0000000..986bed3
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-p2.h
@@ -0,0 +1,242 @@
+#ifndef __MACH_GPIO_P2_H
+#define __MACH_GPIO_P2_H __FILE__
+
+#define GPIO_XMMC0_CDn EXYNOS4_GPK0(2)
+
+#define GPIO_PS_ALS_SDA EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_SCL EXYNOS4_GPK3(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_PS_VOUT EXYNOS4_GPL0(6)
+#define GPIO_PS_VOUT_WAKE EXYNOS4_GPX0(1)
+
+#define GPIO_BUCK1_EN_A EXYNOS4_GPX0(5)
+#define GPIO_BUCK1_EN_B EXYNOS4_GPX0(6)
+#define GPIO_BUCK2_EN EXYNOS4_GPL0(0)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+#define VT_CAM_SDA_18V EXYNOS4_GPC1(0)
+#define VT_CAM_SCL_18V EXYNOS4_GPC1(2)
+
+#define CODEC_VT_SDA_18V EXYNOS4_GPC1(3)
+#define CODEC_VT_SCL_18V EXYNOS4_GPC1(4)
+
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_MASSMEM_EN_LEVEL 0
+
+#define GPIO_CAM_MOVIE_EN EXYNOS4_GPL0(1)
+#define GPIO_CAM_FLASH_EN EXYNOS4_GPL0(2)
+#define GPIO_CAM_FLASH_SET EXYNOS4_GPE0(2)
+
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+#define GPIO_TSP_RST EXYNOS4_GPL0(5)
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+#define GPIO_TSP_SDA EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL EXYNOS4_GPA1(3)
+#define GPIO_TSP_VENDOR1 EXYNOS4_GPY5(6)
+#define GPIO_TSP_VENDOR2 EXYNOS4_GPY5(7)
+
+
+
+#define GPIO_LCD_EN EXYNOS4_GPL0(7)
+#define GPIO_LCD_LDO_EN EXYNOS4_GPK1(1)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+
+#define GPIO_CAM_PCLK EXYNOS4_GPJ0(0)
+#define GPIO_CAM_VSYNC EXYNOS4_GPJ0(1)
+#define GPIO_CAM_HSYNC EXYNOS4_GPJ0(2)
+
+#define GPIO_CAM_MCLK EXYNOS4210_GPJ1(3)
+
+#define GPIO_2M_nSTBY EXYNOS4_GPL2(0)
+#define GPIO_2M_nRST EXYNOS4_GPL2(1)
+#define GPIO_3M_nSTBY EXYNOS4_GPL2(2)
+#define GPIO_3M_nRST EXYNOS4_GPL2(7)
+
+#define GPIO_DET_35 EXYNOS4_GPX3(2)
+#define GPIO_DET_35_AF 0xF
+
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_EAR_SEND_END_AF 0xF
+
+#define GPIO_GPS_nRST EXYNOS4_GPY5(4)
+#define GPIO_GPS_nRST_28V EXYNOS4_GPL0(3)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPY5(5)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_ALC_nRST EXYNOS4_GPX1(7)
+
+#define GPIO_DOUBLE_RR EXYNOS4_GPL2(3)
+/*#define GPIO_2MIC_EN EXYNOS4_GPL2(5)*/
+
+#define GPIO_CURR_ADJ EXYNOS4_GPE2(1)
+#define GPIO_TA_EN EXYNOS4_GPY6(6)
+#define GPIO_TA_nCHG EXYNOS4_GPL2(4)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPX3(5)
+#define GPIO_CHG_SDA EXYNOS4_GPB(2)
+#define GPIO_CHG_SCL EXYNOS4_GPB(3)
+
+#define GPIO_IPC_RXD EXYNOS4_GPA1(4)
+#define GPIO_IPC_RXD_AF 2
+
+#define GPIO_IPC_TXD EXYNOS4_GPA1(5)
+#define GPIO_IPC_TXD_AF 2
+
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_CP_RST EXYNOS4_GPX1(4)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPY4(6)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(3)
+#define GPIO_LVDS_NSHDN EXYNOS4_GPX1(5)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_SUSPEND_REQUEST IRQ_EINT11
+#define IRQ_IPC_HOST_WAKEUP IRQ_EINT9
+
+#define EXYNOS4_GPD_0_0_TOUT_0 (0x2 << 0)
+#if defined(CONFIG_FB_MDNIE_PWM)
+#define EXYNOS4_GPD_0_1_TOUT_1 (0x3 << 4)
+#else
+#define EXYNOS4_GPD_0_1_TOUT_1 (0x2 << 4)
+#endif
+#define EXYNOS4_GPD_0_2_TOUT_2 (0x2 << 8)
+#define EXYNOS4_GPD_0_3_TOUT_3 (0x2 << 12)
+
+#define GPIO_WLAN_EN EXYNOS4_GPL1(2)
+#define GPIO_WLAN_EN2 EXYNOS4_GPL0(6)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_nRST EXYNOS4_GPL0(4)
+
+/* CSR8811 Project(Alan.Ko) 2011.07.02 */
+/*#define GPIO_BT_EN EXYNOS4_GPL0(4)*/
+/* CSR8811 Project(Alan.Ko) end */
+
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_BT_HOST_WAKE_AF 0xF
+
+/* CSR8811 Project(Alan.Ko) 2011.07.02 */
+/*#define GPIO_BT_WAKE EXYNOS4_GPX3(1)*/
+/* CSR8811 Project(Alan.Ko) end */
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_HW_REV0 EXYNOS4_GPE1(0)
+#define GPIO_HW_REV1 EXYNOS4_GPE1(1)
+#define GPIO_HW_REV2 EXYNOS4_GPE1(2)
+#define GPIO_HW_REV3 EXYNOS4_GPE1(3)
+
+#define GPIO_HDMI_EN1 EXYNOS4_GPL1(1)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP_AF S3C_GPIO_SFN(0xF)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_SIM_DETECT EXYNOS4_GPX0(3)
+
+#define GPIO_MSENSE_INT EXYNOS4_GPX2(2)
+#define GPIO_DOCK_INT EXYNOS4_GPX2(4)
+
+#define GPIO_IRDA_CONTROL EXYNOS4_GPX3(0)
+#define GPIO_USB_OTG_EN EXYNOS4_GPX3(3)
+#define GPIO_USB_SEL1 EXYNOS4_GPY3(4)
+#define GPIO_USB_SEL2 EXYNOS4_GPY3(7)
+#define GPIO_USB_SEL3 EXYNOS4_GPY4(5)
+#define GPIO_IF_CON_SENSE EXYNOS4_GPY4(3)
+
+#define GPIO_MSENSOR_MHL_SDA_28V EXYNOS4_GPD0(2)
+#define GPIO_MSENSOR_MHL_SDA_AF 0x3
+#define GPIO_MSENSOR_MHL_SCL_28V EXYNOS4_GPD0(3)
+#define GPIO_MSENSOR_MHL_SCL_AF 0x3
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_SDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_SDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_SCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_SCL_AF
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPY6(7)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4_GPL2(6)
+
+#define GPIO_TDMB_EN EXYNOS4_GPC0(1)
+#define GPIO_TDMB_RST_N EXYNOS4_GPB(5)
+#define GPIO_TDMB_INT EXYNOS4_GPB(4)
+#define GPIO_TDMB_INT_AF 0xf
+
+#define GPIO_PEN_SDA_28V EXYNOS4_GPB(2)
+#define GPIO_PEN_SCL_28V EXYNOS4_GPB(3)
+#define GPIO_PEN_LDO_EN EXYNOS4_GPE0(1)
+#define GPIO_PEN_PDCT_18V EXYNOS4_GPE1(6)
+#define GPIO_PEN_SLP_18V EXYNOS4_GPE1(7)
+#define GPIO_PEN_IRQ_18V EXYNOS4_GPE2(0)
+
+#define GPIO_REMOTE_SENSE_IRQ EXYNOS4_GPE1(5)
+
+#define GPIO_ACCESSORY_EN EXYNOS4_GPY6(1)
+#define GPIO_ACCESSORY_INT EXYNOS4_GPX1(7)
+#define GPIO_ACCESSORY_OUT_5V EXYNOS4_GPY4(4)
+
+#endif /* __MACH_GPIO_P2_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-p4.h b/arch/arm/mach-exynos/include/mach/gpio-p4.h
new file mode 100644
index 0000000..654f742
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-p4.h
@@ -0,0 +1,233 @@
+#ifndef __MACH_GPIO_P4_H
+#define __MACH_GPIO_P4_H __FILE__
+
+#define GPIO_XMMC0_CDn EXYNOS4_GPK0(2)
+
+#define GPIO_PS_ALS_SDA EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_SCL EXYNOS4_GPK3(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_PS_VOUT EXYNOS4_GPL0(6)
+#define GPIO_PS_VOUT_WAKE EXYNOS4_GPX0(1)
+
+#define GPIO_BUCK1_EN_A EXYNOS4_GPX0(5)
+#define GPIO_BUCK1_EN_B EXYNOS4_GPX0(6)
+#define GPIO_BUCK2_EN EXYNOS4_GPL0(0)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(1)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(0)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+#define VT_CAM_SDA_18V EXYNOS4_GPC1(0)
+#define VT_CAM_SCL_18V EXYNOS4_GPC1(2)
+
+#define CODEC_VT_SDA_18V EXYNOS4_GPC1(3)
+#define CODEC_VT_SCL_18V EXYNOS4_GPC1(4)
+
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_MASSMEM_EN_LEVEL 0
+
+#define GPIO_CAM_MOVIE_EN EXYNOS4_GPL0(1)
+#define GPIO_CAM_FLASH_EN EXYNOS4_GPL0(2)
+#define GPIO_CAM_FLASH_SET EXYNOS4210210_GPE0(2)
+
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+#define GPIO_TSP_RST EXYNOS4_GPL0(5)
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+
+#define GPIO_LCD_EN EXYNOS4_GPL0(7)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS4_GPK1(1)
+
+#define GPIO_CAM_PCLK EXYNOS4210_GPJ0(0)
+#define GPIO_CAM_VSYNC EXYNOS4210_GPJ0(1)
+#define GPIO_CAM_HSYNC EXYNOS4210_GPJ0(2)
+
+#define GPIO_CAM_MCLK EXYNOS4210_GPJ1(3)
+
+#define GPIO_2M_nSTBY EXYNOS4_GPL2(0)
+#define GPIO_2M_nRST EXYNOS4_GPL2(1)
+#define GPIO_3M_nSTBY EXYNOS4_GPL2(2)
+#define GPIO_3M_nRST EXYNOS4_GPL2(7)
+
+#define GPIO_DET_35 EXYNOS4_GPX3(2)
+#define GPIO_DET_35_AF 0xF
+
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_EAR_SEND_END_AF 0xF
+
+#define GPIO_GPS_nRST EXYNOS4_GPY5(4)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPY5(5)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_ALC_nRST EXYNOS4_GPX1(7)
+
+#define GPIO_DOUBLE_RR EXYNOS4_GPL2(3)
+/* #define GPIO_2MIC_EN EXYNOS4_GPL2(5) */
+
+#define GPIO_CURR_ADJ EXYNOS4_GPY5(7)
+#define GPIO_TA_EN EXYNOS4_GPY6(6)
+#define GPIO_TA_nCHG EXYNOS4_GPL2(4)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPX3(5)
+
+/* Charger I2C for H/W rev02 */
+#define GPIO_CHG_SDA EXYNOS4_GPC1(2)
+#define GPIO_CHG_SCL EXYNOS4_GPC1(0)
+
+#define GPIO_IPC_RXD EXYNOS4_GPA1(4)
+#define GPIO_IPC_RXD_AF 2
+
+#define GPIO_IPC_TXD EXYNOS4_GPA1(5)
+#define GPIO_IPC_TXD_AF 2
+
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_CP_RST EXYNOS4_GPX1(4)
+#define GPIO_CP_PMU_RST EXYNOS4_GPX1(4)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPY4(6)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(3)
+#define GPIO_LVDS_NSHDN EXYNOS4_GPX1(5)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_SUSPEND_REQUEST IRQ_EINT11
+#define IRQ_IPC_HOST_WAKEUP IRQ_EINT9
+
+#define EXYNOS4_GPD_0_0_TOUT_0 (0x2 << 0)
+#if defined(CONFIG_FB_MDNIE_PWM)
+#define EXYNOS4_GPD_0_1_TOUT_1 (0x3 << 4)
+#else
+#define EXYNOS4_GPD_0_1_TOUT_1 (0x2 << 4)
+#endif
+#define EXYNOS4_GPD_0_2_TOUT_2 (0x2 << 8)
+#define EXYNOS4_GPD_0_3_TOUT_3 (0x2 << 12)
+
+#define GPIO_WLAN_EN EXYNOS4_GPL1(2)
+#define GPIO_WLAN_EN2 EXYNOS4_GPL0(6)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_nRST EXYNOS4_GPL0(4)
+
+//#define GPIO_BT_EN EXYNOS4_GPL0(4)
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_BT_HOST_WAKE_AF 0xF
+
+//#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_HW_REV0 EXYNOS4210_GPE1(0)
+#define GPIO_HW_REV1 EXYNOS4210_GPE1(1)
+#define GPIO_HW_REV2 EXYNOS4210_GPE1(2)
+#define GPIO_HW_REV3 EXYNOS4210_GPE1(3)
+
+#define GPIO_HDMI_EN1 EXYNOS4_GPL1(1)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP_AF S3C_GPIO_SFN(0xF)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_MSENSE_INT EXYNOS4_GPX2(2)
+#define GPIO_DOCK_INT EXYNOS4_GPX2(4)
+
+#define GPIO_IRDA_CONTROL EXYNOS4_GPX3(0)
+#define GPIO_USB_OTG_EN EXYNOS4_GPX3(3)
+#define GPIO_USB_SEL1 EXYNOS4_GPY3(4)
+#define GPIO_USB_SEL2 EXYNOS4_GPY3(7)
+#define GPIO_USB_SEL3 EXYNOS4_GPY4(5)
+#define GPIO_IF_CON_SENSE EXYNOS4_GPY4(3)
+
+#define GPIO_MSENSOR_MHL_SDA_28V EXYNOS4_GPD0(2)
+#define GPIO_MSENSOR_MHL_SDA_AF 0x3
+#define GPIO_MSENSOR_MHL_SCL_28V EXYNOS4_GPD0(3)
+#define GPIO_MSENSOR_MHL_SCL_AF 0x3
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_SDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_SDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_SCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_SCL_AF
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPY6(7)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4_GPL2(6)
+
+#define GPIO_TDMB_EN EXYNOS4_GPC0(1)
+#define GPIO_TDMB_RST_N EXYNOS4_GPB(5)
+#define GPIO_TDMB_INT EXYNOS4_GPB(4)
+#define GPIO_TDMB_INT_AF 0xf
+
+#define GPIO_PEN_SDA_28V EXYNOS4_GPB(2)
+#define GPIO_PEN_SCL_28V EXYNOS4_GPB(3)
+#define GPIO_PEN_LDO_EN EXYNOS4_GPY6(0)
+#define GPIO_PEN_PDCT_18V EXYNOS4_GPY6(4)
+#define GPIO_PEN_SLP_18V EXYNOS4_GPY6(5)
+#define GPIO_PEN_IRQ_18V EXYNOS4_GPL2(5)
+
+#define GPIO_REMOTE_SENSE_IRQ EXYNOS4_GPX0(2)
+
+#define GPIO_ACCESSORY_EN EXYNOS4_GPY6(1)
+#define GPIO_ACCESSORY_INT EXYNOS4_GPX1(7)
+#define GPIO_ACCESSORY_OUT_5V EXYNOS4_GPY4(4)
+
+#define GPIO_SIM_DETECT EXYNOS4_GPX0(3)
+#endif /* __MACH_GPIO_P4_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-p8.h b/arch/arm/mach-exynos/include/mach/gpio-p8.h
new file mode 100644
index 0000000..b6e67b4
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-p8.h
@@ -0,0 +1,233 @@
+#ifndef __MACH_GPIO_P8_H
+#define __MACH_GPIO_P8_H __FILE__
+
+#define GPIO_XMMC0_CDn EXYNOS4_GPK0(2)
+
+#define GPIO_PS_ALS_SDA EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_SCL EXYNOS4_GPK3(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_PS_VOUT EXYNOS4_GPL0(6)
+#define GPIO_PS_VOUT_WAKE EXYNOS4_GPX0(1)
+
+#define GPIO_BUCK1_EN_A EXYNOS4_GPX0(5)
+#define GPIO_BUCK1_EN_B EXYNOS4_GPX0(6)
+#define GPIO_BUCK2_EN EXYNOS4_GPL0(0)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+/* #define VT_CAM_SDA_18V EXYNOS4_GPC1(0) */
+/* #define VT_CAM_SCL_18V EXYNOS4_GPC1(2) */
+
+#define CODEC_VT_SDA_18V EXYNOS4_GPC1(3)
+#define CODEC_VT_SCL_18V EXYNOS4_GPC1(4)
+
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_MASSMEM_EN_LEVEL 0
+
+#define GPIO_CAM_MOVIE_EN EXYNOS4_GPL0(1)
+#define GPIO_CAM_FLASH_EN EXYNOS4_GPL0(2)
+/* #define GPIO_CAM_FLASH_SET EXYNOS4_GPE0(2) */
+
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+/* #define GPIO_TSP_RST EXYNOS4_GPL0(5) */
+/* #define GPIO_TSP_INT EXYNOS4_GPX0(4) */
+#define GPIO_TSP_SDA EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL EXYNOS4_GPA1(3)
+#define GPIO_TSP_VENDOR EXYNOS4_GPY5(6)
+#define GPIO_TSP_INT_18V EXYNOS4_GPX1(5)
+
+#define GPIO_LCD_RST EXYNOS4_GPF0(1)
+#define GPIO_LCD_EN EXYNOS4_GPL0(7)
+#define GPIO_LCD_LDO_EN EXYNOS4_GPK1(1)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+
+/* #define GPIO_CAM_PCLK EXYNOS4_GPJ0(0) */
+/* #define GPIO_CAM_VSYNC EXYNOS4_GPJ0(1) */
+/* #define GPIO_CAM_HSYNC EXYNOS4_GPJ0(2) */
+
+#define GPIO_CAM_MCLK EXYNOS4210_GPJ1(3)
+#define GPIO_CAM_AVDD_EN EXYNOS4210_GPJ1(4)
+
+#define GPIO_2M_nSTBY EXYNOS4_GPL2(0)
+#define GPIO_2M_nRST EXYNOS4_GPL2(1)
+#define GPIO_3M_nSTBY EXYNOS4_GPL2(2)
+#define GPIO_3M_nRST EXYNOS4_GPL2(7)
+
+#define GPIO_DET_35 EXYNOS4_GPX3(2)
+#define GPIO_DET_35_AF 0xF
+
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_EAR_SEND_END_AF 0xF
+
+#define GPIO_GPS_nRST EXYNOS4_GPY5(4)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPY5(5)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+/* #define GPIO_ALC_nRST EXYNOS4_GPX1(7) */
+
+#define GPIO_DOUBLE_RR EXYNOS4_GPL2(3)
+/* #define GPIO_2MIC_EN EXYNOS4_GPL2(5) */
+
+#define GPIO_CURR_ADJ EXYNOS4_GPY5(7)
+#define GPIO_TA_EN EXYNOS4_GPY6(6)
+#define GPIO_TA_nCHG EXYNOS4_GPX0(4)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPX3(5)
+
+/* #define GPIO_CHG_SDA_28V EXYNOS4_GPB(2) */
+/* #define GPIO_CHG_SCL_28V EXYNOS4_GPB(3) */
+
+#define GPIO_IPC_RXD EXYNOS4_GPA1(4)
+#define GPIO_IPC_RXD_AF 2
+
+#define GPIO_IPC_TXD EXYNOS4_GPA1(5)
+#define GPIO_IPC_TXD_AF 2
+
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_CP_RST EXYNOS4_GPX1(4)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPY4(6)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(3)
+/* #define GPIO_LVDS_NSHDN EXYNOS4_GPX1(5) */
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_SUSPEND_REQUEST IRQ_EINT11
+#define IRQ_IPC_HOST_WAKEUP IRQ_EINT9
+
+#define EXYNOS4_GPD_0_0_TOUT_0 (0x2 << 0)
+#define EXYNOS4_GPD_0_1_TOUT_1 (0x2 << 4)
+#define EXYNOS4_GPD_0_2_TOUT_2 (0x2 << 8)
+#define EXYNOS4_GPD_0_3_TOUT_3 (0x2 << 12)
+
+#define GPIO_WLAN_EN EXYNOS4_GPL1(2)
+#define GPIO_WLAN_EN2 EXYNOS4_GPL0(6)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_nRST EXYNOS4_GPL0(4)
+
+/* CSR8811 Project(Alan.Ko) 2011.07.02 */
+/* #define GPIO_BT_EN EXYNOS4_GPL0(4) */
+/* CSR8811 Project(Alan.Ko) end */
+
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_BT_HOST_WAKE_AF 0xF
+
+/* CSR8811 Project(Alan.Ko) 2011.07.02 */
+/* #define GPIO_BT_WAKE EXYNOS4_GPX3(1) */
+/* CSR8811 Project(Alan.Ko) end */
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_HW_REV0 EXYNOS4_GPY5(0)
+#define GPIO_HW_REV1 EXYNOS4_GPY5(1)
+#define GPIO_HW_REV2 EXYNOS4_GPY5(2)
+#define GPIO_HW_REV3 EXYNOS4_GPY5(3)
+
+#define GPIO_HDMI_EN1 EXYNOS4_GPL1(1)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP_AF S3C_GPIO_SFN(0xF)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_SIM_DETECT EXYNOS4_GPX0(3)
+
+#define GPIO_MSENSE_INT EXYNOS4_GPX2(2)
+#define GPIO_DOCK_INT EXYNOS4_GPX2(4)
+
+/* IRDA */
+#define GPIO_IRDA_EN EXYNOS4_GPX3(0)
+#define GPIO_IRDA_nINT EXYNOS4_GPB(4)
+#define GPIO_IRDA_nRST EXYNOS4_GPB(5)
+#define GPIO_IRDA_SCL_28V EXYNOS4_GPK1(0)
+#define GPIO_IRDA_SDA_28V EXYNOS4_GPK1(2)
+
+#define GPIO_USB_OTG_EN EXYNOS4_GPX3(3)
+#define GPIO_USB_SEL1 EXYNOS4_GPY3(4)
+#define GPIO_USB_SEL2 EXYNOS4_GPY3(7)
+#define GPIO_USB_SEL3 EXYNOS4_GPY4(5)
+#define GPIO_IF_CON_SENSE EXYNOS4_GPY4(3)
+
+#define GPIO_MSENSOR_MHL_SDA_28V EXYNOS4_GPD0(2)
+#define GPIO_MSENSOR_MHL_SDA_AF 0x3
+#define GPIO_MSENSOR_MHL_SCL_28V EXYNOS4_GPD0(3)
+#define GPIO_MSENSOR_MHL_SCL_AF 0x3
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_SDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_SDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_SCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_SCL_AF
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+/* #define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP) */
+
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPY6(7)
+#define GPIO_MAIN_MIC_BIAS_EN EXYNOS4_GPC0(1)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4_GPL2(6)
+
+#define GPIO_REMOTE_SENSE_IRQ EXYNOS4_GPX0(2)
+
+#define GPIO_ACCESSORY_EN EXYNOS4_GPY6(1)
+#define GPIO_ACCESSORY_INT EXYNOS4_GPX1(7)
+#define GPIO_ACCESSORY_OUT_5V EXYNOS4_GPY4(4)
+
+#endif /* __MACH_GPIO_P8_REV01_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-q1.h b/arch/arm/mach-exynos/include/mach/gpio-q1.h
new file mode 100644
index 0000000..1119d0b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-q1.h
@@ -0,0 +1,296 @@
+#ifndef __MACH_GPIO_Q1_H
+#define __MACH_GPIO_Q1_H __FILE__
+
+#if defined(CONFIG_MACH_Q1_BD)
+
+#define GPIO_OLED_DET EXYNOS4_GPL0(7)
+
+#define GPIO_XMMC0_CDn EXYNOS4_GPK0(2)
+
+#define GPIO_PS_ALS_SDA EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_SCL EXYNOS4_GPK3(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_GYRO_FIFOP_INT EXYNOS4_GPX0(1)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_BUCK1_EN_A EXYNOS4_GPX0(5)
+#define GPIO_BUCK1_EN_B EXYNOS4_GPX0(6)
+#define GPIO_BUCK2_EN EXYNOS4_GPL0(0)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define VT_CAM_SDA_18V EXYNOS4_GPC1(0)
+#define VT_CAM_SCL_18V EXYNOS4_GPC1(2)
+
+#define CODEC_VT_SDA_18V EXYNOS4_GPC1(3)
+#define CODEC_VT_SCL_18V EXYNOS4_GPC1(4)
+
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_USB_SDA EXYNOS4210_GPE1(0)
+#define GPIO_USB_SCL EXYNOS4210_GPE1(1)
+#define GPIO_MASSMEM_EN EXYNOS4_GPL1(1)
+#define GPIO_MASSMEM_EN_LEVEL 0
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+#define GPIO_TSP_SDA EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL EXYNOS4_GPA1(3)
+
+#define GPIO_CAM_IO_EN EXYNOS4210_GPE2(1)
+#define GPIO_CAM_SENSOR_CORE EXYNOS4210_GPE2(5)
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+
+#define GPIO_LCD_EN EXYNOS4_GPY3(1)
+#define GPIO_MLCD_RST EXYNOS4_GPY4(5)
+
+#define GPIO_USB_SEL EXYNOS4_GPL0(6)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPK1(0)
+#define GPIO_8M_AF_EN EXYNOS4_GPK1(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPK1(2)
+#define GPIO_3_TOUCH_INT EXYNOS4_GPL0(5)
+
+#define GPIO_VT_CAM_15V EXYNOS4210_GPE2(2)
+
+#define GPIO_CAM_MCLK EXYNOS4210_GPJ1(3)
+
+#define GPIO_CAM_VGA_nSTBY EXYNOS4_GPL2(0)
+#define GPIO_CAM_VGA_nRST EXYNOS4_GPL2(1)
+
+#define GPIO_DET_35 EXYNOS4_GPX3(2)
+#define GPIO_DET_35_AF 0xF
+
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_EAR_SEND_END_AF 0xF
+
+#define GPIO_GPS_PWR_EN EXYNOS4210_GPE0(3)
+#define GPIO_GPS_nRST EXYNOS4210_GPE0(4)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_NFC_SCL EXYNOS4_GPY0(0)
+#define GPIO_NFC_SDA EXYNOS4_GPY0(1)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRM EXYNOS4_GPL2(7)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+
+#define GPIO_2MIC_PWDN EXYNOS4_GPL2(3)
+#define GPIO_2MIC_RST EXYNOS4_GPL2(4)
+#define GPIO_2MIC_EN EXYNOS4_GPL2(5)
+
+#ifdef CONFIG_CHARGER_MAX8922_U1 /* sub-charger */
+#define GPIO_CHG_EN EXYNOS4_GPL2(2)
+#define GPIO_CHG_ING_N EXYNOS4_GPL2(4)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPL2(5)
+#endif
+
+#ifdef CONFIG_SMB136_CHARGER_Q1 /* sub-charger */
+#define GPIO_CHG_SDA EXYNOS4_GPY0(4)
+#define GPIO_CHG_SCL EXYNOS4_GPY0(5)
+#define GPIO_CHG_EN EXYNOS4_GPL2(2)
+#define GPIO_OTG_EN EXYNOS4_GPX3(3)
+#define GPIO_CHG_ING_N EXYNOS4_GPL2(5)
+#endif
+
+#ifdef CONFIG_CHARGER_SMB328_Q1 /* sub-charger */
+#define GPIO_CHG_SDA EXYNOS4_GPY0(4)
+#define GPIO_CHG_SCL EXYNOS4_GPY0(5)
+#define GPIO_CHG_EN EXYNOS4_GPL2(2)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPL2(5)
+#endif
+
+#define GPIO_2MIC_SDA EXYNOS4_GPC1(2)
+#define GPIO_2MIC_SCL EXYNOS4_GPC1(0)
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+/* Modem Interface GPIOs - Q1 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_CP_RST EXYNOS4_GPX1(4)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPY4(6)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(3)
+#define GPIO_ISP_INT EXYNOS4_GPX1(5)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_SUSPEND_REQUEST IRQ_EINT11
+#define IRQ_IPC_HOST_WAKEUP IRQ_EINT9
+#else
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPY4(3)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPY3(3)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(4)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPY3(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPY4(4)
+/* not use (S5PV310_GPX1(1) => NC pin) */
+#define GPIO_CP_RST EXYNOS4_GPX1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPX1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(1)
+#define GPIO_ISP_INT EXYNOS4_GPX1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPX1(1)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT12
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_WLAN_EN EXYNOS4_GPL1(2)
+#define GPIO_WLAN_EN_AF 1
+
+#define GPIO_BT_EN EXYNOS4_GPL0(4)
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_BT_HOST_WAKE_AF 0xF
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_HW_REV0 EXYNOS4210_GPE1(0)
+#define GPIO_HW_REV1 EXYNOS4210_GPE1(1)
+#define GPIO_HW_REV2 EXYNOS4210_GPE1(2)
+#define GPIO_HW_REV3 EXYNOS4210_GPE1(3)
+
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4210_GPJ1(4)
+#define GPIO_MHL_WAKE_UP_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_SEL EXYNOS4_GPL0(1)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_MSENSE_INT EXYNOS4_GPX2(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL1(1)
+#define GPIO_HDMI_EN_REV07 EXYNOS4_GPL1(1)
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_ACC_INT EXYNOS4_GPX3(0)
+#define GPIO_USB_OTG_EN EXYNOS4_GPX3(3)
+
+#define GPIO_MSENSOR_MHL_SDA_28V EXYNOS4_GPD0(2)
+#define GPIO_MSENSOR_MHL_SDA_AF 0x3
+#define GPIO_MSENSOR_MHL_SCL_28V EXYNOS4_GPD0(3)
+#define GPIO_MSENSOR_MHL_SCL_AF 0x3
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_SDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_SDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_SCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_SCL_AF
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4210_GPE1(4)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4210_GPE2(0)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4210_GPE2(4)
+
+#define GPIO_TDMB_EN EXYNOS4_GPC0(1)
+#define GPIO_TDMB_RST_N EXYNOS4_GPB(5)
+#define GPIO_TDMB_INT EXYNOS4_GPB(4)
+#define GPIO_TDMB_INT_AF 0xf
+
+#if defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_FM_RST EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX2(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX2(4)
+#define GPIO_FM_SDA_28V EXYNOS4210_GPE2(3)
+#define GPIO_FM_SCL_28V EXYNOS4210_GPE1(5)
+#else
+#define GPIO_FM_RST EXYNOS4_GPB(0)
+#define GPIO_FM_INT EXYNOS4_GPX2(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX2(4)
+#define GPIO_FM_SDA_28V EXYNOS4_GPB(2)
+#define GPIO_FM_SCL_28V EXYNOS4_GPB(3)
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+#define GPIO_PEN_PDCT EXYNOS4210_GPE1(6)
+#define GPIO_PEN_SLP EXYNOS4210_GPE1(7)
+#define GPIO_PEN_IRQ EXYNOS4210_GPE0(0)
+#define GPIO_PEN_RESET EXYNOS4210_GPE0(2)
+#define GPIO_PEN_SDA_18V EXYNOS4_GPC1(3)
+#define GPIO_PEN_SCL_18V EXYNOS4_GPC1(4)
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+#define GPIO_MOTOR_EN EXYNOS4_GPL2(4)
+
+#define GPIO_BARO_INT1 EXYNOS4_GPE1(5)
+#define GPIO_BARO_INT2 EXYNOS4_GPE2(3)
+
+#endif
+#endif /* __MACH_GPIO_Q1_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-c1.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-c1.h
new file mode 100644
index 0000000..827f1f9
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-c1.h
@@ -0,0 +1,293 @@
+#ifndef __MACH_GPIO_C1_H
+#define __MACH_GPIO_C1_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYNOS4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYNOS4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYNOS4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYNOS4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#if 1
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+#else
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+#endif
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY0(1)
+
+#define GPIO_NFC_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1)
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.4 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS4_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS4_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS4_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS4_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS4_GPL2(5)
+#define CP_CMC221_CPU_RST EXYNOS4_GPL2(4)
+
+#define GPIO_LTE_ACTIVE EXYNOS4_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS4_GPX2(0)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS4_GPX0(5)
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS4_GPX3(2)
+
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+#define GPIO_AP2CMC_INT2 EXYNOS4_GPX1(2)
+
+/* Definitions for an USB HUB for CMC221 */
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+
+#endif /* __MACH_GPIO_C1_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-c1ctc.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-c1ctc.h
new file mode 100644
index 0000000..e7c17d0
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-c1ctc.h
@@ -0,0 +1,287 @@
+#ifndef __MACH_GPIO_C1_H
+#define __MACH_GPIO_C1_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY0(1)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#define GPIO_DPRAM_BUSY EXYNOS4_GPY1(2)
+
+/* Definitions for CMC221 */
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_AP_CP_INT EXYNOS4_GPF2(2)
+
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+#define GPIO_USB_HUB_CONNECT EXYNOS4212_GPV3(5)
+#define GPIO_USB_BOOT_EN EXYNOS4212_GPV3(7)
+
+#define GPIO_BOOT_SW_SEL EXYNOS4212_GPV3(6)
+
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+#define GPIO_CP_MSM_PWRON EXYNOS4_GPL2(5)
+ #define GPIO_CP_MSM_RST EXYNOS4_GPL2(4)
+#define GPIO_CP_MSM_PMU_RST EXYNOS4_GPX3(2)
+#define GPIO_CP_MSM_DUMP EXYNOS4_GPX1(2)
+
+#define GPIO_MSM_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define MSM_PHONE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_MSM_DPRAM_INT EXYNOS4_GPX2(0)
+#define MSM_DPRAM_INT_IRQ IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+
+#endif /* __MACH_GPIO_C1_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-c1vzw.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-c1vzw.h
new file mode 100644
index 0000000..605b70c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-c1vzw.h
@@ -0,0 +1,316 @@
+#ifndef __MACH_GPIO_C1VZW_H
+#define __MACH_GPIO_C1VZW_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYNOS4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYNOS4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYNOS4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYNOS4_GPC0(4)
+
+#ifdef CONFIG_AUDIENCE_ES305
+#define GPIO_ES305_WAKEUP EXYNOS4_GPC0(4)
+#define GPIO_ES305_RESET EXYNOS4_GPF2(5)
+#endif
+
+#define GPIO_FM34_PWDN EXYNOS4_GPL0(3)
+#define GPIO_FM34_RESET EXYNOS4_GPY1(3)
+#define GPIO_FM34_BYPASS EXYNOS4_GPY1(2)
+#define GPIO_FM34_SCL EXYNOS4212_GPM4(0)
+#define GPIO_FM34_SDA EXYNOS4212_GPM4(1)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY0(1)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPC0(3)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4_GPF2(0)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_LTE_VIA_UART_SEL EXYNOS4212_GPJ0(6)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.9 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS4_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS4_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS4_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS4_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS4_GPL2(5)
+#define CP_CMC221_CPU_RST EXYNOS4_GPL2(4)
+
+#define GPIO_LTE_ACTIVE EXYNOS4_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS4_GPX3(3)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(27) /* IRQ of GPX3[3] */
+#define GPIO_CMC_IDPRAM_INT_01 EXYNOS4_GPX2(0)
+#define CMC_IDPRAM_INT_IRQ_01 IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS4_GPX0(5)
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS4_GPX3(2)
+
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+/* Definitions for an USB HUB for CMC221 */
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+
+/* Definitions for CBP7.2 */
+#define GPIO_CBP_PMIC_PWRON EXYNOS4212_GPM0(6)
+#define GPIO_CBP_PS_HOLD_OFF EXYNOS4212_GPM1(0)
+#define GPIO_CBP_CP_RST EXYNOS4_GPF2(4)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+
+#define GPIO_CBP_PHONE_ACTIVE EXYNOS4_GPX1(3)
+#define CBP_PHONE_ACTIVE_IRQ IRQ_EINT(11)
+
+#define GPIO_CBP_DPRAM_INT_00 EXYNOS4_GPX2(0)
+#define CBP_DPRAM_INT_IRQ_00 IRQ_EINT(16) /* IRQ of GPX2[0] */
+#define GPIO_CBP_DPRAM_INT_01 EXYNOS4_GPX3(5)
+#define CBP_DPRAM_INT_IRQ_01 IRQ_EINT(29) /* IRQ of GPX3[5] */
+
+#define GPIO_CBP_BOOT_SEL EXYNOS4212_GPM0(5)
+
+#endif /* __MACH_GPIO_C1VZW_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-gc1.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-gc1.h
new file mode 100644
index 0000000..04e3fb8
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-gc1.h
@@ -0,0 +1,321 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4) /* rev0.0, 0.1 */
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+
+#define GPIO_MOT_EN EXYNOS4212_GPM0(5)
+#define GPIO_SAMBAZ_RESET EXYNOS4212_GPM0(6)
+
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#if 1
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+#else
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+#endif
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_TOP_PCB_PWREN EXYNOS4_GPL2(4)
+
+/* Sensors */
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+/* Sensors */
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.9 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+#define GPIO_ISP_INT EXYNOS4_GPX0(2)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#else
+
+/* Modem Interface GPIOs - M0 SPI */
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPX0(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPX3(5)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPX0(4)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPX3(2)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(1)
+
+#define GPIO_CP_RST EXYNOS4_GPF1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPF1(1)
+#define GPIO_ISP_INT EXYNOS4_GPF1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(0)
+
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT9
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1) /*system_rev == 11*/
+#define GPIO_OK_KEY_ANDROID_F EXYNOS4_GPX1(3) /*system_rev >= 15*/
+
+#define GPIO_RECORD_KEY EXYNOS4_GPX0(4)
+#define GPIO_MENU_KEY EXYNOS4_GPX0(5)
+#define GPIO_BACK_KEY EXYNOS4_GPX1(3)
+#define GPIO_PLAY_KEY EXYNOS4_GPX1(4)
+#define GPIO_S1_KEY EXYNOS4_GPX2(0)
+#define GPIO_S2_KEY EXYNOS4_GPX2(1)
+#define GPIO_WIDE_KEY EXYNOS4_GPX2(2)
+#define GPIO_TELE_KEY EXYNOS4_GPX3(3)
+
+#define GPIO_FM_INT_REV15 EXYNOS4_GPX1(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_MIC_SW EXYNOS4_GPL0(3)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPL0(0)
+#define GPIO_TDMB_INT EXYNOS4_GPF0(2)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPC1(1)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPC1(2)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPC1(3)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPC1(4)
+#endif
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-jenga.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-jenga.h
new file mode 100644
index 0000000..42d1f08
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-jenga.h
@@ -0,0 +1,265 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY0(1)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPZ(6)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPZ(5)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4212_GPM4(5)
+#define GPIO_MIC_BIAS_EN_00 EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4212_GPM4(6)
+#define GPIO_SUB_MIC_BIAS_EN_00 EXYNOS4_GPF2(0)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4212_GPM4(7)
+#define GPIO_EAR_MIC_BIAS_EN_00 EXYNOS4212_GPJ0(2)
+
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-m0.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-m0.h
new file mode 100644
index 0000000..13fdb3d
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-m0.h
@@ -0,0 +1,322 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4) /* rev0.0, 0.1 */
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#if 1
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+#else
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+#endif
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPZ(6)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPZ(5)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.9 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+#define GPIO_AP_DUMP_INT EXYNOS4212_GPJ0(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#else
+
+/* Modem Interface GPIOs - M0 SPI */
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPX0(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPX3(5)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPX0(4)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPX3(2)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(1)
+
+#define GPIO_CP_RST EXYNOS4_GPF1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPF1(1)
+#define GPIO_ISP_INT EXYNOS4_GPF1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(0)
+
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT9
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1) /*system_rev == 11*/
+#define GPIO_OK_KEY_ANDROID_F EXYNOS4_GPX1(3) /*system_rev >= 15*/
+
+#define GPIO_FM_INT_REV15 EXYNOS4_GPX1(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_MIC_SW EXYNOS4_GPL0(3)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPL0(0)
+#define GPIO_TDMB_INT EXYNOS4_GPF0(2)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPC1(1)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPC1(2)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPC1(3)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPC1(4)
+#endif
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-m0ctc.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-m0ctc.h
new file mode 100644
index 0000000..2b36a60
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-m0ctc.h
@@ -0,0 +1,296 @@
+#ifndef __MACH_GPIO_C1_H
+#define __MACH_GPIO_C1_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1) /*system_rev == 11*/
+#define GPIO_OK_KEY_ANDROID_F EXYNOS4_GPX1(3) /*system_rev >= 15*/
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.9 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_FM_INT_REV15 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_MIC_SW EXYNOS4_GPL0(3)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#define GPIO_DPRAM_BUSY EXYNOS4_GPY1(2)
+
+/* Definitions for CMC221 */
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_AP_CP_INT EXYNOS4_GPF2(2)
+
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+#define GPIO_USB_HUB_CONNECT EXYNOS4212_GPV3(5)
+#define GPIO_USB_BOOT_EN EXYNOS4212_GPV3(7)
+
+#define GPIO_BOOT_SW_SEL EXYNOS4212_GPV3(6)
+
+/* for revesion 06 higher */
+#define GPIO_USB_BOOT_EN_REV06 EXYNOS4_GPF2(2)
+#define GPIO_BOOT_SW_SEL_REV06 EXYNOS4_GPF1(1)
+
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+#define GPIO_CP_MSM_PWRON EXYNOS4_GPL2(5)
+ #define GPIO_CP_MSM_RST EXYNOS4_GPL2(4)
+#define GPIO_CP_MSM_PMU_RST EXYNOS4_GPX3(2)
+#define GPIO_CP_MSM_DUMP EXYNOS4_GPX1(2)
+
+#define GPIO_MSM_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define MSM_PHONE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_MSM_DPRAM_INT EXYNOS4_GPX2(0)
+#define MSM_DPRAM_INT_IRQ IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+
+#endif /* __MACH_GPIO_C1_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-m0grandectc.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-m0grandectc.h
new file mode 100644
index 0000000..e5c96b4
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-m0grandectc.h
@@ -0,0 +1,227 @@
+#ifndef __MACH_GPIO_C1_H
+#define __MACH_GPIO_C1_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ1(4)
+
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4212_GPJ0(2)
+#define GPIO_S_LED_I2C_SCL
+#define GPIO_S_LED_I2C_SDA
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_LCD_SEL EXYNOS4_GPF2(6)
+#define GPIO_LCD_OE EXYNOS4_GPF2(7)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN EXYNOS4_GPX3(3)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1) /*system_rev == 11*/
+#define GPIO_OK_KEY_ANDROID_F EXYNOS4_GPX1(3) /*system_rev >= 15*/
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#define GPIO_DPRAM_BUSY EXYNOS4_GPY1(2)
+
+/* Definitions for CMC221 */
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_AP_CP_INT EXYNOS4_GPF2(2)
+
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+#define GPIO_USB_HUB_CONNECT EXYNOS4212_GPV3(5)
+#define GPIO_USB_BOOT_EN EXYNOS4212_GPV3(7)
+
+#define GPIO_BOOT_SW_SEL EXYNOS4212_GPV3(6)
+
+/* for revesion 06 higher */
+#define GPIO_USB_BOOT_EN_REV06 EXYNOS4212_GPV3(7)
+#define GPIO_BOOT_SW_SEL_REV06 EXYNOS4212_GPV3(6)
+
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+#define GPIO_CP_MSM_PWRON EXYNOS4_GPL2(5)
+#define GPIO_CP_MSM_RST EXYNOS4_GPL2(4)
+#define GPIO_CP_MSM_PMU_RST EXYNOS4_GPX3(2)
+#define GPIO_CP_MSM_DUMP EXYNOS4_GPX1(2)
+
+#define GPIO_MSM_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define MSM_PHONE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_MSM_DPRAM_INT EXYNOS4_GPX2(0)
+#define MSM_DPRAM_INT_IRQ IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+#define GPIO_CP2_MSM_PWRON EXYNOS4_GPL2(1)
+#define GPIO_CP2_MSM_RST EXYNOS4_GPL2(2)
+
+/* DUMP GPIOS */
+#define GPIO_HDMI_HPD EXYNOS4_GPA1(4)
+#define GPIO_HDMI_EN EXYNOS4_GPA1(4)
+#define GPIO_V_BUS_INT EXYNOS4_GPA1(4)
+
+#endif /* __MACH_GPIO_C1_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-m3.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-m3.h
new file mode 100644
index 0000000..cd3bc9c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-m3.h
@@ -0,0 +1,291 @@
+#ifndef __MACH_GPIO_M3_H
+#define __MACH_GPIO_M3_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYNOS4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYNOS4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYNOS4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYNOS4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY0(1)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+
+/* Definitions for CMC221 */
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_AP_CP_INT EXYNOS4_GPF2(2)
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define CP_CMC221_CPU_RST EXYNOS4_GPL2(4)
+#define CP_CMC221_PMIC_PWRON EXYNOS4_GPL2(5)
+#define GPIO_CMC2AP_INT1_18V EXYNOS4_GPX0(5)
+#define GPIO_AP2CMC_DP_INT3_18V EXYNOS4_GPX3(2)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+#define GPIO_LTE_ACTIVE EXYNOS4_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT EXYNOS4_GPX2(0)
+#define CMC_IDPRAM_INT_IRQ IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+
+#define GPIO_CMC2AP_STATUS EXYNOS4_GPX0(5)
+#define GPIO_AP2CMC_WAKEUP EXYNOS4_GPX1(2)
+
+#define ACTIVE_STATE_HSIC EXYNOS4_GPF1(1)
+#define MDM_LTE_ACTIVE EXYNOS4_GPF2(0)
+#define PDA_ACTIVE EXYNOS4_GPF1(6)
+#define AP2MDM_PMIC_RESET_N EXYNOS4_GPL2(4)
+#define MDM2AP_STATUS EXYNOS4212_GPM1(1)
+#define AP2MDM_STATUS EXYNOS4212_GPM2(4)
+#define MDM2AP_HSIC_READY EXYNOS4_GPX0(4)
+#define AP2MDM_HSIC_READY EXYNOS4_GPX0(5)
+#define AP2MDM_ERRFATAL EXYNOS4_GPX1(0)
+#define MDM2AP_ERRFATAL EXYNOS4_GPX1(1)
+#define MDM_DUMP_INT EXYNOS4_GPX1(2)
+
+#endif /* __MACH_GPIO_M3_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-naples.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-naples.h
new file mode 100644
index 0000000..be3efc7
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-naples.h
@@ -0,0 +1,295 @@
+#ifndef __MACH_GPIO_NAPLES_H
+#define __MACH_GPIO_NAPLES_H __FILE__
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+
+#define GPIO_5M_CAM_nSTBY EXYNOS4212_GPM0(1)
+#define GPIO_5M_CAM_RESET EXYNOS4_GPF1(3)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_VT_CAM_nSTBY EXYNOS4212_GPM0(5)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_CAM_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_CAM_SCL_18V EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPB(5)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPB(4)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_MIC_BIAS_EN_00 EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_SUB_MIC_BIAS_EN_00 EXYNOS4_GPF2(0)
+#define GPIO_EAR_MIC_BIAS_EN_00 EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN EXYNOS4_GPX3(3)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX2(0)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#else
+
+/* Modem Interface GPIOs - M0 SPI */
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPX0(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPX3(5)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPX0(4)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPX3(2)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(1)
+
+#define GPIO_CP_RST EXYNOS4_GPF1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPF1(1)
+#define GPIO_ISP_INT EXYNOS4_GPF1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(0)
+
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT9
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+
+#endif /* __MACH_GPIO_NAPLES_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-p10-lte.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-p10-lte.h
new file mode 100644
index 0000000..9ceb31c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-p10-lte.h
@@ -0,0 +1,376 @@
+#ifndef __MACH_GPIO_P10_H
+#define __MACH_GPIO_P10 __FILE__
+
+#include <mach/gpio.h>
+
+extern void p10_config_gpio_table(void);
+extern void p10_config_sleep_gpio_table(void);
+
+/**
+ * Main GPIO function mapping.
+ */
+#define GPIO_5M_CAM_SCL_18V EXYNOS5_GPF0(1)
+#define GPIO_5M_CAM_SDA_18V EXYNOS5_GPF0(0)
+#define GPIO_5M_CORE_EN EXYNOS5_GPV0(2)
+#define GPIO_5M_SPI_CLK EXYNOS5_GPA2(4)
+#define GPIO_5M_SPI_CS EXYNOS5_GPA2(5)
+#define GPIO_5M_SPI_DI EXYNOS5_GPA2(6)
+#define GPIO_5M_SPI_DO EXYNOS5_GPA2(7)
+
+#define GPIO_ACC_INT EXYNOS5_GPX1(4)
+
+#define GPIO_ACCESSORY_CHECK EXYNOS5_GPE0(4)
+#define GPIO_ACCESSORY_EN EXYNOS5_GPH1(5)
+#define GPIO_ACCESSORY_INT EXYNOS5_GPX3(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+#define GPIO_ADC_SCL_18V EXYNOS5_GPV3(0)
+#define GPIO_ADC_SDA_18V EXYNOS5_GPV3(1)
+
+#define GPIO_ALS_nRST EXYNOS5_GPH1(2)
+#define GPIO_ALS_SCL_18V EXYNOS5_GPG0(1)
+#define GPIO_ALS_SDA_18V EXYNOS5_GPG0(0)
+
+#define GPIO_AP_CP_INT EXYNOS5_GPB0(0)
+#define GPIO_AP_CPU_PWR_DN EXYNOS5_GPX1(5)
+#define GPIO_AP_PMIC_IRQ EXYNOS5_GPX0(2)
+#define GPIO_AP_PMIC_SCL EXYNOS5_GPA2(3)
+#define GPIO_AP_PMIC_SDA EXYNOS5_GPA2(2)
+#define GPIO_AP_RXD EXYNOS5_GPA1(0)
+#define GPIO_AP_TXD EXYNOS5_GPA1(1)
+
+#define GPIO_AP2CMC_INT1_18V EXYNOS5_GPX0(6)
+#define GPIO_AP2CMC_INT2_18V EXYNOS5_GPX1(1)
+#define GPIO_AP2CMC_INT3_18V EXYNOS5_GPX1(2)
+
+#define GPIO_AUTO_DFS EXYNOS5_GPZ(1)
+
+#define GPIO_BARO_INT EXYNOS5_GPB1(0)
+
+#define GPIO_BSENSE_SCL_18V EXYNOS5_GPD0(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS5_GPD0(2)
+
+#define GPIO_BT_HOST_WAKE EXYNOS5_GPX2(6)
+#define GPIO_BT_UART_CTS EXYNOS5_GPA0(2)
+#define GPIO_BT_UART_RTS EXYNOS5_GPA0(3)
+#define GPIO_BT_UART_RXD EXYNOS5_GPA0(0)
+#define GPIO_BT_UART_TXD EXYNOS5_GPA0(1)
+#define GPIO_BT_WAKE EXYNOS5_GPH1(3)
+
+#define GPIO_BTREG_ON EXYNOS5_GPH0(0)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BUCK2_SEL EXYNOS5_GPV0(4)
+
+#define GPIO_BUCK3_SEL EXYNOS5_GPV0(1)
+
+#define GPIO_BUCK4_SEL EXYNOS5_GPV0(0)
+
+#define GPIO_CAM_FLASH_EN_T EXYNOS5_GPG1(0)
+#define GPIO_CAM_FLASH_SET_T EXYNOS5_GPG1(1)
+#define GPIO_CAM_IO_EN EXYNOS5_GPV0(3)
+#define GPIO_CAM_MCLK EXYNOS5_GPH0(3)
+#define GPIO_CAM_VT_nRST EXYNOS5_GPG1(6)
+
+#define GPIO_CHG_SCL_18V EXYNOS5_GPE0(2)
+#define GPIO_CHG_SDA_18V EXYNOS5_GPE0(1)
+
+#define GPIO_CIS_nRST EXYNOS5_GPE0(0)
+
+#define GPIO_CMC_PMIC_PWRON EXYNOS5_GPD1(5)
+#define GPIO_CMC_SPI_CLK_ACK EXYNOS5_GPX1(3)
+#define GPIO_CMC_SPI_CLK_REQ EXYNOS5_GPB0(2)
+#define GPIO_CMC_USB_DETECT EXYNOS5_GPH1(0)
+
+#define GPIO_CMC221_CPU_RST EXYNOS5_GPB0(1)
+
+#define GPIO_CMC2AP_INT1_18V EXYNOS5_GPX0(3)
+#define GPIO_CMC2AP_INT2_18V EXYNOS5_GPX1(0)
+
+#define GPIO_WM8994_LDO EXYNOS5_GPH1(1)
+#define GPIO_CODEC_SCL_18V EXYNOS5_GPB2(3)
+#define GPIO_CODEC_SDA_18V EXYNOS5_GPB2(2)
+
+#define GPIO_DET_35 EXYNOS5_GPX0(1)
+
+#define GPIO_DOCK_INT EXYNOS5_GPX3(0)
+
+#define GPIO_DP_HPD EXYNOS5_GPX0(7)
+
+#define GPIO_DPRAM_A0 EXYNOS5_GPY3(0)
+#define GPIO_DPRAM_A1 EXYNOS5_GPY3(1)
+#define GPIO_DPRAM_A2 EXYNOS5_GPY3(2)
+#define GPIO_DPRAM_A3 EXYNOS5_GPY3(3)
+#define GPIO_DPRAM_A4 EXYNOS5_GPY3(4)
+#define GPIO_DPRAM_A5 EXYNOS5_GPY3(5)
+#define GPIO_DPRAM_A6 EXYNOS5_GPY3(6)
+#define GPIO_DPRAM_A7 EXYNOS5_GPY3(7)
+#define GPIO_DPRAM_A8 EXYNOS5_GPY4(0)
+#define GPIO_DPRAM_A9 EXYNOS5_GPY4(1)
+#define GPIO_DPRAM_A10 EXYNOS5_GPY4(2)
+#define GPIO_DPRAM_A11 EXYNOS5_GPY4(3)
+#define GPIO_DPRAM_A12 EXYNOS5_GPY4(4)
+#define GPIO_DPRAM_A13 EXYNOS5_GPY4(5)
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_D0 EXYNOS5_GPY5(0)
+#define GPIO_DPRAM_D1 EXYNOS5_GPY5(1)
+#define GPIO_DPRAM_D2 EXYNOS5_GPY5(2)
+#define GPIO_DPRAM_D3 EXYNOS5_GPY5(3)
+#define GPIO_DPRAM_D4 EXYNOS5_GPY5(4)
+#define GPIO_DPRAM_D5 EXYNOS5_GPY5(5)
+#define GPIO_DPRAM_D6 EXYNOS5_GPY5(6)
+#define GPIO_DPRAM_D7 EXYNOS5_GPY5(7)
+#define GPIO_DPRAM_D8 EXYNOS5_GPY6(0)
+#define GPIO_DPRAM_D9 EXYNOS5_GPY6(1)
+#define GPIO_DPRAM_D10 EXYNOS5_GPY6(2)
+#define GPIO_DPRAM_D11 EXYNOS5_GPY6(3)
+#define GPIO_DPRAM_D12 EXYNOS5_GPY6(4)
+#define GPIO_DPRAM_D13 EXYNOS5_GPY6(5)
+#define GPIO_DPRAM_D14 EXYNOS5_GPY6(6)
+#define GPIO_DPRAM_D15 EXYNOS5_GPY6(7)
+#define GPIO_DPRAM_INT EXYNOS5_GPX0(5)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+
+#define GPIO_EAR_SEND_END EXYNOS5_GPX3(6)
+
+#define GPIO_eMMC_EN EXYNOS5_GPC0(2)
+
+#define GPIO_FM34_BYPASS EXYNOS5_GPH1(4)
+#define GPIO_FM34_PWDN EXYNOS5_GPG0(3)
+#define GPIO_FM34_RESET EXYNOS5_GPG0(4)
+#define GPIO_FM34_SCL_18V EXYNOS5_GPA2(1)
+#define GPIO_FM34_SDA_18V EXYNOS5_GPA2(0)
+
+#define GPIO_ES305_WAKEUP EXYNOS5_GPG0(3)
+#define GPIO_ES305_RESET EXYNOS5_GPG0(4)
+
+#define GPIO_FUEL_ALERT EXYNOS5_GPX2(3)
+#define GPIO_FUEL_SCL_18V EXYNOS5_GPD0(1)
+#define GPIO_FUEL_SDA_18V EXYNOS5_GPD0(0)
+
+#define GPIO_GPS_PWR_EN EXYNOS5_GPE1(0)
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+#define GPIO_GPS_CTS EXYNOS5_GPA0(6)
+#define GPIO_GPS_RTS EXYNOS5_GPA0(7)
+#define GPIO_GPS_RXD EXYNOS5_GPA0(4)
+#define GPIO_GPS_TXD EXYNOS5_GPA0(5)
+
+#define GPIO_GPS_CTS_AF 2
+#define GPIO_GPS_RTS_AF 2
+#define GPIO_GPS_RXD_AF 2
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GSENSE_SCL_18V EXYNOS5_GPB3(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS5_GPB3(2)
+
+#define GPIO_HDMI_EN EXYNOS5_GPC1(2)
+#define GPIO_HDMI_HPD EXYNOS5_GPX3(7)
+
+#define GPIO_HUM_SCL_18V EXYNOS5_GPV2(4)
+#define GPIO_HUM_SDA_18V EXYNOS5_GPV2(5)
+
+#define GPIO_HW_REV0 EXYNOS5_GPV1(4)
+#define GPIO_HW_REV1 EXYNOS5_GPV1(3)
+#define GPIO_HW_REV2 EXYNOS5_GPV1(2)
+#define GPIO_HW_REV3 EXYNOS5_GPV1(1)
+
+#define GPIO_IPC_RXD EXYNOS5_GPA1(4)
+#define GPIO_IPC_TXD EXYNOS5_GPA1(5)
+
+#define GPIO_ISP_RXD EXYNOS5_GPE1(1)
+#define GPIO_ISP_STANDBY EXYNOS5_GPG1(7)
+#define GPIO_ISP_TXD EXYNOS5_GPE0(7)
+
+#define GPIO_LCD_EN EXYNOS5_GPH1(7)
+#define GPIO_LCD_ID EXYNOS5_GPD1(4)
+#define GPIO_LCD_PWM_IN_18V EXYNOS5_GPB2(0)
+
+#define GPIO_LCDP_SCL__18V EXYNOS5_GPD0(6)
+#define GPIO_LCDP_SDA__18V EXYNOS5_GPD0(7)
+
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS5_GPG0(5)
+
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+
+#define GPIO_MHL_DSCL_18V EXYNOS5_GPB3(1)
+#define GPIO_MHL_DSDA_18V EXYNOS5_GPB3(0)
+#define GPIO_MHL_INT EXYNOS5_GPG0(6)
+#define GPIO_MHL_RST EXYNOS5_GPG0(7)
+#define GPIO_MHL_SCL_18V EXYNOS5_GPD0(5)
+#define GPIO_MHL_SDA_18V EXYNOS5_GPD0(4)
+
+#define GPIO_MM_I2S_CLK EXYNOS5_GPZ(0)
+#define GPIO_MM_I2S_DI EXYNOS5_GPZ(3)
+#define GPIO_MM_I2S_DO EXYNOS5_GPZ(4)
+#define GPIO_MM_I2S_SYNC EXYNOS5_GPZ(2)
+
+#define GPIO_MOTOR_EN EXYNOS5_GPD1(6)
+#define GPIO_MOTOR_PWM EXYNOS5_GPB2(1)
+#define GPIO_MOTOR_SCL_18V EXYNOS5_GPD1(3)
+#define GPIO_MOTOR_SDA_18V EXYNOS5_GPD1(2)
+
+#define GPIO_MSENSE_RDY EXYNOS5_GPX2(2)
+#define GPIO_MSENSE_RST EXYNOS5_GPG2(0)
+#define GPIO_MSENSE_SDA EXYNOS5_GPV2(7)
+#define GPIO_MSENSE_SCL EXYNOS5_GPV2(6)
+
+#define GPIO_PS_ALS_SDA EXYNOS5_GPG0(0)
+#define GPIO_PS_ALS_SCL EXYNOS5_GPG0(1)
+#define GPIO_PS_VOUT EXYNOS5_GPH1(2)
+#define GPIO_HUM_SDA EXYNOS5_GPV2(5)
+#define GPIO_HUM_SCL EXYNOS5_GPV2(4)
+
+
+#define GPIO_M_SDA EXYNOS5_GPB1(3)
+
+#define GPIO_NAND_CLK EXYNOS5_GPC0(0)
+#define GPIO_NAND_CMD EXYNOS5_GPC0(1)
+#define GPIO_NAND_D0 EXYNOS5_GPC0(3)
+#define GPIO_NAND_D1 EXYNOS5_GPC0(4)
+#define GPIO_NAND_D2 EXYNOS5_GPC0(5)
+#define GPIO_NAND_D3 EXYNOS5_GPC0(6)
+#define GPIO_NAND_D4 EXYNOS5_GPC1(3)
+#define GPIO_NAND_D5 EXYNOS5_GPC1(4)
+#define GPIO_NAND_D6 EXYNOS5_GPC1(5)
+#define GPIO_NAND_D7 EXYNOS5_GPC1(6)
+
+#define GPIO_nPOWER EXYNOS5_GPX2(7)
+
+#define GPIO_OTG_EN EXYNOS5_GPC3(2)
+
+#define GPIO_PDA_ACTIVE EXYNOS5_GPE0(3)
+
+#define GPIO_PMIC_DVS1 EXYNOS5_GPV0(7)
+#define GPIO_PMIC_DVS2 EXYNOS5_GPV0(6)
+#define GPIO_PMIC_DVS3 EXYNOS5_GPV0(5)
+
+#define GPIO_REMOTE_SENSE_IRQ EXYNOS5_GPX3(1)
+
+#define GPIO_SIM_DETECT EXYNOS5_GPX3(3)
+
+#define GPIO_T_FLASH_CLK EXYNOS5_GPC2(0)
+#define GPIO_T_FLASH_CMD EXYNOS5_GPC2(1)
+#define GPIO_T_FLASH_D0 EXYNOS5_GPC2(3)
+#define GPIO_T_FLASH_D1 EXYNOS5_GPC2(4)
+#define GPIO_T_FLASH_D2 EXYNOS5_GPC2(5)
+#define GPIO_T_FLASH_D3 EXYNOS5_GPC2(6)
+#define GPIO_T_FLASH_DETECT EXYNOS5_GPX3(4)
+
+#define GPIO_TA_EN EXYNOS5_GPG1(5)
+#define GPIO_TA_nCONNECTED EXYNOS5_GPX0(0)
+#define GPIO_TA_nCHG EXYNOS5_GPG1(4)
+
+#define GPIO_TF_EN EXYNOS5_GPY2(0)
+
+#define GPIO_TOUCH_CHG EXYNOS5_GPG1(2)
+#define GPIO_TOUCH_RESET EXYNOS5_GPG1(3)
+
+#define GPIO_TP400 EXYNOS5_GPH0(2)
+
+#define GPIO_TP405 EXYNOS5_GPX0(4)
+
+#define GPIO_TP406 EXYNOS5_GPX3(5)
+
+#define GPIO_TP411 EXYNOS5_GPG0(2)
+
+#define GPIO_TSP_SCL_18V EXYNOS5_GPA1(3)
+#define GPIO_TSP_SDA_18V EXYNOS5_GPA1(2)
+
+#define GPIO_UART_SEL EXYNOS5_GPE0(5)
+
+#define GPIO_USB_SEL1 EXYNOS5_GPH0(1)
+
+#define GPIO_USB30_EN EXYNOS5_GPC2(2)
+
+#define GPIO_VOL_DOWN EXYNOS5_GPX2(1)
+#define GPIO_VOL_UP EXYNOS5_GPX2(0)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS5_GPF0(3)
+#define GPIO_VT_CAM_SDA_18V EXYNOS5_GPF0(2)
+
+#define GPIO_VTCAM_MCLK EXYNOS5_GPG2(1)
+
+#define GPIO_WLAN_EN EXYNOS5_GPV1(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS5_GPC3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS5_GPC3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS5_GPC3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS5_GPC3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS5_GPC3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS5_GPC3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+/**
+ * Mapping for Func0.
+ */
+#define GPIO_I2C_0_SDA EXYNOS5_GPB3(0)
+#define GPIO_I2C_1_SDA EXYNOS5_GPB3(2)
+
+/**
+ * Mapping for Func1.
+ */
+#define GPIO_I2C_2_SDA EXYNOS5_GPA0(6)
+#define GPIO_I2C_3_SDA EXYNOS5_GPA1(2)
+#define GPIO_I2C_4_SDA EXYNOS5_GPA2(0)
+#define GPIO_I2C_5_SDA EXYNOS5_GPA2(2)
+#define GPIO_I2C_7_SDA EXYNOS5_GPB2(2)
+
+#define GPIO_PCM_0_SCLK EXYNOS5_GPZ(0)
+#define GPIO_PCM_1_SCLK EXYNOS5_GPB0(0)
+#define GPIO_PCM_2_SCLK EXYNOS5_GPB1(0)
+
+/**
+ * Mapping for Func2.
+ */
+#define GPIO_I2C_6_SDA EXYNOS5_GPB1(3)
+
+/**
+ * Remappig for downward compatibility.
+ */
+#define GPIO_PMIC_IRQ GPIO_AP_PMIC_IRQ
+#define GPIO_HDMI_CEC GPIO_EAR_SEND_END
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS5_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS5_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS5_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+/* #define GPIO_DPRAM_LBN EXYNOS4_GPY1(0) // for via modem */
+/* #define GPIO_DPRAM_UBN EXYNOS4_GPY1(1) // for via modem */
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS5_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS5_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS5_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS5_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS5_GPD1(5)
+#define CP_CMC221_CPU_RST EXYNOS5_GPB0(1)
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS5_GPX0(5)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(5) /* IRQ of GPX0[5] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS5_GPX0(3) /* CMC2AP_INT_1 */
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS5_GPX1(2) /* AP2CMC_INT_3 */
+/* #define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1) // for USB */
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS5_GPX0(6) /* AP2CMC_INT_1 */
+#define GPIO_IPC_HOST_WAKEUP EXYNOS5_GPX1(0) /* CMC2AP_INT_2 */
+
+#define GPIO_CMC_CLK_18V EXYNOS5_GPF1(0)
+#define GPIO_CMC_CS_18V EXYNOS5_GPF1(1)
+
+#define GPIO_5M_nRST EXYNOS5_GPE0(0)
+
+#endif /* __MACH_GPIO_P10_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-p10-wifi.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-p10-wifi.h
new file mode 100644
index 0000000..9ceb31c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-p10-wifi.h
@@ -0,0 +1,376 @@
+#ifndef __MACH_GPIO_P10_H
+#define __MACH_GPIO_P10 __FILE__
+
+#include <mach/gpio.h>
+
+extern void p10_config_gpio_table(void);
+extern void p10_config_sleep_gpio_table(void);
+
+/**
+ * Main GPIO function mapping.
+ */
+#define GPIO_5M_CAM_SCL_18V EXYNOS5_GPF0(1)
+#define GPIO_5M_CAM_SDA_18V EXYNOS5_GPF0(0)
+#define GPIO_5M_CORE_EN EXYNOS5_GPV0(2)
+#define GPIO_5M_SPI_CLK EXYNOS5_GPA2(4)
+#define GPIO_5M_SPI_CS EXYNOS5_GPA2(5)
+#define GPIO_5M_SPI_DI EXYNOS5_GPA2(6)
+#define GPIO_5M_SPI_DO EXYNOS5_GPA2(7)
+
+#define GPIO_ACC_INT EXYNOS5_GPX1(4)
+
+#define GPIO_ACCESSORY_CHECK EXYNOS5_GPE0(4)
+#define GPIO_ACCESSORY_EN EXYNOS5_GPH1(5)
+#define GPIO_ACCESSORY_INT EXYNOS5_GPX3(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+#define GPIO_ADC_SCL_18V EXYNOS5_GPV3(0)
+#define GPIO_ADC_SDA_18V EXYNOS5_GPV3(1)
+
+#define GPIO_ALS_nRST EXYNOS5_GPH1(2)
+#define GPIO_ALS_SCL_18V EXYNOS5_GPG0(1)
+#define GPIO_ALS_SDA_18V EXYNOS5_GPG0(0)
+
+#define GPIO_AP_CP_INT EXYNOS5_GPB0(0)
+#define GPIO_AP_CPU_PWR_DN EXYNOS5_GPX1(5)
+#define GPIO_AP_PMIC_IRQ EXYNOS5_GPX0(2)
+#define GPIO_AP_PMIC_SCL EXYNOS5_GPA2(3)
+#define GPIO_AP_PMIC_SDA EXYNOS5_GPA2(2)
+#define GPIO_AP_RXD EXYNOS5_GPA1(0)
+#define GPIO_AP_TXD EXYNOS5_GPA1(1)
+
+#define GPIO_AP2CMC_INT1_18V EXYNOS5_GPX0(6)
+#define GPIO_AP2CMC_INT2_18V EXYNOS5_GPX1(1)
+#define GPIO_AP2CMC_INT3_18V EXYNOS5_GPX1(2)
+
+#define GPIO_AUTO_DFS EXYNOS5_GPZ(1)
+
+#define GPIO_BARO_INT EXYNOS5_GPB1(0)
+
+#define GPIO_BSENSE_SCL_18V EXYNOS5_GPD0(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS5_GPD0(2)
+
+#define GPIO_BT_HOST_WAKE EXYNOS5_GPX2(6)
+#define GPIO_BT_UART_CTS EXYNOS5_GPA0(2)
+#define GPIO_BT_UART_RTS EXYNOS5_GPA0(3)
+#define GPIO_BT_UART_RXD EXYNOS5_GPA0(0)
+#define GPIO_BT_UART_TXD EXYNOS5_GPA0(1)
+#define GPIO_BT_WAKE EXYNOS5_GPH1(3)
+
+#define GPIO_BTREG_ON EXYNOS5_GPH0(0)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BUCK2_SEL EXYNOS5_GPV0(4)
+
+#define GPIO_BUCK3_SEL EXYNOS5_GPV0(1)
+
+#define GPIO_BUCK4_SEL EXYNOS5_GPV0(0)
+
+#define GPIO_CAM_FLASH_EN_T EXYNOS5_GPG1(0)
+#define GPIO_CAM_FLASH_SET_T EXYNOS5_GPG1(1)
+#define GPIO_CAM_IO_EN EXYNOS5_GPV0(3)
+#define GPIO_CAM_MCLK EXYNOS5_GPH0(3)
+#define GPIO_CAM_VT_nRST EXYNOS5_GPG1(6)
+
+#define GPIO_CHG_SCL_18V EXYNOS5_GPE0(2)
+#define GPIO_CHG_SDA_18V EXYNOS5_GPE0(1)
+
+#define GPIO_CIS_nRST EXYNOS5_GPE0(0)
+
+#define GPIO_CMC_PMIC_PWRON EXYNOS5_GPD1(5)
+#define GPIO_CMC_SPI_CLK_ACK EXYNOS5_GPX1(3)
+#define GPIO_CMC_SPI_CLK_REQ EXYNOS5_GPB0(2)
+#define GPIO_CMC_USB_DETECT EXYNOS5_GPH1(0)
+
+#define GPIO_CMC221_CPU_RST EXYNOS5_GPB0(1)
+
+#define GPIO_CMC2AP_INT1_18V EXYNOS5_GPX0(3)
+#define GPIO_CMC2AP_INT2_18V EXYNOS5_GPX1(0)
+
+#define GPIO_WM8994_LDO EXYNOS5_GPH1(1)
+#define GPIO_CODEC_SCL_18V EXYNOS5_GPB2(3)
+#define GPIO_CODEC_SDA_18V EXYNOS5_GPB2(2)
+
+#define GPIO_DET_35 EXYNOS5_GPX0(1)
+
+#define GPIO_DOCK_INT EXYNOS5_GPX3(0)
+
+#define GPIO_DP_HPD EXYNOS5_GPX0(7)
+
+#define GPIO_DPRAM_A0 EXYNOS5_GPY3(0)
+#define GPIO_DPRAM_A1 EXYNOS5_GPY3(1)
+#define GPIO_DPRAM_A2 EXYNOS5_GPY3(2)
+#define GPIO_DPRAM_A3 EXYNOS5_GPY3(3)
+#define GPIO_DPRAM_A4 EXYNOS5_GPY3(4)
+#define GPIO_DPRAM_A5 EXYNOS5_GPY3(5)
+#define GPIO_DPRAM_A6 EXYNOS5_GPY3(6)
+#define GPIO_DPRAM_A7 EXYNOS5_GPY3(7)
+#define GPIO_DPRAM_A8 EXYNOS5_GPY4(0)
+#define GPIO_DPRAM_A9 EXYNOS5_GPY4(1)
+#define GPIO_DPRAM_A10 EXYNOS5_GPY4(2)
+#define GPIO_DPRAM_A11 EXYNOS5_GPY4(3)
+#define GPIO_DPRAM_A12 EXYNOS5_GPY4(4)
+#define GPIO_DPRAM_A13 EXYNOS5_GPY4(5)
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_D0 EXYNOS5_GPY5(0)
+#define GPIO_DPRAM_D1 EXYNOS5_GPY5(1)
+#define GPIO_DPRAM_D2 EXYNOS5_GPY5(2)
+#define GPIO_DPRAM_D3 EXYNOS5_GPY5(3)
+#define GPIO_DPRAM_D4 EXYNOS5_GPY5(4)
+#define GPIO_DPRAM_D5 EXYNOS5_GPY5(5)
+#define GPIO_DPRAM_D6 EXYNOS5_GPY5(6)
+#define GPIO_DPRAM_D7 EXYNOS5_GPY5(7)
+#define GPIO_DPRAM_D8 EXYNOS5_GPY6(0)
+#define GPIO_DPRAM_D9 EXYNOS5_GPY6(1)
+#define GPIO_DPRAM_D10 EXYNOS5_GPY6(2)
+#define GPIO_DPRAM_D11 EXYNOS5_GPY6(3)
+#define GPIO_DPRAM_D12 EXYNOS5_GPY6(4)
+#define GPIO_DPRAM_D13 EXYNOS5_GPY6(5)
+#define GPIO_DPRAM_D14 EXYNOS5_GPY6(6)
+#define GPIO_DPRAM_D15 EXYNOS5_GPY6(7)
+#define GPIO_DPRAM_INT EXYNOS5_GPX0(5)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+
+#define GPIO_EAR_SEND_END EXYNOS5_GPX3(6)
+
+#define GPIO_eMMC_EN EXYNOS5_GPC0(2)
+
+#define GPIO_FM34_BYPASS EXYNOS5_GPH1(4)
+#define GPIO_FM34_PWDN EXYNOS5_GPG0(3)
+#define GPIO_FM34_RESET EXYNOS5_GPG0(4)
+#define GPIO_FM34_SCL_18V EXYNOS5_GPA2(1)
+#define GPIO_FM34_SDA_18V EXYNOS5_GPA2(0)
+
+#define GPIO_ES305_WAKEUP EXYNOS5_GPG0(3)
+#define GPIO_ES305_RESET EXYNOS5_GPG0(4)
+
+#define GPIO_FUEL_ALERT EXYNOS5_GPX2(3)
+#define GPIO_FUEL_SCL_18V EXYNOS5_GPD0(1)
+#define GPIO_FUEL_SDA_18V EXYNOS5_GPD0(0)
+
+#define GPIO_GPS_PWR_EN EXYNOS5_GPE1(0)
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+#define GPIO_GPS_CTS EXYNOS5_GPA0(6)
+#define GPIO_GPS_RTS EXYNOS5_GPA0(7)
+#define GPIO_GPS_RXD EXYNOS5_GPA0(4)
+#define GPIO_GPS_TXD EXYNOS5_GPA0(5)
+
+#define GPIO_GPS_CTS_AF 2
+#define GPIO_GPS_RTS_AF 2
+#define GPIO_GPS_RXD_AF 2
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GSENSE_SCL_18V EXYNOS5_GPB3(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS5_GPB3(2)
+
+#define GPIO_HDMI_EN EXYNOS5_GPC1(2)
+#define GPIO_HDMI_HPD EXYNOS5_GPX3(7)
+
+#define GPIO_HUM_SCL_18V EXYNOS5_GPV2(4)
+#define GPIO_HUM_SDA_18V EXYNOS5_GPV2(5)
+
+#define GPIO_HW_REV0 EXYNOS5_GPV1(4)
+#define GPIO_HW_REV1 EXYNOS5_GPV1(3)
+#define GPIO_HW_REV2 EXYNOS5_GPV1(2)
+#define GPIO_HW_REV3 EXYNOS5_GPV1(1)
+
+#define GPIO_IPC_RXD EXYNOS5_GPA1(4)
+#define GPIO_IPC_TXD EXYNOS5_GPA1(5)
+
+#define GPIO_ISP_RXD EXYNOS5_GPE1(1)
+#define GPIO_ISP_STANDBY EXYNOS5_GPG1(7)
+#define GPIO_ISP_TXD EXYNOS5_GPE0(7)
+
+#define GPIO_LCD_EN EXYNOS5_GPH1(7)
+#define GPIO_LCD_ID EXYNOS5_GPD1(4)
+#define GPIO_LCD_PWM_IN_18V EXYNOS5_GPB2(0)
+
+#define GPIO_LCDP_SCL__18V EXYNOS5_GPD0(6)
+#define GPIO_LCDP_SDA__18V EXYNOS5_GPD0(7)
+
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS5_GPG0(5)
+
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+
+#define GPIO_MHL_DSCL_18V EXYNOS5_GPB3(1)
+#define GPIO_MHL_DSDA_18V EXYNOS5_GPB3(0)
+#define GPIO_MHL_INT EXYNOS5_GPG0(6)
+#define GPIO_MHL_RST EXYNOS5_GPG0(7)
+#define GPIO_MHL_SCL_18V EXYNOS5_GPD0(5)
+#define GPIO_MHL_SDA_18V EXYNOS5_GPD0(4)
+
+#define GPIO_MM_I2S_CLK EXYNOS5_GPZ(0)
+#define GPIO_MM_I2S_DI EXYNOS5_GPZ(3)
+#define GPIO_MM_I2S_DO EXYNOS5_GPZ(4)
+#define GPIO_MM_I2S_SYNC EXYNOS5_GPZ(2)
+
+#define GPIO_MOTOR_EN EXYNOS5_GPD1(6)
+#define GPIO_MOTOR_PWM EXYNOS5_GPB2(1)
+#define GPIO_MOTOR_SCL_18V EXYNOS5_GPD1(3)
+#define GPIO_MOTOR_SDA_18V EXYNOS5_GPD1(2)
+
+#define GPIO_MSENSE_RDY EXYNOS5_GPX2(2)
+#define GPIO_MSENSE_RST EXYNOS5_GPG2(0)
+#define GPIO_MSENSE_SDA EXYNOS5_GPV2(7)
+#define GPIO_MSENSE_SCL EXYNOS5_GPV2(6)
+
+#define GPIO_PS_ALS_SDA EXYNOS5_GPG0(0)
+#define GPIO_PS_ALS_SCL EXYNOS5_GPG0(1)
+#define GPIO_PS_VOUT EXYNOS5_GPH1(2)
+#define GPIO_HUM_SDA EXYNOS5_GPV2(5)
+#define GPIO_HUM_SCL EXYNOS5_GPV2(4)
+
+
+#define GPIO_M_SDA EXYNOS5_GPB1(3)
+
+#define GPIO_NAND_CLK EXYNOS5_GPC0(0)
+#define GPIO_NAND_CMD EXYNOS5_GPC0(1)
+#define GPIO_NAND_D0 EXYNOS5_GPC0(3)
+#define GPIO_NAND_D1 EXYNOS5_GPC0(4)
+#define GPIO_NAND_D2 EXYNOS5_GPC0(5)
+#define GPIO_NAND_D3 EXYNOS5_GPC0(6)
+#define GPIO_NAND_D4 EXYNOS5_GPC1(3)
+#define GPIO_NAND_D5 EXYNOS5_GPC1(4)
+#define GPIO_NAND_D6 EXYNOS5_GPC1(5)
+#define GPIO_NAND_D7 EXYNOS5_GPC1(6)
+
+#define GPIO_nPOWER EXYNOS5_GPX2(7)
+
+#define GPIO_OTG_EN EXYNOS5_GPC3(2)
+
+#define GPIO_PDA_ACTIVE EXYNOS5_GPE0(3)
+
+#define GPIO_PMIC_DVS1 EXYNOS5_GPV0(7)
+#define GPIO_PMIC_DVS2 EXYNOS5_GPV0(6)
+#define GPIO_PMIC_DVS3 EXYNOS5_GPV0(5)
+
+#define GPIO_REMOTE_SENSE_IRQ EXYNOS5_GPX3(1)
+
+#define GPIO_SIM_DETECT EXYNOS5_GPX3(3)
+
+#define GPIO_T_FLASH_CLK EXYNOS5_GPC2(0)
+#define GPIO_T_FLASH_CMD EXYNOS5_GPC2(1)
+#define GPIO_T_FLASH_D0 EXYNOS5_GPC2(3)
+#define GPIO_T_FLASH_D1 EXYNOS5_GPC2(4)
+#define GPIO_T_FLASH_D2 EXYNOS5_GPC2(5)
+#define GPIO_T_FLASH_D3 EXYNOS5_GPC2(6)
+#define GPIO_T_FLASH_DETECT EXYNOS5_GPX3(4)
+
+#define GPIO_TA_EN EXYNOS5_GPG1(5)
+#define GPIO_TA_nCONNECTED EXYNOS5_GPX0(0)
+#define GPIO_TA_nCHG EXYNOS5_GPG1(4)
+
+#define GPIO_TF_EN EXYNOS5_GPY2(0)
+
+#define GPIO_TOUCH_CHG EXYNOS5_GPG1(2)
+#define GPIO_TOUCH_RESET EXYNOS5_GPG1(3)
+
+#define GPIO_TP400 EXYNOS5_GPH0(2)
+
+#define GPIO_TP405 EXYNOS5_GPX0(4)
+
+#define GPIO_TP406 EXYNOS5_GPX3(5)
+
+#define GPIO_TP411 EXYNOS5_GPG0(2)
+
+#define GPIO_TSP_SCL_18V EXYNOS5_GPA1(3)
+#define GPIO_TSP_SDA_18V EXYNOS5_GPA1(2)
+
+#define GPIO_UART_SEL EXYNOS5_GPE0(5)
+
+#define GPIO_USB_SEL1 EXYNOS5_GPH0(1)
+
+#define GPIO_USB30_EN EXYNOS5_GPC2(2)
+
+#define GPIO_VOL_DOWN EXYNOS5_GPX2(1)
+#define GPIO_VOL_UP EXYNOS5_GPX2(0)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS5_GPF0(3)
+#define GPIO_VT_CAM_SDA_18V EXYNOS5_GPF0(2)
+
+#define GPIO_VTCAM_MCLK EXYNOS5_GPG2(1)
+
+#define GPIO_WLAN_EN EXYNOS5_GPV1(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS5_GPC3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS5_GPC3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS5_GPC3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS5_GPC3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS5_GPC3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS5_GPC3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+/**
+ * Mapping for Func0.
+ */
+#define GPIO_I2C_0_SDA EXYNOS5_GPB3(0)
+#define GPIO_I2C_1_SDA EXYNOS5_GPB3(2)
+
+/**
+ * Mapping for Func1.
+ */
+#define GPIO_I2C_2_SDA EXYNOS5_GPA0(6)
+#define GPIO_I2C_3_SDA EXYNOS5_GPA1(2)
+#define GPIO_I2C_4_SDA EXYNOS5_GPA2(0)
+#define GPIO_I2C_5_SDA EXYNOS5_GPA2(2)
+#define GPIO_I2C_7_SDA EXYNOS5_GPB2(2)
+
+#define GPIO_PCM_0_SCLK EXYNOS5_GPZ(0)
+#define GPIO_PCM_1_SCLK EXYNOS5_GPB0(0)
+#define GPIO_PCM_2_SCLK EXYNOS5_GPB1(0)
+
+/**
+ * Mapping for Func2.
+ */
+#define GPIO_I2C_6_SDA EXYNOS5_GPB1(3)
+
+/**
+ * Remappig for downward compatibility.
+ */
+#define GPIO_PMIC_IRQ GPIO_AP_PMIC_IRQ
+#define GPIO_HDMI_CEC GPIO_EAR_SEND_END
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS5_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS5_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS5_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+/* #define GPIO_DPRAM_LBN EXYNOS4_GPY1(0) // for via modem */
+/* #define GPIO_DPRAM_UBN EXYNOS4_GPY1(1) // for via modem */
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS5_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS5_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS5_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS5_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS5_GPD1(5)
+#define CP_CMC221_CPU_RST EXYNOS5_GPB0(1)
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS5_GPX0(5)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(5) /* IRQ of GPX0[5] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS5_GPX0(3) /* CMC2AP_INT_1 */
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS5_GPX1(2) /* AP2CMC_INT_3 */
+/* #define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1) // for USB */
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS5_GPX0(6) /* AP2CMC_INT_1 */
+#define GPIO_IPC_HOST_WAKEUP EXYNOS5_GPX1(0) /* CMC2AP_INT_2 */
+
+#define GPIO_CMC_CLK_18V EXYNOS5_GPF1(0)
+#define GPIO_CMC_CS_18V EXYNOS5_GPF1(1)
+
+#define GPIO_5M_nRST EXYNOS5_GPE0(0)
+
+#endif /* __MACH_GPIO_P10_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-p10.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-p10.h
new file mode 100644
index 0000000..2e8a85c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-p10.h
@@ -0,0 +1,311 @@
+#ifndef __MACH_GPIO_P10_H
+#define __MACH_GPIO_P10 __FILE__
+
+#include <mach/gpio.h>
+
+extern void p10_config_gpio_table(void);
+extern void p10_config_sleep_gpio_table(void);
+
+#define GPIO_5M_CAM_SCL_18V EXYNOS5_GPF0(1)
+#define GPIO_5M_CAM_SDA_18V EXYNOS5_GPF0(0)
+#define GPIO_5M_CORE_EN EXYNOS5_GPV0(2)
+#define GPIO_5M_nRST EXYNOS5_GPE0(0)
+#define GPIO_5M_SPI_CLK EXYNOS5_GPA2(4)
+#define GPIO_5M_SPI_CS EXYNOS5_GPA2(5)
+#define GPIO_5M_SPI_DI EXYNOS5_GPA2(6)
+#define GPIO_5M_SPI_DO EXYNOS5_GPA2(7)
+
+#define GPIO_ACC_INT EXYNOS5_GPX1(4)
+
+#define GPIO_ACCESSORY_CHECK EXYNOS5_GPE0(4)
+#define GPIO_ACCESSORY_EN EXYNOS5_GPH1(5)
+#define GPIO_ACCESSORY_INT EXYNOS5_GPX3(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+#define GPIO_ADC_SCL_18V EXYNOS5_GPV3(0)
+#define GPIO_ADC_SDA_18V EXYNOS5_GPV3(1)
+
+#define GPIO_AMP_L_INT EXYNOS5_GPB0(1)
+#define GPIO_AMP_L_SCL_18V EXYNOS5_GPC1(1)
+#define GPIO_AMP_L_SDA_18V EXYNOS5_GPC1(0)
+#define GPIO_AMP_R_INT EXYNOS5_GPB1(0)
+#define GPIO_AMP_R_SCL_18V EXYNOS5_GPB1(2)
+#define GPIO_AMP_R_SDA_18V EXYNOS5_GPB1(1)
+
+#define GPIO_AP_CP_INT EXYNOS5_GPB0(4)
+#define GPIO_AP_CPU_PWR_DN EXYNOS5_GPX1(5)
+#define GPIO_AP_PMIC_IRQ EXYNOS5_GPX0(2)
+#define GPIO_AP_PMIC_SCL EXYNOS5_GPA2(3)
+#define GPIO_AP_PMIC_SDA EXYNOS5_GPA2(2)
+#define GPIO_AP_RXD EXYNOS5_GPA1(0)
+#define GPIO_AP_TXD EXYNOS5_GPA1(1)
+
+#define GPIO_AP2CMC_INT1_18V EXYNOS5_GPX0(6)
+#define GPIO_AP2CMC_INT2_18V EXYNOS5_GPX1(1)
+#define GPIO_AP2CMC_INT3_18V EXYNOS5_GPX1(2)
+
+#define GPIO_BARO_INT EXYNOS5_GPB0(2)
+
+#define GPIO_BSENSE_SCL_18V EXYNOS5_GPD0(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS5_GPD0(2)
+
+#define GPIO_BT_EN EXYNOS5_GPE0(2)
+#define GPIO_BT_HOST_WAKE EXYNOS5_GPX2(6)
+#define GPIO_BT_nRST EXYNOS5_GPE0(1)
+#define GPIO_BT_UART_CTS EXYNOS5_GPA0(2)
+#define GPIO_BT_UART_RTS EXYNOS5_GPA0(3)
+#define GPIO_BT_UART_RXD EXYNOS5_GPA0(0)
+#define GPIO_BT_UART_TXD EXYNOS5_GPA0(1)
+#define GPIO_BT_WAKE EXYNOS5_GPH1(3)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BUCK2_SEL EXYNOS5_GPV0(4)
+#define GPIO_BUCK3_SEL EXYNOS5_GPV0(1)
+#define GPIO_BUCK4_SEL EXYNOS5_GPV0(0)
+
+#define GPIO_CAM_FLASH_EN EXYNOS5_GPG1(0)
+#define GPIO_CAM_FLASH_SET EXYNOS5_GPG1(1)
+#define GPIO_CAM_IO_EN EXYNOS5_GPV0(3)
+#define GPIO_CAM_MCLK EXYNOS5_GPH0(3)
+#define GPIO_CAM_VT_nRST EXYNOS5_GPG1(6)
+
+#define GPIO_CHG_SDA_18V EXYNOS5_GPE0(1)
+#define GPIO_CHG_SCL_18V EXYNOS5_GPE0(2)
+
+#define GPIO_CMC_CLK_18V EXYNOS5_GPF1(0)
+#define GPIO_CMC_CS_18V EXYNOS5_GPF1(1)
+#define GPIO_CMC_DI_18V EXYNOS5_GPF1(3)
+#define GPIO_CMC_DO_18V EXYNOS5_GPF1(2)
+#define GPIO_CMC_PMIC_PWRON EXYNOS5_GPD1(5)
+#define GPIO_CMC_SPI_CLK_ACK EXYNOS5_GPX1(3)
+#define GPIO_CMC_SPI_CLK_REQ EXYNOS5_GPB0(3)
+
+#define GPIO_CMC221_CPU_RST EXYNOS5_GPB0(0)
+
+#define GPIO_CMC2AP_INT1_18V EXYNOS5_GPX0(3)
+#define GPIO_CMC2AP_INT2_18V EXYNOS5_GPX1(0)
+
+#define GPIO_WM8994_LDO EXYNOS5_GPH1(1)
+#define GPIO_CODEC_SCL_18V EXYNOS5_GPB2(3)
+#define GPIO_CODEC_SDA_18V EXYNOS5_GPB2(2)
+
+#define GPIO_DET_35 EXYNOS5_GPX0(1)
+
+#define GPIO_DOCK_INT EXYNOS5_GPX3(0)
+
+#define GPIO_DP_HPD EXYNOS5_GPX0(7)
+
+#define GPIO_DPRAM_A0 EXYNOS5_GPY3(0)
+#define GPIO_DPRAM_A1 EXYNOS5_GPY3(1)
+#define GPIO_DPRAM_A2 EXYNOS5_GPY3(2)
+#define GPIO_DPRAM_A3 EXYNOS5_GPY3(3)
+#define GPIO_DPRAM_A4 EXYNOS5_GPY3(4)
+#define GPIO_DPRAM_A5 EXYNOS5_GPY3(5)
+#define GPIO_DPRAM_A6 EXYNOS5_GPY3(6)
+#define GPIO_DPRAM_A7 EXYNOS5_GPY3(7)
+#define GPIO_DPRAM_A8 EXYNOS5_GPY4(0)
+#define GPIO_DPRAM_A9 EXYNOS5_GPY4(1)
+#define GPIO_DPRAM_A10 EXYNOS5_GPY4(2)
+#define GPIO_DPRAM_A11 EXYNOS5_GPY4(3)
+#define GPIO_DPRAM_A12 EXYNOS5_GPY4(4)
+#define GPIO_DPRAM_A13 EXYNOS5_GPY4(5)
+
+#define GPIO_DPRAM_D0 EXYNOS5_GPY5(0)
+#define GPIO_DPRAM_D1 EXYNOS5_GPY5(1)
+#define GPIO_DPRAM_D2 EXYNOS5_GPY5(2)
+#define GPIO_DPRAM_D3 EXYNOS5_GPY5(3)
+#define GPIO_DPRAM_D4 EXYNOS5_GPY5(4)
+#define GPIO_DPRAM_D5 EXYNOS5_GPY5(5)
+#define GPIO_DPRAM_D6 EXYNOS5_GPY5(6)
+#define GPIO_DPRAM_D7 EXYNOS5_GPY5(7)
+#define GPIO_DPRAM_D8 EXYNOS5_GPY6(0)
+#define GPIO_DPRAM_D9 EXYNOS5_GPY6(1)
+#define GPIO_DPRAM_D10 EXYNOS5_GPY6(2)
+#define GPIO_DPRAM_D11 EXYNOS5_GPY6(3)
+#define GPIO_DPRAM_D12 EXYNOS5_GPY6(4)
+#define GPIO_DPRAM_D13 EXYNOS5_GPY6(5)
+#define GPIO_DPRAM_D14 EXYNOS5_GPY6(6)
+#define GPIO_DPRAM_D15 EXYNOS5_GPY6(7)
+
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_INT EXYNOS5_GPX0(5)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+
+#define GPIO_EAR_SEND_END EXYNOS5_GPX3(6)
+
+#define GPIO_eMMC_EN EXYNOS5_GPC0(2)
+
+#define GPIO_FM34_PWDN EXYNOS5_GPG0(3)
+#define GPIO_FM34_RESET EXYNOS5_GPG0(4)
+#define GPIO_FM34_BYPASS EXYNOS5_GPH1(4)
+
+#define GPIO_ES305_WAKEUP EXYNOS5_GPG0(3)
+#define GPIO_ES305_RESET EXYNOS5_GPG0(4)
+
+#define GPIO_FUEL_ALERT EXYNOS5_GPX2(3)
+#define GPIO_FUEL_SCL_18V EXYNOS5_GPD0(1)
+#define GPIO_FUEL_SDA_18V EXYNOS5_GPD0(0)
+
+#define GPIO_GPS_PWR_EN EXYNOS5_GPE1(0)
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+#define GPIO_GPS_CTS EXYNOS5_GPA0(6)
+#define GPIO_GPS_RTS EXYNOS5_GPA0(7)
+#define GPIO_GPS_RXD EXYNOS5_GPA0(4)
+#define GPIO_GPS_TXD EXYNOS5_GPA0(5)
+
+#define GPIO_GPS_CTS_AF 2
+#define GPIO_GPS_RTS_AF 2
+#define GPIO_GPS_RXD_AF 2
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GSENSE_SCL_18V EXYNOS5_GPB3(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS5_GPB3(2)
+
+#define GPIO_HDMI_EN EXYNOS5_GPC1(2)
+#define GPIO_HDMI_HPD EXYNOS5_GPX3(7)
+
+#define GPIO_HUM_SCL_18V EXYNOS5_GPV2(4)
+#define GPIO_HUM_SDA_18V EXYNOS5_GPV2(5)
+
+#define GPIO_HW_REV0 EXYNOS5_GPV1(4)
+#define GPIO_HW_REV1 EXYNOS5_GPV1(3)
+#define GPIO_HW_REV2 EXYNOS5_GPV1(2)
+#define GPIO_HW_REV3 EXYNOS5_GPV1(1)
+
+#define GPIO_IPC_RXD EXYNOS5_GPA1(4)
+#define GPIO_IPC_TXD EXYNOS5_GPA1(5)
+
+#define GPIO_IRDA_DOUT_AP EXYNOS5_GPG0(1)
+
+#define GPIO_ISP_RXD EXYNOS5_GPE1(1)
+#define GPIO_ISP_TXD EXYNOS5_GPE0(7)
+
+#define GPIO_LCD_APS_EN_18V EXYNOS5_GPG0(3)
+#define GPIO_LCD_EN EXYNOS5_GPH1(7)
+#define GPIO_LCD_ID EXYNOS5_GPD1(4)
+#define GPIO_LCD_PWM_IN_18V EXYNOS5_GPB2(0)
+
+#define GPIO_LCDP_SCL__18V EXYNOS5_GPD0(6)
+#define GPIO_LCDP_SDA__18V EXYNOS5_GPD0(7)
+
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS5_GPG0(5)
+
+#define GPIO_LIGHT_I2C_SCL EXYNOS5_GPB1(4)
+#define GPIO_LIGHT_I2C_SDA EXYNOS5_GPB1(3)
+#define GPIO_LIGHT_nINT EXYNOS5_GPH1(2)
+
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+
+#define GPIO_MHL_DSCL_18V EXYNOS5_GPB3(1)
+#define GPIO_MHL_DSDA_18V EXYNOS5_GPB3(0)
+#define GPIO_MHL_INT EXYNOS5_GPG0(6)
+#define GPIO_MHL_RST EXYNOS5_GPG0(7)
+#define GPIO_MHL_SCL_18V EXYNOS5_GPD0(5)
+#define GPIO_MHL_SDA_18V EXYNOS5_GPD0(4)
+
+#define GPIO_MM_I2S_CLK EXYNOS5_GPZ(0)
+#define GPIO_MM_I2S_DI EXYNOS5_GPZ(3)
+#define GPIO_MM_I2S_DO EXYNOS5_GPZ(4)
+#define GPIO_MM_I2S_SYNC EXYNOS5_GPZ(2)
+
+#define GPIO_MOTOR_SCL_18V EXYNOS5_GPD1(3)
+#define GPIO_MOTOR_SDA_18V EXYNOS5_GPD1(2)
+
+#define GPIO_MSENSE_INT EXYNOS5_GPX2(2)
+#define GPIO_MSENSE_SCL_18V EXYNOS5_GPV2(6)
+#define GPIO_MSENSE_SDA_18V EXYNOS5_GPV2(7)
+
+#define GPIO_NAND_CLK EXYNOS5_GPC0(0)
+#define GPIO_NAND_CMD EXYNOS5_GPC0(1)
+#define GPIO_NAND_D0 EXYNOS5_GPC0(3)
+#define GPIO_NAND_D1 EXYNOS5_GPC0(4)
+#define GPIO_NAND_D2 EXYNOS5_GPC0(5)
+#define GPIO_NAND_D3 EXYNOS5_GPC0(6)
+#define GPIO_NAND_D4 EXYNOS5_GPC1(3)
+#define GPIO_NAND_D5 EXYNOS5_GPC1(4)
+#define GPIO_NAND_D6 EXYNOS5_GPC1(5)
+#define GPIO_NAND_D7 EXYNOS5_GPC1(6)
+
+#define GPIO_NFC_EN EXYNOS5_GPD1(6)
+#define GPIO_NFC_FIRMWARE EXYNOS5_GPD1(7)
+#define GPIO_NFC_IRQ EXYNOS5_GPX1(7)
+#define GPIO_NFC_SCL_18V EXYNOS5_GPV2(1)
+#define GPIO_NFC_SDA_18V EXYNOS5_GPV2(0)
+
+#define GPIO_nPOWER EXYNOS5_GPX2(7)
+
+#define GPIO_OTG_EN EXYNOS5_GPC3(2)
+
+#define GPIO_PDA_ACTIVE EXYNOS5_GPE0(3)
+
+#define GPIO_PMIC_DVS1 EXYNOS5_GPV0(7)
+#define GPIO_PMIC_DVS2 EXYNOS5_GPV0(6)
+#define GPIO_PMIC_DVS3 EXYNOS5_GPV0(5)
+
+#define GPIO_REMOTE_SENSE_IRQ EXYNOS5_GPX3(1)
+
+#define GPIO_RGB_SCL_18V EXYNOS5_GPD1(1)
+#define GPIO_RGB_SDA_18V EXYNOS5_GPD1(0)
+
+#define GPIO_SIM_DETECT EXYNOS5_GPX3(3)
+
+#define GPIO_T_FLASH_CLK EXYNOS5_GPC2(0)
+#define GPIO_T_FLASH_CMD EXYNOS5_GPC2(1)
+#define GPIO_T_FLASH_D0 EXYNOS5_GPC2(3)
+#define GPIO_T_FLASH_D1 EXYNOS5_GPC2(4)
+#define GPIO_T_FLASH_D2 EXYNOS5_GPC2(5)
+#define GPIO_T_FLASH_D3 EXYNOS5_GPC2(6)
+#define GPIO_T_FLASH_DETECT EXYNOS5_GPX3(4)
+
+#define GPIO_TA_EN EXYNOS5_GPG1(5)
+#define GPIO_TA_nCHG EXYNOS5_GPG1(4)
+#define GPIO_TA_nCONNECTED EXYNOS5_GPX0(0)
+
+#define GPIO_TF_EN EXYNOS5_GPY2(0)
+
+#define GPIO_TOUCH_CHG EXYNOS5_GPG1(2)
+#define GPIO_TOUCH_RESET EXYNOS5_GPG1(3)
+
+#define GPIO_TSP_SCL_18V EXYNOS5_GPA1(3)
+#define GPIO_TSP_SDA_18V EXYNOS5_GPA1(2)
+
+#define GPIO_UART_SEL EXYNOS5_GPE0(5)
+
+#define GPIO_USB_SEL1 EXYNOS5_GPH0(1)
+
+#define GPIO_USB30_EN EXYNOS5_GPG0(2)
+
+#define GPIO_VOL_DOWN EXYNOS5_GPX2(1)
+#define GPIO_VOL_UP EXYNOS5_GPX2(0)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS5_GPF0(3)
+#define GPIO_VT_CAM_SDA_18V EXYNOS5_GPF0(2)
+
+#define GPIO_VTCAM_MCLK EXYNOS5_GPG2(1)
+
+#define GPIO_WLAN_EN EXYNOS5_GPH0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS5_GPC3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS5_GPC3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS5_GPC3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS5_GPC3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS5_GPC3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS5_GPC3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+#define GPIO_WLAN_WAKE EXYNOS5_GPV1(0)
+
+/**
+ * Remappig for downward compatibility.
+ */
+#define GPIO_PMIC_IRQ GPIO_AP_PMIC_IRQ
+#define GPIO_HDMI_CEC GPIO_EAR_SEND_END
+
+#endif /* __MACH_GPIO_P10_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-p4note.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-p4note.h
new file mode 100644
index 0000000..b5dc8a7
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-p4note.h
@@ -0,0 +1,346 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_3M_nRST EXYNOS4_GPL1(1)
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_3M_nSTBY EXYNOS4212_GPM0(6)
+#define GPIO_2M_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_2M_nSTBY EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* 30pin Accessory */
+/*
+#define GPIO_ACCESSORY_CHECK EXYNOS4_GPE0(4)
+#define GPIO_ACCESSORY_EN EXYNOS4_GPL2(6)
+#define GPIO_ACCESSORY_OUT_5V EXYNOS4_GPY4(4)
+*/
+#define GPIO_ACCESSORY_INT EXYNOS4_GPX1(3)
+#define GPIO_DOCK_INT EXYNOS4_GPX0(4)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPL0(2)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPL0(1)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPX0(6)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPM4(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPZ(6)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPZ(5)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(6) /*tmp*/
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4212_GPM0(0)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+#define GPIO_TSP_RST EXYNOS4_GPL0(5)
+
+#define GPIO_PEN_PDCT_18V EXYNOS4_GPC1(0)
+#define GPIO_PEN_LDO_EN EXYNOS4_GPC1(1)
+#define GPIO_PEN_IRQ_18V EXYNOS4_GPC1(2)
+#define GPIO_PEN_SDA_28V EXYNOS4_GPC1(3)
+#define GPIO_PEN_SCL_28V EXYNOS4_GPC1(4
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4212_GPM0(0)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL2(3)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4_GPC1(3)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPM3(5)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL0 EXYNOS4_GPY0(4)
+#define GPIO_USB_SEL1 EXYNOS4_GPY0(5)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+/* charger */
+#define GPIO_CHG_SDA EXYNOS4212_GPM2(0)
+#define GPIO_CHG_SCL EXYNOS4212_GPM2(1)
+#define GPIO_TA_EN EXYNOS4_GPY1(3)
+#define GPIO_TA_nCHG EXYNOS4_GPL2(1)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPX1(4)
+
+/* adc */
+#define GPIO_ADC_SCL EXYNOS4212_GPM4(0)
+#define GPIO_ADC_SDA EXYNOS4212_GPM4(1)
+#define GPIO_ADC_INT EXYNOS4_GPX0(1)
+
+/* fuelgauge */
+#define GPIO_FUEL_SCL EXYNOS4_GPY0(3)
+#define GPIO_FUEL_SDA EXYNOS4_GPY0(2)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+#define GPIO_IF_CON_SENSE EXYNOS4_GPY4(3)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPL2(7)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPX2(4)
+#define GPIO_BUCK3_SEL EXYNOS4_GPX2(0)
+#define GPIO_BUCK4_SEL EXYNOS4_GPX2(1)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.9 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPM4(4)
+#define GPIO_WM8994_LDO EXYNOS4212_GPM4(4)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPL0(0)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPL1(0)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#else
+
+/* Modem Interface GPIOs - M0 SPI */
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPX0(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPX3(5)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPX0(4)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPX3(2)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(1)
+
+#define GPIO_CP_RST EXYNOS4_GPF1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPF1(1)
+#define GPIO_ISP_INT EXYNOS4_GPF1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(0)
+
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT9
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX1(3)
+
+#define GPIO_FM_INT_REV15 EXYNOS4_GPX1(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_MIC_SW EXYNOS4_GPL0(3)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPL0(0)
+#define GPIO_TDMB_INT EXYNOS4_GPF0(2)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPC1(1)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPC1(2)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPC1(3)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPC1(4)
+#endif
+
+#if defined(CONFIG_FB_S5P_S6C1372)
+#define GPIO_LCD_EN EXYNOS4_GPC0(1)
+#define GPIO_LED_BACKLIGHT_PWM EXYNOS4_GPD0(1)
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS4212_GPM0(1)
+#define GPIO_LVDS_NSHDN EXYNOS4212_GPM0(5)
+#endif
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-p4notepq.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-p4notepq.h
new file mode 100644
index 0000000..3c62331
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-p4notepq.h
@@ -0,0 +1,336 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+/* Camera */
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#ifdef CONFIG_VIDEO_ISX012
+#define GPIO_5M_nRST EXYNOS4_GPL1(1)
+#else
+#define GPIO_3M_nRST EXYNOS4_GPL1(1)
+#endif
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#ifdef CONFIG_VIDEO_ISX012
+#define GPIO_CAM_EN2 EXYNOS4212_GPJ0(5)
+#define GPIO_CAM_EN1 EXYNOS4212_GPJ0(6)
+#define GPIO_5M_nSTBY EXYNOS4212_GPJ0(7)
+#else
+#define GPIO_3M_nSTBY EXYNOS4212_GPM0(6)
+#endif
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+#define GPIO_2M_nRST EXYNOS4212_GPM1(6)
+#else
+#define GPIO_VT_CAM_nRST EXYNOS4212_GPJ1(0)
+#endif
+#define GPIO_CAM_MOVIE_EN EXYNOS4212_GPM3(6)
+#define GPIO_CAM_FLASH_EN EXYNOS4212_GPM3(7)
+
+/*
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+*/
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_2M_nSTBY EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* 30pin Accessory */
+#define GPIO_ACCESSORY_EN EXYNOS4_GPL2(6)
+#define GPIO_ACCESSORY_OUT_5V EXYNOS4_GPX3(5)
+#define GPIO_ACCESSORY_INT EXYNOS4_GPX1(3)
+#define GPIO_DOCK_INT EXYNOS4_GPX0(4)
+
+/* Sensors*/
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPL0(2)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPL0(1)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+#define GPIO_GYRO_INT EXYNOS4_GPX0(6)
+
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPM4(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+/* Sensors*/
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_DET_35 EXYNOS4_GPX0(3)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4212_GPM0(0)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4212_GPJ0(3)
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_LINEOUT_EN EXYNOS4212_GPJ1(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+#define GPIO_TSP_LDO_ON EXYNOS4212_GPM4(5)
+#define GPIO_TSP_RST EXYNOS4_GPL0(5)
+
+#define GPIO_PEN_PDCT_18V EXYNOS4_GPC1(0)
+#define GPIO_PEN_LDO_EN EXYNOS4_GPC1(1)
+#define GPIO_PEN_IRQ_18V EXYNOS4_GPC1(2)
+#define GPIO_PEN_SDA_28V EXYNOS4_GPC1(3)
+#define GPIO_PEN_SCL_28V EXYNOS4_GPC1(4)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4_GPX3(3)
+
+#define GPIO_VIBTONE_PWM GPIO_PWM0
+#define GPIO_MOTOR_EN EXYNOS4_GPL2(4)
+#define GPIO_MOTOR_SDA EXYNOS4212_GPM1(0)
+#define GPIO_MOTOR_SCL EXYNOS4212_GPM1(1)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPM3(5)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_IRDA_CONTROL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPY2(2)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPY2(3)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+/* USB/UART switch */
+#define GPIO_USB_SEL0 EXYNOS4_GPY0(4)
+#define GPIO_USB_SEL1 EXYNOS4_GPY0(5)
+#define GPIO_USB_SEL_CP EXYNOS4212_GPM0(7)
+#define GPIO_UART_SEL EXYNOS4_GPL2(7)
+
+/* charger */
+#define GPIO_CHG_SDA EXYNOS4212_GPM2(0)
+#define GPIO_CHG_SCL EXYNOS4212_GPM2(1)
+#define GPIO_TA_EN EXYNOS4212_GPM4(2)
+#define GPIO_TA_nCHG EXYNOS4212_GPM0(3)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPX1(4)
+
+/* adc */
+#define GPIO_ADC_SCL EXYNOS4212_GPM4(0)
+#define GPIO_ADC_SDA EXYNOS4212_GPM4(1)
+#define GPIO_ADC_INT EXYNOS4_GPX0(1)
+
+/* fuelgauge */
+#define GPIO_FUEL_SCL EXYNOS4_GPY0(3)
+#define GPIO_FUEL_SDA EXYNOS4_GPY0(2)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+#define GPIO_IF_CON_SENSE EXYNOS4_GPX3(0)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPX2(4)
+#define GPIO_BUCK3_SEL EXYNOS4_GPX2(0)
+#define GPIO_BUCK4_SEL EXYNOS4_GPX2(1)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPM4(4)
+#define GPIO_WM8994_LDO EXYNOS4212_GPM4(4)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPL0(0)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPL1(0)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+#define GPIO_SIM_DETECT EXYNOS4_GPX1(7)
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_AP_DUMP_INT EXYNOS4212_GPM3(4)
+#else
+
+/* Modem Interface GPIOs - M0 SPI */
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPX0(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPX3(5)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPX0(4)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPX3(2)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(1)
+
+#define GPIO_CP_RST EXYNOS4_GPF1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPF1(1)
+#define GPIO_ISP_INT EXYNOS4_GPF1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(0)
+
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT9
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX1(3)
+
+#define GPIO_FM_INT_REV15 EXYNOS4_GPX1(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPL0(0)
+#define GPIO_TDMB_INT EXYNOS4_GPF0(2)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPC1(1)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPC1(2)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPC1(3)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPC1(4)
+#endif
+
+#if defined(CONFIG_FB_S5P_S6C1372)
+#define GPIO_LCD_PCLK EXYNOS4_GPF0(3)
+#define GPIO_LCD_EN EXYNOS4_GPC0(1)
+#define GPIO_LED_BACKLIGHT_PWM EXYNOS4_GPD0(1)
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS4212_GPM0(1)
+#define GPIO_LVDS_NSHDN EXYNOS4212_GPM0(5)
+#endif
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-s2plus.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-s2plus.h
new file mode 100644
index 0000000..3423451
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-s2plus.h
@@ -0,0 +1,715 @@
+#if 1
+/*
+ * Gpio-rev00-s2plus.h
+ *
+ * 2011. 12.21 Sexykyu
+ *
+ * S2Plus H/W REV00 Board Gpio Setup
+ *
+ */
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_DUMMP EXYNOS4212_GPM3(4)
+
+/*********************** GPA0 Block *********/
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+
+/*********************** GPA1 Block *********/
+#define GPIO_AP_RXD EXYNOS4_GPA1(0)
+#define GPIO_AP_TXD EXYNOS4_GPA1(1)
+
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+
+/*********************** GPB Block *********/
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPB(1)
+
+#define GPIO_NFC_SDA_18V EXYNOS4_GPB(2)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPB(3)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+/*********************** GPC0 Block *********/
+
+#define GPIO_REC_PCM_CLK EXYNOS4_GPC0(0)
+#define GPIO_REC_PCM_SYNC EXYNOS4_GPC0(2)
+#define GPIO_REC_PCM_IN EXYNOS4_GPC0(3)
+#define GPIO_REC_PCM_OUT EXYNOS4_GPC0(4)
+
+
+/*********************** GPC1 Block *********/
+
+#define GPIO_FM_I2S_CLK EXYNOS4_GPC1(0)
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_FM_I2S_SYNC EXYNOS4_GPC1(2)
+#define GPIO_FM_I2S_DI EXYNOS4_GPC1(3)
+#define GPIO_FM_I2S_DO EXYNOS4_GPC1(4)
+
+
+/*********************** GPD0 Block *********/
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(0)
+#define GPIO_PMIC_SDA EXYNOS4_GPD0(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPD0(3)
+
+
+/*********************** GPD1 Block *********/
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+
+/*********************** GPF0 Block *********/
+#define GPIO_LCD_HYNC EXYNOS4_GPF0(0)
+#define GPIO_LCD_VSYNC EXYNOS4_GPF0(1)
+#define GPIO_LCD_DE EXYNOS4_GPF0(2)
+#define GPIO_LCD_PCLK EXYNOS4_GPF0(3)
+#define GPIO_LCD_D_0 EXYNOS4_GPF0(4)
+#define GPIO_LCD_D_1 EXYNOS4_GPF0(5)
+#define GPIO_LCD_D_2 EXYNOS4_GPF0(6)
+#define GPIO_LCD_D_3 EXYNOS4_GPF0(7)
+
+
+/*********************** GPF1 Block *********/
+#define GPIO_LCD_D_4 EXYNOS4_GPF1(0)
+#define GPIO_LCD_D_5 EXYNOS4_GPF1(1)
+#define GPIO_LCD_D_6 EXYNOS4_GPF1(2)
+#define GPIO_LCD_D_7 EXYNOS4_GPF1(3)
+#define GPIO_LCD_D_8 EXYNOS4_GPF1(4)
+#define GPIO_LCD_D_9 EXYNOS4_GPF1(5)
+#define GPIO_LCD_D_10 EXYNOS4_GPF1(6)
+#define GPIO_LCD_D_11 EXYNOS4_GPF1(7)
+
+/*********************** GPF2 Block *********/
+#define GPIO_LCD_D_12 EXYNOS4_GPF2(0)
+#define GPIO_LCD_D_13 EXYNOS4_GPF2(1)
+#define GPIO_LCD_D_14 EXYNOS4_GPF2(2)
+#define GPIO_LCD_D_15 EXYNOS4_GPF2(3)
+#define GPIO_LCD_D_16 EXYNOS4_GPF2(4)
+#define GPIO_LCD_D_17 EXYNOS4_GPF2(5)
+#define GPIO_LCD_D_18 EXYNOS4_GPF2(6)
+#define GPIO_LCD_D_19 EXYNOS4_GPF2(7)
+
+
+/*********************** GPF3 Block *********/
+#define GPIO_LCD_D_20 EXYNOS4_GPF3(0)
+#define GPIO_LCD_D_21 EXYNOS4_GPF3(1)
+#define GPIO_LCD_D_22 EXYNOS4_GPF3(2)
+#define GPIO_LCD_D_23 EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+
+
+/*********************** GPJ0 Block *********/
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4) /*old name*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+
+/*********************** GPJ1 Block *********/
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+
+/*********************** GPK0 Block *********/
+#define GPIO_NAND_CLK EXYNOS4_GPK0(0)
+#define GPIO_NAND_CMD EXYNOS4_GPK0(1)
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+#define GPIO_NAND_D_0 EXYNOS4_GPK0(3)
+#define GPIO_NAND_D_1 EXYNOS4_GPK0(4)
+#define GPIO_NAND_D_2 EXYNOS4_GPK0(5)
+#define GPIO_NAND_D_3 EXYNOS4_GPK0(6)
+
+
+/*********************** GPK1 Block *********/
+#define GPIO_NAND_D_4 EXYNOS4_GPK1(3)
+#define GPIO_NAND_D_5 EXYNOS4_GPK1(4)
+#define GPIO_NAND_D_6 EXYNOS4_GPK1(5)
+#define GPIO_NAND_D_7 EXYNOS4_GPK1(6)
+
+
+/*********************** GPK2 Block *********/
+#define GPIO_T_FLASH_CLK EXYNOS4_GPK2(0)
+#define GPIO_T_FLASH_CMD EXYNOS4_GPK2(1)
+
+#define GPIO_T_FLASH_D_0 EXYNOS4_GPK2(3)
+#define GPIO_T_FLASH_D_1 EXYNOS4_GPK2(4)
+#define GPIO_T_FLASH_D_2 EXYNOS4_GPK2(5)
+#define GPIO_T_FLASH_D_3 EXYNOS4_GPK2(6)
+
+/*********************** GPK3 Block *********/
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+/*********************** GPL0 Block *********/
+#define GPIO_BUCK2_SEL EXYNOS4_GPL0(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPL0(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPL0(3)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+
+/*********************** GPL1 Block *********/
+#define GPIO_PS_ALS_SCL_18V EXYNOS4_GPL1(0)
+#define GPIO_PS_ALS_SDA_18V EXYNOS4_GPL1(1)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPL1(0)
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPL1(1)
+
+/*********************** GPL2 Block *********/
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+#define GPIO_WLAN_WAKE EXYNOS4_GPL2(3)
+#define GPIO_CHG_EN EXYNOS4_GPL2(4)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+
+
+/*********************** GPM0 Block *********/
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_VT_nSTBY EXYNOS4212_GPM0(5)
+#define GPIO_TA_nCONNECTED EXYNOS4212_GPM0(6)
+#define GPIO_CHG_ING_N EXYNOS4212_GPM0(7)
+
+
+/*********************** GPM1 Block *********/
+#define GPIO_HW_REV0 EXYNOS4212_GPM1(2)
+#define GPIO_HW_REV1 EXYNOS4212_GPM1(3)
+#define GPIO_HW_REV2 EXYNOS4212_GPM1(4)
+#define GPIO_HW_REV3 EXYNOS4212_GPM1(5)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+
+/*********************** GPM2 Block *********/
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_TP_VT_CAM_MCLK EXYNOS4212_GPM2(2)
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+
+
+/*********************** GPM3 Block *********/
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+
+
+/*********************** GPM4 Block *********/
+#define GPIO_3_TOUCH_SCL EXYNOS4212_GPM4(0)
+#define GPIO_3_TOUCH_SDA EXYNOS4212_GPM4(1)
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4212_GPM4(5)
+#define GPIO_MIC_BIAS_EN_00 EXYNOS4212_GPM4(5)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4212_GPM4(6)
+#define GPIO_SUB_MIC_BIAS_EN_00 EXYNOS4212_GPM4(6)
+
+
+/*********************** GPX0 Block *********/
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+#define GPIO_GYRO_INT EXYNOS4_GPX0(4)
+#define GPIO_OLED_DET EXYNOS4_GPX0(5)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+
+/*********************** GPX1 Block *********/
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3) /*old name*/
+#define GPIO_BARO_INT EXYNOS4_GPX1(4)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+
+
+/*********************** GPX2 Block *********/
+#define GPIO_VOL_UP GPIO_DUMMP
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+
+
+/*********************** GPX3 Block *********/
+#define GPIO_ISP_INT EXYNOS4_GPX3(0)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+#define GPIO_VOL_DOWN GPIO_DUMMP
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+#define GPIO_T_FLASH_DETECT EXYNOS4_GPX3(4)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+/*********************** GPY0 Block *********/
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+
+/*********************** GPY2 Block *********/
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BSENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+
+/*********************** GPY3 Block *********/
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_LCD_SCLK EXYNOS4_GPY3(1)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPY3(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+#define GPIO_LCD_SDI EXYNOS4_GPY3(3)
+#define GPIO_OLED_ID EXYNOS4_GPY3(4)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+
+
+/*********************** GPY4 Block *********/
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_LCD_nCS EXYNOS4_GPY4(3)
+#define GPIO_3_TOUCH_EN EXYNOS4_GPY4(4)
+#define GPIO_MLCD_RST EXYNOS4_GPY4(5)
+#define GPIO_MHL_SEL EXYNOS4_GPY4(6)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+
+
+/****************** DUMMP ********************/
+#define GPIO_MHL_DSDA_2_8V GPIO_DUMMP
+#define GPIO_MHL_DSCL_2_8V GPIO_DUMMP
+#define GPIO_WPC_INT GPIO_DUMMP
+#define GPIO_OTG_EN GPIO_DUMMP /*don't used pin*/
+#define GPIO_CAM_IO_EN GPIO_DUMMP
+#define GPIO_VTCAM_MCLK GPIO_DUMMP
+#define GPIO_CAM_AF_EN GPIO_DUMMP
+#define GPIO_FLM_RXD GPIO_DUMMP
+#define GPIO_FLM_RXD_AF 2
+#define GPIO_FLM_TXD GPIO_DUMMP
+#define GPIO_FLM_TXD_AF 2
+#define GPIO_GPS_CNTL GPIO_DUMMP
+#define GPIO_PS_ALS_SDA_28V GPIO_DUMMP
+#define GPIO_PS_ALS_SCL_28V GPIO_DUMMP
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+
+
+#endif /* __MACH_GPIO_MIDAS_H */
+
+#else
+
+/* linux/arch/arm/mach-exynos/include/mach/gpio-exynos4.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S2Plus GPIO common lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_DUMMP EXYNOS4212_GPM3(4)
+
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+
+#define GPIO_AP_RXD EXYNOS4_GPA1(0)
+#define GPIO_AP_TXD EXYNOS4_GPA1(1)
+
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPB(1)
+
+#define GPIO_NFC_SDA_18V EXYNOS4_GPB(2)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPB(3)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+
+#define GPIO_REC_PCM_CLK EXYNOS4_GPC0(0)
+#define GPIO_REC_PCM_SYNC EXYNOS4_GPC0(2)
+#define GPIO_REC_PCM_IN EXYNOS4_GPC0(3)
+#define GPIO_REC_PCM_OUT EXYNOS4_GPC0(4)
+
+
+
+#define GPIO_FM_I2S_CLK EXYNOS4_GPC1(0)
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#define GPIO_FM_I2S_SYNC EXYNOS4_GPC1(2)
+#define GPIO_FM_I2S_DI EXYNOS4_GPC1(3)
+#define GPIO_FM_I2S_DO EXYNOS4_GPC1(4)
+
+
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(0)
+#define GPIO_PMIC_SDA EXYNOS4_GPD0(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPD0(3)
+
+
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+
+#define GPIO_LCD_HYNC EXYNOS4_GPF0(0)
+#define GPIO_LCD_VSYNC EXYNOS4_GPF0(1)
+#define GPIO_LCD_DE EXYNOS4_GPF0(2)
+#define GPIO_LCD_PCLK EXYNOS4_GPF0(3)
+#define GPIO_LCD_D_0 EXYNOS4_GPF0(4)
+#define GPIO_LCD_D_1 EXYNOS4_GPF0(5)
+#define GPIO_LCD_D_2 EXYNOS4_GPF0(6)
+#define GPIO_LCD_D_3 EXYNOS4_GPF0(7)
+
+
+#define GPIO_LCD_D_4 EXYNOS4_GPF1(0)
+#define GPIO_LCD_D_5 EXYNOS4_GPF1(1)
+#define GPIO_LCD_D_6 EXYNOS4_GPF1(2)
+#define GPIO_LCD_D_7 EXYNOS4_GPF1(3)
+#define GPIO_LCD_D_8 EXYNOS4_GPF1(4)
+#define GPIO_LCD_D_9 EXYNOS4_GPF1(5)
+#define GPIO_LCD_D_10 EXYNOS4_GPF1(6)
+#define GPIO_LCD_D_11 EXYNOS4_GPF1(7)
+
+#define GPIO_LCD_D_12 EXYNOS4_GPF2(0)
+#define GPIO_LCD_D_13 EXYNOS4_GPF2(1)
+#define GPIO_LCD_D_14 EXYNOS4_GPF2(2)
+#define GPIO_LCD_D_15 EXYNOS4_GPF2(3)
+#define GPIO_LCD_D_16 EXYNOS4_GPF2(4)
+#define GPIO_LCD_D_17 EXYNOS4_GPF2(5)
+#define GPIO_LCD_D_18 EXYNOS4_GPF2(6)
+#define GPIO_LCD_D_19 EXYNOS4_GPF2(7)
+
+
+#define GPIO_LCD_D_20 EXYNOS4_GPF3(0)
+#define GPIO_LCD_D_21 EXYNOS4_GPF3(1)
+#define GPIO_LCD_D_22 EXYNOS4_GPF3(2)
+#define GPIO_LCD_D_23 EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+
+#define GPIO_NAND_CLK EXYNOS4_GPK0(0)
+#define GPIO_NAND_CMD EXYNOS4_GPK0(1)
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+#define GPIO_NAND_D_0 EXYNOS4_GPK0(3)
+#define GPIO_NAND_D_1 EXYNOS4_GPK0(4)
+#define GPIO_NAND_D_2 EXYNOS4_GPK0(5)
+#define GPIO_NAND_D_3 EXYNOS4_GPK0(6)
+
+
+#define GPIO_NAND_D_4 EXYNOS4_GPK1(3)
+#define GPIO_NAND_D_5 EXYNOS4_GPK1(4)
+#define GPIO_NAND_D_6 EXYNOS4_GPK1(5)
+#define GPIO_NAND_D_7 EXYNOS4_GPK1(6)
+
+
+#define GPIO_T_FLASH_CLK EXYNOS4_GPK2(0)
+#define GPIO_T_FLASH_CMD EXYNOS4_GPK2(1)
+
+#define GPIO_T_FLASH_D_0 EXYNOS4_GPK2(3)
+#define GPIO_T_FLASH_D_1 EXYNOS4_GPK2(4)
+#define GPIO_T_FLASH_D_2 EXYNOS4_GPK2(5)
+#define GPIO_T_FLASH_D_3 EXYNOS4_GPK2(6)
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_BUCK2_SEL EXYNOS4_GPL0(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPL0(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPL0(3)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+
+#define GPIO_PS_ALS_SCL_18V EXYNOS4_GPL1(0)
+#define GPIO_PS_ALS_SDA_18V EXYNOS4_GPL1(1)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPL1(0)
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPL1(1)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+#define GPIO_WLAN_WAKE EXYNOS4_GPL2(3)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+
+
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_VT_nSTBY EXYNOS4212_GPM0(5)
+
+
+#define GPIO_HW_REV0 EXYNOS4212_GPM1(2)
+#define GPIO_HW_REV1 EXYNOS4212_GPM1(3)
+#define GPIO_HW_REV2 EXYNOS4212_GPM1(4)
+#define GPIO_HW_REV3 EXYNOS4212_GPM1(5)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_TP_VT_CAM_MCLK EXYNOS4212_GPM2(2)
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+
+
+#define GPIO_3_TOUCH_SCL EXYNOS4212_GPM4(0)
+#define GPIO_3_TOUCH_SDA EXYNOS4212_GPM4(1)
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4212_GPM4(5)
+#define GPIO_MIC_BIAS_EN_00 EXYNOS4212_GPM4(5)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4212_GPM4(6)
+#define GPIO_SUB_MIC_BIAS_EN_00 EXYNOS4212_GPM4(6)
+
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+#define GPIO_GYRO_INT EXYNOS4_GPX0(4)
+#define GPIO_OLED_DET EXYNOS4_GPX0(5)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_BARO_INT EXYNOS4_GPX1(4)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+
+
+#define GPIO_VOL_UP GPIO_DUMMP
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+
+
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+#define GPIO_VOL_DOWN GPIO_DUMMP
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+#define GPIO_T_FLASH_DETECT EXYNOS4_GPX3(4)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+
+
+#define GPIO_MHL_SDA_1_8V GPIO_DUMMP
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPY3(0)
+#define GPIO_LCD_SCLK EXYNOS4_GPY3(1)
+#define GPIO_MHL_SCL_1_8V GPIO_DUMMP
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPY3(2)
+#define GPIO_LCD_SDI EXYNOS4_GPY3(3)
+#define GPIO_OLED_ID EXYNOS4_GPY3(4)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+
+
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_LCD_nCS EXYNOS4_GPY4(3)
+#define GPIO_3_TOUCH_EN EXYNOS4_GPY4(4)
+#define GPIO_MLCD_RST EXYNOS4_GPY4(5)
+#define GPIO_MHL_SEL EXYNOS4_GPY4(6)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+
+
+
+#define GPIO_MHL_DSCL_2_8V GPIO_DUMMP
+#define GPIO_MHL_DSDA_2_8V GPIO_DUMMP
+#define GPIO_OTG_EN GPIO_DUMMP
+#define GPIO_CAM_IO_EN GPIO_DUMMP
+#define GPIO_VTCAM_MCLK GPIO_DUMMP
+#define GPIO_CAM_AF_EN GPIO_DUMMP
+#define GPIO_FLM_RXD GPIO_DUMMP
+#define GPIO_FLM_RXD_AF 2
+#define GPIO_FLM_TXD GPIO_DUMMP
+#define GPIO_FLM_TXD_AF 2
+#define GPIO_GPS_CNTL GPIO_DUMMP
+#define GPIO_PS_ALS_SDA_28V GPIO_DUMMP
+#define GPIO_PS_ALS_SCL_28V GPIO_DUMMP
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+
+
+#endif /* __MACH_GPIO_MIDAS_H */
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev00-t0.h b/arch/arm/mach-exynos/include/mach/gpio-rev00-t0.h
new file mode 100644
index 0000000..13fdb3d
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev00-t0.h
@@ -0,0 +1,322 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYSNO4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYSNO4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYSNO4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4) /* rev0.0, 0.1 */
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#if 1
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+#else
+#define GPIO_8M_CAM_SCL_18V EXYNOS4212_GPM4(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4212_GPM4(1)
+#define GPIO_8M_CAM_SCL_18V_00 EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V_00 EXYNOS4_GPD1(1)
+#endif
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+#define GPIO_NFC_SCL_18V EXYNOS4_GPZ(6)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPZ(5)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+#define GPIO_THIRD_MIC_BIAS_EN EXYNOS4212_GPJ0(2)
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4) /* rev0.9 ~ */
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Modem Interface GPIOs - M0 HSIC */
+#if !defined(CONFIG_SEC_MODEM_M0_TD)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_SUSPEND_REQUEST EXYNOS4212_GPM2(4)
+#define GPIO_CP_REQ_RESET EXYNOS4212_GPM3(3)
+#define GPIO_GPS_CNTL EXYNOS4212_GPM3(4)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_CP_RST EXYNOS4_GPX3(2)
+#define GPIO_AP_DUMP_INT EXYNOS4212_GPJ0(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(1)
+#else
+
+/* Modem Interface GPIOs - M0 SPI */
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+#define GPIO_PHONE_ON EXYNOS4_GPL2(5)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define GPIO_AP_CP_INT1 EXYNOS4_GPX0(5)
+#define GPIO_AP_CP_INT2 EXYNOS4_GPX3(5)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_MRDY EXYNOS4_GPX0(4)
+#define GPIO_IPC_SRDY EXYNOS4_GPX1(0)
+#define GPIO_IPC_SUB_MRDY EXYNOS4_GPX3(2)
+#define GPIO_IPC_SUB_SRDY EXYNOS4_GPX1(1)
+
+#define GPIO_CP_RST EXYNOS4_GPF1(1)
+#define GPIO_CP_REQ_RESET EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX2(0)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPF1(1)
+#define GPIO_ISP_INT EXYNOS4_GPF1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+
+#define GPIO_FM_RST EXYNOS4_GPC1(0)
+
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_IPC_SRDY IRQ_EINT8
+#define IRQ_IPC_SUB_SRDY IRQ_EINT9
+#define IRQ_CP_DUMP_INT IRQ_EINT10
+#endif
+
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1) /*system_rev == 11*/
+#define GPIO_OK_KEY_ANDROID_F EXYNOS4_GPX1(3) /*system_rev >= 15*/
+
+#define GPIO_FM_INT_REV15 EXYNOS4_GPX1(4)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX1(3)
+#define GPIO_FM_INT EXYNOS4_GPX1(3)
+#define GPIO_FM_MIC_SW EXYNOS4_GPL0(3)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPL0(0)
+#define GPIO_TDMB_INT EXYNOS4_GPF0(2)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPC1(1)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPC1(2)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPC1(3)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPC1(4)
+#endif
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev01-midas.h b/arch/arm/mach-exynos/include/mach/gpio-rev01-midas.h
new file mode 100644
index 0000000..421bb3b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev01-midas.h
@@ -0,0 +1,215 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_CHARGER_SDA_18V EXYNOS4_GPB(0)
+#define GPIO_CHARGER_SCL_18V EXYNOS4_GPB(1)
+#define GPIO_CAM_VT_nRST EXYNOS4_GPL2(1)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4_GPX2(2)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY4(3)
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY4(4)
+#define GPIO_BARO_INT EXYNOS4_GPX0(1)
+
+#define GPIO_NFC_SCL_18V EXYNOS4_GPY0(0)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPY0(1)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+/* Sensors & NFC*/
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+/* #define GPIO_BUCK1_EN_A EXYNOS4212_GPJ1(1) */
+/* #define GPIO_BUCK1_EN_B EXYNOS4212_GPJ1(2) */
+/* #define GPIO_BUCK2_EN EXYNOS4_GPL0(0) */
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_PMIC_DVS1 EXYSNO4_GPY5(5)
+#define GPIO_PMIC_DVS2 EXYSNO4_GPY5(6)
+#define GPIO_PMIC_DVS3 EXYSNO4_GPY5(7)
+
+#define GPIO_BUCK2_SEL EXYNOS4_GPY6(0)
+#define GPIO_BUCK3_SEL EXYNOS4_GPY6(3)
+#define GPIO_BUCK4_SEL EXYNOS4_GPY6(4)
+
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_CNTL EXYNOS4_GPY3(6)
+#define GPIO_GPS_nRST EXYNOS4_GPY6(6)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPY6(7)
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+
+#define GPIO_MHL_DSDA_28V EXYNOS4_GPK(2)
+#define GPIO_MHL_DSCL_28V EXYNOS4_GPK(0)
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_DSDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_DSDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_DSCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_DSCL_AF
+
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_ACC_INT EXYNOS4_GPX1(4)
+
+
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+#define GPIO_ISP_STANDBY EXYNOS4_GPY5(4)
+
+
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+
+#define GPIO_MLCD_RST EXYNOS4_GPY4(5)
+
+
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+
+#define GPIO_HW_REV0 EXYNOS4_GPY5(0)
+#define GPIO_HW_REV1 EXYNOS4_GPY5(1)
+#define GPIO_HW_REV2 EXYNOS4_GPY5(2)
+#define GPIO_HW_REV3 EXYNOS4_GPY5(3)
+
+#define GPIO_CAM_IO_EN EXYNOS4_GPY6(1)
+#define GPIO_ISP_CORE_EN EXYNOS4_GPY6(2)
+#define GPIO_8M_12V_EN EXYNOS4_GPY6(5)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for XMM6262 and C2C */
+#define CP_PMU_RST_N EXYNOS4_GPX3(2)
+#define CP_RESET_REQ_N EXYNOS4_GPY4(6)
+#define CP_ON EXYNOS4_GPL2(5)
+#define PDA_ACTIVE EXYNOS4_GPY4(2)
+#define PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define PHONE_ACTIVE_IRQ IRQ_EINT(14)
+#define CP_DUMP_INT EXYNOS4_GPX1(2)
+#define CP_DUMP_INT_IRQ IRQ_EINT(10)
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo-wifi.h b/arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo-wifi.h
new file mode 100644
index 0000000..ce182f0
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo-wifi.h
@@ -0,0 +1,387 @@
+#ifndef __MACH_GPIO_P10_H
+#define __MACH_GPIO_P10 __FILE__
+
+#include <mach/gpio.h>
+
+extern void p10_config_gpio_table(void);
+extern void p10_config_sleep_gpio_table(void);
+
+/**
+ * Main GPIO function mapping.
+ */
+#define GPIO_BT_UART_RXD EXYNOS5_GPA0(0)
+#define GPIO_BT_UART_TXD EXYNOS5_GPA0(1)
+#define GPIO_BT_UART_CTS EXYNOS5_GPA0(2)
+#define GPIO_BT_UART_RTS EXYNOS5_GPA0(3)
+
+#define GPIO_HDMI_DCDC_EN EXYNOS5_GPA0(4)
+
+#define GPIO_CHG_SDA_18V EXYNOS5_GPE0(1)
+#define GPIO_CHG_SCL_18V EXYNOS5_GPE0(2)
+
+#define GPIO_AP_RXD EXYNOS5_GPA1(0)
+#define GPIO_AP_TXD EXYNOS5_GPA1(1)
+
+#define GPIO_TSP_SDA_18V EXYNOS5_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS5_GPA1(3)
+
+#define GPIO_IPC_RXD EXYNOS5_GPA1(4)
+#define GPIO_IPC_TXD EXYNOS5_GPA1(5)
+
+#define GPIO_MM_SDA_18V EXYNOS5_GPA2(0)
+#define GPIO_MM_SCL_18V EXYNOS5_GPA2(1)
+
+#define GPIO_AP_PMIC_SDA EXYNOS5_GPA2(2)
+#define GPIO_AP_PMIC_SCL EXYNOS5_GPA2(3)
+
+#define GPIO_5M_SPI_CLK EXYNOS5_GPA2(4)
+#define GPIO_5M_SPI_CS EXYNOS5_GPA2(5)
+#define GPIO_5M_SPI_DI EXYNOS5_GPA2(6)
+#define GPIO_5M_SPI_DO EXYNOS5_GPA2(7)
+
+#define GPIO_OTG_EN EXYNOS5_GPB0(3)
+
+#define GPIO_USB30_EN EXYNOS5_GPB0(4)
+
+#define GPIO_POGO_SPDIF EXYNOS5_GPB1(0)
+
+#define GPIO_LCD_PWM_IN_18V EXYNOS5_GPB2(0)
+
+#define GPIO_ACCESSORY_CHECK EXYNOS5_GPE0(4)
+#define GPIO_ACCESSORY_EN EXYNOS5_GPH1(5)
+#define GPIO_ACCESSORY_INT EXYNOS5_GPX3(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+#define GPIO_ADC_SCL_18V EXYNOS5_GPV3(0)
+#define GPIO_ADC_SDA_18V EXYNOS5_GPV3(1)
+
+#define GPIO_MOTOR_PWM EXYNOS5_GPB2(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS5_GPB2(2)
+#define GPIO_CODEC_SCL_18V EXYNOS5_GPB2(3)
+
+#define GPIO_DISP_SDA_18V EXYNOS5_GPB3(0)
+#define GPIO_DISP_SCL_18V EXYNOS5_GPB3(1)
+
+#define GPIO_SENSE_SDA_18V EXYNOS5_GPB3(2)
+#define GPIO_SENSE_SCL_18V EXYNOS5_GPB3(3)
+
+#define GPIO_NAND_CLK EXYNOS5_GPC0(0)
+#define GPIO_NAND_CMD EXYNOS5_GPC0(1)
+
+#define GPIO_eMMC_EN EXYNOS5_GPC0(2)
+
+#define GPIO_NAND_D0 EXYNOS5_GPC0(3)
+#define GPIO_NAND_D1 EXYNOS5_GPC0(4)
+#define GPIO_NAND_D2 EXYNOS5_GPC0(5)
+#define GPIO_NAND_D3 EXYNOS5_GPC0(6)
+#define GPIO_NAND_D4 EXYNOS5_GPC1(0)
+#define GPIO_NAND_D5 EXYNOS5_GPC1(1)
+#define GPIO_NAND_D6 EXYNOS5_GPC1(2)
+#define GPIO_NAND_D7 EXYNOS5_GPC1(3)
+
+#define GPIO_BTREG_ON EXYNOS5_GPH0(0)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_T_FLASH_CLK EXYNOS5_GPC3(0)
+#define GPIO_T_FLASH_CMD EXYNOS5_GPC3(1)
+#define GPIO_T_FLASH_D0 EXYNOS5_GPC3(3)
+#define GPIO_T_FLASH_D1 EXYNOS5_GPC3(4)
+#define GPIO_T_FLASH_D2 EXYNOS5_GPC3(5)
+#define GPIO_T_FLASH_D3 EXYNOS5_GPC3(6)
+
+#define GPIO_GPS_UART_RXD EXYNOS5_GPD0(0)
+#define GPIO_GPS_UART_TXD EXYNOS5_GPD0(1)
+#define GPIO_GPS_UART_CTS EXYNOS5_GPD0(2)
+#define GPIO_GPS_UART_RTS EXYNOS5_GPD0(3)
+
+#define GPIO_HDMI_EN EXYNOS5_GPD1(0)
+
+#define GPIO_TOUCH_EN EXYNOS5_GPD1(1)
+
+#define GPIO_LCD_ID EXYNOS5_GPD1(4)
+
+#define GPIO_MOTOR_EN EXYNOS5_GPD1(6)
+
+#define GPIO_NFC_EN EXYNOS5_GPD1(7)
+
+#define GPIO_TA_INT EXYNOS5_GPX0(0)
+
+#define GPIO_DET_35 EXYNOS5_GPX0(1)
+
+#define GPIO_AP_PMIC_IRQ EXYNOS5_GPX0(2)
+
+#define GPIO_CHG_INT EXYNOS5_GPX0(4)
+
+/*#define GPIO_POGO_DET EXYNOS5_GPX0(5) */
+
+#define GPIO_DOCK_INT EXYNOS5_GPX3(0)
+
+
+#define GPIO_DP_HPD EXYNOS5_GPX0(7)
+
+#define GPIO_DPRAM_A0 EXYNOS5_GPY3(0)
+#define GPIO_DPRAM_A1 EXYNOS5_GPY3(1)
+#define GPIO_DPRAM_A2 EXYNOS5_GPY3(2)
+#define GPIO_DPRAM_A3 EXYNOS5_GPY3(3)
+#define GPIO_DPRAM_A4 EXYNOS5_GPY3(4)
+#define GPIO_DPRAM_A5 EXYNOS5_GPY3(5)
+#define GPIO_DPRAM_A6 EXYNOS5_GPY3(6)
+#define GPIO_DPRAM_A7 EXYNOS5_GPY3(7)
+#define GPIO_DPRAM_A8 EXYNOS5_GPY4(0)
+#define GPIO_DPRAM_A9 EXYNOS5_GPY4(1)
+#define GPIO_DPRAM_A10 EXYNOS5_GPY4(2)
+#define GPIO_DPRAM_A11 EXYNOS5_GPY4(3)
+#define GPIO_DPRAM_A12 EXYNOS5_GPY4(4)
+#define GPIO_DPRAM_A13 EXYNOS5_GPY4(5)
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_D0 EXYNOS5_GPY5(0)
+#define GPIO_DPRAM_D1 EXYNOS5_GPY5(1)
+#define GPIO_DPRAM_D2 EXYNOS5_GPY5(2)
+#define GPIO_DPRAM_D3 EXYNOS5_GPY5(3)
+#define GPIO_DPRAM_D4 EXYNOS5_GPY5(4)
+#define GPIO_DPRAM_D5 EXYNOS5_GPY5(5)
+#define GPIO_DPRAM_D6 EXYNOS5_GPY5(6)
+#define GPIO_DPRAM_D7 EXYNOS5_GPY5(7)
+#define GPIO_DPRAM_D8 EXYNOS5_GPY6(0)
+#define GPIO_DPRAM_D9 EXYNOS5_GPY6(1)
+#define GPIO_DPRAM_D10 EXYNOS5_GPY6(2)
+#define GPIO_DPRAM_D11 EXYNOS5_GPY6(3)
+#define GPIO_DPRAM_D12 EXYNOS5_GPY6(4)
+#define GPIO_DPRAM_D13 EXYNOS5_GPY6(5)
+#define GPIO_DPRAM_D14 EXYNOS5_GPY6(6)
+#define GPIO_DPRAM_D15 EXYNOS5_GPY6(7)
+#define GPIO_DPRAM_INT EXYNOS5_GPX0(5)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+
+#define GPIO_ACC_INT EXYNOS5_GPX1(4)
+
+#define GPIO_NFC_WAKE EXYNOS5_GPX1(5)
+
+#define GPIO_SPI_INT EXYNOS5_GPX1(6)
+
+#define GPIO_NFC_IRQ EXYNOS5_GPX1(7)
+
+#define GPIO_VOL_UP EXYNOS5_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS5_GPX2(1)
+
+#define GPIO_MSENSE_RDY EXYNOS5_GPX2(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+
+#define GPIO_BT_HOST_WAKE EXYNOS5_GPX2(6)
+
+#define GPIO_nPOWER EXYNOS5_GPX2(7)
+
+#define GPIO_FUEL_ALERT EXYNOS5_GPX2(3)
+#define GPIO_FUEL_SCL_18V EXYNOS5_GPZ(6)
+#define GPIO_FUEL_SDA_18V EXYNOS5_GPZ(5)
+
+#define GPIO_GPS_PWR_EN EXYNOS5_GPE1(0)
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+#define GPIO_GPS_CTS EXYNOS5_GPA0(6)
+#define GPIO_GPS_RTS EXYNOS5_GPA0(7)
+#define GPIO_GPS_RXD EXYNOS5_GPA0(4)
+#define GPIO_GPS_TXD EXYNOS5_GPA0(5)
+
+#define GPIO_GPS_CTS_AF 2
+#define GPIO_GPS_RTS_AF 2
+#define GPIO_GPS_RXD_AF 2
+#define GPIO_GPS_TXD_AF 2
+
+
+#define GPIO_T_FLASH_DETECT EXYNOS5_GPX3(4)
+
+#define GPIO_EAR_SEND_END EXYNOS5_GPX3(5)
+
+#define GPIO_HDMI_CEC EXYNOS5_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS5_GPX3(7)
+
+#define GPIO_TF_EN EXYNOS5_GPY2(0)
+
+#define GPIO_5M_CAM_RESET EXYNOS5_GPE0(0)
+
+#define GPIO_CAM_FLASH_EN EXYNOS5_GPE0(3)
+#define GPIO_CAM_FLASH_SET EXYNOS5_GPE0(4)
+
+#define GPIO_UART_SEL EXYNOS5_GPE0(5)
+
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+
+#define GPIO_ISP_TXD EXYNOS5_GPE0(7)
+
+#define GPIO_GPS_EN EXYNOS5_GPE1(0)
+
+#define GPIO_ISP_RXD EXYNOS5_GPE1(1)
+
+#define GPIO_5M_CAM_SDA_18V EXYNOS5_GPF0(0)
+#define GPIO_5M_CAM_SCL_18V EXYNOS5_GPF0(1)
+
+#define GPIO_VT_CAM_SDA_18V EXYNOS5_GPF0(2)
+#define GPIO_VT_CAM_SCL_18V EXYNOS5_GPF0(3)
+
+#define GPIO_NFC_SPI_CLK EXYNOS5_GPF1(0)
+#define GPIO_NFC_SPI_CS EXYNOS5_GPF1(1)
+#define GPIO_NFC_SPI_MISO EXYNOS5_GPF1(2)
+#define GPIO_NFC_SPI_MOSI EXYNOS5_GPF1(3)
+
+#define GPIO_NFC_CLK_REQ EXYNOS5_GPG0(2)
+
+#define GPIO_2MIC_WAKE EXYNOS5_GPG0(3)
+#define GPIO_2MIC_RST EXYNOS5_GPG0(4)
+
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS5_GPG0(5)
+
+#define GPIO_HDMI_LS_EN EXYNOS5_GPG0(7)
+
+#define GPIO_MHL_DSCL_18V EXYNOS5_GPB3(1)
+#define GPIO_MHL_DSDA_18V EXYNOS5_GPB3(0)
+#define GPIO_MHL_INT EXYNOS5_GPG0(6)
+#define GPIO_MHL_RST EXYNOS5_GPG0(7)
+#define GPIO_MHL_SCL_18V EXYNOS5_GPA0(5)
+#define GPIO_MHL_SDA_18V EXYNOS5_GPA0(4)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+
+#define GPIO_MOTOR_EN EXYNOS5_GPD1(6)
+#define GPIO_MOTOR_PWM EXYNOS5_GPB2(1)
+#define GPIO_MOTOR_SCL_18V EXYNOS5_GPD1(3)
+#define GPIO_MOTOR_SDA_18V EXYNOS5_GPD1(2)
+
+#define GPIO_MSENSE_RDY EXYNOS5_GPX2(2)
+#define GPIO_MSENSE_RST EXYNOS5_GPG2(0)
+#define GPIO_MSENSE_SDA EXYNOS5_GPV2(7)
+#define GPIO_MSENSE_SCL EXYNOS5_GPV2(6)
+
+#define GPIO_PS_ALS_SDA EXYNOS5_GPG0(0)
+#define GPIO_PS_ALS_SCL EXYNOS5_GPG0(1)
+#define GPIO_PS_VOUT EXYNOS5_GPH1(2)
+#define GPIO_HUM_SDA EXYNOS5_GPV2(5)
+#define GPIO_HUM_SCL EXYNOS5_GPV2(4)
+
+#define GPIO_CAM_FLASH_EN_T EXYNOS5_GPG1(0)
+#define GPIO_CAM_FLASH_SET_T EXYNOS5_GPG1(1)
+
+#define GPIO_TOUCH_CHG EXYNOS5_GPG1(2)
+#define GPIO_TOUCH_RESET EXYNOS5_GPG1(3)
+
+#define GPIO_TA_nCHG EXYNOS5_GPG1(4)
+#define GPIO_TA_EN EXYNOS5_GPG1(5)
+#define GPIO_TA_nCONNECTED EXYNOS5_GPX0(0)
+
+#define GPIO_CAM_VT_nRST EXYNOS5_GPG1(6)
+
+#define GPIO_MSENSE_RST EXYNOS5_GPG2(0)
+
+#define GPIO_VTCAM_MCLK EXYNOS5_GPG2(1)
+
+#define GPIO_USB_SEL1 EXYNOS5_GPH0(1)
+
+#define GPIO_TP EXYNOS5_GPH0(2)
+
+#define GPIO_CAM_MCLK EXYNOS5_GPH0(3)
+
+#define GPIO_WM8994_LDO EXYNOS5_GPH1(1)
+
+#define GPIO_ALS_nRST EXYNOS5_GPH1(2)
+
+#define GPIO_BT_WAKE EXYNOS5_GPH1(3)
+
+#define GPIO_LCD_EN EXYNOS5_GPH1(7)
+
+#define GPIO_MM_I2S_CLK EXYNOS5_GPZ(0)
+#define GPIO_MM_I2S_SYNC EXYNOS5_GPZ(2)
+#define GPIO_MM_I2S_DI EXYNOS5_GPZ(3)
+#define GPIO_MM_I2S_DO EXYNOS5_GPZ(4)
+
+#define GPIO_BUCK4_SEL EXYNOS5_GPV0(0)
+
+#define GPIO_BUCK3_SEL EXYNOS5_GPV0(1)
+
+#define GPIO_5M_CORE_EN EXYNOS5_GPV0(2)
+
+#define GPIO_CAM_IO_EN EXYNOS5_GPV0(3)
+
+#define GPIO_BUCK2_SEL EXYNOS5_GPV0(4)
+
+#define GPIO_PMIC_DVS3 EXYNOS5_GPV0(5)
+#define GPIO_PMIC_DVS2 EXYNOS5_GPV0(6)
+#define GPIO_PMIC_DVS1 EXYNOS5_GPV0(7)
+
+#define GPIO_WLREG_ON EXYNOS5_GPV1(0)
+
+#define GPIO_HW_REV3 EXYNOS5_GPV1(1)
+#define GPIO_HW_REV2 EXYNOS5_GPV1(2)
+#define GPIO_HW_REV1 EXYNOS5_GPV1(3)
+#define GPIO_HW_REV0 EXYNOS5_GPV1(4)
+
+#define GPIO_WLAN_EN EXYNOS5_GPV1(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS5_GPC3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS5_GPC3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS5_GPC3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS5_GPC3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS5_GPC3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS5_GPC3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+/**
+ * Remappig for downward compatibility.
+ */
+#define GPIO_PMIC_IRQ GPIO_AP_PMIC_IRQ
+
+#define GPIO_5M_nRST GPIO_5M_CAM_RESET
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS5_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS5_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS5_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+/* #define GPIO_DPRAM_LBN EXYNOS4_GPY1(0) // for via modem */
+/* #define GPIO_DPRAM_UBN EXYNOS4_GPY1(1) // for via modem */
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS5_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS5_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS5_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS5_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS5_GPD1(5)
+#define CP_CMC221_CPU_RST EXYNOS5_GPB0(1)
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS5_GPX0(5)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(5) /* IRQ of GPX0[5] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS5_GPX0(3) /* CMC2AP_INT_1 */
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS5_GPX1(2) /* AP2CMC_INT_3 */
+/* #define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1) // for USB */
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS5_GPX0(6) /* AP2CMC_INT_1 */
+#define GPIO_IPC_HOST_WAKEUP EXYNOS5_GPX1(0) /* CMC2AP_INT_2 */
+
+#define GPIO_CMC_CLK_18V GPIO_NFC_SPI_CLK
+#define GPIO_CMC_CS_18V GPIO_NFC_SPI_CS
+
+#define GPIO_FM34_BYPASS EXYNOS5_GPH1(4)
+#define GPIO_FM34_PWDN GPIO_2MIC_WAKE
+#define GPIO_FM34_RESET GPIO_2MIC_RST
+#define GPIO_FM34_SCL_18V GPIO_MM_SCL_18V
+#define GPIO_FM34_SDA_18V GPIO_MM_SDA_18V
+
+#define GPIO_ES305_WAKEUP GPIO_2MIC_WAKE
+#define GPIO_ES305_RESET GPIO_2MIC_RST
+
+#endif /* __MACH_GPIO_P10_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo.h b/arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo.h
new file mode 100644
index 0000000..98d9acf
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev01-p10-lungo.h
@@ -0,0 +1,387 @@
+#ifndef __MACH_GPIO_P10_H
+#define __MACH_GPIO_P10 __FILE__
+
+#include <mach/gpio.h>
+
+extern void p10_config_gpio_table(void);
+extern void p10_config_sleep_gpio_table(void);
+
+/**
+ * Main GPIO function mapping.
+ */
+#define GPIO_BT_UART_RXD EXYNOS5_GPA0(0)
+#define GPIO_BT_UART_TXD EXYNOS5_GPA0(1)
+#define GPIO_BT_UART_CTS EXYNOS5_GPA0(2)
+#define GPIO_BT_UART_RTS EXYNOS5_GPA0(3)
+
+#define GPIO_HDMI_DCDC_EN EXYNOS5_GPA0(4)
+
+#define GPIO_CHG_SDA_18V EXYNOS5_GPE0(1)
+#define GPIO_CHG_SCL_18V EXYNOS5_GPE0(2)
+
+#define GPIO_AP_RXD EXYNOS5_GPA1(0)
+#define GPIO_AP_TXD EXYNOS5_GPA1(1)
+
+#define GPIO_TSP_SDA_18V EXYNOS5_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS5_GPA1(3)
+
+#define GPIO_IPC_RXD EXYNOS5_GPA1(4)
+#define GPIO_IPC_TXD EXYNOS5_GPA1(5)
+
+#define GPIO_MM_SDA_18V EXYNOS5_GPA2(0)
+#define GPIO_MM_SCL_18V EXYNOS5_GPA2(1)
+
+#define GPIO_AP_PMIC_SDA EXYNOS5_GPA2(2)
+#define GPIO_AP_PMIC_SCL EXYNOS5_GPA2(3)
+
+#define GPIO_5M_SPI_CLK EXYNOS5_GPA2(4)
+#define GPIO_5M_SPI_CS EXYNOS5_GPA2(5)
+#define GPIO_5M_SPI_DI EXYNOS5_GPA2(6)
+#define GPIO_5M_SPI_DO EXYNOS5_GPA2(7)
+
+#define GPIO_OTG_EN EXYNOS5_GPB0(3)
+
+#define GPIO_USB30_EN EXYNOS5_GPB0(4)
+
+#define GPIO_POGO_SPDIF EXYNOS5_GPB1(0)
+
+#define GPIO_LCD_PWM_IN_18V EXYNOS5_GPB2(0)
+
+#define GPIO_ACCESSORY_CHECK EXYNOS5_GPE0(4)
+#define GPIO_ACCESSORY_EN EXYNOS5_GPH1(5)
+#define GPIO_ACCESSORY_INT EXYNOS5_GPX3(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+#define GPIO_ADC_SCL_18V EXYNOS5_GPV3(0)
+#define GPIO_ADC_SDA_18V EXYNOS5_GPV3(1)
+
+#define GPIO_MOTOR_PWM EXYNOS5_GPB2(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS5_GPB2(2)
+#define GPIO_CODEC_SCL_18V EXYNOS5_GPB2(3)
+
+#define GPIO_DISP_SDA_18V EXYNOS5_GPB3(0)
+#define GPIO_DISP_SCL_18V EXYNOS5_GPB3(1)
+
+#define GPIO_SENSE_SDA_18V EXYNOS5_GPB3(2)
+#define GPIO_SENSE_SCL_18V EXYNOS5_GPB3(3)
+
+#define GPIO_NAND_CLK EXYNOS5_GPC0(0)
+#define GPIO_NAND_CMD EXYNOS5_GPC0(1)
+
+#define GPIO_eMMC_EN EXYNOS5_GPC0(2)
+
+#define GPIO_NAND_D0 EXYNOS5_GPC0(3)
+#define GPIO_NAND_D1 EXYNOS5_GPC0(4)
+#define GPIO_NAND_D2 EXYNOS5_GPC0(5)
+#define GPIO_NAND_D3 EXYNOS5_GPC0(6)
+#define GPIO_NAND_D4 EXYNOS5_GPC1(0)
+#define GPIO_NAND_D5 EXYNOS5_GPC1(1)
+#define GPIO_NAND_D6 EXYNOS5_GPC1(2)
+#define GPIO_NAND_D7 EXYNOS5_GPC1(3)
+
+#define GPIO_BTREG_ON EXYNOS5_GPH0(0)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_T_FLASH_CLK EXYNOS5_GPC3(0)
+#define GPIO_T_FLASH_CMD EXYNOS5_GPC3(1)
+#define GPIO_T_FLASH_D0 EXYNOS5_GPC3(3)
+#define GPIO_T_FLASH_D1 EXYNOS5_GPC3(4)
+#define GPIO_T_FLASH_D2 EXYNOS5_GPC3(5)
+#define GPIO_T_FLASH_D3 EXYNOS5_GPC3(6)
+
+#define GPIO_GPS_UART_RXD EXYNOS5_GPD0(0)
+#define GPIO_GPS_UART_TXD EXYNOS5_GPD0(1)
+#define GPIO_GPS_UART_CTS EXYNOS5_GPD0(2)
+#define GPIO_GPS_UART_RTS EXYNOS5_GPD0(3)
+
+#define GPIO_HDMI_EN EXYNOS5_GPD1(0)
+
+#define GPIO_TOUCH_EN EXYNOS5_GPD1(1)
+
+#define GPIO_LCD_ID EXYNOS5_GPD1(4)
+
+#define GPIO_MOTOR_EN EXYNOS5_GPD1(6)
+
+#define GPIO_NFC_EN EXYNOS5_GPD1(7)
+
+#define GPIO_TA_INT EXYNOS5_GPX0(0)
+
+#define GPIO_DET_35 EXYNOS5_GPX0(1)
+
+#define GPIO_AP_PMIC_IRQ EXYNOS5_GPX0(2)
+
+#define GPIO_CHG_INT EXYNOS5_GPX0(4)
+
+/*#define GPIO_POGO_DET EXYNOS5_GPX0(5) */
+
+#define GPIO_DOCK_INT EXYNOS5_GPX3(0)
+
+
+#define GPIO_DP_HPD EXYNOS5_GPX0(7)
+
+#define GPIO_DPRAM_A0 EXYNOS5_GPY3(0)
+#define GPIO_DPRAM_A1 EXYNOS5_GPY3(1)
+#define GPIO_DPRAM_A2 EXYNOS5_GPY3(2)
+#define GPIO_DPRAM_A3 EXYNOS5_GPY3(3)
+#define GPIO_DPRAM_A4 EXYNOS5_GPY3(4)
+#define GPIO_DPRAM_A5 EXYNOS5_GPY3(5)
+#define GPIO_DPRAM_A6 EXYNOS5_GPY3(6)
+#define GPIO_DPRAM_A7 EXYNOS5_GPY3(7)
+#define GPIO_DPRAM_A8 EXYNOS5_GPY4(0)
+#define GPIO_DPRAM_A9 EXYNOS5_GPY4(1)
+#define GPIO_DPRAM_A10 EXYNOS5_GPY4(2)
+#define GPIO_DPRAM_A11 EXYNOS5_GPY4(3)
+#define GPIO_DPRAM_A12 EXYNOS5_GPY4(4)
+#define GPIO_DPRAM_A13 EXYNOS5_GPY4(5)
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_D0 EXYNOS5_GPY5(0)
+#define GPIO_DPRAM_D1 EXYNOS5_GPY5(1)
+#define GPIO_DPRAM_D2 EXYNOS5_GPY5(2)
+#define GPIO_DPRAM_D3 EXYNOS5_GPY5(3)
+#define GPIO_DPRAM_D4 EXYNOS5_GPY5(4)
+#define GPIO_DPRAM_D5 EXYNOS5_GPY5(5)
+#define GPIO_DPRAM_D6 EXYNOS5_GPY5(6)
+#define GPIO_DPRAM_D7 EXYNOS5_GPY5(7)
+#define GPIO_DPRAM_D8 EXYNOS5_GPY6(0)
+#define GPIO_DPRAM_D9 EXYNOS5_GPY6(1)
+#define GPIO_DPRAM_D10 EXYNOS5_GPY6(2)
+#define GPIO_DPRAM_D11 EXYNOS5_GPY6(3)
+#define GPIO_DPRAM_D12 EXYNOS5_GPY6(4)
+#define GPIO_DPRAM_D13 EXYNOS5_GPY6(5)
+#define GPIO_DPRAM_D14 EXYNOS5_GPY6(6)
+#define GPIO_DPRAM_D15 EXYNOS5_GPY6(7)
+#define GPIO_DPRAM_INT EXYNOS5_GPX0(5)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+
+#define GPIO_ACC_INT EXYNOS5_GPX1(4)
+
+#define GPIO_NFC_WAKE EXYNOS5_GPX1(5)
+
+#define GPIO_SPI_INT EXYNOS5_GPX1(6)
+
+#define GPIO_NFC_IRQ EXYNOS5_GPX1(7)
+
+#define GPIO_VOL_UP EXYNOS5_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS5_GPX2(1)
+
+#define GPIO_MSENSE_RDY EXYNOS5_GPX2(2)
+
+#define GPIO_ADC_INT EXYNOS5_GPX2(4)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+
+#define GPIO_BT_HOST_WAKE EXYNOS5_GPX2(6)
+
+#define GPIO_nPOWER EXYNOS5_GPX2(7)
+
+#define GPIO_FUEL_ALERT EXYNOS5_GPX2(3)
+#define GPIO_FUEL_SCL_18V EXYNOS5_GPZ(6)
+#define GPIO_FUEL_SDA_18V EXYNOS5_GPZ(5)
+
+#define GPIO_GPS_PWR_EN EXYNOS5_GPE1(0)
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+#define GPIO_GPS_CTS EXYNOS5_GPA0(6)
+#define GPIO_GPS_RTS EXYNOS5_GPA0(7)
+#define GPIO_GPS_RXD EXYNOS5_GPA0(4)
+#define GPIO_GPS_TXD EXYNOS5_GPA0(5)
+
+#define GPIO_GPS_CTS_AF 2
+#define GPIO_GPS_RTS_AF 2
+#define GPIO_GPS_RXD_AF 2
+#define GPIO_GPS_TXD_AF 2
+
+
+#define GPIO_T_FLASH_DETECT EXYNOS5_GPX3(4)
+
+#define GPIO_EAR_SEND_END EXYNOS5_GPX3(5)
+
+#define GPIO_HDMI_CEC EXYNOS5_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS5_GPX3(7)
+
+#define GPIO_TF_EN EXYNOS5_GPY2(0)
+
+#define GPIO_5M_CAM_RESET EXYNOS5_GPE0(0)
+
+#define GPIO_CAM_FLASH_EN EXYNOS5_GPE0(3)
+#define GPIO_CAM_FLASH_SET EXYNOS5_GPE0(4)
+
+#define GPIO_UART_SEL EXYNOS5_GPE0(5)
+
+#define GPIO_GPS_nRST EXYNOS5_GPE0(6)
+
+#define GPIO_ISP_TXD EXYNOS5_GPE0(7)
+
+#define GPIO_GPS_EN EXYNOS5_GPE1(0)
+
+#define GPIO_ISP_RXD EXYNOS5_GPE1(1)
+
+#define GPIO_5M_CAM_SDA_18V EXYNOS5_GPF0(0)
+#define GPIO_5M_CAM_SCL_18V EXYNOS5_GPF0(1)
+
+#define GPIO_VT_CAM_SDA_18V EXYNOS5_GPF0(2)
+#define GPIO_VT_CAM_SCL_18V EXYNOS5_GPF0(3)
+
+#define GPIO_NFC_SPI_CLK EXYNOS5_GPF1(0)
+#define GPIO_NFC_SPI_CS EXYNOS5_GPF1(1)
+#define GPIO_NFC_SPI_MISO EXYNOS5_GPF1(2)
+#define GPIO_NFC_SPI_MOSI EXYNOS5_GPF1(3)
+
+#define GPIO_NFC_CLK_REQ EXYNOS5_GPG0(2)
+
+#define GPIO_2MIC_WAKE EXYNOS5_GPG0(3)
+#define GPIO_2MIC_RST EXYNOS5_GPG0(4)
+
+#define GPIO_LED_BACKLIGHT_RESET EXYNOS5_GPG0(5)
+
+#define GPIO_HDMI_LS_EN EXYNOS5_GPG0(7)
+
+#define GPIO_MHL_DSCL_18V EXYNOS5_GPB3(1)
+#define GPIO_MHL_DSDA_18V EXYNOS5_GPB3(0)
+#define GPIO_MHL_INT EXYNOS5_GPG0(6)
+#define GPIO_MHL_RST EXYNOS5_GPG0(7)
+#define GPIO_MHL_SCL_18V EXYNOS5_GPA0(5)
+#define GPIO_MHL_SDA_18V EXYNOS5_GPA0(4)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+
+#define GPIO_MOTOR_EN EXYNOS5_GPD1(6)
+#define GPIO_MOTOR_PWM EXYNOS5_GPB2(1)
+#define GPIO_MOTOR_SCL_18V EXYNOS5_GPD1(3)
+#define GPIO_MOTOR_SDA_18V EXYNOS5_GPD1(2)
+
+#define GPIO_MSENSE_RDY EXYNOS5_GPX2(2)
+#define GPIO_MSENSE_RST EXYNOS5_GPG2(0)
+#define GPIO_MSENSE_SDA EXYNOS5_GPV2(7)
+#define GPIO_MSENSE_SCL EXYNOS5_GPV2(6)
+
+#define GPIO_PS_ALS_SDA EXYNOS5_GPG0(0)
+#define GPIO_PS_ALS_SCL EXYNOS5_GPG0(1)
+#define GPIO_PS_VOUT EXYNOS5_GPH1(2)
+#define GPIO_HUM_SDA EXYNOS5_GPV2(5)
+#define GPIO_HUM_SCL EXYNOS5_GPV2(4)
+
+#define GPIO_CAM_FLASH_EN_T EXYNOS5_GPG1(0)
+#define GPIO_CAM_FLASH_SET_T EXYNOS5_GPG1(1)
+
+#define GPIO_TOUCH_CHG EXYNOS5_GPG1(2)
+#define GPIO_TOUCH_RESET EXYNOS5_GPG1(3)
+
+#define GPIO_TA_nCHG EXYNOS5_GPG1(4)
+#define GPIO_TA_EN EXYNOS5_GPG1(5)
+#define GPIO_TA_nCONNECTED EXYNOS5_GPX0(0)
+
+#define GPIO_CAM_VT_nRST EXYNOS5_GPG1(6)
+
+#define GPIO_MSENSE_RST EXYNOS5_GPG2(0)
+
+#define GPIO_VTCAM_MCLK EXYNOS5_GPG2(1)
+
+#define GPIO_USB_SEL1 EXYNOS5_GPH0(1)
+
+#define GPIO_TP EXYNOS5_GPH0(2)
+
+#define GPIO_CAM_MCLK EXYNOS5_GPH0(3)
+
+#define GPIO_WM8994_LDO EXYNOS5_GPH1(1)
+
+#define GPIO_ALS_nRST EXYNOS5_GPH1(2)
+
+#define GPIO_BT_WAKE EXYNOS5_GPH1(3)
+
+#define GPIO_LCD_EN EXYNOS5_GPH1(7)
+
+#define GPIO_MM_I2S_CLK EXYNOS5_GPZ(0)
+#define GPIO_MM_I2S_SYNC EXYNOS5_GPZ(2)
+#define GPIO_MM_I2S_DI EXYNOS5_GPZ(3)
+#define GPIO_MM_I2S_DO EXYNOS5_GPZ(4)
+
+#define GPIO_BUCK4_SEL EXYNOS5_GPV0(0)
+
+#define GPIO_BUCK3_SEL EXYNOS5_GPV0(1)
+
+#define GPIO_5M_CORE_EN EXYNOS5_GPV0(2)
+
+#define GPIO_CAM_IO_EN EXYNOS5_GPV0(3)
+
+#define GPIO_BUCK2_SEL EXYNOS5_GPV0(4)
+
+#define GPIO_PMIC_DVS3 EXYNOS5_GPV0(5)
+#define GPIO_PMIC_DVS2 EXYNOS5_GPV0(6)
+#define GPIO_PMIC_DVS1 EXYNOS5_GPV0(7)
+
+#define GPIO_WLREG_ON EXYNOS5_GPV1(0)
+
+#define GPIO_HW_REV3 EXYNOS5_GPV1(1)
+#define GPIO_HW_REV2 EXYNOS5_GPV1(2)
+#define GPIO_HW_REV1 EXYNOS5_GPV1(3)
+#define GPIO_HW_REV0 EXYNOS5_GPV1(4)
+
+#define GPIO_WLAN_EN EXYNOS5_GPV1(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS5_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS5_GPC3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS5_GPC3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS5_GPC3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS5_GPC3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS5_GPC3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS5_GPC3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+/**
+ * Remappig for downward compatibility.
+ */
+#define GPIO_PMIC_IRQ GPIO_AP_PMIC_IRQ
+
+#define GPIO_5M_nRST GPIO_5M_CAM_RESET
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS5_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS5_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS5_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS5_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS5_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS5_GPY0(5)
+/* #define GPIO_DPRAM_LBN EXYNOS4_GPY1(0) // for via modem */
+/* #define GPIO_DPRAM_UBN EXYNOS4_GPY1(1) // for via modem */
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS5_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS5_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS5_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS5_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS5_GPD1(5)
+#define CP_CMC221_CPU_RST EXYNOS5_GPB0(1)
+#define GPIO_LTE_ACTIVE EXYNOS5_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS5_GPX0(5)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(5) /* IRQ of GPX0[5] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS5_GPX0(3) /* CMC2AP_INT_1 */
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS5_GPX1(2) /* AP2CMC_INT_3 */
+/* #define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1) // for USB */
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS5_GPX0(6) /* AP2CMC_INT_1 */
+#define GPIO_IPC_HOST_WAKEUP EXYNOS5_GPX1(0) /* CMC2AP_INT_2 */
+
+#define GPIO_CMC_CLK_18V GPIO_NFC_SPI_CLK
+#define GPIO_CMC_CS_18V GPIO_NFC_SPI_CS
+
+#define GPIO_FM34_BYPASS EXYNOS5_GPH1(4)
+#define GPIO_FM34_PWDN GPIO_2MIC_WAKE
+#define GPIO_FM34_RESET GPIO_2MIC_RST
+#define GPIO_FM34_SCL_18V GPIO_MM_SCL_18V
+#define GPIO_FM34_SDA_18V GPIO_MM_SDA_18V
+
+#define GPIO_ES305_WAKEUP GPIO_2MIC_WAKE
+#define GPIO_ES305_RESET GPIO_2MIC_RST
+
+#endif /* __MACH_GPIO_P10_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev02-midas.h b/arch/arm/mach-exynos/include/mach/gpio-rev02-midas.h
new file mode 100644
index 0000000..d847177
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev02-midas.h
@@ -0,0 +1,244 @@
+#ifndef __MACH_GPIO_MIDAS_H
+#define __MACH_GPIO_MIDAS_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_REC_PCM_SYNC EXYSNO4_GPC0(2)
+#define GPIO_REC_PCM_IN EXYSNO4_GPC0(3)
+#define GPIO_REC_PCM_OUT EXYSNO4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4_GPB(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4_GPB(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+#define GPIO_VT_CCAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CCAM_SDA_18V EXYNOS4212_GPM4(3)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4_GPX2(2)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY4(3)
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY4(4)
+#define GPIO_BARO_INT EXYNOS4_GPX0(1)
+
+#define GPIO_NFC_SCL_18V EXYNOS4_GPY0(0)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPY0(1)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_TF_EN EXYNOS4_GPY0(4)
+
+
+#define GPIO_PMU_RST EXYNOS4_GPX3(2)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_PMIC_DVS1 EXYSNO4_GPY5(5)
+#define GPIO_PMIC_DVS2 EXYSNO4_GPY5(6)
+#define GPIO_PMIC_DVS3 EXYSNO4_GPY5(7)
+
+#define GPIO_BUCK2_SEL EXYNOS4_GPY6(0)
+#define GPIO_BUCK3_SEL EXYNOS4_GPY6(3)
+#define GPIO_BUCK4_SEL EXYNOS4_GPY6(4)
+
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_CNTL EXYNOS4_GPY3(6)
+#define GPIO_GPS_nRST EXYNOS4_GPY6(6)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPY6(7)
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ1(0)
+#define GPIO_TOUCH_EN EXYNOS4212_GPJ0(3)
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+
+#define GPIO_OTG_EN EXYNOS4_GPY3(2)
+
+#define GPIO_ISP_CORE_EN EXYNOS4_GPY6(2)
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPY3(2)
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPY3(0)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_EN EXYNOS4_GPL1(1)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_ACC_INT EXYNOS4_GPX1(4)
+
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(3)
+#define GPIO_SIM_DETECT EXYNOS4_GPX3(3)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+#define GPIO_ISP_STANDBY EXYNOS4_GPY5(4)
+
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_ADC_SDA EXYNOS4_GPY2(2)
+#define GPIO_ADC_SCL EXYNOS4_GPY2(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_MLCD_RST EXYNOS4_GPY4(5)
+
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+
+#define GPIO_HW_REV0 EXYNOS4_GPY5(0)
+#define GPIO_HW_REV1 EXYNOS4_GPY5(1)
+#define GPIO_HW_REV2 EXYNOS4_GPY5(2)
+#define GPIO_HW_REV3 EXYNOS4_GPY5(3)
+
+#define GPIO_CAM_IO_EN EXYNOS4_GPY6(1)
+#define GPIO_CAM_AF_EN EXYNOS4_GPY6(5)
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for XMM6262 and C2C */
+#define CP_PMU_RST_N EXYNOS4_GPX3(2)
+#define CP_RESET_REQ_N EXYNOS4_GPY4(6)
+#define CP_ON EXYNOS4_GPL2(5)
+#define PDA_ACTIVE EXYNOS4_GPY4(2)
+#define PHONE_ACTIVE EXYNOS4_GPX1(6)
+#define PHONE_ACTIVE_IRQ IRQ_EINT(14)
+#define CP_DUMP_INT EXYNOS4_GPX1(2)
+#define CP_DUMP_INT_IRQ IRQ_EINT(10)
+
+#endif /* __MACH_GPIO_MIDAS_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-rev03-c1kor.h b/arch/arm/mach-exynos/include/mach/gpio-rev03-c1kor.h
new file mode 100644
index 0000000..809b19d
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-rev03-c1kor.h
@@ -0,0 +1,346 @@
+#ifndef __MACH_GPIO_C1KOR_H
+#define __MACH_GPIO_C1KOR_H __FILE__
+
+#include <mach/gpio.h>
+
+extern void midas_config_gpio_table(void);
+extern void midas_config_sleep_gpio_table(void);
+
+#define GPIO_eMMC_EN EXYNOS4_GPK0(2)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_FM_I2S_CLK EXYNOS4_GPC0(0)
+#define GPIO_FM_I2S_SYNC EXYNOS4_GPC0(2)
+#define GPIO_FM_I2S_DI EXYNOS4_GPC0(3)
+#define GPIO_FM_I2S_DO EXYNOS4_GPC0(4)
+
+#define GPIO_IF_PMIC_SDA EXYNOS4212_GPM2(0)
+#define GPIO_IF_PMIC_SCL EXYNOS4212_GPM2(1)
+#define GPIO_PMIC_SDA EXYNOS4_GPB(2)
+#define GPIO_PMIC_SCL EXYNOS4_GPB(3)
+
+#define GPIO_ADC_SCL EXYNOS4_GPY0(2)
+#define GPIO_ADC_SDA EXYNOS4_GPY0(3)
+#define GPIO_ADC_INT EXYNOS4_GPX2(4)
+
+#define GPIO_CAM_SPI_SCLK EXYNOS4_GPB(4)
+#define GPIO_CAM_SPI_SSN EXYNOS4_GPB(5)
+#define GPIO_CAM_SPI_MISO EXYNOS4_GPB(6)
+#define GPIO_CAM_SPI_MOSI EXYNOS4_GPB(7)
+
+#define GPIO_CAM_MCLK EXYNOS4212_GPJ1(3)
+#define GPIO_VTCAM_MCLK EXYNOS4212_GPM2(2)
+
+#define GPIO_ISP_STANDBY EXYNOS4212_GPM0(1)
+#define GPIO_CAM_IO_EN EXYNOS4212_GPM0(2)
+#define GPIO_ISP_CORE_EN EXYNOS4212_GPM0(3)
+#define GPIO_CAM_AF_EN EXYNOS4212_GPM0(4)
+#define GPIO_CAM_SENSOR_CORE_EN EXYNOS4212_GPM0(7)
+#define GPIO_CAM_VT_nRST EXYNOS4212_GPM1(6)
+
+#define GPIO_8M_CAM_SCL_18V EXYNOS4_GPD1(0)
+#define GPIO_8M_CAM_SDA_18V EXYNOS4_GPD1(1)
+
+#define GPIO_VT_CAM_SCL_18V EXYNOS4212_GPM4(2)
+#define GPIO_VT_CAM_SDA_18V EXYNOS4212_GPM4(3)
+#define GPIO_VT_CAM_ID EXYNOS4_GPF1(2)
+
+/* Sensors & NFC*/
+#define GPIO_PS_ALS_EN EXYNOS4212_GPJ0(5)
+#define GPIO_PS_ALS_SDA_28V EXYNOS4_GPK1(1)
+#define GPIO_PS_ALS_SCL_28V EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_ACC_INT EXYNOS4_GPX0(0)
+
+#define GPIO_GYRO_DE EXYNOS4_GPL2(0)
+#define GPIO_GPS_nRST EXYNOS4_GPL2(1)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL2(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPF0(3)
+#define GPIO_GSENSE_SDA_18V EXYNOS4_GPD1(2)
+#define GPIO_GSENSE_SCL_18V EXYNOS4_GPD1(3)
+
+#define GPIO_MSENSOR_INT EXYNOS4212_GPJ0(7)
+#define GPIO_MSENSOR_SDA_18V EXYNOS4_GPY2(4)
+#define GPIO_MSENSOR_SCL_18V EXYNOS4_GPY2(5)
+
+#define GPIO_BENSE_SCL_18V EXYNOS4_GPY2(3)
+#define GPIO_BSENSE_SDA_18V EXYNOS4_GPY2(2)
+#define GPIO_BARO_INT EXYNOS4_GPF0(5)
+
+#define GPIO_TF_EN EXYNOS4_GPY2(0)
+
+#define GPIO_NFC_SCL_18V EXYNOS4_GPD1(1)
+#define GPIO_NFC_SDA_18V EXYNOS4_GPD1(0)
+#define GPIO_NFC_SCL_18V_00 EXYNOS4_GPB(3)
+#define GPIO_NFC_SDA_18V_00 EXYNOS4_GPB(2)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRMWARE EXYNOS4_GPL2(7)
+#define GPIO_NFC_CLK_REQ EXYNOS4212_GPM0(0)
+/* Sensors & NFC*/
+
+#define GPIO_DET_35 EXYNOS4_GPX0(1)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4_GPF1(7)
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4_GPF2(0)
+
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+#define GPIO_IF_PMIC_IRQ EXYNOS4_GPX1(5)
+
+#define GPIO_TSP_INT EXYNOS4212_GPM2(3)
+#define GPIO_TSP_SDA_18V EXYNOS4_GPA1(2)
+#define GPIO_TSP_SCL_18V EXYNOS4_GPA1(3)
+
+#define GPIO_BT_EN EXYNOS4_GPL0(6)
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#ifdef CONFIG_FM34_WE395
+#define GPIO_FM34_PWDN EXYNOS4_GPL0(3)
+#define GPIO_FM34_RESET EXYNOS4_GPL0(1)
+#define GPIO_FM34_BYPASS EXYNOS4_GPL0(2)
+#define GPIO_FM34_RESET_05 EXYNOS4_GPY1(3)
+#define GPIO_FM34_BYPASS_05 EXYNOS4_GPY1(2)
+#define GPIO_FM34_SCL EXYNOS4212_GPM4(0)
+#define GPIO_FM34_SDA EXYNOS4212_GPM4(1)
+#endif
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPL0(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPL0(2)
+
+
+#define GPIO_HDMI_EN EXYNOS4_GPL0(4)
+
+#define GPIO_3_TOUCH_INT EXYNOS4212_GPJ0(3)
+#define GPIO_OK_KEY_ANDROID EXYNOS4_GPX0(1)
+#define GPIO_3_TOUCH_EN EXYNOS4212_GPM0(0)
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+#define GPIO_3_TOUCH_LDO_EN EXYNOS4212_GPM3(4)
+#endif
+
+#define GPIO_PWM0 EXYNOS4_GPD0(0)
+#define GPIO_PWM1 EXYNOS4_GPD0(1)
+#define GPIO_PWM2 EXYNOS4_GPD0(2)
+#define GPIO_PWM3 EXYNOS4_GPD0(3)
+
+#define GPIO_VIBTONE_EN EXYNOS4212_GPJ0(6)
+
+#define GPIO_WLAN_EN EXYNOS4212_GPJ0(0)
+#define GPIO_WLAN_EN_AF 1
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_USB_SEL EXYNOS4212_GPJ0(1)
+
+#define GPIO_LCD_22V_EN EXYNOS4212_GPM4(4)
+#define GPIO_LCD_22V_EN_00 EXYNOS4_GPC0(1)
+
+#define GPIO_ISP_TXD EXYNOS4212_GPM4(5)
+#define GPIO_ISP_RXD EXYNOS4212_GPM4(6)
+
+#define GPIO_TA_EN EXYNOS4_GPL2(2)
+
+#if !defined(CONFIG_MACH_C1_KOR_LGT)
+#define GPIO_MHL_SEL EXYNOS4_GPL0(3)
+#endif
+
+#define GPIO_MHL_SDA_1_8V EXYNOS4_GPF0(4)
+#define GPIO_MHL_SCL_1_8V EXYNOS4_GPF0(6)
+#define GPIO_MHL_SDA_1_8V_00 EXYNOS4_GPB(2)
+#define GPIO_MHL_SCL_1_8V_00 EXYNOS4_GPB(3)
+
+#define GPIO_OTG_EN EXYNOS4_GPF0(7)
+
+#define GPIO_OLED_ID EXYNOS4_GPF1(0)
+#define GPIO_ISP_RESET EXYNOS4_GPF1(3)
+#define GPIO_FUEL_SCL EXYNOS4_GPF1(4)
+#define GPIO_FUEL_SDA EXYNOS4_GPF1(5)
+
+#define GPIO_MLCD_RST EXYNOS4_GPF2(1)
+#define GPIO_UART_SEL EXYNOS4_GPF2(3)
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+#define GPIO_LTE_VIA_UART_SEL EXYNOS4212_GPJ0(6)
+#endif
+#define GPIO_S_LED_I2C_SCL EXYNOS4_GPF2(6)
+#define GPIO_S_LED_I2C_SDA EXYNOS4_GPF2(7)
+#define GPIO_OLED_DET EXYNOS4_GPF3(0)
+
+#define GPIO_PMIC_DVS1 EXYNOS4212_GPM3(0)
+#define GPIO_PMIC_DVS2 EXYNOS4212_GPM3(1)
+
+/* Definitions for Sii 9244B0 */
+#define GPIO_PMIC_DVS3 EXYNOS4212_GPM3(2)
+#define GPIO_BUCK2_SEL EXYNOS4_GPF3(1)
+#define GPIO_BUCK3_SEL EXYNOS4_GPF3(2)
+#define GPIO_BUCK4_SEL EXYNOS4_GPF3(3)
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4212_GPJ1(4)
+
+#define GPIO_RGB_SDA_1_8V EXYNOS4_GPF0(0)
+#define GPIO_RGB_SCL_1_8V EXYNOS4_GPF0(1)
+#define GPIO_RGB_INT EXYNOS4_GPX2(2)
+#define GPIO_VOL_UP EXYNOS4212_GPJ1(1)
+#define GPIO_VOL_DOWN EXYNOS4212_GPJ1(2)
+#define GPIO_VOL_UP_00 EXYNOS4_GPX2(2)
+#define GPIO_VOL_DOWN_00 EXYNOS4_GPX3(3)
+
+#define GPIO_CAM_SW_EN EXYNOS4212_GPJ1(0)
+#define GPIO_TORCH_EN EXYNOS4212_GPJ1(1)
+#define GPIO_TORCH_SET EXYNOS4212_GPJ1(2)
+
+#define GPIO_MHL_DSCL_2_8V EXYNOS4_GPK1(0)
+#define GPIO_MHL_DSDA_2_8V EXYNOS4_GPK1(2)
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+#define GPIO_V_BUS_INT EXYNOS4_GPX2(4)
+#define GPIO_WPC_INT EXYNOS4_GPX3(0)
+
+#define GPIO_VIBTONE_PWM EXYNOS4_GPD0(1)
+
+#define GPIO_CODEC_SDA_18V EXYNOS4_GPD0(2)
+#define GPIO_CODEC_SCL_18V EXYNOS4_GPD0(3)
+#define GPIO_CODEC_SDA_18V_00 EXYNOS4_GPB(0)
+#define GPIO_CODEC_SCL_18V_00 EXYNOS4_GPB(1)
+
+#define GPIO_CODEC_LDO_EN EXYNOS4212_GPJ0(4)
+
+#define GPIO_WM8994_LDO EXYNOS4212_GPJ0(4)
+
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#define GPIO_SROM_ADDR_BUS_LOW EXYNOS4_GPY3(0)
+#define GPIO_SROM_ADDR_BUS_HIGH EXYNOS4_GPY4(0)
+#define GPIO_SROM_DATA_BUS_LOW EXYNOS4_GPY5(0)
+#define GPIO_SROM_DATA_BUS_HIGH EXYNOS4_GPY6(0)
+
+/* Definitions for CMC221 */
+#define CP_CMC221_PMIC_PWRON EXYNOS4_GPL2(5)
+#define CP_CMC221_CPU_RST EXYNOS4_GPL2(4)
+
+#define GPIO_LTE_ACTIVE EXYNOS4_GPX1(6)
+#define LTE_ACTIVE_IRQ IRQ_EINT(14) /* IRQ of GPX1[6] */
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS4_GPX3(3)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(27) /* IRQ of GPX3[3] */
+#else
+#define GPIO_CMC_IDPRAM_INT_00 EXYNOS4_GPX2(0)
+#define CMC_IDPRAM_INT_IRQ_00 IRQ_EINT(16) /* IRQ of GPX2[0] */
+#endif
+#define GPIO_CMC_IDPRAM_INT_01 EXYNOS4_GPX2(0)
+#define CMC_IDPRAM_INT_IRQ_01 IRQ_EINT(16) /* IRQ of GPX2[0] */
+
+#define GPIO_CMC_IDPRAM_STATUS EXYNOS4_GPX0(5)
+#define GPIO_CMC_IDPRAM_WAKEUP EXYNOS4_GPX3(2)
+
+#define GPIO_ACTIVE_STATE EXYNOS4_GPF1(1)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+
+#define GPIO_AP2CMC_INT2 EXYNOS4_GPX1(2)
+
+/* Definitions for an USB HUB for CMC221 */
+#define GPIO_USB_HUB_RST EXYNOS4_GPL0(0)
+#define GPIO_USB_HUB_SCL EXYNOS4_GPL1(0)
+#define GPIO_USB_HUB_SDA EXYNOS4_GPL1(1)
+#define GPIO_USB_HUB_INT EXYNOS4_GPX2(1)
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+/* Definitions for CBP7.2 */
+#define GPIO_CBP_PMIC_PWRON EXYNOS4212_GPM0(6)
+#define GPIO_CBP_PS_HOLD_OFF EXYNOS4212_GPM1(0)
+#define GPIO_CBP_CP_RST EXYNOS4_GPF2(4)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPF1(6)
+
+#define GPIO_CBP_PHONE_ACTIVE EXYNOS4_GPX1(3)
+#define CBP_PHONE_ACTIVE_IRQ IRQ_EINT(11)
+
+#define GPIO_CBP_DPRAM_INT_00 EXYNOS4_GPX2(0)
+#define CBP_DPRAM_INT_IRQ_00 IRQ_EINT(16) /* IRQ of GPX2[0] */
+#define GPIO_CBP_DPRAM_INT_01 EXYNOS4_GPX3(5)
+#define CBP_DPRAM_INT_IRQ_01 IRQ_EINT(29) /* IRQ of GPX3[5] */
+
+#define GPIO_CBP_BOOT_SEL EXYNOS4212_GPM0(5)
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+#define GPIO_TDMB_EN EXYNOS4_GPC0(0)
+#else
+#define GPIO_TDMB_EN EXYNOS4_GPC0(2)
+#endif
+#define GPIO_TDMB_INT EXYNOS4_GPC0(4)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPC1(1)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPC1(2)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPC1(3)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPC1(4)
+#endif
+
+#endif /* __MACH_GPIO_C1KOR_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-u1.h b/arch/arm/mach-exynos/include/mach/gpio-u1.h
new file mode 100644
index 0000000..a4b85ac
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-u1.h
@@ -0,0 +1,337 @@
+#ifndef __MACH_GPIO_U1_H
+#define __MACH_GPIO_U1_H __FILE__
+
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define DUMMY_GPIO EXYNOS4_GPL2(2)
+#endif
+#if defined(CONFIG_MACH_U1_BD)
+
+#define GPIO_XMMC0_CDn EXYNOS4_GPK0(2)
+
+#define GPIO_PS_ALS_SDA EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_SCL EXYNOS4_GPK3(2)
+
+#define GPIO_GYRO_INT EXYNOS4_GPX0(0)
+#define GPIO_GYRO_FIFOP_INT EXYNOS4_GPX0(1)
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_BUCK1_EN_A EXYNOS4_GPX0(5)
+#define GPIO_BUCK1_EN_B EXYNOS4_GPX0(6)
+#define GPIO_BUCK2_EN EXYNOS4_GPL0(0)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define VT_CAM_SDA_18V EXYNOS4_GPC1(0)
+#define VT_CAM_SCL_18V EXYNOS4_GPC1(2)
+
+#define CODEC_VT_SDA_18V EXYNOS4_GPC1(3)
+#define CODEC_VT_SCL_18V EXYNOS4_GPC1(4)
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_ISP_RESET EXYNOS4210_GPE0(4)
+#else
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+#endif
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_FUEL_SDA EXYNOS4210_GPE1(7)
+#define GPIO_FUEL_SCL EXYNOS4210_GPE2(0)
+#else
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#endif
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_USB_SDA EXYNOS4210_GPE1(0)
+#define GPIO_USB_SCL EXYNOS4210_GPE1(1)
+#define GPIO_MASSMEM_EN EXYNOS4_GPL1(1)
+#define GPIO_MASSMEM_EN_LEVEL 0
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+
+#define GPIO_CAM_IO_EN EXYNOS4210_GPE2(1)
+#define GPIO_CAM_SENSOR_CORE EXYNOS4210_GPE2(5)
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+
+#define GPIO_USB_SEL EXYNOS4_GPL0(6)
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+#else
+#define GPIO_UART_SEL EXYNOS4_GPL2(7)
+#endif
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPK1(0)
+#define GPIO_8M_AF_EN EXYNOS4_GPK1(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPK1(2)
+#define GPIO_3_TOUCH_INT EXYNOS4_GPL0(5)
+
+#define GPIO_VT_CAM_15V EXYNOS4210_GPE2(2)
+
+#define GPIO_CAM_MCLK EXYNOS4210_GPJ1(3)
+
+#define GPIO_CAM_VGA_nSTBY EXYNOS4_GPL2(0)
+#define GPIO_CAM_VGA_nRST EXYNOS4_GPL2(1)
+
+#define GPIO_DET_35 EXYNOS4_GPX3(2)
+#define GPIO_DET_35_AF 0xF
+
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_EAR_SEND_END_AF 0xF
+
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_GPS_PWR_EN DUMMY_GPIO
+#define GPIO_GPS_nRST DUMMY_GPIO
+#elif defined(CONFIG_TARGET_LOCALE_NTT)
+#define GPIO_GPS_PWR_EN EXYNOS4210_GPE2(3)
+#define GPIO_GPS_PWR_EN_SPI EXYNOS4210_GPE0(3)
+#define GPIO_GPS_nRST EXYNOS4210_GPE0(4)
+#else
+#define GPIO_GPS_PWR_EN EXYNOS4210_GPE0(3)
+#define GPIO_GPS_nRST EXYNOS4210_GPE0(4)
+#endif
+
+#define GPIO_BT_RXD EXYNOS4_GPA0(0)
+#define GPIO_BT_RXD_AF 2
+
+#define GPIO_BT_TXD EXYNOS4_GPA0(1)
+#define GPIO_BT_TXD_AF 2
+
+#define GPIO_BT_CTS EXYNOS4_GPA0(2)
+#define GPIO_BT_CTS_AF 2
+
+#define GPIO_BT_RTS EXYNOS4_GPA0(3)
+#define GPIO_BT_RTS_AF 2
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_GPS_RXD EXYNOS4_GPA0(4)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(5)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(6)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(7)
+#define GPIO_GPS_RTS_AF 2
+#else
+#define GPIO_GPS_RXD DUMMY_GPIO
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD DUMMY_GPIO
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS DUMMY_GPIO
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS DUMMY_GPIO
+#define GPIO_GPS_RTS_AF 2
+#endif
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_BOOT_SW_SEL EXYNOS4_GPA0(6)
+#define GPIO_USB_BOOT_EN EXYNOS4_GPA0(7)
+#endif
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_NFC_SCL EXYNOS4_GPY0(0)
+#else
+#define GPIO_NFC_SCL DUMMY_GPIO
+#endif
+#define GPIO_NFC_SDA EXYNOS4_GPY0(1)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRM EXYNOS4_GPL2(7)
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_NFC_IRQ EXYNOS4_GPX1(7)
+#else
+#define GPIO_NFC_IRQ DUMMY_GPIO
+#endif
+
+#define GPIO_2MIC_PWDN EXYNOS4_GPL2(3)
+#define GPIO_2MIC_RST EXYNOS4_GPL2(4)
+#define GPIO_2MIC_EN EXYNOS4_GPL2(5)
+
+#ifdef CONFIG_CHARGER_MAX8922_U1 /* sub-charger */
+#define GPIO_CHG_EN EXYNOS4_GPL2(2)
+#define GPIO_CHG_ING_N EXYNOS4_GPL2(4)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPL2(5)
+#endif
+
+#define GPIO_2MIC_SDA EXYNOS4_GPC1(2)
+#define GPIO_2MIC_SCL EXYNOS4_GPC1(0)
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_DPRAM_INT_N EXYNOS4_GPX1(0)
+#define GPIO_DPRAM_INT_N_AF 0xF
+#endif
+
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPX1(6)
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_PHONE_ACTIVE_AF 2
+#endif
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPX1(2)
+#else
+#define GPIO_PDA_ACTIVE EXYNOS4_GPX1(7)
+#define GPIO_CP_DUMP_INT DUMMY_GPIO
+#endif
+#define GPIO_CP_RST EXYNOS4_GPX1(4)
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_CP_RST_MSM EXYNOS4_GPL2(6)
+#endif
+#define GPIO_CP_REQ_RESET EXYNOS4_GPY4(6)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPX1(0)
+#ifndef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPX1(1)
+#else
+#define GPIO_IPC_HOST_WAKEUP DUMMY_GPIO
+#endif
+#ifndef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_SUSPEND_REQUEST EXYNOS4_GPX1(3)
+#else
+#define GPIO_SUSPEND_REQUEST DUMMY_GPIO
+#endif
+#define GPIO_ISP_INT EXYNOS4_GPX1(5)
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_SUSPEND_REQUEST IRQ_EINT11
+#define IRQ_IPC_HOST_WAKEUP IRQ_EINT9
+
+#define GPIO_WLAN_EN EXYNOS4_GPL1(2)
+#define GPIO_WLAN_EN_AF 1
+
+#define GPIO_BT_EN EXYNOS4_GPL0(4)
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE EXYNOS4_GPX2(6)
+#define GPIO_BT_HOST_WAKE_AF 0xF
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_WAKE EXYNOS4_GPX3(1)
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_HW_REV0 EXYNOS4210_GPE1(0)
+#define GPIO_HW_REV1 EXYNOS4210_GPE1(1)
+#define GPIO_HW_REV2 EXYNOS4210_GPE1(2)
+#define GPIO_HW_REV3 EXYNOS4210_GPE1(3)
+
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4210_GPJ1(4)
+#define GPIO_MHL_WAKE_UP_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_SEL EXYNOS4_GPL0(1)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_MSENSE_INT EXYNOS4_GPX2(2)
+#define GPIO_HDMI_EN EXYNOS4_GPX2(4)
+#define GPIO_HDMI_EN_REV07 EXYNOS4_GPL1(1)
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_ACC_INT EXYNOS4_GPX3(0)
+#define GPIO_USB_OTG_EN EXYNOS4_GPX3(3)
+
+#define GPIO_MSENSOR_MHL_SDA_28V EXYNOS4_GPD0(2)
+#define GPIO_MSENSOR_MHL_SDA_AF 0x3
+#define GPIO_MSENSOR_MHL_SCL_28V EXYNOS4_GPD0(3)
+#define GPIO_MSENSOR_MHL_SCL_AF 0x3
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+#else
+#define GPIO_MHL_SDA_18V EXYNOS4210_GPE1(6)
+#define GPIO_MHL_SCL_18V EXYNOS4210_GPE1(5)
+#endif
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_SDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_SDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_SCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_SCL_AF
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4210_GPE1(4)
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4210_GPE0(2)
+#else
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4210_GPE2(0)
+#endif
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4210_GPE2(4)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPC0(1)
+#define GPIO_TDMB_RST_N EXYNOS4_GPB(5)
+#define GPIO_TDMB_INT EXYNOS4_GPB(4)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPB(0)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPB(1)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPB(2)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPB(3)
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+#define GPIO_FM_RST EXYNOS4_GPB(0)
+#define GPIO_FM_INT EXYNOS4_GPB(1)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX2(4)
+#define GPIO_FM_SDA_28V EXYNOS4_GPB(2)
+#define GPIO_FM_SCL_28V EXYNOS4_GPB(3)
+#endif
+
+#ifdef CONFIG_ISDBT_FC8100
+#define GPIO_ISDBT_SCL_28V EXYNOS4210_GPE1(6)
+#define GPIO_ISDBT_SDA_28V EXYNOS4210_GPE1(7)
+#define GPIO_ISDBT_PWR_EN EXYNOS4_GPC0(1)
+#define GPIO_ISDBT_RST EXYNOS4210_GPE1(5)
+#endif
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#endif
+
+#endif
+#endif /* __MACH_GPIO_U1_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio-u1camera.h b/arch/arm/mach-exynos/include/mach/gpio-u1camera.h
new file mode 100644
index 0000000..5d7b8c5
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio-u1camera.h
@@ -0,0 +1,296 @@
+#ifndef __MACH_GPIO_U1CAMERA_H
+#define __MACH_GPIO_U1CAMERA_H __FILE__
+
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define DUMMY_GPIO EXYNOS4_GPL2(2)
+#endif
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+
+#define GPIO_XMMC0_CDn EXYNOS4_GPK0(2)
+
+#define GPIO_PS_ALS_SDA EXYNOS4_GPK2(2)
+#define GPIO_PS_ALS_SCL EXYNOS4_GPK3(2)
+
+#define GPIO_GYRO_INT 0/*EXYNOS4_GPX0(0)*/
+#define GPIO_GYRO_FIFOP_INT 0/*EXYNOS4_GPX0(1)*/
+#define GPIO_PS_ALS_INT EXYNOS4_GPX0(2)
+
+#define GPIO_BUCK1_EN_A EXYNOS4_GPX0(5)
+#define GPIO_BUCK1_EN_B EXYNOS4_GPX0(6)
+#define GPIO_BUCK2_EN EXYNOS4_GPL0(0)
+#define GPIO_PMIC_IRQ EXYNOS4_GPX0(7)
+
+#define GPIO_VOL_UP EXYNOS4_GPX2(0)
+#define GPIO_VOL_DOWN EXYNOS4_GPX2(1)
+#define GPIO_nPOWER EXYNOS4_GPX2(7)
+
+#define GPIO_OK_KEY EXYNOS4_GPX3(5)
+
+#define VT_CAM_SDA_18V EXYNOS4_GPC1(0)
+#define VT_CAM_SCL_18V EXYNOS4_GPC1(2)
+
+#define CODEC_VT_SDA_18V EXYNOS4_GPC1(3)
+#define CODEC_VT_SCL_18V EXYNOS4_GPC1(4)
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_ISP_RESET EXYNOS4210_GPE0(4)
+#else
+#define GPIO_ISP_RESET EXYNOS4_GPY3(7)
+#endif
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_FUEL_SDA EXYNOS4210_GPE1(7)
+#define GPIO_FUEL_SCL EXYNOS4210_GPE2(0)
+#else
+#define GPIO_FUEL_SDA EXYNOS4_GPY4(0)
+#define GPIO_FUEL_SCL EXYNOS4_GPY4(1)
+#endif
+#define GPIO_FUEL_ALERT EXYNOS4_GPX2(3)
+
+#define GPIO_USB_SDA EXYNOS4210_GPE1(0)
+#define GPIO_USB_SCL EXYNOS4210_GPE1(1)
+#define GPIO_MASSMEM_EN EXYNOS4_GPL1(1)
+#define GPIO_MASSMEM_EN_LEVEL 0
+#define GPIO_TSP_INT EXYNOS4_GPX0(4)
+
+#define GPIO_CAM_IO_EN EXYNOS4210_GPE2(1)
+#define GPIO_CAM_SENSOR_CORE EXYNOS4210_GPE2(5)
+#define GPIO_TSP_LDO_ON EXYNOS4_GPL0(3)
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_UART_SEL EXYNOS4_GPY4(7)
+#else
+#define GPIO_UART_SEL EXYNOS4_GPL2(7)
+#endif
+
+#define GPIO_3_TOUCH_SCL EXYNOS4_GPK1(0)
+#define GPIO_8M_AF_EN EXYNOS4_GPK1(1)
+#define GPIO_3_TOUCH_SDA EXYNOS4_GPK1(2)
+#define GPIO_3_TOUCH_INT EXYNOS4_GPL0(5)
+
+#define GPIO_VT_CAM_15V EXYNOS4210_GPE2(2)
+
+#define GPIO_CAM_MCLK EXYNOS4210_GPJ1(3)
+
+#define GPIO_CAM_VGA_nSTBY EXYNOS4_GPL2(0)
+#define GPIO_CAM_VGA_nRST EXYNOS4_GPL2(1)
+
+#define GPIO_DET_35 EXYNOS4_GPX3(2)
+#define GPIO_DET_35_AF 0xF
+
+#define GPIO_EAR_SEND_END EXYNOS4_GPX3(6)
+#define GPIO_EAR_SEND_END_AF 0xF
+
+#define GPIO_GPS_nRST EXYNOS4_GPL0(6)
+#define GPIO_GPS_PWR_EN EXYNOS4_GPL0(7)
+
+#define GPIO_GPS_RXD EXYNOS4_GPA0(0)
+#define GPIO_GPS_RXD_AF 2
+
+#define GPIO_GPS_TXD EXYNOS4_GPA0(1)
+#define GPIO_GPS_TXD_AF 2
+
+#define GPIO_GPS_CTS EXYNOS4_GPA0(2)
+#define GPIO_GPS_CTS_AF 2
+
+#define GPIO_GPS_RTS EXYNOS4_GPA0(3)
+#define GPIO_GPS_RTS_AF 2
+
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_BOOT_SW_SEL EXYNOS4_GPA0(6)
+#define GPIO_USB_BOOT_EN EXYNOS4_GPA0(7)
+#endif
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_NFC_SCL EXYNOS4_GPY0(0)
+#else
+#define GPIO_NFC_SCL DUMMY_GPIO
+#endif
+#define GPIO_NFC_SDA EXYNOS4_GPY0(1)
+#define GPIO_NFC_EN EXYNOS4_GPL2(6)
+#define GPIO_NFC_FIRM EXYNOS4_GPL2(7)
+
+#define GPIO_2MIC_PWDN EXYNOS4_GPL2(3)
+#define GPIO_2MIC_RST EXYNOS4_GPL2(4)
+#define GPIO_2MIC_EN EXYNOS4_GPL2(5)
+
+#ifdef CONFIG_CHARGER_MAX8922_U1 /* sub-charger */
+#define GPIO_CHG_EN EXYNOS4_GPL2(2)
+#define GPIO_CHG_ING_N EXYNOS4_GPL2(4)
+#define GPIO_TA_nCONNECTED EXYNOS4_GPL2(5)
+#endif
+
+#define GPIO_2MIC_SDA EXYNOS4_GPC1(2)
+#define GPIO_2MIC_SCL EXYNOS4_GPC1(0)
+
+#define GPIO_FLM_RXD EXYNOS4_GPA1(4)
+#define GPIO_FLM_RXD_AF 2
+
+#define GPIO_FLM_TXD EXYNOS4_GPA1(5)
+#define GPIO_FLM_TXD_AF 2
+
+#define GPIO_PHONE_ON EXYNOS4_GPC1(1)
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2)
+#else
+#define GPIO_CP_DUMP_INT DUMMY_GPIO
+#endif
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_CP_RST_MSM EXYNOS4_GPL2(6)
+#endif
+#define GPIO_CP_REQ_RESET EXYNOS4_GPY4(6)
+
+#define GPIO_S1_KEY EXYNOS4_GPX0(0)
+#define GPIO_S2_KEY EXYNOS4_GPX0(1)
+
+#define GPIO_TELE_KEY EXYNOS4_GPX2(6)
+#define GPIO_WIDE_KEY EXYNOS4_GPX3(1)
+#define GPIO_RSERVED_KEY EXYNOS4_GPX1(0)
+#define GPIO_PLAY_KEY EXYNOS4_GPX1(1)
+#define GPIO_RECORD_KEY EXYNOS4_GPX1(2)
+#define GPIO_MENU_KEY EXYNOS4_GPX1(3)
+#define GPIO_ROTARY_PUSH EXYNOS4_GPX1(4)
+#define GPIO_ISP_INT EXYNOS4_GPX1(5)
+#define GPIO_HOME_KEY EXYNOS4_GPX1(6)
+#define GPIO_BACK_KEY EXYNOS4_GPX1(7)
+#define GPIO_NFC_IRQ EXYNOS4_GPL2(6)
+#define GPIO_IPC_HOST_WAKEUP EXYNOS4_GPL2(6)
+#define GPIO_IPC_SLAVE_WAKEUP EXYNOS4_GPL2(6)
+#define GPIO_CP_RST EXYNOS4_GPL2(6)
+#define GPIO_PHONE_ACTIVE EXYNOS4_GPL2(6)
+#define GPIO_CP_DUMP_INT EXYNOS4_GPL2(6)
+
+
+#define GPIO_ACTIVE_STATE EXYNOS4_GPY3(5)
+
+#define IRQ_PHONE_ACTIVE IRQ_EINT14
+#define IRQ_SUSPEND_REQUEST IRQ_EINT11
+#define IRQ_IPC_HOST_WAKEUP IRQ_EINT9
+
+#define GPIO_WLAN_EN EXYNOS4_GPL1(2)
+#define GPIO_WLAN_EN_AF 1
+
+#define GPIO_BT_EN EXYNOS4_GPL0(4)
+#define GPIO_BT_nRST EXYNOS4_GPL1(0)
+
+#define GPIO_WLAN_HOST_WAKE EXYNOS4_GPX2(5)
+#define GPIO_WLAN_HOST_WAKE_AF 0xF
+
+#define GPIO_BT_HOST_WAKE 0/*EXYNOS4_GPX2(6)*/
+#define GPIO_BT_HOST_WAKE_AF 0xF
+#define IRQ_BT_HOST_WAKE IRQ_EINT(22)
+
+#define GPIO_BT_WAKE 0/*EXYNOS4_GPX3(1)*/
+
+#define GPIO_WLAN_SDIO_CLK EXYNOS4_GPK3(0)
+#define GPIO_WLAN_SDIO_CLK_AF 2
+
+#define GPIO_WLAN_SDIO_CMD EXYNOS4_GPK3(1)
+#define GPIO_WLAN_SDIO_CMD_AF 2
+
+#define GPIO_WLAN_SDIO_D0 EXYNOS4_GPK3(3)
+#define GPIO_WLAN_SDIO_D0_AF 2
+
+#define GPIO_WLAN_SDIO_D1 EXYNOS4_GPK3(4)
+#define GPIO_WLAN_SDIO_D1_AF 2
+
+#define GPIO_WLAN_SDIO_D2 EXYNOS4_GPK3(5)
+#define GPIO_WLAN_SDIO_D2_AF 2
+
+#define GPIO_WLAN_SDIO_D3 EXYNOS4_GPK3(6)
+#define GPIO_WLAN_SDIO_D3_AF 2
+
+#define GPIO_HW_REV0 EXYNOS4210_GPE1(0)
+#define GPIO_HW_REV1 EXYNOS4210_GPE1(1)
+#define GPIO_HW_REV2 EXYNOS4210_GPE1(2)
+#define GPIO_HW_REV3 EXYNOS4210_GPE1(3)
+
+#define GPIO_MHL_RST EXYNOS4_GPF3(4)
+#define GPIO_MHL_INT EXYNOS4_GPF3(5)
+#define GPIO_MHL_INT_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_WAKE_UP EXYNOS4210_GPJ1(4)
+#define GPIO_MHL_WAKE_UP_AF S3C_GPIO_SFN(0xF)
+#define GPIO_MHL_SEL EXYNOS4_GPL0(1)
+
+#define GPIO_BOOT_MODE EXYNOS4_GPX0(3)
+
+#define GPIO_MSENSE_INT EXYNOS4_GPX2(2)
+#define GPIO_HDMI_EN EXYNOS4_GPX2(4)
+#define GPIO_HDMI_EN_REV07 EXYNOS4_GPL1(1)
+#define GPIO_HDMI_CEC EXYNOS4_GPX3(6)
+#define GPIO_HDMI_HPD EXYNOS4_GPX3(7)
+
+#define GPIO_ACC_INT EXYNOS4_GPX3(0)
+#define GPIO_USB_OTG_EN EXYNOS4_GPX3(3)
+
+#define GPIO_MSENSOR_MHL_SDA_28V EXYNOS4_GPD0(2)
+#define GPIO_MSENSOR_MHL_SDA_AF 0x3
+#define GPIO_MSENSOR_MHL_SCL_28V EXYNOS4_GPD0(3)
+#define GPIO_MSENSOR_MHL_SCL_AF 0x3
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define GPIO_MHL_SDA_18V EXYNOS4_GPY3(0)
+#define GPIO_MHL_SCL_18V EXYNOS4_GPY3(2)
+#else
+#define GPIO_MHL_SDA_18V EXYNOS4210_GPE1(6)
+#define GPIO_MHL_SCL_18V EXYNOS4210_GPE1(5)
+#endif
+
+#define GPIO_AP_HDMI_SDA GPIO_MSENSOR_MHL_SDA_28V
+#define GPIO_AP_HDMI_SDA_AF GPIO_MSENSOR_MHL_SDA_AF
+#define GPIO_AP_HDMI_SCL GPIO_MSENSOR_MHL_SCL_28V
+#define GPIO_AP_HDMI_SCL_AF GPIO_MSENSOR_MHL_SCL_AF
+#define GPIO_AP_SDA_18V GPIO_MHL_SDA_18V
+#define GPIO_AP_SCL_18V GPIO_MHL_SCL_18V
+
+#define MHL_INT_IRQ gpio_to_irq(GPIO_MHL_INT)
+#define MHL_WAKEUP_IRQ gpio_to_irq(GPIO_MHL_WAKE_UP)
+
+#define GPIO_MIC_BIAS_EN EXYNOS4210_GPE1(4)
+#ifdef CONFIG_MACH_U1_KOR_LGT
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4210_GPE0(2)
+#else
+#define GPIO_SUB_MIC_BIAS_EN EXYNOS4210_GPE2(0)
+#endif
+#define GPIO_EAR_MIC_BIAS_EN EXYNOS4210_GPE2(4)
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#define GPIO_TDMB_EN EXYNOS4_GPC0(1)
+#define GPIO_TDMB_RST_N EXYNOS4_GPB(5)
+#define GPIO_TDMB_INT EXYNOS4_GPB(4)
+#define GPIO_TDMB_IRQ gpio_to_irq(GPIO_TDMB_INT)
+#define GPIO_TDMB_INT_AF 0xf
+#define GPIO_TDMB_SPI_CLK EXYNOS4_GPB(0)
+#define GPIO_TDMB_SPI_CS EXYNOS4_GPB(1)
+#define GPIO_TDMB_SPI_MISO EXYNOS4_GPB(2)
+#define GPIO_TDMB_SPI_MOSI EXYNOS4_GPB(3)
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+#define GPIO_FM_RST EXYNOS4_GPB(0)
+#define GPIO_FM_INT EXYNOS4_GPB(1)
+#define GPIO_FM_INT_REV07 EXYNOS4_GPX2(4)
+#define GPIO_FM_SDA_28V EXYNOS4_GPB(2)
+#define GPIO_FM_SCL_28V EXYNOS4_GPB(3)
+#endif
+
+#ifdef CONFIG_ISDBT_FC8100
+#define GPIO_ISDBT_SCL_28V EXYNOS4210_GPE1(6)
+#define GPIO_ISDBT_SDA_28V EXYNOS4210_GPE1(7)
+#define GPIO_ISDBT_PWR_EN EXYNOS4_GPC0(1)
+#define GPIO_ISDBT_RST EXYNOS4210_GPE1(5)
+#endif
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+/* Definitions for DPRAM */
+#define GPIO_DPRAM_CSN EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN0 EXYNOS4_GPY0(0)
+#define GPIO_DPRAM_CSN1 EXYNOS4_GPY0(1)
+#define GPIO_DPRAM_CSN2 EXYNOS4_GPY0(2)
+#define GPIO_DPRAM_CSN3 EXYNOS4_GPY0(3)
+#define GPIO_DPRAM_REN EXYNOS4_GPY0(4)
+#define GPIO_DPRAM_WEN EXYNOS4_GPY0(5)
+#define GPIO_DPRAM_LBN EXYNOS4_GPY1(0)
+#define GPIO_DPRAM_UBN EXYNOS4_GPY1(1)
+#endif
+
+#endif
+#endif /* __MACH_GPIO_U1CAMERA_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h
new file mode 100644
index 0000000..63d66f1
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpio.h
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-exynos/include/mach/gpio.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - gpio map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#include "gpio-exynos4.h"
+#include "gpio-exynos5.h"
+
+extern void (*exynos4_sleep_gpio_table_set)(void);
+extern void (*exynos5_sleep_gpio_table_set)(void);
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#define S3C_GPIO_END EXYNOS4_GPIO_END
+#define ARCH_NR_GPIOS (EXYNOS4XXX_GPIO_END + \
+ CONFIG_SAMSUNG_GPIO_EXTRA)
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#define S3C_GPIO_END EXYNOS5_GPIO_END
+#define ARCH_NR_GPIOS (EXYNOS5_GPIO_END + \
+ CONFIG_SAMSUNG_GPIO_EXTRA)
+#else
+#error "ARCH_EXYNOS* is not defined"
+#endif
+
+#define GPIO_LEVEL_LOW 0
+#define GPIO_LEVEL_HIGH 1
+#define GPIO_LEVEL_NONE 2
+
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-exynos/include/mach/gpufreq.h b/arch/arm/mach-exynos/include/mach/gpufreq.h
new file mode 100644
index 0000000..3ecb393
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/gpufreq.h
@@ -0,0 +1,38 @@
+/*
+ * linux/arch/arm/mach-exynos/include/mach/gpufreq.h
+ *
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_CPU_EXYNOS4210
+extern int mali_dvfs_bottom_lock_push(void);
+extern int mali_dvfs_bottom_lock_pop(void);
+
+static inline int exynos_gpufreq_lock(void)
+{
+ return mali_dvfs_bottom_lock_push();
+}
+
+static inline int exynos_gpufreq_unlock(void)
+{
+ return mali_dvfs_bottom_lock_pop();
+}
+
+#else
+static inline int exynos_gpufreq_lock(void)
+{
+ return 0;
+}
+static inline int exynos_gpufreq_unlock(void)
+{
+ return 0;
+}
+#endif
+
diff --git a/arch/arm/mach-exynos4/include/mach/hardware.h b/arch/arm/mach-exynos/include/mach/hardware.h
index 5109eb2..4470917 100644
--- a/arch/arm/mach-exynos4/include/mach/hardware.h
+++ b/arch/arm/mach-exynos/include/mach/hardware.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/hardware.h
+/* linux/arch/arm/mach-exynos/include/mach/hardware.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/iic-hdmiphy.h b/arch/arm/mach-exynos/include/mach/iic-hdmiphy.h
new file mode 100644
index 0000000..4f070e0
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/iic-hdmiphy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series i2c hdmiphy helper definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef PLAT_S5P_IIC_HDMIPHY_H_
+#define PLAT_S5P_IIC_HDMIPHY_H_
+
+#define S5P_IIC_HDMIPHY_BUS_NUM (8)
+
+#endif
diff --git a/arch/arm/mach-exynos4/include/mach/io.h b/arch/arm/mach-exynos/include/mach/io.h
index d5478d2..0d0544f 100644
--- a/arch/arm/mach-exynos4/include/mach/io.h
+++ b/arch/arm/mach-exynos/include/mach/io.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/io.h
+/* linux/arch/arm/mach-exynos/include/mach/io.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/irqs-exynos4.h b/arch/arm/mach-exynos/include/mach/irqs-exynos4.h
new file mode 100644
index 0000000..6a9d79d
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/irqs-exynos4.h
@@ -0,0 +1,248 @@
+/* linux/arch/arm/mach-exynos/include/mach/irqs-exynos4.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_EXYNOS4_H
+#define __ASM_ARCH_IRQS_EXYNOS4_H __FILE__
+
+#define IRQ_EINT0 IRQ_SPI(16)
+#define IRQ_EINT1 IRQ_SPI(17)
+#define IRQ_EINT2 IRQ_SPI(18)
+#define IRQ_EINT3 IRQ_SPI(19)
+#define IRQ_EINT4 IRQ_SPI(20)
+#define IRQ_EINT5 IRQ_SPI(21)
+#define IRQ_EINT6 IRQ_SPI(22)
+#define IRQ_EINT7 IRQ_SPI(23)
+#define IRQ_EINT8 IRQ_SPI(24)
+#define IRQ_EINT9 IRQ_SPI(25)
+#define IRQ_EINT10 IRQ_SPI(26)
+#define IRQ_EINT11 IRQ_SPI(27)
+#define IRQ_EINT12 IRQ_SPI(28)
+#define IRQ_EINT13 IRQ_SPI(29)
+#define IRQ_EINT14 IRQ_SPI(30)
+#define IRQ_EINT15 IRQ_SPI(31)
+#define IRQ_EINT16_31 IRQ_SPI(32)
+#define IRQ_MDMA0 IRQ_SPI(33)
+#define IRQ_C2C_SSCM0 IRQ_SPI(33)
+#define IRQ_MDMA1 IRQ_SPI(34)
+#define IRQ_PDMA0 IRQ_SPI(35)
+#define IRQ_PDMA1 IRQ_SPI(36)
+#define IRQ_TIMER0_VIC IRQ_SPI(37)
+#define IRQ_TIMER1_VIC IRQ_SPI(38)
+#define IRQ_TIMER2_VIC IRQ_SPI(39)
+#define IRQ_TIMER3_VIC IRQ_SPI(40)
+#define IRQ_TIMER4_VIC IRQ_SPI(41)
+#define IRQ_MCT_L0 IRQ_SPI(42)
+#define IRQ_WDT IRQ_SPI(43)
+#define IRQ_RTC_ALARM IRQ_SPI(44)
+#define IRQ_RTC_TIC IRQ_SPI(45)
+
+#define IRQ_GPIO_XB IRQ_SPI(46)
+#define IRQ_GPIO_XA IRQ_SPI(47)
+
+#define IRQ_MCT_L1 IRQ_SPI(48)
+
+#define IRQ_UART0 IRQ_SPI(52)
+#define IRQ_UART1 IRQ_SPI(53)
+#define IRQ_UART2 IRQ_SPI(54)
+#define IRQ_UART3 IRQ_SPI(55)
+#define IRQ_UART4 IRQ_SPI(56)
+#define IRQ_MCT_G0 IRQ_SPI(57)
+#define IRQ_IIC IRQ_SPI(58)
+#define IRQ_IIC1 IRQ_SPI(59)
+#define IRQ_IIC2 IRQ_SPI(60)
+#define IRQ_IIC3 IRQ_SPI(61)
+#define IRQ_IIC4 IRQ_SPI(62)
+#define IRQ_IIC5 IRQ_SPI(63)
+#define IRQ_IIC6 IRQ_SPI(64)
+#define IRQ_IIC7 IRQ_SPI(65)
+#define IRQ_SPI0 IRQ_SPI(66)
+#define IRQ_SPI1 IRQ_SPI(67)
+#define IRQ_SPI2 IRQ_SPI(68)
+
+#define IRQ_USB_HOST IRQ_SPI(70)
+#define IRQ_USB_HSOTG IRQ_SPI(71)
+#define IRQ_MODEM_IF IRQ_SPI(72)
+#define IRQ_GPIO_C2C IRQ_SPI(72)
+#define IRQ_HSMMC0 IRQ_SPI(73)
+#define IRQ_HSMMC1 IRQ_SPI(74)
+#define IRQ_HSMMC2 IRQ_SPI(75)
+#define IRQ_HSMMC3 IRQ_SPI(76)
+#define IRQ_DWMCI IRQ_SPI(77)
+
+#define IRQ_MIPICSI0 IRQ_SPI(78)
+#define IRQ_MIPIDSI0 IRQ_SPI(79)
+#define IRQ_MIPICSI1 IRQ_SPI(80)
+#define IRQ_MIPIDSI1 IRQ_SPI(81)
+
+#define IRQ_ONENAND_AUDI IRQ_SPI(82)
+#define IRQ_ROTATOR IRQ_SPI(83)
+#define IRQ_FIMC0 IRQ_SPI(84)
+#define IRQ_FIMC1 IRQ_SPI(85)
+#define IRQ_FIMC2 IRQ_SPI(86)
+#define IRQ_FIMC3 IRQ_SPI(87)
+#define IRQ_JPEG IRQ_SPI(88)
+#define IRQ_2D IRQ_SPI(89)
+#define IRQ_PCIE IRQ_SPI(90)
+#define IRQ_FIMC_IS0 IRQ_SPI(90)
+#define IRQ_MIXER IRQ_SPI(91)
+#define IRQ_HDMI IRQ_SPI(92)
+#define IRQ_HDMI_I2C IRQ_SPI(93)
+#define IRQ_IIC_HDMIPHY IRQ_SPI(93)
+#define IRQ_MFC IRQ_SPI(94)
+#define IRQ_TVENC IRQ_SPI(95)
+#define IRQ_SDO IRQ_SPI(95)
+#define IRQ_FIMC_IS1 IRQ_SPI(95)
+#define IRQ_AUDIO_SS IRQ_SPI(96)
+#define IRQ_I2S0 IRQ_SPI(97)
+#define IRQ_I2S1 IRQ_SPI(98)
+#define IRQ_I2S2 IRQ_SPI(99)
+#define IRQ_AC97 IRQ_SPI(100)
+
+#define IRQ_SPDIF IRQ_SPI(104)
+#define IRQ_ADC0 IRQ_SPI(105)
+#define IRQ_PEN0 IRQ_SPI(106)
+#define IRQ_FIMC_LITE0 IRQ_SPI(105)
+#define IRQ_FIMC_LITE1 IRQ_SPI(106)
+#define IRQ_ADC1 IRQ_SPI(107)
+#define IRQ_PEN1 IRQ_SPI(108)
+#define IRQ_KEYPAD IRQ_SPI(109)
+#define IRQ_POWER_PMU IRQ_SPI(110)
+#define IRQ_GPS IRQ_SPI(111)
+#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(112)
+#define IRQ_SLIMBUS IRQ_SPI(113)
+#define IRQ_CEC IRQ_SPI(114)
+#define IRQ_TSI IRQ_SPI(115)
+#define IRQ_SATA IRQ_SPI(116)
+#define IRQ_C2C_SSCM1 IRQ_SPI(116)
+
+#define IRQ_PPMMU0_3D IRQ_SPI(118)
+#define IRQ_PPMMU1_3D IRQ_SPI(119)
+#define IRQ_PPMMU2_3D IRQ_SPI(120)
+#define IRQ_PPMMU3_3D IRQ_SPI(121)
+#define IRQ_GPMMU_3D IRQ_SPI(122)
+
+#define IRQ_PP0_3D IRQ_SPI(123)
+#define IRQ_PP1_3D IRQ_SPI(124)
+#define IRQ_PP2_3D IRQ_SPI(125)
+#define IRQ_PP3_3D IRQ_SPI(126)
+#define IRQ_GP_3D IRQ_SPI(127)
+#define IRQ_PMU_3D IRQ_SPI(117)
+
+#define MAX_IRQ_IN_COMBINER 8
+#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
+#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
+
+#define IRQ_LCD_LITE0 COMBINER_IRQ(0, 0)
+#define IRQ_LCD_LITE1 COMBINER_IRQ(0, 1)
+
+#define IRQ_PMU_CPU0 COMBINER_IRQ(2, 2)
+#define IRQ_PMU IRQ_PMU_CPU0
+#define IRQ_TMU COMBINER_IRQ(2, 4)
+
+#define IRQ_PMU_CPU1 COMBINER_IRQ(3, 2)
+
+#define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0)
+#define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1)
+#define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2)
+#define IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3)
+#define IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4)
+#define IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5)
+#define IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6)
+#define IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7)
+
+#define IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0)
+#define IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1)
+#define IRQ_SYSMMU_FIMD0_0 COMBINER_IRQ(5, 2)
+#define IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(5, 3)
+#define IRQ_SYSMMU_TV_0 COMBINER_IRQ(5, 4)
+#define IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(5, 5)
+#define IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(5, 6)
+#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
+
+#define IRQ_EXYNOS4412_ADC COMBINER_IRQ(10, 3)
+
+#define IRQ_FIMD0_FIFO COMBINER_IRQ(11, 0)
+#define IRQ_FIMD0_VSYNC COMBINER_IRQ(11, 1)
+#define IRQ_FIMD0_SYSTEM COMBINER_IRQ(11, 2)
+
+#define IRQ_FIMD1_FIFO COMBINER_IRQ(12, 0)
+#define IRQ_FIMD1_VSYNC COMBINER_IRQ(12, 1)
+#define IRQ_FIMD1_SYSTEM COMBINER_IRQ(12, 2)
+
+#define IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(16, 0)
+#define IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(16, 1)
+#define IRQ_SYSMMU_ISP_0 COMBINER_IRQ(16, 2)
+#define IRQ_SYSMMU_DRC_0 COMBINER_IRQ(16, 3)
+#define IRQ_SYSMMU_FD_0 COMBINER_IRQ(16, 4)
+#define IRQ_SYSMMU_MCUISP_0 COMBINER_IRQ(16, 5)
+
+#define IRQ_PMU_CPU2 COMBINER_IRQ(18, 2)
+#define IRQ_PMU_CPU3 COMBINER_IRQ(19, 2)
+
+#define COMMON_COMBINER_NR 16
+#define MAX_COMBINER_NR 20
+
+#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
+
+#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
+#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
+
+#define IRQ_TVOUT_HPD (S5P_IRQ_EINT_BASE + 31)
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+#if defined(CONFIG_S3C_DEV_ADC)
+#define IRQ_ADC IRQ_ADC0
+#define IRQ_TC IRQ_PEN0
+#else
+#define IRQ_ADC IRQ_ADC1
+#define IRQ_TC IRQ_PEN1
+#endif
+#elif defined(CONFIG_CPU_EXYNOS4412)
+#define IRQ_ADC IRQ_EXYNOS4412_ADC
+#define IRQ_TC IRQ_PEN0
+#endif
+
+/* optional GPIO interrupts */
+#define S5P_GPIOINT_BASE (S5P_IRQ_EINT_BASE + 32)
+#define IRQ_GPIO1_NR_GROUPS 16
+#define IRQ_GPIO2_NR_GROUPS 12
+#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
+
+#define IRQ_BOARD_START IRQ_GPIO_END
+
+#if defined(CONFIG_MFD_MAX77693) || defined(CONFIG_MFD_MAX77686) ||\
+ defined(CONFIG_MFD_S5M_CORE)
+#define IRQ_BOARD_IFIC_START (IRQ_BOARD_START)
+#define IRQ_BOARD_IFIC_NR 29
+#define IRQ_BOARD_PMIC_START (IRQ_BOARD_START + IRQ_BOARD_IFIC_NR)
+#define IRQ_BOARD_PMIC_NR 16
+#define IRQ_BOARD_CODEC_START (IRQ_BOARD_PMIC_START + IRQ_BOARD_PMIC_NR)
+#define IRQ_BOARD_CODEC_NR 32
+#define IRQ_NR_BOARD (IRQ_BOARD_PMIC_NR + IRQ_BOARD_IFIC_NR \
+ + IRQ_BOARD_CODEC_NR)
+#elif defined(CONFIG_MFD_MAX8997)
+#define IRQ_BOARD_PMIC_START (IRQ_BOARD_START)
+#define IRQ_BOARD_PMIC_NR 35
+#define IRQ_BOARD_FUEL_START (IRQ_BOARD_PMIC_START + IRQ_BOARD_PMIC_NR)
+#define IRQ_BOARD_FUEL_NR 10
+#define IRQ_BOARD_CODEC_START (IRQ_BOARD_FUEL_START + IRQ_BOARD_FUEL_NR)
+#define IRQ_BOARD_CODEC_NR 32
+#define IRQ_NR_BOARD (IRQ_BOARD_PMIC_NR + IRQ_BOARD_FUEL_NR \
+ + IRQ_BOARD_CODEC_NR)
+#else
+#define IRQ_NR_BOARD 40
+#endif
+
+/* Set the default NR_IRQS */
+#define NR_IRQS (IRQ_GPIO_END + IRQ_NR_BOARD)
+
+#endif /* __ASM_ARCH_IRQS_EXYNOS4_H */
diff --git a/arch/arm/mach-exynos/include/mach/irqs-exynos5.h b/arch/arm/mach-exynos/include/mach/irqs-exynos5.h
new file mode 100644
index 0000000..9885a55
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/irqs-exynos5.h
@@ -0,0 +1,274 @@
+/* linux/arch/arm/mach-exynos/include/mach/irqs-exynos5.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_EXYNOS5_H
+#define __ASM_ARCH_IRQS_EXYNOS5_H __FILE__
+
+#define IRQ_EINT16_31 IRQ_SPI(32)
+#define IRQ_MDMA0 IRQ_SPI(33)
+#define IRQ_PDMA0 IRQ_SPI(34)
+#define IRQ_PDMA1 IRQ_SPI(35)
+#define IRQ_TIMER0_VIC IRQ_SPI(36)
+#define IRQ_TIMER1_VIC IRQ_SPI(37)
+#define IRQ_TIMER2_VIC IRQ_SPI(38)
+#define IRQ_TIMER3_VIC IRQ_SPI(39)
+#define IRQ_TIMER4_VIC IRQ_SPI(40)
+#define IRQ_RTIC IRQ_SPI(41)
+#define IRQ_WDT IRQ_SPI(42)
+#define IRQ_RTC_ALARM IRQ_SPI(43)
+#define IRQ_RTC_TIC IRQ_SPI(44)
+#define IRQ_GPIO_XB IRQ_SPI(45)
+#define IRQ_GPIO_XA IRQ_SPI(46)
+#define IRQ_GPIO IRQ_SPI(47)
+#define IRQ_IEM_IEC IRQ_SPI(48)
+#define IRQ_IEM_APC IRQ_SPI(49)
+#define IRQ_GPIO_C2C IRQ_SPI(50)
+#define IRQ_UART0 IRQ_SPI(51)
+#define IRQ_UART1 IRQ_SPI(52)
+#define IRQ_UART2 IRQ_SPI(53)
+#define IRQ_UART3 IRQ_SPI(54)
+#define IRQ_MONOCNT IRQ_SPI(55)
+#define IRQ_IIC IRQ_SPI(56)
+#define IRQ_IIC1 IRQ_SPI(57)
+#define IRQ_IIC2 IRQ_SPI(58)
+#define IRQ_IIC3 IRQ_SPI(59)
+#define IRQ_IIC4 IRQ_SPI(60)
+#define IRQ_IIC5 IRQ_SPI(61)
+#define IRQ_IIC6 IRQ_SPI(62)
+#define IRQ_IIC7 IRQ_SPI(63)
+#define IRQ_IIC_HDMIPHY IRQ_SPI(64)
+#define IRQ_TMU IRQ_SPI(65)
+#define IRQ_FIQ_0 IRQ_SPI(66)
+#define IRQ_FIQ_1 IRQ_SPI(67)
+#define IRQ_SPI0 IRQ_SPI(68)
+#define IRQ_SPI1 IRQ_SPI(69)
+#define IRQ_SPI2 IRQ_SPI(70)
+#define IRQ_USB_HOST IRQ_SPI(71)
+#define IRQ_USB3_DRD IRQ_SPI(72)
+#define IRQ_MIPI_HSI IRQ_SPI(73)
+#define IRQ_USB_HSOTG IRQ_SPI(74)
+#define IRQ_HSMMC0 IRQ_SPI(75)
+#define IRQ_HSMMC1 IRQ_SPI(76)
+#define IRQ_HSMMC2 IRQ_SPI(77)
+#define IRQ_HSMMC3 IRQ_SPI(78)
+#define IRQ_MIPICSI0 IRQ_SPI(79)
+#define IRQ_MIPICSI1 IRQ_SPI(80)
+#define IRQ_EFNFCON_DMA_ABORT IRQ_SPI(81)
+#define IRQ_MIPIDSI0 IRQ_SPI(82)
+#define IRQ_WDT_IOP IRQ_SPI(83)
+#define IRQ_ROTATOR IRQ_SPI(84)
+#define IRQ_GSC0 IRQ_SPI(85)
+#define IRQ_GSC1 IRQ_SPI(86)
+#define IRQ_GSC2 IRQ_SPI(87)
+#define IRQ_GSC3 IRQ_SPI(88)
+#define IRQ_JPEG IRQ_SPI(89)
+#define IRQ_EFNFCON_DMA IRQ_SPI(90)
+#define IRQ_2D IRQ_SPI(91)
+#define IRQ_EFNFCON_0 IRQ_SPI(92)
+#define IRQ_EFNFCON_1 IRQ_SPI(93)
+#define IRQ_MIXER IRQ_SPI(94)
+#define IRQ_HDMI IRQ_SPI(95)
+#define IRQ_MFC IRQ_SPI(96)
+#define IRQ_AUDIO_SS IRQ_SPI(97)
+#define IRQ_I2S0 IRQ_SPI(98)
+#define IRQ_I2S1 IRQ_SPI(99)
+#define IRQ_I2S2 IRQ_SPI(100)
+#define IRQ_AC97 IRQ_SPI(101)
+#define IRQ_PCM0 IRQ_SPI(102)
+#define IRQ_PCM1 IRQ_SPI(103)
+#define IRQ_PCM2 IRQ_SPI(104)
+#define IRQ_SPDIF IRQ_SPI(105)
+#define IRQ_ADC0 IRQ_SPI(106)
+#define IRQ_ADC1 IRQ_SPI(107)
+#define IRQ_SATA_PHY IRQ_SPI(108)
+#define IRQ_SATA_PMEREQ IRQ_SPI(109)
+#define IRQ_FIMC_LITE2 IRQ_SPI(110)
+#define IRQ_EAGLE_PMU IRQ_SPI(111)
+#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(112)
+#define IRQ_DP1_INTP1 IRQ_SPI(113)
+#define IRQ_CEC IRQ_SPI(114)
+#define IRQ_SATA IRQ_SPI(115)
+
+#define GPU_IRQ_NUMBER IRQ_SPI(117)
+#define JOB_IRQ_NUMBER IRQ_SPI(118)
+#define MMU_IRQ_NUMBER IRQ_SPI(119)
+#define IRQ_MCT_L0 IRQ_SPI(120)
+#define IRQ_MCT_L1 IRQ_SPI(121)
+
+#define IRQ_DWMCI IRQ_SPI(123)
+#define IRQ_MDMA1 IRQ_SPI(124)
+#define IRQ_FIMC_LITE0 IRQ_SPI(125)
+#define IRQ_FIMC_LITE1 IRQ_SPI(126)
+#define IRQ_RP_TIMER IRQ_SPI(127)
+
+#define MAX_IRQ_IN_COMBINER 8
+#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(128))
+#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
+
+#define IRQ_PMU COMBINER_IRQ(1, 2)
+
+#define EXYNOS5_IRQ_SYSMMU_GSC0_0 COMBINER_IRQ(2, 0)
+#define EXYNOS5_IRQ_SYSMMU_GSC0_1 COMBINER_IRQ(2, 1)
+#define EXYNOS5_IRQ_SYSMMU_GSC1_0 COMBINER_IRQ(2, 2)
+#define EXYNOS5_IRQ_SYSMMU_GSC1_1 COMBINER_IRQ(2, 3)
+#define EXYNOS5_IRQ_SYSMMU_GSC2_0 COMBINER_IRQ(2, 4)
+#define EXYNOS5_IRQ_SYSMMU_GSC2_1 COMBINER_IRQ(2, 5)
+#define EXYNOS5_IRQ_SYSMMU_GSC3_0 COMBINER_IRQ(2, 6)
+#define EXYNOS5_IRQ_SYSMMU_GSC3_1 COMBINER_IRQ(2, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_LITE2_0 COMBINER_IRQ(3, 0)
+#define EXYNOS5_IRQ_SYSMMU_LITE2_1 COMBINER_IRQ(3, 1)
+#define EXYNOS5_IRQ_SYSMMU_FIMD1_0 COMBINER_IRQ(3, 2)
+#define EXYNOS5_IRQ_SYSMMU_FIMD1_1 COMBINER_IRQ(3, 3)
+#define EXYNOS5_IRQ_SYSMMU_LITE0_0 COMBINER_IRQ(3, 4)
+#define EXYNOS5_IRQ_SYSMMU_LITE0_1 COMBINER_IRQ(3, 5)
+#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_0 COMBINER_IRQ(3, 6)
+#define EXYNOS5_IRQ_SYSMMU_SCALERPISP_1 COMBINER_IRQ(3, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(4, 0)
+#define EXYNOS5_IRQ_SYSMMU_ROTATOR_1 COMBINER_IRQ(4, 1)
+#define EXYNOS5_IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 2)
+#define EXYNOS5_IRQ_SYSMMU_JPEG_1 COMBINER_IRQ(4, 3)
+
+#define EXYNOS5_IRQ_SYSMMU_FD_0 COMBINER_IRQ(5, 0)
+#define EXYNOS5_IRQ_SYSMMU_FD_1 COMBINER_IRQ(5, 1)
+#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_0 COMBINER_IRQ(5, 2)
+#define EXYNOS5_IRQ_SYSMMU_SCALERCISP_1 COMBINER_IRQ(5, 3)
+#define EXYNOS5_IRQ_SYSMMU_MCUISP_0 COMBINER_IRQ(5, 4)
+#define EXYNOS5_IRQ_SYSMMU_MCUISP_1 COMBINER_IRQ(5, 5)
+#define EXYNOS5_IRQ_SYSMMU_3DNR_0 COMBINER_IRQ(5, 6)
+#define EXYNOS5_IRQ_SYSMMU_3DNR_1 COMBINER_IRQ(5, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_ARM_0 COMBINER_IRQ(6, 0)
+#define EXYNOS5_IRQ_SYSMMU_ARM_1 COMBINER_IRQ(6, 1)
+#define EXYNOS5_IRQ_SYSMMU_MFC_R_0 COMBINER_IRQ(6, 2)
+#define EXYNOS5_IRQ_SYSMMU_MFC_R_1 COMBINER_IRQ(6, 3)
+#define EXYNOS5_IRQ_SYSMMU_RTIC_0 COMBINER_IRQ(6, 4)
+#define EXYNOS5_IRQ_SYSMMU_RTIC_1 COMBINER_IRQ(6, 5)
+#define EXYNOS5_IRQ_SYSMMU_SSS_0 COMBINER_IRQ(6, 6)
+#define EXYNOS5_IRQ_SYSMMU_SSS_1 COMBINER_IRQ(6, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(7, 0)
+#define EXYNOS5_IRQ_SYSMMU_MDMA0_1 COMBINER_IRQ(7, 1)
+#define EXYNOS5_IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(7, 2)
+#define EXYNOS5_IRQ_SYSMMU_MDMA1_1 COMBINER_IRQ(7, 3)
+#define EXYNOS5_IRQ_SYSMMU_TV_0 COMBINER_IRQ(7, 4)
+#define EXYNOS5_IRQ_SYSMMU_TV_1 COMBINER_IRQ(7, 5)
+#define EXYNOS5_IRQ_SYSMMU_GPSX_0 COMBINER_IRQ(7, 6)
+#define EXYNOS5_IRQ_SYSMMU_GPSX_1 COMBINER_IRQ(7, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_MFC_L_0 COMBINER_IRQ(8, 5)
+#define EXYNOS5_IRQ_SYSMMU_MFC_L_1 COMBINER_IRQ(8, 6)
+
+#define EXYNOS5_IRQ_SYSMMU_DIS1_0 COMBINER_IRQ(9, 4)
+#define EXYNOS5_IRQ_SYSMMU_DIS1_1 COMBINER_IRQ(9, 5)
+
+#define IRQ_DP COMBINER_IRQ(10, 3)
+#define EXYNOS5_IRQ_SYSMMU_DIS0_0 COMBINER_IRQ(10, 4)
+#define EXYNOS5_IRQ_SYSMMU_DIS0_1 COMBINER_IRQ(10, 5)
+#define EXYNOS5_IRQ_SYSMMU_ISP_0 COMBINER_IRQ(10, 6)
+#define EXYNOS5_IRQ_SYSMMU_ISP_1 COMBINER_IRQ(10, 7)
+
+#define EXYNOS5_IRQ_SYSMMU_ODC_0 COMBINER_IRQ(11, 0)
+#define EXYNOS5_IRQ_SYSMMU_ODC_1 COMBINER_IRQ(11, 1)
+#define EXYNOS5_IRQ_SYSMMU_DRC_0 COMBINER_IRQ(11, 6)
+#define EXYNOS5_IRQ_SYSMMU_DRC_1 COMBINER_IRQ(11, 7)
+
+#define IRQ_MDMA1_ABORT COMBINER_IRQ(13, 1)
+
+#define IRQ_MDMA0_ABORT COMBINER_IRQ(15, 3)
+
+#define IRQ_C2C_SSCM0 COMBINER_IRQ(17, 0)
+#define IRQ_C2C_SSCM1 COMBINER_IRQ(17, 1)
+
+#define IRQ_FIMD0_FIFO COMBINER_IRQ(18, 0)
+#define IRQ_FIMD0_VSYNC COMBINER_IRQ(18, 1)
+#define IRQ_FIMD0_SYSTEM COMBINER_IRQ(18, 2)
+
+#define IRQ_FIMD1_FIFO COMBINER_IRQ(18, 4)
+#define IRQ_FIMD1_VSYNC COMBINER_IRQ(18, 5)
+#define IRQ_FIMD1_SYSTEM COMBINER_IRQ(18, 6)
+
+#define IRQ_ARMIOP_GIC COMBINER_IRQ(19, 0)
+#define IRQ_ARMISP_GIC COMBINER_IRQ(19, 1)
+#define IRQ_IOP_GIC COMBINER_IRQ(19, 3)
+#define IRQ_ISP_GIC COMBINER_IRQ(19, 4)
+
+#define IRQ_PMU_CPU1 COMBINER_IRQ(22, 4)
+
+#define IRQ_EINT0 COMBINER_IRQ(23, 0)
+#define IRQ_MCT_G0 COMBINER_IRQ(23, 3)
+#define IRQ_MCT_G1 COMBINER_IRQ(23, 4)
+
+#define IRQ_EINT1 COMBINER_IRQ(24, 0)
+#define EXYNOS5_IRQ_SYSMMU_LITE1_0 COMBINER_IRQ(24, 1)
+#define EXYNOS5_IRQ_SYSMMU_LITE1_1 COMBINER_IRQ(24, 2)
+#define EXYNOS5_IRQ_SYSMMU_2D_0 COMBINER_IRQ(24, 5)
+#define EXYNOS5_IRQ_SYSMMU_2D_1 COMBINER_IRQ(24, 6)
+
+#define IRQ_EINT2 COMBINER_IRQ(25, 0)
+#define IRQ_EINT3 COMBINER_IRQ(25, 1)
+
+#define IRQ_EINT4 COMBINER_IRQ(26, 0)
+#define IRQ_EINT5 COMBINER_IRQ(26, 1)
+
+#define IRQ_EINT6 COMBINER_IRQ(27, 0)
+#define IRQ_EINT7 COMBINER_IRQ(27, 1)
+
+#define IRQ_EINT8 COMBINER_IRQ(28, 0)
+#define IRQ_EINT9 COMBINER_IRQ(28, 1)
+
+#define IRQ_EINT10 COMBINER_IRQ(29, 0)
+#define IRQ_EINT11 COMBINER_IRQ(29, 1)
+
+#define IRQ_EINT12 COMBINER_IRQ(30, 0)
+#define IRQ_EINT13 COMBINER_IRQ(30, 1)
+
+#define IRQ_EINT14 COMBINER_IRQ(31, 0)
+#define IRQ_EINT15 COMBINER_IRQ(31, 1)
+
+#define MAX_COMBINER_NR 32
+
+#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
+
+#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
+#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
+
+#define IRQ_TVOUT_HPD (S5P_IRQ_EINT_BASE + 31)
+
+#define IRQ_ADC IRQ_ADC0
+
+/* optional GPIO interrupts */
+#define S5P_GPIOINT_BASE (S5P_IRQ_EINT_BASE + 32)
+#define IRQ_GPIO1_NR_GROUPS 14
+#define IRQ_GPIO2_NR_GROUPS 9
+#define IRQ_GPIO3_NR_GROUPS 5
+#define IRQ_GPIO4_NR_GROUPS 1
+#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
+
+#define IRQ_BOARD_START IRQ_GPIO_END
+
+#if defined(CONFIG_MFD_MAX77693) || defined(CONFIG_MFD_MAX77686)
+#define IRQ_BOARD_IFIC_START (IRQ_BOARD_START)
+#define IRQ_BOARD_IFIC_NR 29
+#define IRQ_BOARD_PMIC_START (IRQ_BOARD_START + IRQ_BOARD_IFIC_NR)
+#define IRQ_BOARD_PMIC_NR 16
+#define IRQ_BOARD_CODEC_START (IRQ_BOARD_PMIC_START + IRQ_BOARD_PMIC_NR)
+#define IRQ_BOARD_CODEC_NR 32
+#define IRQ_NR_BOARD (IRQ_BOARD_PMIC_NR + IRQ_BOARD_IFIC_NR + IRQ_BOARD_CODEC_NR)
+#else
+#define IRQ_NR_BOARD 40
+#endif
+/* Set the default NR_IRQS */
+#define NR_IRQS (IRQ_GPIO_END + IRQ_NR_BOARD)
+
+#endif /* __ASM_ARCH_IRQS_EXYNOS5_H */
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
new file mode 100644
index 0000000..2c5bb1d
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -0,0 +1,40 @@
+/* linux/arch/arm/mach-exynos/include/mach/irqs.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* SGI: Software Generated Interrupt */
+
+#define IRQ_SGI(x) S5P_IRQ(x)
+
+/* PPI: Private Peripheral Interrupt */
+
+#define IRQ_PPI(x) S5P_IRQ(x+16)
+
+#define IRQ_PPI_MCT_L IRQ_PPI(12)
+
+/* SPI: Shared Peripheral Interrupt */
+
+#define IRQ_SPI(x) S5P_IRQ(x+32)
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#include "irqs-exynos4.h"
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#include "irqs-exynos5.h"
+#else
+#error "ARCH_EXYNOS* is not defined"
+#endif
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos/include/mach/map-exynos4.h b/arch/arm/mach-exynos/include/mach/map-exynos4.h
new file mode 100644
index 0000000..0a22891
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/map-exynos4.h
@@ -0,0 +1,319 @@
+/* linux/arch/arm/mach-exynos/include/mach/map-exynos4.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_EXYNOS4_H
+#define __ASM_ARCH_MAP_EXYNOS4_H __FILE__
+
+#define EXYNOS4_PA_SYSRAM0 0x02025000
+#define EXYNOS4_PA_SYSRAM1 0x02020000
+#define EXYNOS4_PA_SYSRAM_NS 0x0203F000
+#define EXYNOS4_PA_SYSRAM_NS_4212 0x0204F000
+
+#define EXYNOS4_PA_FIMC0 0x11800000
+#define EXYNOS4_PA_FIMC1 0x11810000
+#define EXYNOS4_PA_FIMC2 0x11820000
+#define EXYNOS4_PA_FIMC3 0x11830000
+
+#define EXYNOS4_PA_JPEG 0x11840000
+
+#define EXYNOS4_PA_AUDSS 0x03810000
+#define EXYNOS4_PA_I2S0 0x03830000
+#define EXYNOS4_PA_I2S1 0xE2100000
+#define EXYNOS4_PA_I2S2 0xE2A00000
+#define EXYNOS4212_PA_I2S1 0x13960000
+#define EXYNOS4212_PA_I2S2 0x13970000
+
+#define EXYNOS4_PA_PCM0 0x03840000
+#define EXYNOS4_PA_PCM1 0x13980000
+#define EXYNOS4_PA_PCM2 0x13990000
+
+#define EXYNOS4_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
+
+#define EXYNOS4_PA_ONENAND 0x0C000000
+#define EXYNOS4_PA_ONENAND_DMA 0x0C600000
+
+#define EXYNOS4_PA_CHIPID 0x10000000
+
+#define EXYNOS4_PA_SYSCON 0x10010000
+#define EXYNOS4_PA_PMU 0x10020000
+#define EXYNOS4_PA_CMU 0x10030000
+
+#define EXYNOS4_PA_SYSTIMER 0x10050000
+#define EXYNOS4_PA_WATCHDOG 0x10060000
+#define EXYNOS4_PA_RTC 0x10070000
+
+#define EXYNOS4_PA_KEYPAD 0x100A0000
+
+#define EXYNOS4_PA_CEC 0x100B0000
+
+#define EXYNOS4_PA_TMU 0x100C0000
+
+#define EXYNOS4_PA_DMC0 0x10400000
+#define EXYNOS4_PA_DMC1 0x10410000
+
+#define EXYNOS4_PA_COMBINER 0x10440000
+
+#define EXYNOS4_PA_IEM 0x10460000
+
+#define EXYNOS4_PA_GIC_CPU 0x10480000
+#define EXYNOS4_PA_GIC_DIST 0x10490000
+
+#define EXYNOS4_PA_COREPERI 0x10500000
+#define EXYNOS4_PA_TWD 0x10500600
+#define EXYNOS4_PA_L2CC 0x10502000
+
+#define EXYNOS4_PA_C2C 0x10540000
+#define EXYNOS4_PA_C2C_CP 0x10580000
+
+#define EXYNOS4_PA_DMC0_4212 0x10600000
+#define EXYNOS4_PA_DMC1_4212 0x10610000
+
+#define EXYNOS4_PA_PPMU_DMC0 0x106A0000
+#define EXYNOS4_PA_PPMU_DMC1 0x106B0000
+#define EXYNOS4_PA_PPMU_CPU 0x106C0000
+
+#define EXYNOS4_PA_GDL 0x11600000
+#define EXYNOS4_PA_GDR 0x11200000
+
+#define EXYNOS4_PA_S_MDMA0 0x10800000
+#define EXYNOS4_PA_NS_MDMA0 0x10810000
+#define EXYNOS4_PA_ACE 0x10830000
+#define EXYNOS4_PA_S_MDMA1 0x12840000
+#define EXYNOS4_PA_NS_MDMA1 0x12850000
+#define EXYNOS4_PA_PDMA0 0x12680000
+#define EXYNOS4_PA_PDMA1 0x12690000
+
+#define EXYNOS4_PA_SYSMMU_G2D_ACP 0x10A40000
+#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000
+#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000
+#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000
+#define EXYNOS4_PA_SYSMMU_FIMC2 0x11A40000
+#define EXYNOS4_PA_SYSMMU_FIMC3 0x11A50000
+#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000
+#define EXYNOS4_PA_LCD_LITE0 0x11C40000
+#define EXYNOS4_PA_DSIM0 0x11C80000
+#define EXYNOS4_PA_MDNIE0 0x11CA0000
+#define EXYNOS4_PA_DSIM1 0x12080000
+#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000
+#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000
+#define EXYNOS4_PA_SYSMMU_ISP 0x12260000
+#define EXYNOS4_PA_SYSMMU_DRC 0x12270000
+#define EXYNOS4_PA_SYSMMU_FD 0x122A0000
+#define EXYNOS4_PA_SYSMMU_ISPCPU 0x122B0000
+#define EXYNOS4_PA_SYSMMU_LITE0 0x123B0000
+#define EXYNOS4_PA_SYSMMU_LITE1 0x123C0000
+#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000
+#define EXYNOS4_PA_SYSMMU_GPS 0x12730000
+#define EXYNOS4_PA_SYSMMU_2D 0x12A20000
+#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000
+#define EXYNOS4_PA_SYSMMU_MDMA2 0x12A40000
+#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
+#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
+#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
+
+#define EXYNOS4_PA_GPIO1 0x11400000
+#define EXYNOS4_PA_GPIO2 0x11000000
+#define EXYNOS4_PA_GPIO3 0x03860000
+#define EXYNOS4_PA_GPIO4 0x106E0000
+
+#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
+#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
+
+#define EXYNOS4_PA_FIMD0 0x11C00000
+#define EXYNOS4_PA_FIMD1 0x12000000
+#define EXYNOS4_PA_FIMC_IS 0x12000000
+
+#define EXYNOS4_PA_FIMC_LITE0 0x12390000
+#define EXYNOS4_PA_FIMC_LITE1 0x123A0000
+
+#define EXYNOS4_PA_HSOTG 0x12480000
+#define EXYNOS4_PA_HSPHY 0x125B0000
+
+/* s3c-tsi */
+#define EXYNOS4_PA_TSI (0x12500000)
+
+#define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
+#define EXYNOS4_PA_DWMCI 0x12550000
+
+#define EXYNOS4_PA_SATA 0x12560000
+#define EXYNOS4_PA_SATAPHY 0x125D0000
+#define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000
+
+#define EXYNOS4_PA_SROMC 0x12570000
+
+#define EXYNOS4_PA_EHCI 0x12580000
+#define EXYNOS4_PA_OHCI 0x12590000
+#define EXYNOS4_PA_HSPHY 0x125B0000
+
+#define EXYNOS4412_PA_ADC 0x126C0000
+
+#define EXYNOS4_PA_GPS 0x12700000
+
+#define EXYNOS4_PA_FIMG2D 0x10800000
+
+#define EXYNOS4_PA_ROTATOR 0x12810000
+
+#define EXYNOS4_PA_VP 0x12C00000
+#define EXYNOS4_PA_MIXER 0x12C10000
+#define EXYNOS4_PA_TVENC 0x12C20000
+#define EXYNOS4_PA_SDO 0x12C20000
+#define EXYNOS4_PA_HDMI 0x12D00000
+
+#define EXYNOS4_PA_G3D 0x13000000
+
+#define EXYNOS4_PA_MFC 0x13400000
+
+#define EXYNOS4_PA_UART 0x13800000
+
+#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
+
+#define EXYNOS4_I2C_HDMI_PHY 0x138E0000
+#define EXYNOS4_PA_IIC_HDMIPHY 0x138E0000
+
+#define EXYNOS4210_PA_ADC 0x13910000
+#define EXYNOS4210_PA_ADC1 0x13911000
+
+#define EXYNOS4_PA_SPI0 0x13920000
+#define EXYNOS4_PA_SPI1 0x13930000
+#define EXYNOS4_PA_SPI2 0x13940000
+
+#define EXYNOS4_PA_AC97 0x139A0000
+
+#define EXYNOS4_PA_SPDIF 0x139B0000
+
+#define EXYNOS4_PA_TIMER 0x139D0000
+
+#define EXYNOS4_PA_SDRAM 0x40000000
+
+/* Compatibiltiy Defines */
+
+#define EXYNOS_PA_DWMCI EXYNOS4_PA_DWMCI
+
+#define EXYNOS_PA_AUDSS EXYNOS4_PA_AUDSS
+#define EXYNOS_PA_I2S0 EXYNOS4_PA_I2S0
+#define EXYNOS_PA_I2S1 EXYNOS4_PA_I2S1
+#define EXYNOS_PA_I2S2 EXYNOS4_PA_I2S2
+
+#define EXYNOS_PA_PCM0 EXYNOS4_PA_PCM0
+#define EXYNOS_PA_PCM1 EXYNOS4_PA_PCM1
+#define EXYNOS_PA_PCM2 EXYNOS4_PA_PCM2
+
+#define EXYNOS_PA_SPI0 EXYNOS4_PA_SPI0
+#define EXYNOS_PA_SPI1 EXYNOS4_PA_SPI1
+#define EXYNOS_PA_SPI2 EXYNOS4_PA_SPI2
+
+#define EXYNOS_PA_AC97 EXYNOS4_PA_AC97
+
+#define EXYNOS_PA_SPDIF EXYNOS4_PA_SPDIF
+
+#define EXYNOS_PA_FIMC_LITE0 EXYNOS4_PA_FIMC_LITE0
+#define EXYNOS_PA_FIMC_LITE1 EXYNOS4_PA_FIMC_LITE1
+
+#define EXYNOS_PA_ROTATOR EXYNOS4_PA_ROTATOR
+
+#define EXYNOS_PA_C2C EXYNOS4_PA_C2C
+#define EXYNOS_PA_C2C_CP EXYNOS4_PA_C2C_CP
+
+#define S5P_PA_TSI EXYNOS4_PA_TSI
+#define S5P_SZ_TSI SZ_256
+
+#define S3C_PA_HSMMC0 EXYNOS4_PA_HSMMC(0)
+#define S3C_PA_HSMMC1 EXYNOS4_PA_HSMMC(1)
+#define S3C_PA_HSMMC2 EXYNOS4_PA_HSMMC(2)
+#define S3C_PA_HSMMC3 EXYNOS4_PA_HSMMC(3)
+#define S3C_PA_IIC EXYNOS4_PA_IIC(0)
+#define S3C_PA_IIC1 EXYNOS4_PA_IIC(1)
+#define S3C_PA_IIC2 EXYNOS4_PA_IIC(2)
+#define S3C_PA_IIC3 EXYNOS4_PA_IIC(3)
+#define S3C_PA_IIC4 EXYNOS4_PA_IIC(4)
+#define S3C_PA_IIC5 EXYNOS4_PA_IIC(5)
+#define S3C_PA_IIC6 EXYNOS4_PA_IIC(6)
+#define S3C_PA_IIC7 EXYNOS4_PA_IIC(7)
+#if defined(CONFIG_CPU_EXYNOS4210)
+#define SAMSUNG_PA_ADC EXYNOS4210_PA_ADC
+#define SAMSUNG_PA_ADC1 EXYNOS4210_PA_ADC1
+#elif defined(CONFIG_CPU_EXYNOS4412)
+#define SAMSUNG_PA_ADC EXYNOS4412_PA_ADC
+#endif
+#define S3C_PA_RTC EXYNOS4_PA_RTC
+#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG
+
+#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID
+#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
+#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
+#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
+#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
+#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
+#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
+#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
+#define S5P_PA_FIMD1 EXYNOS4_PA_FIMD1
+#define S5P_PA_FIMG2D EXYNOS4_PA_FIMG2D
+#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
+#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
+#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
+#define S5P_PA_SROMC EXYNOS4_PA_SROMC
+#define S5P_PA_MFC EXYNOS4_PA_MFC
+#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
+#define S5P_PA_TIMER EXYNOS4_PA_TIMER
+#define S5P_PA_HSOTG EXYNOS4_PA_HSOTG
+#define S5P_PA_HSPHY EXYNOS4_PA_HSPHY
+#define S5P_PA_EHCI EXYNOS4_PA_EHCI
+#define S5P_PA_OHCI EXYNOS4_PA_OHCI
+#define S5P_PA_JPEG EXYNOS4_PA_JPEG
+#define S5P_PA_TMU EXYNOS4_PA_TMU
+#define S5P_PA_DSIM0 EXYNOS4_PA_DSIM0
+#define S5P_PA_DSIM1 EXYNOS4_PA_DSIM1
+
+#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD
+
+#define S5P_PA_HDMI_CEC EXYNOS4_PA_CEC
+#define S5P_SZ_HDMI_CEC SZ_4K
+
+#define S5P_PA_VP EXYNOS4_PA_VP
+#define S5P_PA_MIXER EXYNOS4_PA_MIXER
+#define S5P_PA_TVENC EXYNOS4_PA_TVENC
+#define S5P_PA_SDO EXYNOS4_PA_SDO
+#define S5P_PA_HDMI EXYNOS4_PA_HDMI
+#define S5P_I2C_HDMI_PHY EXYNOS4_I2C_HDMI_PHY
+#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY
+#define S5P_SZ_LCD_LITE0 SZ_32K
+#define S5P_SZ_MDNIE0 SZ_4K
+#define S5P_SZ_VP SZ_64K
+#define S5P_SZ_MIXER SZ_64K
+#define S5P_SZ_TVENC SZ_64K
+#define S5P_SZ_SDO SZ_64K
+#define S5P_SZ_HDMI SZ_1M
+#define S5P_I2C_HDMI_SZ_PHY SZ_1K
+#define S5P_SZ_IIC_HDMIPHY SZ_1K
+#define S5P_PA_ACE EXYNOS4_PA_ACE
+
+#define S5P_PA_MDMA0 EXYNOS4_PA_NS_MDMA0
+#define S5P_PA_MDMA1 EXYNOS4_PA_NS_MDMA1
+#define S5P_PA_PDMA0 EXYNOS4_PA_PDMA0
+#define S5P_PA_PDMA1 EXYNOS4_PA_PDMA1
+
+/* UART */
+
+#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+
+#define S3C_PA_UART EXYNOS4_PA_UART
+
+#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
+#define S5P_PA_UART0 S5P_PA_UART(0)
+#define S5P_PA_UART1 S5P_PA_UART(1)
+#define S5P_PA_UART2 S5P_PA_UART(2)
+#define S5P_PA_UART3 S5P_PA_UART(3)
+#define S5P_PA_UART4 S5P_PA_UART(4)
+
+#define S5P_SZ_UART SZ_256
+
+#endif /* __ASM_ARCH_MAP_EXYNOS4_H */
diff --git a/arch/arm/mach-exynos/include/mach/map-exynos5.h b/arch/arm/mach-exynos/include/mach/map-exynos5.h
new file mode 100644
index 0000000..536356e
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/map-exynos5.h
@@ -0,0 +1,295 @@
+/* linux/arch/arm/mach-exynos/include/mach/map-exynos5.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS5 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_EXYNOS5_H
+#define __ASM_ARCH_MAP_EXYNOS5_H __FILE__
+
+#define EXYNOS5_PA_SYSRAM 0x02020000
+#define EXYNOS5_PA_SYSRAM_NS 0x0204F000
+
+#define EXYNOS5_PA_CHIPID 0x10000000
+
+#define EXYNOS5_PA_CMU 0x10010000
+
+#define EXYNOS5_PA_PMU 0x10040000
+
+#define EXYNOS5_PA_HDMI_CEC 0x101B0000
+#define EXYNOS5_PA_SYSTIMER 0x101C0000
+#define EXYNOS5_PA_WATCHDOG 0x101D0000
+#define EXYNOS5_PA_RTC 0x101E0000
+
+#define EXYNOS5_PA_COMBINER 0x10440000
+
+#define EXYNOS5250_REV0_PA_GIC_CPU 0x10480000
+#define EXYNOS5250_REV0_PA_GIC_DIST 0x10490000
+#define EXYNOS5250_REV1_PA_GIC_CPU 0x10482000
+#define EXYNOS5250_REV1_PA_GIC_DIST 0x10481000
+
+#define EXYNOS5_PA_SYSCON 0x10050000
+#define EXYNOS5_PA_TMU 0x10060000
+#define EXYNOS5_PA_ACE 0x10830000
+
+#define EXYNOS5_PA_DMC_PHY0 0x10C00000
+#define EXYNOS5_PA_DMC_PHY1 0x10C10000
+#define EXYNOS5_PA_DMC 0x10DD0000
+
+#define EXYNOS5_PA_PPMU_DDR_C 0x10C40000
+#define EXYNOS5_PA_PPMU_DDR_R1 0x10C50000
+#define EXYNOS5_PA_PPMU_CPU 0x10C60000
+#define EXYNOS5_PA_PPMU_DDR_L 0x10CB0000
+#define EXYNOS5_PA_PPMU_RIGHT0_BUS 0x13660000
+
+#define EXYNOS5_PA_C2C 0x10E00000
+#define EXYNOS5_PA_C2C_CP 0x10E40000
+
+#define EXYNOS5_PA_SYSMMU_MDMA1 0x10A40000
+#define EXYNOS5_PA_SYSMMU_SSS 0x10A50000
+#define EXYNOS5_PA_SYSMMU_2D 0x10A60000
+#define EXYNOS5_PA_SYSMMU_MFC_R 0x11200000
+#define EXYNOS5_PA_SYSMMU_MFC_L 0x11210000
+#define EXYNOS5_PA_SYSMMU_ROTATOR 0x11D40000
+#define EXYNOS5_PA_SYSMMU_MDMA2 0x11D50000
+#define EXYNOS5_PA_SYSMMU_JPEG 0x11F20000
+#define EXYNOS5_PA_SYSMMU_IOP 0x12360000
+#define EXYNOS5_PA_SYSMMU_RTIC 0x12370000
+#define EXYNOS5_PA_SYSMMU_GPS 0x12630000
+#define EXYNOS5_PA_SYSMMU_ISP 0x13260000
+#define EXYNOS5_PA_SYSMMU_DRC 0x13270000
+#define EXYNOS5_PA_SYSMMU_SCALERC 0x13280000
+#define EXYNOS5_PA_SYSMMU_SCALERP 0x13290000
+#define EXYNOS5_PA_SYSMMU_FD 0x132A0000
+#define EXYNOS5_PA_SYSMMU_ISPCPU 0x132B0000
+#define EXYNOS5_PA_SYSMMU_ODC 0x132C0000
+#define EXYNOS5_PA_SYSMMU_DIS0 0x132D0000
+#define EXYNOS5_PA_SYSMMU_DIS1 0x132E0000
+#define EXYNOS5_PA_SYSMMU_3DNR 0x132F0000
+#define EXYNOS5_PA_SYSMMU_LITE0 0x13C40000
+#define EXYNOS5_PA_SYSMMU_LITE1 0x13C50000
+#define EXYNOS5_PA_SYSMMU_LITE2 0x13CA0000
+#define EXYNOS5_PA_SYSMMU_GSC0 0x13E80000
+#define EXYNOS5_PA_SYSMMU_GSC1 0x13E90000
+#define EXYNOS5_PA_SYSMMU_GSC2 0x13EA0000
+#define EXYNOS5_PA_SYSMMU_GSC3 0x13EB0000
+#define EXYNOS5_PA_SYSMMU_FIMD1 0x14640000
+#define EXYNOS5_PA_SYSMMU_TV 0x14650000
+
+#define EXYNOS5_PA_FIMG2D 0x10850000
+#define EXYNOS5_PA_MFC 0x11000000
+
+#define EXYNOS5_PA_GPIO1 0x11400000
+#define EXYNOS5_PA_GPIO2 0x13400000
+#define EXYNOS5_PA_GPIO3 0x10D10000
+#define EXYNOS5_PA_GPIO4 0x03860000
+
+#define EXYNOS5_PA_G3D 0x11800000
+
+#define EXYNOS5_PA_HSMMC(x) (0x12200000 + ((x) * 0x10000))
+#define EXYNOS5_PA_DWMCI 0x12240000
+
+#define EXYNOS5_PA_SS_UDC 0x1200C100
+#define EXYNOS5_PA_SS_DRD 0x12000000
+#define EXYNOS5_PA_SS_PHY 0x12100000
+#define EXYNOS5_PA_EHCI 0x12110000
+#define EXYNOS5_PA_OHCI 0x12120000
+#define EXYNOS5_PA_HSPHY 0x12130000
+#define EXYNOS5_PA_HSOTG 0x12140000
+
+#define EXYNOS5_PA_SATA_PHY_CTRL 0x12170000
+#define EXYNOS5_PA_SATA_PHY_I2C 0x121D0000
+#define EXYNOS5_PA_SATA_BASE 0x122F0000
+
+#define EXYNOS5_PA_SROMC 0x12250000
+#define EXYNOS4_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
+
+#define EXYNOS5_PA_UART 0x12C00000
+
+#define EXYNOS5_PA_IIC(x) (0x12C60000 + ((x) * 0x10000))
+#define EXYNOS5_PA_IIC_HDMIPHY 0x12CE0000
+
+#define EXYNOS5_PA_ADC 0x12D10000
+
+#define EXYNOS5_PA_SPI0 0x12D20000
+#define EXYNOS5_PA_SPI1 0x12D30000
+#define EXYNOS5_PA_SPI2 0x12D40000
+
+#define EXYNOS5_PA_TIMER 0x12DD0000
+
+#define EXYNOS5_PA_FIMD0 0x13800000
+#define EXYNOS5_PA_FIMD1 0x14400000
+#define EXYNOS5_PA_MIXER 0x14450000
+#define EXYNOS5_PA_DSIM0 0x14500000
+#define EXYNOS5_PA_DP 0x145B0000
+#define EXYNOS5_PA_HDMI 0x14530000
+
+#define EXYNOS5_PA_FIMC_IS 0x13000000
+
+#define EXYNOS5_PA_FIMC_LITE0 0x13C00000
+#define EXYNOS5_PA_FIMC_LITE1 0x13C10000
+#define EXYNOS5_PA_FIMC_LITE2 0x13C90000
+
+#define EXYNOS5_PA_MIPI_CSIS0 0x13C20000
+#define EXYNOS5_PA_MIPI_CSIS1 0x13C30000
+
+#define EXYNOS5_PA_GSC0 0x13E00000
+#define EXYNOS5_PA_GSC1 0x13E10000
+#define EXYNOS5_PA_GSC2 0x13E20000
+#define EXYNOS5_PA_GSC3 0x13E30000
+
+#define EXYNOS5_PA_ROTATOR 0x11c00000
+
+#define EXYNOS5_PA_SDRAM 0x40000000
+
+#define EXYNOS5_PA_NS_MDMA0 0x10800000
+#define EXYNOS5_PA_NS_MDMA1 0x11c10000
+#define EXYNOS5_PA_PDMA0 0x121a0000
+#define EXYNOS5_PA_PDMA1 0x121b0000
+
+#define EXYNOS5_PA_AUDSS 0x03810000
+#define EXYNOS5_PA_I2S0 0x03830000
+#define EXYNOS5_PA_I2S1 0x12D60000
+#define EXYNOS5_PA_I2S2 0x12D70000
+
+#define EXYNOS5_PA_PCM0 0x03840000
+#define EXYNOS5_PA_PCM1 0x12D80000
+#define EXYNOS5_PA_PCM2 0x12D90000
+
+#define EXYNOS5_PA_AC97 0x12DA0000
+
+#define EXYNOS5_PA_SPDIF 0x12DB0000
+#define EXYNOS4_PA_JPEG 0x11E00000
+
+#define EXYNOS5_PA_BTS_CPU 0x10C80000
+#define EXYNOS5_PA_BTS_G3D_ACP 0x10EA0000
+#define EXYNOS5_PA_BTS_MFC0 0x11220000
+#define EXYNOS5_PA_BTS_MFC1 0x11230000
+#define EXYNOS5_PA_BTS_ROTATOR 0x11D60000
+#define EXYNOS5_PA_BTS_MDMA1 0x11D70000
+#define EXYNOS5_PA_BTS_JPEG 0x11F40000
+#define EXYNOS5_PA_BTS_GSCL0 0x13EC0000
+#define EXYNOS5_PA_BTS_GSCL1 0x13ED0000
+#define EXYNOS5_PA_BTS_GSCL2 0x13EE0000
+#define EXYNOS5_PA_BTS_GSCL3 0x13EF0000
+#define EXYNOS5_PA_BTS_DISP10 0x14660000
+#define EXYNOS5_PA_BTS_DISP11 0x14670000
+#define EXYNOS5_PA_BTS_TV0 0x14690000
+#define EXYNOS5_PA_BTS_TV1 0x146A0000
+#define EXYNOS5_PA_BTS_C2C 0x10c90000
+#define EXYNOS5_PA_FBM_DDR_R1 0x10c30000
+#define EXYNOS5_PA_FBM_DDR_R0 0x10dc0000
+#define EXYNOS5_PA_BTS_FIMC_ISP 0x13300000
+#define EXYNOS5_PA_BTS_FIMC_SCALER_C 0x13320000
+#define EXYNOS5_PA_BTS_FIMC_SCALER_P 0x13330000
+#define EXYNOS5_PA_BTS_FIMC_FD 0x13340000
+#define EXYNOS5_PA_BTS_FIMC_ODC 0x13370000
+#define EXYNOS5_PA_BTS_FIMC_DIS0 0x13380000
+#define EXYNOS5_PA_BTS_FIMC_DIS1 0x13390000
+#define EXYNOS5_PA_BTS_FIMC_3DNR 0x133A0000
+
+/* Compatibiltiy Defines */
+
+#define EXYNOS_PA_DWMCI EXYNOS5_PA_DWMCI
+
+#define EXYNOS_PA_SPI0 EXYNOS5_PA_SPI0
+#define EXYNOS_PA_SPI1 EXYNOS5_PA_SPI1
+#define EXYNOS_PA_SPI2 EXYNOS5_PA_SPI2
+
+#define S5P_PA_HDMI_CEC EXYNOS5_PA_HDMI_CEC
+
+#define S3C_PA_HSMMC0 EXYNOS5_PA_HSMMC(0)
+#define S3C_PA_HSMMC1 EXYNOS5_PA_HSMMC(1)
+#define S3C_PA_HSMMC2 EXYNOS5_PA_HSMMC(2)
+#define S3C_PA_HSMMC3 EXYNOS5_PA_HSMMC(3)
+
+#define EXYNOS_PA_AUDSS EXYNOS5_PA_AUDSS
+#define EXYNOS_PA_I2S0 EXYNOS5_PA_I2S0
+#define EXYNOS_PA_I2S1 EXYNOS5_PA_I2S1
+#define EXYNOS_PA_I2S2 EXYNOS5_PA_I2S2
+
+#define EXYNOS_PA_PCM0 EXYNOS5_PA_PCM0
+#define EXYNOS_PA_PCM1 EXYNOS5_PA_PCM1
+#define EXYNOS_PA_PCM2 EXYNOS5_PA_PCM2
+
+#define EXYNOS_PA_AC97 EXYNOS5_PA_AC97
+
+#define EXYNOS_PA_SPDIF EXYNOS5_PA_SPDIF
+
+#define EXYNOS_PA_FIMC_LITE0 EXYNOS5_PA_FIMC_LITE0
+#define EXYNOS_PA_FIMC_LITE1 EXYNOS5_PA_FIMC_LITE1
+#define EXYNOS_PA_FIMC_LITE2 EXYNOS5_PA_FIMC_LITE2
+
+#define EXYNOS_PA_ROTATOR EXYNOS5_PA_ROTATOR
+
+#define EXYNOS_PA_C2C EXYNOS5_PA_C2C
+#define EXYNOS_PA_C2C_CP EXYNOS5_PA_C2C_CP
+
+#define S3C_PA_IIC EXYNOS5_PA_IIC(0)
+#define S3C_PA_IIC1 EXYNOS5_PA_IIC(1)
+#define S3C_PA_IIC2 EXYNOS5_PA_IIC(2)
+#define S3C_PA_IIC3 EXYNOS5_PA_IIC(3)
+#define S3C_PA_IIC4 EXYNOS5_PA_IIC(4)
+#define S3C_PA_IIC5 EXYNOS5_PA_IIC(5)
+#define S3C_PA_IIC6 EXYNOS5_PA_IIC(6)
+#define S3C_PA_IIC7 EXYNOS5_PA_IIC(7)
+#define SAMSUNG_PA_ADC EXYNOS5_PA_ADC
+#define S5P_PA_IIC_HDMIPHY EXYNOS5_PA_IIC_HDMIPHY
+#define S3C_PA_WDT EXYNOS5_PA_WATCHDOG
+#define S3C_PA_RTC EXYNOS5_PA_RTC
+#define S5P_PA_CHIPID EXYNOS5_PA_CHIPID
+#define S5P_PA_SYSCON EXYNOS5_PA_SYSCON
+#define S5P_PA_SROMC EXYNOS5_PA_SROMC
+#define S5P_PA_TIMER EXYNOS5_PA_TIMER
+#define S5P_PA_HSOTG EXYNOS5_PA_HSOTG
+#define S5P_PA_MFC EXYNOS5_PA_MFC
+#define S5P_PA_HSPHY EXYNOS5_PA_HSPHY
+#define S5P_PA_EHCI EXYNOS5_PA_EHCI
+#define S5P_PA_OHCI EXYNOS5_PA_OHCI
+#define S5P_PA_FIMD0 EXYNOS5_PA_FIMD0
+#define S5P_PA_FIMD1 EXYNOS5_PA_FIMD1
+#define S5P_PA_MIXER EXYNOS5_PA_MIXER
+#define S5P_PA_DP EXYNOS5_PA_DP
+#define S5P_PA_HDMI EXYNOS5_PA_HDMI
+#define S5P_PA_SDRAM EXYNOS5_PA_SDRAM
+#define S5P_PA_FIMG2D EXYNOS5_PA_FIMG2D
+
+#define S5P_PA_MDMA0 EXYNOS5_PA_NS_MDMA0
+#define S5P_PA_MDMA1 EXYNOS5_PA_NS_MDMA1
+#define S5P_PA_PDMA0 EXYNOS5_PA_PDMA0
+#define S5P_PA_PDMA1 EXYNOS5_PA_PDMA1
+#define S5P_PA_DSIM0 EXYNOS5_PA_DSIM0
+#define S5P_PA_JPEG EXYNOS4_PA_JPEG
+#define S5P_PA_MIPI_CSIS0 EXYNOS5_PA_MIPI_CSIS0
+#define S5P_PA_MIPI_CSIS1 EXYNOS5_PA_MIPI_CSIS1
+
+#define S5P_PA_ACE EXYNOS5_PA_ACE
+#define S5P_PA_TMU EXYNOS5_PA_TMU
+/* UART */
+
+#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+
+#define S3C_PA_UART EXYNOS5_PA_UART
+
+#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
+#define S5P_PA_UART0 S5P_PA_UART(0)
+#define S5P_PA_UART1 S5P_PA_UART(1)
+#define S5P_PA_UART2 S5P_PA_UART(2)
+#define S5P_PA_UART3 S5P_PA_UART(3)
+#define S5P_PA_UART4 S5P_PA_UART(4)
+
+#define S5P_SZ_HDMI_CEC SZ_64K
+
+#define S5P_SZ_UART SZ_256
+
+#define S5P_SZ_MIXER SZ_64K
+#define S5P_SZ_HDMI SZ_1M
+#define S5P_SZ_IIC_HDMIPHY SZ_64K
+
+#endif /* __ASM_ARCH_MAP_EXYNOS5_H */
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
new file mode 100644
index 0000000..5efb7b6
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -0,0 +1,34 @@
+/* linux/arch/arm/mach-exynos/include/mach/map.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+
+/*
+ * EXYNOS4 UART offset is 0x10000 but the older S5P SoCs are 0x400.
+ * So need to define it, and here is to avoid redefinition warning.
+ */
+#define S3C_UART_OFFSET (0x10000)
+
+#include <plat/map-s5p.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#include "map-exynos4.h"
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#include "map-exynos5.h"
+#else
+#error "ARCH_EXYNOS* is not defined"
+#endif
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/include/mach/mdm2.h b/arch/arm/mach-exynos/include/mach/mdm2.h
new file mode 100644
index 0000000..78ca88f
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/mdm2.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_MDM2_H
+#define _ARCH_ARM_MACH_MSM_MDM2_H
+
+struct mdm_platform_data {
+ char *mdm_version;
+ int ramdump_delay_ms;
+ struct platform_device *peripheral_platform_device;
+};
+
+#endif
+
diff --git a/arch/arm/mach-exynos/include/mach/media.h b/arch/arm/mach-exynos/include/mach/media.h
new file mode 100644
index 0000000..ce0e53e
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/media.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-exysnos4/include/mach/media.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung Media device descriptions for exynos4
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _EXYNOS4_MEDIA_H
+#define _EXYNOS4_MEDIA_H
+
+#ifdef CONFIG_CMA
+#define S5P_MDEV_FIMC0 0
+#define S5P_MDEV_FIMC1 1
+#define S5P_MDEV_FIMC2 2
+#define S5P_MDEV_FIMC3 3
+#define S5P_MDEV_MFC 4
+#define S5P_MDEV_JPEG 5
+#define S5P_MDEV_FIMD 6
+#define S5P_MDEV_FIMG2D 7
+#define S5P_MDEV_SRP 8
+#define S5P_MDEV_TVOUT 9
+
+
+#ifdef CONFIG_MACH_U1
+#define S5P_MDEV_PMEM 10
+#endif
+
+
+#define S5P_RANGE_MFC SZ_256M
+#endif /* CONFIG_CMA */
+#endif
diff --git a/arch/arm/mach-exynos4/include/mach/memory.h b/arch/arm/mach-exynos/include/mach/memory.h
index 374ef2c..9e3d051 100644
--- a/arch/arm/mach-exynos4/include/mach/memory.h
+++ b/arch/arm/mach-exynos/include/mach/memory.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/memory.h
+/* linux/arch/arm/mach-exynos/include/mach/memory.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -14,9 +14,17 @@
#define __ASM_ARCH_MEMORY_H __FILE__
#define PLAT_PHYS_OFFSET UL(0x40000000)
+#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_8M + SZ_4M)
+
+#if defined(CONFIG_MACH_SMDKV310) || defined(CONFIG_MACH_SMDK5250)
+#define NR_BANKS 16
+#endif
/* Maximum of 256MiB in one bank */
#define MAX_PHYSMEM_BITS 32
#define SECTION_SIZE_BITS 28
+/* Required by ION to allocate scatterlist(sglist) with nents > 256 */
+#define ARCH_HAS_SG_CHAIN
+
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-exynos/include/mach/midas-lcd.h b/arch/arm/mach-exynos/include/mach/midas-lcd.h
new file mode 100644
index 0000000..1e54994
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/midas-lcd.h
@@ -0,0 +1,34 @@
+/*
+ * midas-lcd.h - lcd Driver of MIDAS Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MIDAS_LCD_H
+#define __MIDAS_LCD_H __FILE__
+
+extern struct s3c_platform_fb fb_platform_data;
+extern struct platform_device mdnie_device;
+#ifdef CONFIG_FB_S5P_S6C1372
+extern struct platform_device lcd_s6c1372;
+#endif
+extern struct ld9040_panel_data s2plus_panel_data;
+extern struct samsung_bl_gpio_info smdk4212_bl_gpio_info;
+extern struct platform_pwm_backlight_data smdk4212_bl_data;
+extern unsigned int lcdtype;
+
+void mipi_fb_init(void);
+
+#endif /* __MIDAS_LCD_H */
diff --git a/arch/arm/mach-exynos/include/mach/midas-power.h b/arch/arm/mach-exynos/include/mach/midas-power.h
new file mode 100644
index 0000000..1742a1f
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/midas-power.h
@@ -0,0 +1,35 @@
+/*
+ * midas-power.h - Power Management of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Chiwoong Byun <woong.byun@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MIDAS_POWER_H
+#define __MIDAS_POWER_H __FILE__
+
+#if defined(CONFIG_MFD_S5M_CORE)
+extern struct s5m_platform_data exynos4_s5m8767_info;
+#else
+extern struct max77686_platform_data exynos4_max77686_info;
+extern struct max8997_platform_data exynos4_max8997_info;
+#endif
+
+void midas_power_init(void);
+void midas_power_set_muic_pdata(void *, int);
+void midas_power_gpio_init(void);
+#endif /* __MIDAS_POWER_H */
diff --git a/arch/arm/mach-exynos/include/mach/midas-sound.h b/arch/arm/mach-exynos/include/mach/midas-sound.h
new file mode 100644
index 0000000..184ec7b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/midas-sound.h
@@ -0,0 +1,32 @@
+/*
+ * midas-sound.h - Sound Management of MIDAS Project
+ *
+ * Copyright (C) 2012 Samsung Electrnoics
+ * JS Park <aitdark.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MIDAS_SOUND_H__
+#define __MIDAS_SOUND_H__ __FILE__
+
+void midas_sound_init(void);
+void midas_snd_set_mclk(bool on, bool forced);
+bool midas_snd_get_mclk(void);
+
+extern struct platform_device vbatt_device;
+extern struct platform_device s3c_device_fm34;
+
+#endif /* __MIDAS_SOUND_H__ */
diff --git a/arch/arm/mach-exynos/include/mach/midas-thermistor.h b/arch/arm/mach-exynos/include/mach/midas-thermistor.h
new file mode 100644
index 0000000..4a29313
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/midas-thermistor.h
@@ -0,0 +1,59 @@
+/*
+ * midas-thermistor.h - thermistor of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * SangYoung Son <hello.son@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MIDAS_THERMISTOR_H
+#define __MIDAS_THERMISTOR_H __FILE__
+
+#include <linux/platform_device.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-midas.h>
+#ifdef CONFIG_STMPE811_ADC
+#include <linux/stmpe811-adc.h>
+#endif
+
+/* class for factory mode */
+extern struct class *sec_class;
+
+/*
+ * struct sec_bat_adc_table_data - adc to temperature table for sec battery
+ * driver
+ * @adc: adc value
+ * @value: value
+ */
+struct adc_table_data {
+ int adc;
+ int value;
+};
+
+#ifdef CONFIG_S3C_ADC
+int convert_adc(int adc_data, int channel);
+#endif
+
+#ifdef CONFIG_STMPE811_ADC
+extern struct stmpe811_platform_data stmpe811_pdata;
+#endif
+
+#ifdef CONFIG_SEC_THERMISTOR
+extern struct platform_device sec_device_thermistor;
+#endif
+
+#endif /* __MIDAS_THERMISTOR_H */
+
diff --git a/arch/arm/mach-exynos/include/mach/midas-tsp.h b/arch/arm/mach-exynos/include/mach/midas-tsp.h
new file mode 100644
index 0000000..4cbee4c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/midas-tsp.h
@@ -0,0 +1,35 @@
+/*
+ * linux/arch/arm/mach-exynos/include/mach/midas-tsp.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MIDAS_TSP_H
+#define __MIDAS_TSP_H __FILE__
+
+#if defined(CONFIG_TOUCHSCREEN_MELFAS)
+#include <linux/platform_data/mms_ts.h>
+#else
+#include <linux/melfas_ts.h>
+#endif
+
+extern int melfas_power(int on);
+void melfas_set_touch_i2c(void);
+void melfas_set_touch_i2c_to_gpio(void);
+void midas_tsp_set_platdata(struct melfas_tsi_platform_data *pdata);
+void midas_tsp_init(void);
+int is_melfas_vdd_on(void);
+int melfas_mux_fw_flash(bool to_gpios);
+void midas_tsp_set_lcdtype(int lcd_type);
+
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+extern void midas_tsp_request_qos(void *data);
+#else
+#define midas_tsp_request_qos NULL
+#endif
+
+#endif /* __MIDAS_TSP_H */
diff --git a/arch/arm/mach-exynos/include/mach/mipi_ddi.h b/arch/arm/mach-exynos/include/mach/mipi_ddi.h
new file mode 100644
index 0000000..17fae16
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/mipi_ddi.h
@@ -0,0 +1,63 @@
+/* linux/arm/arch/mach-exynos/include/mach/mipi_ddi.h
+ *
+ * definitions for DDI based MIPI-DSI.
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _MIPI_DDI_H
+#define _MIPI_DDI_H
+
+enum mipi_ddi_interface {
+ RGB_IF = 0x4000,
+ I80_IF = 0x8000,
+ YUV_601 = 0x10000,
+ YUV_656 = 0x20000,
+ MIPI_VIDEO = 0x1000,
+ MIPI_COMMAND = 0x2000,
+};
+
+enum mipi_ddi_panel_select {
+ DDI_MAIN_LCD = 0,
+ DDI_SUB_LCD = 1,
+};
+
+enum mipi_ddi_model {
+ S6DR117 = 0,
+};
+
+enum mipi_ddi_parameter {
+ /* DSIM video interface parameter */
+ DSI_VIRTUAL_CH_ID = 0,
+ DSI_FORMAT = 1,
+ DSI_VIDEO_MODE_SEL = 2,
+};
+
+struct mipi_ddi_spec {
+ unsigned int parameter[3];
+};
+
+struct mipi_ddi_platform_data {
+ unsigned int dsim_base;
+ unsigned int te_irq;
+ unsigned int resume_complete;
+
+ int (*lcd_reset) (void);
+ int (*lcd_power_on) (void *pdev, int enable);
+ int (*backlight_on) (int enable);
+
+ unsigned char (*cmd_write) (unsigned int dsim_base, unsigned int data0,
+ unsigned int data1, unsigned int data2);
+ int (*cmd_read) (unsigned int reg_base, u8 addr, u16 count, u8 *buf);
+
+ unsigned int reset_delay;
+ unsigned int power_on_delay;
+ unsigned int power_off_delay;
+};
+
+#endif /* _MIPI_DDI_H */
diff --git a/arch/arm/mach-exynos/include/mach/naples-tsp.h b/arch/arm/mach-exynos/include/mach/naples-tsp.h
new file mode 100644
index 0000000..f3fa320
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/naples-tsp.h
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/arm/mach-exynos/include/mach/naples-tsp.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __NAPLES_TSP_H
+#define __NAPLES_TSP_H __FILE__
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224
+#include <linux/i2c/mxt224.h>
+#endif
+extern bool is_cable_attached;
+void naples_tsp_init(void);
+void tsp_charger_infom(bool en);
+
+#endif /* __MIDAS_TSP_H */
diff --git a/arch/arm/mach-exynos/include/mach/p10-battery.h b/arch/arm/mach-exynos/include/mach/p10-battery.h
new file mode 100644
index 0000000..09989e5
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/p10-battery.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-exynos/include/mach/p10-battery.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __P10_BATTERY_H
+#define __P10_BATTERY_H __FILE__
+
+void p10_battery_init(void);
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/p10-input.h b/arch/arm/mach-exynos/include/mach/p10-input.h
new file mode 100644
index 0000000..47d96d7
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/p10-input.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-exynos/include/mach/p10-input.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __P10_INPUT_H
+#define __P10_INPUT_H __FILE__
+
+void p10_tsp_init(void);
+void p10_key_init(void);
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/p4-input.h b/arch/arm/mach-exynos/include/mach/p4-input.h
new file mode 100644
index 0000000..b7ecddb
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/p4-input.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-exynos/include/mach/p4-input.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __P4_INPUT_H
+#define __P4_INPUT_H __FILE__
+
+void p4_tsp_init(u32 system_rev);
+void p4_wacom_init(void);
+void p4_key_init(void);
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301)
+extern void synaptics_ts_charger_infom(bool en);
+#endif
+
+#endif /* __P4_INPUT_H */
diff --git a/arch/arm/mach-exynos/include/mach/p4note-jack.h b/arch/arm/mach-exynos/include/mach/p4note-jack.h
new file mode 100644
index 0000000..c6a343c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/p4note-jack.h
@@ -0,0 +1,25 @@
+/*
+ * p4note-jack.h - Jack Management of P4NOTE Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __P4NOTE_JACK_H__
+#define __P4NOTE_JACK_H__ __FILE__
+
+void p4note_jack_init(void);
+void sec_set_jack_micbias(bool);
+
+#endif /* __P4NOTE_JACK_H__ */
diff --git a/arch/arm/mach-exynos4/include/mach/pm-core.h b/arch/arm/mach-exynos/include/mach/pm-core.h
index f26e46b..ef84c7c 100644
--- a/arch/arm/mach-exynos4/include/mach/pm-core.h
+++ b/arch/arm/mach-exynos/include/mach/pm-core.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
+/* linux/arch/arm/mach-exynos/include/mach/pm-core.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -15,6 +15,7 @@
* published by the Free Software Foundation.
*/
#include <mach/regs-pmu.h>
+#include <mach/regs-gpio.h>
static inline void s3c_pm_debug_init_uart(void)
{
@@ -23,12 +24,11 @@ static inline void s3c_pm_debug_init_uart(void)
static inline void s3c_pm_arch_prepare_irqs(void)
{
- unsigned int tmp;
- tmp = __raw_readl(S5P_WAKEUP_MASK);
- tmp &= ~(1 << 31);
- __raw_writel(tmp, S5P_WAKEUP_MASK);
-
- __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
+#if defined(CONFIG_EXYNOS4212) || defined(CONFIG_EXYNOS4412)
+ /* Mask externel GIC and GPS_ALIVE wakeup source */
+ s3c_irqwake_intmask |= 0x3BF0000;
+#endif
+ __raw_writel((s3c_irqwake_intmask & S5P_WAKEUP_MASK_BIT), S5P_WAKEUP_MASK);
__raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
}
@@ -39,7 +39,15 @@ static inline void s3c_pm_arch_stop_clocks(void)
static inline void s3c_pm_arch_show_resume_irqs(void)
{
- /* nothing here yet */
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_CPU_EXYNOS4412)\
+ || defined(CONFIG_CPU_EXYNOS5250)
+ pr_info("WAKEUP_STAT: 0x%x\n", __raw_readl(S5P_WAKEUP_STAT));
+ pr_info("WAKEUP_INTx_PEND: 0x%x, 0x%x, 0x%x, 0x%x\n",
+ __raw_readl(S5P_EINT_PEND(0)),
+ __raw_readl(S5P_EINT_PEND(1)),
+ __raw_readl(S5P_EINT_PEND(2)),
+ __raw_readl(S5P_EINT_PEND(3)));
+#endif
}
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
@@ -47,3 +55,13 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
{
/* nothing here yet */
}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_saved_gpios(void)
+{
+ /* nothing here yet */
+}
diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h
new file mode 100644
index 0000000..d475dd5
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/pmu.h
@@ -0,0 +1,117 @@
+/* linux/arch/arm/mach-exynos/include/mach/pmu.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4210 - PMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PMU_H
+#define __ASM_ARCH_PMU_H __FILE__
+
+#include <linux/cpu.h>
+#include <linux/io.h>
+#include <mach/regs-pmu.h>
+
+static inline void exynos4_reset_assert_ctrl(unsigned int on)
+{
+ unsigned int i;
+ unsigned int core_option;
+
+ for (i = 0; i < num_possible_cpus(); i++) {
+ core_option = __raw_readl(S5P_ARM_CORE_OPTION(i));
+ core_option &= ~S5P_USE_DELAYED_RESET_ASSERTION;
+ core_option |= (on << S5P_USE_DELAYED_RESET_OFFSET);
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("%s %p %08x\n", __func__,
+ S5P_ARM_CORE_OPTION(i), core_option);
+#endif
+ __raw_writel(core_option, S5P_ARM_CORE_OPTION(i));
+ }
+}
+
+static inline int exynos4_is_c2c_use(void)
+{
+ unsigned int ret;
+
+ ret = __raw_readl(S5P_C2C_CTRL);
+
+ return ret;
+}
+
+enum sys_powerdown {
+ SYS_AFTR,
+ SYS_LPA,
+ SYS_SLEEP,
+ NUM_SYS_POWERDOWN,
+};
+
+struct exynos4_pmu_conf {
+ void __iomem *reg;
+ unsigned long val[NUM_SYS_POWERDOWN];
+};
+
+enum c2c_pwr_mode {
+ MIN_LATENCY,
+ SHORT_LATENCY,
+ MAX_LATENCY,
+};
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+enum xclkout_select {
+ XCLKOUT_CMU_DMC = 0x0,
+ XCLKOUT_CMU_TOP = 0x1,
+ XCLKOUT_CMU_LEFTBUS = 0x2,
+ XCLKOUT_CMU_RIGHTBUS = 0x3,
+ XCLKOUT_CMU_CPU = 0x4,
+ XCLKOUT_CMU_ISP = 0x5, /* Not support at EXYNOS4210 */
+ XCLKOUT_XXTI = 0x8,
+ XCLKOUT_XUSBXTI = 0x9,
+ XCLKOUT_RTC_TICCLK = 0xC,
+ XCLKOUT_RTCCLK = 0xD,
+ XCLKOUT_CLKOUT_DEBUG = 0xE, /* Not support at EXYNOS4210 */
+};
+#elif defined(CONFIG_CPU_EXYNOS5250)
+enum xclkout_select {
+ XCLKOUT_DEBUG = 0x0,
+ XCLKOUT_CMU_CDREX = 0x1,
+ XCLKOUT_CMU_CORE = 0x2,
+ XCLKOUT_CMU_ISP = 0x3,
+ XCLKOUT_CMU_LEX = 0x4,
+ XCLKOUT_CMU_MIX = 0x5,
+ XCLKOUT_CMU_RIX = 0x6,
+ XCLKOUT_CMU_TOP = 0x7,
+ XCLKOUT_CMU_CPU = 0x8,
+ XCLKOUT_CMU_ACP = 0x9,
+ XCLKOUT_XXTI = 0x10,
+ XCLKOUT_XUSBXTI = 0x11,
+ XCLKOUT_TICCLK = 0x12,
+ XCLKOUT_RTCCLK = 0x13,
+};
+#endif
+
+struct exynos4_c2c_pmu_conf {
+ void __iomem *reg;
+ unsigned long val;
+};
+
+/* external function for exynos4 series */
+extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
+extern int exynos4_enter_lp(unsigned long *saveblk, long);
+extern void exynos4_idle_resume(void);
+extern void exynos4_c2c_request_pwr_mode(enum c2c_pwr_mode mode);
+extern void exynos4_sys_powerdown_xusbxti_control(unsigned int enable);
+extern void exynos4_pmu_xclkout_set(unsigned int enable, enum xclkout_select source);
+
+/* external function for exynos5 series */
+extern void exynos5_sys_powerdown_conf(enum sys_powerdown mode);
+extern int exynos5_enter_lp(unsigned long *saveblk, long);
+extern void exynos5_idle_resume(void);
+extern void exynos5_sys_powerdown_xxti_control(unsigned int enable);
+extern void exynos5_pmu_xclkout_set(unsigned int enable, enum xclkout_select source);
+
+#endif /* __ASM_ARCH_PMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/ppmu.h b/arch/arm/mach-exynos/include/mach/ppmu.h
new file mode 100644
index 0000000..684ce5c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/ppmu.h
@@ -0,0 +1,122 @@
+/* linux/arch/arm/mach-exynos/include/mach/ppmu.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - PPMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PPMU_H
+#define __ASM_ARCH_PPMU_H __FILE__
+
+#define NUMBER_OF_COUNTER 4
+
+#define PPMU_CNTENS 0x10
+#define PPMU_CNTENC 0x20
+#define PPMU_INTENS 0x30
+#define PPMU_INTENC 0x40
+#define PPMU_FLAG 0x50
+
+#define PPMU_CCNT 0x100
+#define PPMU_PMCNT0 0x110
+#define PPMU_PMCNT_OFFSET 0x10
+
+#define PPMU_BEVT0SEL 0x1000
+#define PPMU_BEVTSEL_OFFSET 0x100
+#define PPMU_CNT_RESET 0x1800
+
+#define DEVT0_SEL 0x1000
+#define DEVT0_ID 0x1010
+#define DEVT0_IDMSK 0x1014
+#define DEVT_ID_OFFSET 0x100
+
+#define DEFAULT_WEIGHT 1
+
+#define MAX_CCNT 100
+
+/* For flags */
+#define VIDEO_DOMAIN 0x00000001
+#define AUDIO_DOMAIN 0x00000002
+#define ALL_DOMAIN 0xffffffff
+
+/* For event */
+#define RD_DATA_COUNT 0x00000005
+#define WR_DATA_COUNT 0x00000006
+#define RDWR_DATA_COUNT 0x00000007
+
+#define PMCNT_OFFSET(i) (PPMU_PMCNT0 + (PPMU_PMCNT_OFFSET * i))
+
+enum ppmu_counter {
+ PPMU_PMNCNT0,
+ PPMU_PMCCNT1,
+ PPMU_PMNCNT2,
+ PPMU_PMNCNT3,
+ PPMU_PMNCNT_MAX,
+};
+
+enum ppmu_ch {
+ DMC0,
+ DMC1,
+};
+
+enum ppmu_type {
+ PPMU_MIF,
+ PPMU_INT,
+ PPMU_TYPE_END,
+};
+
+enum exynos4_ppmu {
+ PPMU_DMC0,
+ PPMU_DMC1,
+ PPMU_CPU,
+#ifdef CONFIG_ARCH_EXYNOS5
+ PPMU_DDR_C,
+ PPMU_DDR_R1,
+ PPMU_DDR_L,
+ PPMU_RIGHT0_BUS,
+#endif
+ PPMU_END,
+};
+
+extern unsigned long long ppmu_load[PPMU_END];
+extern unsigned long long ppmu_load_detail[2][PPMU_END];
+
+struct exynos4_ppmu_hw {
+ struct list_head node;
+ void __iomem *hw_base;
+ unsigned int ccnt;
+ unsigned int event[NUMBER_OF_COUNTER];
+ unsigned int weight;
+ int usage;
+ int id;
+ unsigned int flags;
+ struct device *dev;
+ unsigned int count[NUMBER_OF_COUNTER];
+};
+
+void exynos4_ppc_reset(struct exynos4_ppmu_hw *ppmu);
+void exynos4_ppc_start(struct exynos4_ppmu_hw *ppmu);
+void exynos4_ppc_stop(struct exynos4_ppmu_hw *ppmu);
+void exynos4_ppc_setevent(struct exynos4_ppmu_hw *ppmu,
+ unsigned int evt_num);
+unsigned long long exynos4_ppc_update(struct exynos4_ppmu_hw *ppmu);
+
+void exynos4_ppmu_reset(struct exynos4_ppmu_hw *ppmu);
+void exynos4_ppmu_start(struct exynos4_ppmu_hw *ppmu);
+void exynos4_ppmu_stop(struct exynos4_ppmu_hw *ppmu);
+void exynos4_ppmu_setevent(struct exynos4_ppmu_hw *ppmu,
+ unsigned int evt_num);
+unsigned long long exynos4_ppmu_update(struct exynos4_ppmu_hw *ppmu, int ch);
+
+void ppmu_init(struct exynos4_ppmu_hw *ppmu, struct device *dev);
+void ppmu_start(struct device *dev);
+void ppmu_update(struct device *dev, int ch);
+void ppmu_reset(struct device *dev);
+
+extern struct exynos4_ppmu_hw exynos_ppmu[];
+#endif /* __ASM_ARCH_PPMU_H */
+
diff --git a/arch/arm/mach-exynos4/include/mach/pwm-clock.h b/arch/arm/mach-exynos/include/mach/pwm-clock.h
index 8e12090..5e06b94 100644
--- a/arch/arm/mach-exynos4/include/mach/pwm-clock.h
+++ b/arch/arm/mach-exynos/include/mach/pwm-clock.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/pwm-clock.h
+/* linux/arch/arm/mach-exynos/include/mach/pwm-clock.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/regs-audss.h b/arch/arm/mach-exynos/include/mach/regs-audss.h
new file mode 100644
index 0000000..a480753
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-audss.h
@@ -0,0 +1,46 @@
+/* arch/arm/mach-exynos/include/mach/regs-audss.h
+ *
+ * Copyright 2011 Samsung Electronics
+ *
+ * EXYNOS4 Audio SubSystem clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_REGS_AUDSS_H
+#define __PLAT_REGS_AUDSS_H __FILE__
+
+#define EXYNOS4_AUDSSREG(x) (S5P_VA_AUDSS + (x))
+
+#define S5P_CLKSRC_AUDSS EXYNOS4_AUDSSREG(0x0)
+#define S5P_CLKDIV_AUDSS EXYNOS4_AUDSSREG(0x4)
+#define S5P_CLKGATE_AUDSS EXYNOS4_AUDSSREG(0x8)
+
+/* CLKSRC0 */
+#define S5P_AUDSS_CLKSRC_MAIN_MASK (0x1<<0)
+#define S5P_AUDSS_CLKSRC_MAIN_SHIFT (0)
+#define S5P_AUDSS_CLKSRC_I2SCLK_MASK (0x3<<2)
+#define S5P_AUDSS_CLKSRC_I2SCLK_SHIFT (2)
+
+/* CLKDIV0 */
+#define S5P_AUDSS_CLKDIV_RP_MASK (0xf<<0)
+#define S5P_AUDSS_CLKDIV_RP_SHIFT (0)
+#define S5P_AUDSS_CLKDIV_BUSCLK_MASK (0xf<<4)
+#define S5P_AUDSS_CLKDIV_BUSCLK_SHIFT (4)
+#define S5P_AUDSS_CLKDIV_I2SCLK_MASK (0xf<<8)
+#define S5P_AUDSS_CLKDIV_I2SCLK_SHIFT (8)
+
+/* IP Clock Gate 0 Registers */
+#define S5P_AUDSS_CLKGATE_RP (1<<0)
+#define S5P_AUDSS_CLKGATE_INTMEM (1<<1)
+#define S5P_AUDSS_CLKGATE_I2SBUS (1<<2)
+#define S5P_AUDSS_CLKGATE_I2SSPECIAL (1<<3)
+#define S5P_AUDSS_CLKGATE_PCMBUS (1<<4)
+#define S5P_AUDSS_CLKGATE_PCMSPECIAL (1<<5)
+#define S5P_AUDSS_CLKGATE_GPIO (1<<6)
+#define S5P_AUDSS_CLKGATE_UART (1<<7)
+#define S5P_AUDSS_CLKGATE_TIMER (1<<8)
+
+#endif /* _PLAT_REGS_AUDSS_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-c2c.h b/arch/arm/mach-exynos/include/mach/regs-c2c.h
new file mode 100644
index 0000000..14b35d2
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-c2c.h
@@ -0,0 +1,73 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-c2c.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung C2C
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_S5P_C2C_H
+#define __ASM_ARM_REGS_S5P_C2C_H
+
+#include <plat/map-base.h>
+
+/***************************************************************/
+/* C2C Registers part */
+/***************************************************************/
+#define EXYNOS_C2C_REVISION 0x0
+#define EXYNOS_C2C_SYSCONFIG 0x4
+#define EXYNOS_C2C_SYSSTATUS 0x8
+#define EXYNOS_C2C_PORTCONFIG 0xc
+#define EXYNOS_C2C_MIRRORMODE 0x10
+#define EXYNOS_C2C_IRQ_RAW_STAT0 0x14
+#define EXYNOS_C2C_IRQ_RAW_STAT1 0x18
+#define EXYNOS_C2C_IRQ_EN_STAT0 0x1c
+#define EXYNOS_C2C_IRQ_EN_STAT1 0x20
+#define EXYNOS_C2C_IRQ_EN_SET0 0x24
+#define EXYNOS_C2C_IRQ_EN_SET1 0x28
+#define EXYNOS_C2C_IRQ_EN_CLEAR0 0x2c
+#define EXYNOS_C2C_IRQ_EN_CLEAR1 0x30
+#define EXYNOS_C2C_IRQ_EOI 0x34
+
+#define EXYNOS_C2C_FCLK_FREQ 0x40
+#define EXYNOS_C2C_RX_MAX_FREQ 0x44
+#define EXYNOS_C2C_TX_MAX_FREQ 0x48
+#define EXYNOS_C2C_RX_MAX_FREQ_ACK 0x4c
+#define EXYNOS_C2C_WAKE_REQ 0x50
+#define EXYNOS_C2C_WAKE_ACK 0x54
+#define EXYNOS_C2C_STANDBY 0x60
+#define EXYNOS_C2C_STANDBY_IN 0x64
+#define EXYNOS_C2C_WAIT 0x68
+#define EXYNOS_C2C_GENI_CONTROL 0x70
+#define EXYNOS_C2C_GENI_MASK 0x74
+#define EXYNOS_C2C_GENO_STATUS 0x80
+
+#define EXYNOS_C2C_GENO_INT 0x84
+#define EXYNOS_C2C_GENO_LEVEL 0x88
+
+/***************************************************************/
+/* C2C Bit definition part */
+/***************************************************************/
+/* SYSREG Bit definition */
+#define C2C_SYSREG_CG (31) /* C2C Clock Gating [31] */
+#define C2C_SYSREG_MO (30) /* Master On [30] */
+#define C2C_SYSREG_FCLK (20) /* Default Functional Clock Freq [29:20] */
+#define C2C_SYSREG_TXW (18) /* Default Tx Width [19:18] */
+#define C2C_SYSREG_RXW (16) /* Default Rx Width [17:16] */
+#define C2C_SYSREG_RST (15) /* Reset [15] */
+#define C2C_SYSREG_MD (14) /* Master On [14] */
+#define C2C_SYSREG_RTRST (13) /* Reset retention registers [13] */
+#define C2C_SYSREG_BASE_ADDR (3) /* DRAM Base Address [12:3] */
+#define C2C_SYSREG_DRAM_SIZE (0) /* DRAM Size [2:0] */
+
+#define C2C_GENIO_LATENCY_INT (26)
+#define C2C_GENIO_OPP_INT (27)
+#define C2C_GENIO_OPP_MODE0 (28)
+#define C2C_GENIO_OPP_MODE1 (29)
+#define C2C_GENIO_LATENCY0 (30)
+#define C2C_GENIO_LATENCY1 (31)
+#endif /* __ASM_ARM_REGS_S5P_C2C_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-cec.h b/arch/arm/mach-exynos/include/mach/regs-cec.h
new file mode 100644
index 0000000..1b5ed09
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-cec.h
@@ -0,0 +1,93 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-cec.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * CEC register header file for Samsung TVOUT driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_REGS_CEC_H
+#define __ARCH_ARM_REGS_CEC_H
+
+/*
+ * Register part
+ */
+#define S5P_CES_STATUS_0 (0x0000)
+#define S5P_CES_STATUS_1 (0x0004)
+#define S5P_CES_STATUS_2 (0x0008)
+#define S5P_CES_STATUS_3 (0x000C)
+#define S5P_CES_IRQ_MASK (0x0010)
+#define S5P_CES_IRQ_CLEAR (0x0014)
+#define S5P_CES_LOGIC_ADDR (0x0020)
+#define S5P_CES_DIVISOR_0 (0x0030)
+#define S5P_CES_DIVISOR_1 (0x0034)
+#define S5P_CES_DIVISOR_2 (0x0038)
+#define S5P_CES_DIVISOR_3 (0x003C)
+
+#define S5P_CES_TX_CTRL (0x0040)
+#define S5P_CES_TX_BYTES (0x0044)
+#define S5P_CES_TX_STAT0 (0x0060)
+#define S5P_CES_TX_STAT1 (0x0064)
+#define S5P_CES_TX_BUFF0 (0x0080)
+#define S5P_CES_TX_BUFF1 (0x0084)
+#define S5P_CES_TX_BUFF2 (0x0088)
+#define S5P_CES_TX_BUFF3 (0x008C)
+#define S5P_CES_TX_BUFF4 (0x0090)
+#define S5P_CES_TX_BUFF5 (0x0094)
+#define S5P_CES_TX_BUFF6 (0x0098)
+#define S5P_CES_TX_BUFF7 (0x009C)
+#define S5P_CES_TX_BUFF8 (0x00A0)
+#define S5P_CES_TX_BUFF9 (0x00A4)
+#define S5P_CES_TX_BUFF10 (0x00A8)
+#define S5P_CES_TX_BUFF11 (0x00AC)
+#define S5P_CES_TX_BUFF12 (0x00B0)
+#define S5P_CES_TX_BUFF13 (0x00B4)
+#define S5P_CES_TX_BUFF14 (0x00B8)
+#define S5P_CES_TX_BUFF15 (0x00BC)
+
+#define S5P_CES_RX_CTRL (0x00C0)
+#define S5P_CES_RX_STAT0 (0x00E0)
+#define S5P_CES_RX_STAT1 (0x00E4)
+#define S5P_CES_RX_BUFF0 (0x0100)
+#define S5P_CES_RX_BUFF1 (0x0104)
+#define S5P_CES_RX_BUFF2 (0x0108)
+#define S5P_CES_RX_BUFF3 (0x010C)
+#define S5P_CES_RX_BUFF4 (0x0110)
+#define S5P_CES_RX_BUFF5 (0x0114)
+#define S5P_CES_RX_BUFF6 (0x0118)
+#define S5P_CES_RX_BUFF7 (0x011C)
+#define S5P_CES_RX_BUFF8 (0x0120)
+#define S5P_CES_RX_BUFF9 (0x0124)
+#define S5P_CES_RX_BUFF10 (0x0128)
+#define S5P_CES_RX_BUFF11 (0x012C)
+#define S5P_CES_RX_BUFF12 (0x0130)
+#define S5P_CES_RX_BUFF13 (0x0134)
+#define S5P_CES_RX_BUFF14 (0x0138)
+#define S5P_CES_RX_BUFF15 (0x013C)
+
+#define S5P_CES_RX_FILTER_CTRL (0x0180)
+#define S5P_CES_RX_FILTER_TH (0x0184)
+
+/*
+ * Bit definition part
+ */
+#define S5P_CES_IRQ_TX_DONE (1<<0)
+#define S5P_CES_IRQ_TX_ERROR (1<<1)
+#define S5P_CES_IRQ_RX_DONE (1<<4)
+#define S5P_CES_IRQ_RX_ERROR (1<<5)
+
+#define S5P_CES_TX_CTRL_START (1<<0)
+#define S5P_CES_TX_CTRL_BCAST (1<<1)
+#define S5P_CES_TX_CTRL_RETRY (0x04<<4)
+#define S5P_CES_TX_CTRL_RESET (1<<7)
+
+#define S5P_CES_RX_CTRL_ENABLE (1<<0)
+#define S5P_CES_RX_CTRL_RESET (1<<7)
+
+#define S5P_CES_LOGIC_ADDR_MASK (0xF)
+
+#endif /* __ARCH_ARM_REGS_CEC_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
new file mode 100644
index 0000000..a0aab7c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
@@ -0,0 +1,699 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+/* For EXYNOS4 */
+#define EXYNOS_CLKREG(x) (S5P_VA_CMU + (x))
+
+#define EXYNOS4_CLKSRC_LEFTBUS EXYNOS_CLKREG(0x04200)
+#define EXYNOS4_CLKMUX_STAT_LEFTBUS EXYNOS_CLKREG(0x04400)
+#define EXYNOS4_CLKDIV_LEFTBUS EXYNOS_CLKREG(0x04500)
+#define EXYNOS4_CLKDIV_STAT_LEFTBUS EXYNOS_CLKREG(0x04600)
+#define EXYNOS4_CLKGATE_IP_LEFTBUS EXYNOS_CLKREG(0x04800)
+#define EXYNOS4_CLKOUT_CMU_LEFTBUS EXYNOS_CLKREG(0x04A00)
+
+#define EXYNOS4_CLKSRC_RIGHTBUS EXYNOS_CLKREG(0x08200)
+#define EXYNOS4_CLKMUX_STAT_RIGHTBUS EXYNOS_CLKREG(0x08400)
+#define EXYNOS4_CLKDIV_RIGHTBUS EXYNOS_CLKREG(0x08500)
+#define EXYNOS4_CLKDIV_STAT_RIGHTBUS EXYNOS_CLKREG(0x08600)
+#define EXYNOS4_CLKGATE_IP_RIGHTBUS EXYNOS_CLKREG(0x08800)
+#define EXYNOS4_CLKOUT_CMU_RIGHTBUS EXYNOS_CLKREG(0x08A00)
+
+#define EXYNOS4_EPLL_LOCK EXYNOS_CLKREG(0x0C010)
+#define EXYNOS4_VPLL_LOCK EXYNOS_CLKREG(0x0C020)
+
+#define EXYNOS4_EPLL_CON0 EXYNOS_CLKREG(0x0C110)
+#define EXYNOS4_EPLL_CON1 EXYNOS_CLKREG(0x0C114)
+#define EXYNOS4_VPLL_CON0 EXYNOS_CLKREG(0x0C120)
+#define EXYNOS4_VPLL_CON1 EXYNOS_CLKREG(0x0C124)
+
+#define EXYNOS4_CLKSRC_TOP0 EXYNOS_CLKREG(0x0C210)
+#define EXYNOS4_CLKSRC_TOP1 EXYNOS_CLKREG(0x0C214)
+#define EXYNOS4_CLKSRC_CAM EXYNOS_CLKREG(0x0C220)
+#define EXYNOS4_CLKSRC_TV EXYNOS_CLKREG(0x0C224)
+#define EXYNOS4_CLKSRC_MFC EXYNOS_CLKREG(0x0C228)
+#define EXYNOS4_CLKSRC_G3D EXYNOS_CLKREG(0x0C22C)
+#define EXYNOS4_CLKSRC_IMAGE EXYNOS_CLKREG(0x0C230)
+#define EXYNOS4_CLKSRC_LCD0 EXYNOS_CLKREG(0x0C234)
+#define EXYNOS4_CLKSRC_MAUDIO EXYNOS_CLKREG(0x0C23C)
+#define EXYNOS4_CLKSRC_FSYS EXYNOS_CLKREG(0x0C240)
+#define EXYNOS4_CLKSRC_PERIL0 EXYNOS_CLKREG(0x0C250)
+#define EXYNOS4_CLKSRC_PERIL1 EXYNOS_CLKREG(0x0C254)
+
+#define EXYNOS4_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x0C310)
+#define EXYNOS4_CLKSRC_MASK_CAM EXYNOS_CLKREG(0x0C320)
+#define EXYNOS4_CLKSRC_MASK_TV EXYNOS_CLKREG(0x0C324)
+#define EXYNOS4_CLKSRC_MASK_LCD0 EXYNOS_CLKREG(0x0C334)
+#define EXYNOS4_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x0C33C)
+#define EXYNOS4_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x0C340)
+#define EXYNOS4_CLKSRC_MASK_PERIL0 EXYNOS_CLKREG(0x0C350)
+#define EXYNOS4_CLKSRC_MASK_PERIL1 EXYNOS_CLKREG(0x0C354)
+
+#define EXYNOS4_CLKDIV_TOP EXYNOS_CLKREG(0x0C510)
+#define EXYNOS4_CLKDIV_CAM EXYNOS_CLKREG(0x0C520)
+#define EXYNOS4_CLKDIV_TV EXYNOS_CLKREG(0x0C524)
+#define EXYNOS4_CLKDIV_MFC EXYNOS_CLKREG(0x0C528)
+#define EXYNOS4_CLKDIV_G3D EXYNOS_CLKREG(0x0C52C)
+#define EXYNOS4_CLKDIV_IMAGE EXYNOS_CLKREG(0x0C530)
+#define EXYNOS4_CLKDIV_LCD0 EXYNOS_CLKREG(0x0C534)
+#define EXYNOS4_CLKDIV_ISP EXYNOS_CLKREG(0x0C538)
+#define EXYNOS4_CLKDIV_MAUDIO EXYNOS_CLKREG(0x0C53C)
+#define EXYNOS4_CLKDIV_FSYS0 EXYNOS_CLKREG(0x0C540)
+#define EXYNOS4_CLKDIV_FSYS1 EXYNOS_CLKREG(0x0C544)
+#define EXYNOS4_CLKDIV_FSYS2 EXYNOS_CLKREG(0x0C548)
+#define EXYNOS4_CLKDIV_FSYS3 EXYNOS_CLKREG(0x0C54C)
+#define EXYNOS4_CLKDIV_PERIL0 EXYNOS_CLKREG(0x0C550)
+#define EXYNOS4_CLKDIV_PERIL1 EXYNOS_CLKREG(0x0C554)
+#define EXYNOS4_CLKDIV_PERIL2 EXYNOS_CLKREG(0x0C558)
+#define EXYNOS4_CLKDIV_PERIL3 EXYNOS_CLKREG(0x0C55C)
+#define EXYNOS4_CLKDIV_PERIL4 EXYNOS_CLKREG(0x0C560)
+#define EXYNOS4_CLKDIV_PERIL5 EXYNOS_CLKREG(0x0C564)
+
+#define EXYNOS4_CLKDIV_STAT_TOP EXYNOS_CLKREG(0x0C610)
+#define EXYNOS4_CLKDIV_STAT_CAM EXYNOS_CLKREG(0x0C620)
+#define EXYNOS4_CLKDIV_STAT_MFC EXYNOS_CLKREG(0x0C628)
+#define EXYNOS4_CLKDIV_STAT_IMAGE EXYNOS_CLKREG(0x0C630)
+
+#define EXYNOS4_CLKDIV_STAT_FSYS3 EXYNOS_CLKREG(0x0C64C)
+
+#define EXYNOS4_CLKGATE_SCLKCAM EXYNOS_CLKREG(0x0C820)
+#define EXYNOS4_CLKGATE_IP_CAM EXYNOS_CLKREG(0x0C920)
+#define EXYNOS4_CLKGATE_IP_TV EXYNOS_CLKREG(0x0C924)
+#define EXYNOS4_CLKGATE_IP_MFC EXYNOS_CLKREG(0x0C928)
+#define EXYNOS4_CLKGATE_IP_G3D EXYNOS_CLKREG(0x0C92C)
+#define EXYNOS4_CLKGATE_IP_IMAGE (soc_is_exynos4210() ? \
+ EXYNOS_CLKREG(0x0C930) : \
+ EXYNOS_CLKREG(0x04930))
+#define EXYNOS4_CLKGATE_IP_IMAGE_4210 EXYNOS_CLKREG(0x0C930)
+#define EXYNOS4_CLKGATE_IP_IMAGE_4212 EXYNOS_CLKREG(0x04930)
+#define EXYNOS4_CLKGATE_IP_LCD0 EXYNOS_CLKREG(0x0C934)
+#define EXYNOS4_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x0C940)
+#define EXYNOS4_CLKGATE_IP_GPS EXYNOS_CLKREG(0x0C94C)
+#define EXYNOS4_CLKGATE_IP_PERIL EXYNOS_CLKREG(0x0C950)
+#define EXYNOS4_CLKGATE_IP_PERIR (soc_is_exynos4210() ? \
+ EXYNOS_CLKREG(0x0C960) : \
+ EXYNOS_CLKREG(0x08960))
+#define EXYNOS4_CLKGATE_IP_PERIR_4210 EXYNOS_CLKREG(0x0C960)
+#define EXYNOS4_CLKGATE_IP_PERIR_4212 EXYNOS_CLKREG(0x08960)
+#define EXYNOS4_CLKGATE_BLOCK EXYNOS_CLKREG(0x0C970)
+#define EXYNOS4_CLKOUT_CMU_TOP EXYNOS_CLKREG(0x0CA00)
+
+#define EXYNOS4_CLKSRC_MASK_DMC EXYNOS_CLKREG(0x10300)
+#define EXYNOS4_CLKSRC_DMC EXYNOS_CLKREG(0x10200)
+
+#define EXYNOS4_CLKSRC_DMC_MASK (0xF1111)
+
+#define EXYNOS4_CLKDIV_DMC0 EXYNOS_CLKREG(0x10500)
+#define EXYNOS4_CLKDIV_DMC1 EXYNOS_CLKREG(0x10504)
+#define EXYNOS4_CLKDIV_STAT_DMC0 EXYNOS_CLKREG(0x10600)
+#define EXYNOS4_CLKDIV_STAT_DMC1 EXYNOS_CLKREG(0x10604)
+#define EXYNOS4_CLKGATE_IP_DMC EXYNOS_CLKREG(0x10900)
+#define EXYNOS4_CLKOUT_CMU_DMC EXYNOS_CLKREG(0x10A00)
+
+#define EXYNOS4_DMC_PAUSE_CTRL EXYNOS_CLKREG(0x11094)
+#define DMC_PAUSE_ENABLE (1 << 0)
+
+#define EXYNOS4_APLL_LOCK EXYNOS_CLKREG(0x14000)
+#define EXYNOS4_APLL_CON0 EXYNOS_CLKREG(0x14100)
+#define EXYNOS4_APLL_CON1 EXYNOS_CLKREG(0x14104)
+#define EXYNOS4_MPLL_CON0 (soc_is_exynos4210() ? \
+ EXYNOS_CLKREG(0x14108) : \
+ EXYNOS_CLKREG(0x10108))
+#define EXYNOS4_MPLL_CON1 (soc_is_exynos4210() ? \
+ EXYNOS_CLKREG(0x1410C) : \
+ EXYNOS_CLKREG(0x1010C))
+
+#define EXYNOS4_CLKSRC_CPU EXYNOS_CLKREG(0x14200)
+#define EXYNOS4_CLKMUX_STATCPU EXYNOS_CLKREG(0x14400)
+
+#define EXYNOS4_CLKDIV_CPU EXYNOS_CLKREG(0x14500)
+#define EXYNOS4_CLKDIV_CPU1 EXYNOS_CLKREG(0x14504)
+#define EXYNOS4_CLKDIV_STATCPU EXYNOS_CLKREG(0x14600)
+#define EXYNOS4_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x14604)
+
+#define EXYNOS4_CLKGATE_SCLKCPU EXYNOS_CLKREG(0x14800)
+#define EXYNOS4_CLKGATE_IP_CPU EXYNOS_CLKREG(0x14900)
+#define EXYNOS4_CLKOUT_CMU_CPU EXYNOS_CLKREG(0x14A00)
+
+#define EXYNOS4_PMREG(x) (S5P_VA_PMU + (x))
+
+#define EXYNOS4_MIPI_CONTROL0 EXYNOS4_PMREG(0x0710)
+#define EXYNOS4_MIPI_CONTROL1 EXYNOS4_PMREG(0x0714)
+#define EXYNOS4_MIPI_DPHY_EN (1 << 0)
+#define EXYNOS4_MIPI_DPHY_S_RESETN (1 << 1)
+#define EXYNOS4_MIPI_DPHY_M_RESETN (1 << 2)
+
+#define EXYNOS4_APLL_CON0L8 EXYNOS_CLKREG(0x15100)
+#define EXYNOS4_APLL_CON0L7 EXYNOS_CLKREG(0x15104)
+#define EXYNOS4_APLL_CON0L6 EXYNOS_CLKREG(0x15108)
+#define EXYNOS4_APLL_CON0L5 EXYNOS_CLKREG(0x1510C)
+#define EXYNOS4_APLL_CON0L4 EXYNOS_CLKREG(0x15110)
+#define EXYNOS4_APLL_CON0L3 EXYNOS_CLKREG(0x15114)
+#define EXYNOS4_APLL_CON0L2 EXYNOS_CLKREG(0x15118)
+#define EXYNOS4_APLL_CON0L1 EXYNOS_CLKREG(0x1511C)
+
+#define EXYNOS4_CLKDIV_IEM_L8 EXYNOS_CLKREG(0x15300)
+#define EXYNOS4_CLKDIV_IEM_L7 EXYNOS_CLKREG(0x15304)
+#define EXYNOS4_CLKDIV_IEM_L6 EXYNOS_CLKREG(0x15308)
+#define EXYNOS4_CLKDIV_IEM_L5 EXYNOS_CLKREG(0x1530C)
+#define EXYNOS4_CLKDIV_IEM_L4 EXYNOS_CLKREG(0x15310)
+#define EXYNOS4_CLKDIV_IEM_L3 EXYNOS_CLKREG(0x15314)
+#define EXYNOS4_CLKDIV_IEM_L2 EXYNOS_CLKREG(0x15318)
+#define EXYNOS4_CLKDIV_IEM_L1 EXYNOS_CLKREG(0x1531C)
+
+#define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */
+
+#define EXYNOS4_APLLCON0_ENABLE_SHIFT (31)
+#define EXYNOS4_APLLCON0_LOCKED_SHIFT (29)
+#define EXYNOS4_APLLCON0_LOCKED_MASK (1 << EXYNOS4_APLLCON0_LOCKED_SHIFT)
+#define EXYNOS4_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
+#define EXYNOS4_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
+
+#define EXYNOS4_EPLLCON0_ENABLE_SHIFT (31)
+#define EXYNOS4_EPLLCON0_LOCKED_SHIFT (29)
+
+#define EXYNOS4_VPLLCON0_ENABLE_SHIFT (31)
+#define EXYNOS4_VPLLCON0_LOCKED_SHIFT (29)
+
+#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT (16)
+#define EXYNOS4_CLKSRC_CPU_MUXHPM_SHIFT (20)
+#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)
+
+#define EXYNOS4_CLKDIV_CPU0_CORE_SHIFT (0)
+#define EXYNOS4_CLKDIV_CPU0_CORE_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_CORE_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT (4)
+#define EXYNOS4_CLKDIV_CPU0_COREM0_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_COREM0_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT (8)
+#define EXYNOS4_CLKDIV_CPU0_COREM1_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_COREM1_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT (12)
+#define EXYNOS4_CLKDIV_CPU0_PERIPH_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_PERIPH_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_ATB_SHIFT (16)
+#define EXYNOS4_CLKDIV_CPU0_ATB_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_ATB_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
+#define EXYNOS4_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_PCLKDBG_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_APLL_SHIFT (24)
+#define EXYNOS4_CLKDIV_CPU0_APLL_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_APLL_SHIFT)
+#define EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT 28
+#define EXYNOS4_CLKDIV_CPU0_CORE2_MASK (0x7 << EXYNOS4_CLKDIV_CPU0_CORE2_SHIFT)
+
+#define EXYNOS4_CLKDIV_CPU1_COPY_SHIFT (0)
+#define EXYNOS4_CLKDIV_CPU1_COPY_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_COPY_SHIFT)
+#define EXYNOS4_CLKDIV_CPU1_HPM_SHIFT (4)
+#define EXYNOS4_CLKDIV_CPU1_HPM_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_HPM_SHIFT)
+#define EXYNOS4_CLKDIV_CPU1_CORES_SHIFT (8)
+#define EXYNOS4_CLKDIV_CPU1_CORES_MASK (0x7 << EXYNOS4_CLKDIV_CPU1_CORES_SHIFT)
+
+#define EXYNOS4_CLKDIV_DMC0_ACP_SHIFT (0)
+#define EXYNOS4_CLKDIV_DMC0_ACP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACP_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
+#define EXYNOS4_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_ACPPCLK_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT (8)
+#define EXYNOS4_CLKDIV_DMC0_DPHY_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DPHY_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DMC_SHIFT (12)
+#define EXYNOS4_CLKDIV_DMC0_DMC_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMC_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT (16)
+#define EXYNOS4_CLKDIV_DMC0_DMCD_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCD_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT (20)
+#define EXYNOS4_CLKDIV_DMC0_DMCP_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_DMCP_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT (24)
+#define EXYNOS4_CLKDIV_DMC0_COPY2_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_COPY2_SHIFT)
+#define EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT (28)
+#define EXYNOS4_CLKDIV_DMC0_CORETI_MASK (0x7 << EXYNOS4_CLKDIV_DMC0_CORETI_SHIFT)
+
+#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT (0)
+#define EXYNOS4_CLKDIV_DMC1_G2D_ACP_MASK (0xf << EXYNOS4_CLKDIV_DMC1_G2D_ACP_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_C2C_SHIFT (4)
+#define EXYNOS4_CLKDIV_DMC1_C2C_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2C_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_PWI_SHIFT (8)
+#define EXYNOS4_CLKDIV_DMC1_PWI_MASK (0xf << EXYNOS4_CLKDIV_DMC1_PWI_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT (12)
+#define EXYNOS4_CLKDIV_DMC1_C2CACLK_MASK (0x7 << EXYNOS4_CLKDIV_DMC1_C2CACLK_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT (16)
+#define EXYNOS4_CLKDIV_DMC1_DVSEM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DVSEM_SHIFT)
+#define EXYNOS4_CLKDIV_DMC1_DPM_SHIFT (24)
+#define EXYNOS4_CLKDIV_DMC1_DPM_MASK (0x7f << EXYNOS4_CLKDIV_DMC1_DPM_SHIFT)
+
+#define EXYNOS4_CLKDIV_MFC_SHIFT (0)
+#define EXYNOS4_CLKDIV_MFC_MASK (0x7 << EXYNOS4_CLKDIV_MFC_SHIFT)
+
+#define EXYNOS4_CLKDIV_CAM_SHIFT (0)
+#define EXYNOS4_CLKDIV_CAM_MASK (0xffff << EXYNOS4_CLKDIV_CAM_SHIFT)
+
+#define EXYNOS4_CLKDIV_IMAGE_SHIFT (0)
+#define EXYNOS4_CLKDIV_IMAGE_MASK (0x7 << EXYNOS4_CLKDIV_IMAGE_SHIFT)
+
+#define EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT (0)
+#define EXYNOS4_CLKDIV_TOP_ACLK200_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK200_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT (4)
+#define EXYNOS4_CLKDIV_TOP_ACLK100_MASK (0xf << EXYNOS4_CLKDIV_TOP_ACLK100_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT (8)
+#define EXYNOS4_CLKDIV_TOP_ACLK160_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK160_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT (12)
+#define EXYNOS4_CLKDIV_TOP_ACLK133_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK133_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT (16)
+#define EXYNOS4_CLKDIV_TOP_ONENAND_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ONENAND_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT (20)
+#define EXYNOS4_CLKDIV_TOP_ACLK266_GPS_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK266_GPS_SHIFT)
+#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT (24)
+#define EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_MASK (0x7 << EXYNOS4_CLKDIV_TOP_ACLK400_MCUISP_SHIFT)
+
+#define EXYNOS4_CLKDIV_TOP1_ACLK200_SUB_SHIFT (20)
+#define EXYNOS4_CLKDIV_TOP1_ACLK400_MCUISP_SUB_SHIFT (24)
+
+#define EXYNOS4_CLKDIV_BUS_GDLR_SHIFT (0)
+#define EXYNOS4_CLKDIV_BUS_GDLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GDLR_SHIFT)
+#define EXYNOS4_CLKDIV_BUS_GPLR_SHIFT (4)
+#define EXYNOS4_CLKDIV_BUS_GPLR_MASK (0x7 << EXYNOS4_CLKDIV_BUS_GPLR_SHIFT)
+
+#define EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT (0)
+#define EXYNOS4_CLKDIV_CAM_FIMC0_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC0_SHIFT)
+#define EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT (4)
+#define EXYNOS4_CLKDIV_CAM_FIMC1_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC1_SHIFT)
+#define EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT (8)
+#define EXYNOS4_CLKDIV_CAM_FIMC2_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC2_SHIFT)
+#define EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT (12)
+#define EXYNOS4_CLKDIV_CAM_FIMC3_MASK (0xf << EXYNOS4_CLKDIV_CAM_FIMC3_SHIFT)
+
+#define EXYNOS4_CLKDIV_FSYS3_MMC4_SHIFT (0)
+#define EXYNOS4_CLKDIV_FSYS3_MMC4_MASK (0xf << EXYNOS4_CLKDIV_FSYS3_MMC4_SHIFT)
+#define EXYNOS4_CLKDIV_FSYS3_MMC4PRE_SHIFT (8)
+#define EXYNOS4_CLKDIV_FSYS3_MMC4PRE_MASK (0xff << EXYNOS4_CLKDIV_FSYS3_MMC4PRE_SHIFT)
+
+/* CLK_GATE_IP_IMAGE */
+#define EXYNOS4_CLKGATE_IP_IMAGE_MDMA (0x1 << 2)
+#define EXYNOS4_CLKGATE_IP_IMAGE_SMMUMDMA (0x1 << 5)
+#define EXYNOS4_CLKGATE_IP_IMAGE_QEMDMA (0x1 << 8)
+
+/* CLK_GATE_IP_FSYS */
+#define EXYNOS4_CLKGATE_IP_FSYS_PDMA0 (0x1 << 0)
+#define EXYNOS4_CLKGATE_IP_FSYS_PDMA1 (0x1 << 1)
+
+/* CLK_GATE_IP_PERIL */
+#define EXYNOS4_CLKGATE_IP_PERIL_I2C0_7 (0xff << 6)
+
+/* Only for EXYNOS4210 */
+#define EXYNOS4_CLKSRC_LCD1 EXYNOS_CLKREG(0x0C238)
+#define EXYNOS4_CLKSRC_MASK_LCD1 EXYNOS_CLKREG(0x0C338)
+#define EXYNOS4_CLKDIV_LCD1 EXYNOS_CLKREG(0x0C538)
+#define EXYNOS4_CLKGATE_IP_LCD1 EXYNOS_CLKREG(0x0C938)
+
+/* Only for EXYNOS4212 */
+#define EXYNOS4_CLKGATE_BUS_LEFTBUS EXYNOS_CLKREG(0x04700)
+#define EXYNOS4_CLKGATE_BUS_IMAGE EXYNOS_CLKREG(0x04730)
+
+#define EXYNOS4_CLKGATE_BUS_RIGHTBUS EXYNOS_CLKREG(0x08700)
+#define EXYNOS4_CLKGATE_BUS_PERIR EXYNOS_CLKREG(0x08760)
+
+#define EXYNOS4_EPLL_CON2 EXYNOS_CLKREG(0x0C118)
+#define EXYNOS4_VPLL_CON2 EXYNOS_CLKREG(0x0C128)
+
+#define EXYNOS4_CLKSRC_ISP EXYNOS_CLKREG(0x0C238)
+#define EXYNOS4_CLKSRC_CAM1 EXYNOS_CLKREG(0x0C258)
+
+#define EXYNOS4_CLKSRC_MASK_ISP EXYNOS_CLKREG(0x0C338)
+
+#define EXYNOS4_CLKDIV_ISP EXYNOS_CLKREG(0x0C538)
+#define EXYNOS4_CLKDIV_CAM1 EXYNOS_CLKREG(0x0C568)
+
+#define EXYNOS4_CLKDIV_STAT_CAM1 EXYNOS_CLKREG(0x0C668)
+
+#define EXYNOS4_CLKGATE_BUS_PERIL EXYNOS_CLKREG(0x0C750)
+
+#define EXYNOS4_CLKGATE_IP_ISP EXYNOS_CLKREG(0x0C938)
+#define EXYNOS4_CLKGATE_IP_MAUDIO EXYNOS_CLKREG(0x0C93C)
+
+#define EXYNOS4_CLKGATE_BUS_DMC0 EXYNOS_CLKREG(0x10700)
+#define EXYNOS4_CLKGATE_BUS_DMC1 EXYNOS_CLKREG(0x10704)
+#define EXYNOS4_CLKGATE_SCLK_DMC EXYNOS_CLKREG(0x10800)
+#define EXYNOS4_CLKGATE_IP_DMC1 EXYNOS_CLKREG(0x10904)
+
+#define EXYNOS4_PWR_CTRL1 EXYNOS_CLKREG(0x15020)
+#define EXYNOS4_PWR_CTRL2 EXYNOS_CLKREG(0x15024)
+
+#define EXYNOS4_CLKDIV_ISP0 EXYNOS_CLKREG(0x18300)
+#define EXYNOS4_CLKDIV_ISP1 EXYNOS_CLKREG(0x18304)
+
+#define EXYNOS4_CLKDIV_STAT_ISP0 EXYNOS_CLKREG(0x18400)
+#define EXYNOS4_CLKDIV_STAT_ISP1 EXYNOS_CLKREG(0x18404)
+
+#define EXYNOS4_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x18800)
+#define EXYNOS4_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x18804)
+#define EXYNOS4_CLKOUT_CMU_ISP EXYNOS_CLKREG(0x18A00)
+
+#define EXYNOS4_CLKDIV_ISP_PWMISP_SHIFT (0)
+#define EXYNOS4_CLKDIV_ISP_PWMISP_MASK (0xf << EXYNOS4_CLKDIV_ISP_PWMISP_SHIFT)
+#define EXYNOS4_CLKDIV_ISP_SPI0ISP_SHIFT (4)
+#define EXYNOS4_CLKDIV_ISP_SPI0ISP_MASK (0xf << EXYNOS4_CLKDIV_ISP_SPI0ISP_SHIFT)
+#define EXYNOS4_CLKDIV_ISP_SPI0ISP_PRE_SHIFT (8)
+#define EXYNOS4_CLKDIV_ISP_SPI0ISP_PRE_MASK (0xff << EXYNOS4_CLKDIV_ISP_SPI0ISP_PRE_SHIFT)
+#define EXYNOS4_CLKDIV_ISP_SPI1ISP_SHIFT (16)
+#define EXYNOS4_CLKDIV_ISP_SPI1ISP_MASK (0xf << EXYNOS4_CLKDIV_ISP_SPI1ISP_SHIFT)
+#define EXYNOS4_CLKDIV_ISP_SPI1ISP_PRE_SHIFT (20)
+#define EXYNOS4_CLKDIV_ISP_SPI1ISP_PRE_MASK (0xff << EXYNOS4_CLKDIV_ISP_SPI1ISP_PRE_SHIFT)
+#define EXYNOS4_CLKDIV_ISP_UARTISP_SHIFT (28)
+#define EXYNOS4_CLKDIV_ISP_UARTISP_MASK (0xf << EXYNOS4_CLKDIV_ISP_SPI1ISP_SHIFT)
+
+#define EXYNOS4_CLKDIV_ISP0_ISP0_SHIFT (0)
+#define EXYNOS4_CLKDIV_ISP0_ISP0_MASK (0x7 << EXYNOS4_CLKDIV_ISP0_ISP0_SHIFT)
+#define EXYNOS4_CLKDIV_ISP0_ISP1_SHIFT (4)
+#define EXYNOS4_CLKDIV_ISP0_ISP1_MASK (0x7 << EXYNOS4_CLKDIV_ISP0_ISP1_SHIFT)
+#define EXYNOS4_CLKDIV_ISP1_MPWM_SHIFT (0)
+#define EXYNOS4_CLKDIV_ISP1_MPWM_MASK (0x7 << EXYNOS4_CLKDIV_ISP1_MPWM_SHIFT)
+#define EXYNOS4_CLKDIV_ISP1_MCUISP0_SHIFT (4)
+#define EXYNOS4_CLKDIV_ISP1_MCUISP0_MASK (0x7 << EXYNOS4_CLKDIV_ISP1_MCUISP0_SHIFT)
+#define EXYNOS4_CLKDIV_ISP1_MCUISP1_SHIFT (8)
+#define EXYNOS4_CLKDIV_ISP1_MCUISP1_MASK (0x7 << EXYNOS4_CLKDIV_ISP1_MCUISP1_SHIFT)
+
+#define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT (0)
+#define EXYNOS4_CLKDIV_CAM1_JPEG_MASK (0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT)
+
+/* PWR_CTRL */
+#define PWR_CTRL1_CORE2_DOWN_RATIO 28
+#define PWR_CTRL1_CORE2_DOWN_MASK (0x7 << PWR_CTRL1_CORE2_DOWN_RATIO)
+#define PWR_CTRL1_CORE1_DOWN_RATIO 16
+#define PWR_CTRL1_CORE1_DOWN_MASK (0x7 << PWR_CTRL1_CORE1_DOWN_RATIO)
+#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9)
+#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8)
+
+#define PWR_CTRL1_USE_CORE3_WFE (1 << 7)
+#define PWR_CTRL1_USE_CORE2_WFE (1 << 6)
+#define PWR_CTRL1_USE_CORE1_WFE (1 << 5)
+#define PWR_CTRL1_USE_CORE0_WFE (1 << 4)
+
+#define PWR_CTRL1_USE_CORE3_WFI (1 << 3)
+#define PWR_CTRL1_USE_CORE2_WFI (1 << 2)
+#define PWR_CTRL1_USE_CORE1_WFI (1 << 1)
+#define PWR_CTRL1_USE_CORE0_WFI (1 << 0)
+
+#define PWR_CTRL2_DIV2_UP_EN (1 << 25)
+#define PWR_CTRL2_DIV1_UP_EN (1 << 24)
+#define PWR_CTRL2_DUR_STANDBY2 16
+#define PWR_CTRL2_DUR_STANDBY2_MASK (0xff << PWR_CTRL2_DUR_STANDBY2)
+#define PWR_CTRL2_DUR_STANDBY1 8
+#define PWR_CTRL2_DUR_STANDBY1_MASK (0xff << PWR_CTRL2_DUR_STANDBY1)
+#define PWR_CTRL2_CORE2_UP_RATIO 4
+#define PWR_CTRL2_CORE2_UP_MASK (0x7 << PWR_CTRL2_CORE2_UP_RATIO)
+#define PWR_CTRL2_CORE1_UP_RATIO 0
+#define PWR_CTRL2_CORE1_UP_MASK (0x7 << PWR_CTRL2_CORE1_UP_RATIO)
+
+/* For EXYNOS5 */
+#define EXYNOS5_APLL_LOCK EXYNOS_CLKREG(0x00000)
+#define EXYNOS5_APLL_CON0 EXYNOS_CLKREG(0x00100)
+#define EXYNOS5_APLL_CON1 EXYNOS_CLKREG(0x00104)
+#define EXYNOS5_CLKSRC_CPU EXYNOS_CLKREG(0x00200)
+#define EXYNOS5_CLKMUX_STATCPU EXYNOS_CLKREG(0x00400)
+#define EXYNOS5_CLKDIV_CPU0 EXYNOS_CLKREG(0x00500)
+#define EXYNOS5_CLKDIV_CPU1 EXYNOS_CLKREG(0x00504)
+#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600)
+#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604)
+
+#define EXYNOS5_ARMCLK_STOPCTRL EXYNOS_CLKREG(0x01000)
+#define EXYNOS5_ATCLK_STOPCTRL EXYNOS_CLKREG(0x01004)
+
+#define EXYNOS5_PARITYFAIL_STATUS EXYNOS_CLKREG(0x01010)
+#define EXYNOS5_PARITYFAIL_CLEAR EXYNOS_CLKREG(0x01014)
+
+#define EXYNOS5_PWR_CTRL1 EXYNOS_CLKREG(0x01020)
+#define EXYNOS5_PWR_CTRL2 EXYNOS_CLKREG(0x01024)
+
+#define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100)
+#define EXYNOS5_MPLL_CON1 EXYNOS_CLKREG(0x04104)
+#define EXYNOS5_CLKSRC_CORE0 EXYNOS_CLKREG(0x04200)
+#define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204)
+
+#define EXYNOS5_CLKSRC_MASK_CORE EXYNOS_CLKREG(0x04300)
+
+#define EXYNOS5_C2C_MONITOR EXYNOS_CLKREG(0x04910)
+
+#define EXYNOS5_C2C_CONFIG EXYNOS_CLKREG(0x06000)
+
+#define EXYNOS5_UFMC_CONFIG EXYNOS_CLKREG(0x08A10)
+
+#define EXYNOS5_CPLL_LOCK EXYNOS_CLKREG(0x10020)
+#define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030)
+#define EXYNOS5_VPLL_LOCK EXYNOS_CLKREG(0x10040)
+#define EXYNOS5_GPLL_LOCK EXYNOS_CLKREG(0x10050)
+#define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120)
+#define EXYNOS5_CPLL_CON1 EXYNOS_CLKREG(0x10124)
+#define EXYNOS5_EPLL_CON0 EXYNOS_CLKREG(0x10130)
+#define EXYNOS5_EPLL_CON1 EXYNOS_CLKREG(0x10134)
+#define EXYNOS5_EPLL_CON2 EXYNOS_CLKREG(0x10138)
+#define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140)
+#define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144)
+#define EXYNOS5_VPLL_CON2 EXYNOS_CLKREG(0x10148)
+#define EXYNOS5_GPLL_CON0 EXYNOS_CLKREG(0x10150)
+#define EXYNOS5_GPLL_CON1 EXYNOS_CLKREG(0x10154)
+#define EXYNOS5_BPLL_CON0 EXYNOS_CLKREG(0x20110)
+#define EXYNOS5_BPLL_CON1 EXYNOS_CLKREG(0x20114)
+
+/* Clock Source Control Registers */
+#define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210)
+#define EXYNOS5_CLKSRC_TOP1 EXYNOS_CLKREG(0x10214)
+#define EXYNOS5_CLKSRC_TOP2 EXYNOS_CLKREG(0x10218)
+#define EXYNOS5_CLKSRC_TOP3 EXYNOS_CLKREG(0x1021C)
+#define EXYNOS5_CLKSRC_GSCL EXYNOS_CLKREG(0x10220)
+#define EXYNOS5_CLKSRC_DISP1_0 EXYNOS_CLKREG(0x1022C)
+#define EXYNOS5_CLKSRC_MAUDIO EXYNOS_CLKREG(0x10240)
+#define EXYNOS5_CLKSRC_FSYS EXYNOS_CLKREG(0x10244)
+#define EXYNOS5_CLKSRC_GEN EXYNOS_CLKREG(0x10248)
+#define EXYNOS5_CLKSRC_PERIC0 EXYNOS_CLKREG(0x10250)
+#define EXYNOS5_CLKSRC_PERIC1 EXYNOS_CLKREG(0x10254)
+#define EXYNOS5_SCLK_SRC_ISP EXYNOS_CLKREG(0x10270)
+#define EXYNOS5_CLKSRC_MASK_TOP EXYNOS_CLKREG(0x10310)
+#define EXYNOS5_CLKSRC_MASK_GSCL EXYNOS_CLKREG(0x10320)
+#define EXYNOS5_CLKSRC_MASK_DISP1_0 EXYNOS_CLKREG(0x1032C)
+#define EXYNOS5_CLKSRC_MASK_MAUDIO EXYNOS_CLKREG(0x10334)
+#define EXYNOS5_CLKSRC_MASK_FSYS EXYNOS_CLKREG(0x10340)
+#define EXYNOS5_CLKSRC_MASK_GEN EXYNOS_CLKREG(0x10344)
+#define EXYNOS5_CLKSRC_MASK_PERIC0 EXYNOS_CLKREG(0x10350)
+#define EXYNOS5_CLKSRC_MASK_PERIC1 EXYNOS_CLKREG(0x10354)
+#define EXYNOS5_CLKSRC_MASK_ISP EXYNOS_CLKREG(0x10370)
+#define EXYNOS5_CLKSRC_LEX EXYNOS_CLKREG(0x14200)
+#define EXYNOS5_CLKSRC_CDREX EXYNOS_CLKREG(0x20200)
+
+/* Clock Rate Control Registers */
+#define EXYNOS5_CLKDIV_CORE0 EXYNOS_CLKREG(0x04500)
+#define EXYNOS5_CLKDIV_CORE1 EXYNOS_CLKREG(0x04504)
+#define EXYNOS5_CLKDIV_SYSRGT EXYNOS_CLKREG(0x04508)
+#define EXYNOS5_CLKDIV_ACP EXYNOS_CLKREG(0x08500)
+#define EXYNOS5_CLKDIV_SYSLFT EXYNOS_CLKREG(0x08900)
+#define EXYNOS5_CLKDIV_ISP0 EXYNOS_CLKREG(0x0C300)
+#define EXYNOS5_CLKDIV_ISP1 EXYNOS_CLKREG(0x0C304)
+#define EXYNOS5_CLKDIV_ISP2 EXYNOS_CLKREG(0x0C308)
+#define EXYNOS5_CLKDIV_TOP0 EXYNOS_CLKREG(0x10510)
+#define EXYNOS5_CLKDIV_TOP1 EXYNOS_CLKREG(0x10514)
+#define EXYNOS5_CLKDIV_GSCL EXYNOS_CLKREG(0x10520)
+#define EXYNOS5_CLKDIV_DISP1_0 EXYNOS_CLKREG(0x1052C)
+#define EXYNOS5_CLKDIV_GEN EXYNOS_CLKREG(0x1053C)
+#define EXYNOS5_CLKDIV_MAUDIO EXYNOS_CLKREG(0x10544)
+#define EXYNOS5_CLKDIV_FSYS0 EXYNOS_CLKREG(0x10548)
+#define EXYNOS5_CLKDIV_FSYS1 EXYNOS_CLKREG(0x1054C)
+#define EXYNOS5_CLKDIV_FSYS2 EXYNOS_CLKREG(0x10550)
+#define EXYNOS5_CLKDIV_FSYS3 EXYNOS_CLKREG(0x10554)
+#define EXYNOS5_CLKDIV_PERIC0 EXYNOS_CLKREG(0x10558)
+#define EXYNOS5_CLKDIV_PERIC1 EXYNOS_CLKREG(0x1055C)
+#define EXYNOS5_CLKDIV_PERIC2 EXYNOS_CLKREG(0x10560)
+#define EXYNOS5_CLKDIV_PERIC3 EXYNOS_CLKREG(0x10564)
+#define EXYNOS5_CLKDIV_PERIC4 EXYNOS_CLKREG(0x10568)
+#define EXYNOS5_CLKDIV_PERIC5 EXYNOS_CLKREG(0x1056C)
+#define EXYNOS5_SCLK_DIV_ISP EXYNOS_CLKREG(0x10580)
+#define EXYNOS5_CLKDIV_ISP0 EXYNOS_CLKREG(0x0C300)
+#define EXYNOS5_CLKDIV_ISP1 EXYNOS_CLKREG(0x0C304)
+#define EXYNOS5_CLKDIV_ISP2 EXYNOS_CLKREG(0x0C308)
+#define EXYNOS5_CLKDIV2_RATIO0 EXYNOS_CLKREG(0x10590)
+#define EXYNOS5_CLKDIV2_RATIO1 EXYNOS_CLKREG(0x10594)
+#define EXYNOS5_CLKDIV4_RATIO EXYNOS_CLKREG(0x105A0)
+#define EXYNOS5_CLKDIV_LEX EXYNOS_CLKREG(0x14500)
+#define EXYNOS5_CLKDIV_R0X EXYNOS_CLKREG(0x18500)
+#define EXYNOS5_CLKDIV_R1X EXYNOS_CLKREG(0x1C500)
+#define EXYNOS5_CLKDIV_CDREX EXYNOS_CLKREG(0x20500)
+#define EXYNOS5_CLKDIV_CDREX2 EXYNOS_CLKREG(0x20504)
+
+#define EXYNOS5_CLKDIV_STAT_CPU0 EXYNOS_CLKREG(0x00600)
+#define EXYNOS5_CLKDIV_STAT_CPU1 EXYNOS_CLKREG(0x00604)
+#define EXYNOS5_CLKDIV_STAT_CORE0 EXYNOS_CLKREG(0x04600)
+#define EXYNOS5_CLKDIV_STAT_CORE1 EXYNOS_CLKREG(0x04604)
+#define EXYNOS5_CLKDIV_STAT_SYSRGT EXYNOS_CLKREG(0x04608)
+#define EXYNOS5_CLKDIV_STAT_ACP EXYNOS_CLKREG(0x08600)
+#define EXYNOS5_CLKDIV_STAT_SYSLFT EXYNOS_CLKREG(0x08910)
+#define EXYNOS5_CLKDIV_STAT_ISP0 EXYNOS_CLKREG(0x0C400)
+#define EXYNOS5_CLKDIV_STAT_ISP1 EXYNOS_CLKREG(0x0C404)
+#define EXYNOS5_CLKDIV_STAT_ISP2 EXYNOS_CLKREG(0x0C408)
+#define EXYNOS5_CLKDIV_STAT_TOP0 EXYNOS_CLKREG(0x10610)
+#define EXYNOS5_CLKDIV_STAT_TOP1 EXYNOS_CLKREG(0x10614)
+#define EXYNOS5_CLKDIV_STAT_GSCL EXYNOS_CLKREG(0x10620)
+#define EXYNOS5_CLKDIV_STAT_DISP1_0 EXYNOS_CLKREG(0x1062C)
+#define EXYNOS5_CLKDIV_STAT_GEN EXYNOS_CLKREG(0x1063C)
+#define EXYNOS5_CLKDIV_STAT_MAUDIO EXYNOS_CLKREG(0x10644)
+#define EXYNOS5_CLKDIV_STAT_FSYS0 EXYNOS_CLKREG(0x10648)
+#define EXYNOS5_CLKDIV_STAT_FSYS1 EXYNOS_CLKREG(0x1064C)
+#define EXYNOS5_CLKDIV_STAT_FSYS2 EXYNOS_CLKREG(0x10650)
+#define EXYNOS5_CLKDIV_STAT_PERIC0 EXYNOS_CLKREG(0x10658)
+#define EXYNOS5_CLKDIV_STAT_PERIC1 EXYNOS_CLKREG(0x1065C)
+#define EXYNOS5_CLKDIV_STAT_PERIC2 EXYNOS_CLKREG(0x10660)
+#define EXYNOS5_CLKDIV_STAT_PERIC3 EXYNOS_CLKREG(0x10664)
+#define EXYNOS5_CLKDIV_STAT_PERIC4 EXYNOS_CLKREG(0x10668)
+#define EXYNOS5_CLKDIV_STAT_PERIC5 EXYNOS_CLKREG(0x1066C)
+#define EXYNOS5_SCLK_DIV_STAT_ISP EXYNOS_CLKREG(0x10680)
+#define EXYNOS5_CLKDIV_STAT_LEX EXYNOS_CLKREG(0x14600)
+#define EXYNOS5_CLKDIV_STAT_R0X EXYNOS_CLKREG(0x18600)
+#define EXYNOS5_CLKDIV_STAT_R1X EXYNOS_CLKREG(0x1C600)
+#define EXYNOS5_CLKDIV_STAT_CDREX EXYNOS_CLKREG(0x20600)
+#define EXYNOS5_CLKDIV_STAT_CDREX2 EXYNOS_CLKREG(0x20604)
+
+/* Clock Gate Control Registers */
+#define EXYNOS5_CLKGATE_IP_CORE EXYNOS_CLKREG(0x04900)
+#define EXYNOS5_CLKGATE_IP_SYSRGT EXYNOS_CLKREG(0x04904)
+#define EXYNOS5_CLKGATE_IP_ACP EXYNOS_CLKREG(0x08800)
+#define EXYNOS5_CLKGATE_IP_SYSLFT EXYNOS_CLKREG(0x08930)
+#define EXYNOS5_CLKGATE_ISP0 EXYNOS_CLKREG(0x0C800)
+#define EXYNOS5_CLKGATE_ISP1 EXYNOS_CLKREG(0x0C804)
+#define EXYNOS5_CLKGATE_SCLK_ISP EXYNOS_CLKREG(0x0C900)
+#define EXYNOS5_CLKGATE_TOP_SCLK_DISP1 EXYNOS_CLKREG(0x10828)
+#define EXYNOS5_CLKGATE_TOP_SCLK_GEN EXYNOS_CLKREG(0x1082C)
+#define EXYNOS5_CLKGATE_TOP_SCLK_MAUDIO EXYNOS_CLKREG(0x1083C)
+#define EXYNOS5_CLKGATE_TOP_SCLK_FSYS EXYNOS_CLKREG(0x10840)
+#define EXYNOS5_CLKGATE_TOP_SCLK_PERIC EXYNOS_CLKREG(0x10850)
+#define EXYNOS5_CLKGATE_TOP_SCLK_ISP EXYNOS_CLKREG(0x10870)
+#define EXYNOS5_CLKGATE_IP_GSCL EXYNOS_CLKREG(0x10920)
+#define EXYNOS5_CLKGATE_IP_DISP1 EXYNOS_CLKREG(0x10928)
+#define EXYNOS5_CLKGATE_IP_MFC EXYNOS_CLKREG(0x1092C)
+#define EXYNOS5_CLKGATE_IP_G3D EXYNOS_CLKREG(0x10930)
+#define EXYNOS5_CLKGATE_IP_GEN EXYNOS_CLKREG(0x10934)
+#define EXYNOS5_CLKGATE_IP_FSYS EXYNOS_CLKREG(0x10944)
+#define EXYNOS5_CLKGATE_IP_GPS EXYNOS_CLKREG(0x1094C)
+#define EXYNOS5_CLKGATE_IP_PERIC EXYNOS_CLKREG(0x10950)
+#define EXYNOS5_CLKGATE_IP_PERIS EXYNOS_CLKREG(0x10960)
+#define EXYNOS5_CLKGATE_BLOCK EXYNOS_CLKREG(0x10980)
+#define EXYNOS5_CLKGATE_ISP0 EXYNOS_CLKREG(0x0C800)
+#define EXYNOS5_CLKGATE_ISP1 EXYNOS_CLKREG(0x0C804)
+
+#define EXYNOS5_CLKOUT_CMU_CPU EXYNOS_CLKREG(0x00A00)
+#define EXYNOS5_CLKOUT_CMU_CORE EXYNOS_CLKREG(0x04A00)
+#define EXYNOS5_CLKOUT_CMU_ACP EXYNOS_CLKREG(0x08A00)
+#define EXYNOS5_CLKOUT_CMU_ISP EXYNOS_CLKREG(0x0CA00)
+#define EXYNOS5_CLKOUT_CMU_TOP EXYNOS_CLKREG(0x10A00)
+#define EXYNOS5_CLKOUT_CMU_LEX EXYNOS_CLKREG(0x14A00)
+#define EXYNOS5_CLKOUT_CMU_R0X EXYNOS_CLKREG(0x18A00)
+#define EXYNOS5_CLKOUT_CMU_R1X EXYNOS_CLKREG(0x1CA00)
+#define EXYNOS5_CLKOUT_CMU_CDREX EXYNOS_CLKREG(0x20A00)
+#define EXYNOS5_CLKGATE_IP_LEX EXYNOS_CLKREG(0x14800)
+#define EXYNOS5_CLKGATE_IP_R0X EXYNOS_CLKREG(0x18800)
+#define EXYNOS5_CLKGATE_IP_R1X EXYNOS_CLKREG(0x1C800)
+#define EXYNOS5_CLKGATE_IP_CDREX EXYNOS_CLKREG(0x20900)
+
+#define EXYNOS5_MCUIOP_PWR_CTRL EXYNOS_CLKREG(0x109A0)
+
+#define EXYNOS5_CLKOUT_CMU_ACP EXYNOS_CLKREG(0x08A00)
+#define EXYNOS5_CLKOUT_CMU_ISP EXYNOS_CLKREG(0x0CA00)
+#define EXYNOS5_CLKOUT_CMU_TOP EXYNOS_CLKREG(0x10A00)
+#define EXYNOS5_CLKOUT_CMU_LEX EXYNOS_CLKREG(0x14A00)
+#define EXYNOS5_CLKOUT_CMU_R0X EXYNOS_CLKREG(0x18A00)
+#define EXYNOS5_CLKOUT_CMU_R1X EXYNOS_CLKREG(0x1CA00)
+#define EXYNOS5_CLKOUT_CMU_CDREX EXYNOS_CLKREG(0x20A00)
+
+#define EXYNOS5_CLKGATE_IP_CPU EXYNOS_CLKREG(0x20900)
+#define EXYNOS5_DMC_FREQ_CTRL EXYNOS_CLKREG(0x20914)
+#define EXYNOS5_DREX2_PAUSE EXYNOS_CLKREG(0x2091C)
+
+#define EXYNOS5_LPDDR3PHY_CTRL EXYNOS_CLKREG(0x20A10)
+#define EXYNOS5_LPDDR3PHY_CON0 EXYNOS_CLKREG(0x20A14)
+#define EXYNOS5_LPDDR3PHY_CON1 EXYNOS_CLKREG(0x20A18)
+#define EXYNOS5_LPDDR3PHY_CON2 EXYNOS_CLKREG(0x20A1C)
+#define EXYNOS5_LPDDR3PHY_CON3 EXYNOS_CLKREG(0x20A20)
+#define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24)
+
+
+
+#define EXYNOS5_EPLLCON0_ENABLE_SHIFT (31)
+#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29)
+#define EXYNOS5_VPLLCON0_LOCKED_SHIFT (29)
+
+#define EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_SHIFT (28)
+#define EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK300_DISP1_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK400_SHIFT (24)
+#define EXYNOS5_CLKDIV_TOP0_ACLK400_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK400_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK333_SHIFT (20)
+#define EXYNOS5_CLKDIV_TOP0_ACLK333_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK333_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK266_SHIFT (16)
+#define EXYNOS5_CLKDIV_TOP0_ACLK266_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK266_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK200_SHIFT (12)
+#define EXYNOS5_CLKDIV_TOP0_ACLK200_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK200_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK166_SHIFT (8)
+#define EXYNOS5_CLKDIV_TOP0_ACLK166_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK166_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK133_SHIFT (4)
+#define EXYNOS5_CLKDIV_TOP0_ACLK133_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK133_SHIFT)
+#define EXYNOS5_CLKDIV_TOP0_ACLK66_SHIFT (0)
+#define EXYNOS5_CLKDIV_TOP0_ACLK66_MASK (0x7 << EXYNOS5_CLKDIV_TOP0_ACLK66_SHIFT)
+
+#define EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_SHIFT (24)
+#define EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_MASK (0x7 << EXYNOS5_CLKDIV_TOP1_ACLK66_PRE_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_SHIFT (20)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_MASK (0x7 << EXYNOS5_CLKDIV_TOP1_ACLK400_ISP_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_SHIFT (16)
+#define EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_MASK (0x7 << EXYNOS5_CLKDIV_TOP1_ACLK400_IOP_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_SHIFT (12)
+#define EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_MASK (0x7 << EXYNOS5_CLKDIV_TOP1_ACLK300_GSCL_SHIFT)
+#define EXYNOS5_CLKDIV_TOP1_ACLK266_GPS_SHIFT (8)
+#define EXYNOS5_CLKDIV_TOP1_ACLK266_GPS_MASK (0x7 << EXYNOS5_CLKDIV_TOP1_ACLK266_GPS_SHIFT)
+
+#define EXYNOS5_CLKDIV_LEX_ATCLK_LEX_SHIFT (8)
+#define EXYNOS5_CLKDIV_LEX_ATCLK_LEX_MASK (0x7 << EXYNOS5_CLKDIV_LEX_ATCLK_LEX_SHIFT)
+#define EXYNOS5_CLKDIV_LEX_PCLK_LEX_SHIFT (4)
+#define EXYNOS5_CLKDIV_LEX_PCLK_LEX_MASK (0x7 << EXYNOS5_CLKDIV_LEX_PCLK_LEX_SHIFT)
+
+#define EXYNOS5_CLKDIV_R0X_PCLK_R0X_SHIFT (4)
+#define EXYNOS5_CLKDIV_R0X_PCLK_R0X_MASK (0x7 << EXYNOS5_CLKDIV_R0X_PCLK_R0X_SHIFT)
+
+#define EXYNOS5_CLKDIV_R1X_PCLK_R1X_SHIFT (4)
+#define EXYNOS5_CLKDIV_R1X_PCLK_R1X_MASK (0x7 << EXYNOS5_CLKDIV_R1X_PCLK_R1X_SHIFT)
+
+#define EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_SHIFT (28)
+#define EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_MCLK_CDREX2_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_SHIFT (24)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_ACLK_EFCON_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_SHIFT (20)
+#define EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_MCLK_DPHY_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_SHIFT (16)
+#define EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_MCLK_CDREX_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_C2C200_SHIFT (12)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_C2C200_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_ACLK_C2C200_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_CLK400_SHIFT (8)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_CLK400_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_ACLK_CLK400_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_SHIFT (4)
+#define EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_PCLK_CDREX_SHIFT)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_SHIFT (0)
+#define EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_MASK (0x7 << EXYNOS5_CLKDIV_CDREX_ACLK_CDREX_SHIFT)
+
+#define EXYNOS5_CLKDIV_CDREX2_MCLK_EFPHY_SHIFT (0)
+#define EXYNOS5_CLKDIV_CDREX2_MCLK_EFPHY_MASK (0xf << EXYNOS5_CLKDIV_CDREX2_MCLK_EFPHY_SHIFT)
+
+#define EXYNOS5_VPLLCON0_LOCKED_SHIFT (29)
+#define EXYNOS5_GPLLCON0_LOCKED_SHIFT (29)
+
+/* Compatibility defines and inclusion */
+
+#include <mach/regs-pmu.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#define S5P_EPLL_CON EXYNOS4_EPLL_CON0
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#define S5P_EPLL_CON EXYNOS5_EPLL_CON0
+#else
+#error "ARCH_EXYNOS* is not defined"
+#endif
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-fimg2d3x.h b/arch/arm/mach-exynos/include/mach/regs-fimg2d3x.h
new file mode 100644
index 0000000..5c62252
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-fimg2d3x.h
@@ -0,0 +1,162 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-fimg2d3x.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register Definitions for Samsung Graphics 2D Hardware
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_FIMG2D3X_H
+#define __ASM_ARCH_REGS_FIMG2D3X_H __FILE__
+
+/* Macros */
+#define FIMG2D_ADDR(v) ((v) << 0)
+#define FIMG2D_STRIDE(v) (((v) & (0xffff)) << 0)
+#define FIMG2D_OFFSET(x, y) ((((y) & 0x1fff) << 16) | (((x) & 0x1fff) << 0))
+#define FIMG2D_SIZE(w, h) ((((h) & 0x1fff) << 16) | (((w) & 0x1fff) << 0))
+#define FIMG2D_COLOR(v) ((v) << 0)
+
+/* Registers */
+#define FIMG2D_SOFT_RESET_REG (0x000)
+#define FIMG2D_INTEN_REG (0x004)
+#define FIMG2D_INTC_PEND_REG (0x00c)
+#define FIMG2D_FIFO_STAT_REG (0x010)
+#define FIMG2D_AXI_ID_MODE_REG (0x014)
+#define FIMG2D_CACHECTL_REG (0x018)
+#define FIMG2D_BITBLT_START_REG (0x100)
+#define FIMG2D_BITBLT_COMMAND_REG (0x104)
+#define FIMG2D_ROTATE_REG (0x200)
+#define FIMG2D_SRC_MSK_DIRECT_REG (0x204)
+#define FIMG2D_DST_PAT_DIRECT_REG (0x208)
+#define FIMG2D_SRC_SELECT_REG (0x300)
+#define FIMG2D_SRC_BASE_ADDR_REG (0x304)
+#define FIMG2D_SRC_STRIDE_REG (0x308)
+#define FIMG2D_SRC_COLOR_MODE_REG (0x30c)
+#define FIMG2D_SRC_LEFT_TOP_REG (0x310)
+#define FIMG2D_SRC_RIGHT_BOTTOM_REG (0x314)
+#define FIMG2D_DST_SELECT_REG (0x400)
+#define FIMG2D_DST_BASE_ADDR_REG (0x404)
+#define FIMG2D_DST_STRIDE_REG (0x408)
+#define FIMG2D_DST_COLOR_MODE_REG (0x40c)
+#define FIMG2D_DST_LEFT_TOP_REG (0x410)
+#define FIMG2D_DST_RIGHT_BOTTOM_REG (0x414)
+#define FIMG2D_PAT_BASE_ADDR_REG (0x500)
+#define FIMG2D_PAT_SIZE_REG (0x504)
+#define FIMG2D_PAT_COLOR_MODE_REG (0x508)
+#define FIMG2D_PAT_OFFSET_REG (0x50c)
+#define FIMG2D_PAT_STRIDE_REG (0x510)
+#define FIMG2D_CW_LT_REG (0x600)
+#define FIMG2D_CW_RB_REG (0x604)
+#define FIMG2D_THIRD_OPERAND_REG (0x610)
+#define FIMG2D_ROP4_REG (0x614)
+#define FIMG2D_ALPHA_REG (0x618)
+#define FIMG2D_FG_COLOR_REG (0x700)
+#define FIMG2D_BG_COLOR_REG (0x704)
+#define FIMG2D_BS_COLOR_REG (0x708)
+#define FIMG2D_SRC_COLORKEY_CTRL_REG (0x710)
+#define FIMG2D_SRC_COLORKEY_DR_MIN_REG (0x714)
+#define FIMG2D_SRC_COLORKEY_DR_MAX_REG (0x718)
+#define FIMG2D_DST_COLORKEY_CTRL_REG (0x71c)
+#define FIMG2D_DST_COLORKEY_DR_MIN_REG (0x720)
+#define FIMG2D_DST_COLORKEY_DR_MAX_REG (0x724)
+
+/* Bit Definitions */
+
+/* SOFT_RESET_REG */
+#define FIMG2D_SOFT_RESET (1 << 0)
+
+/* INTEN_REG */
+#define FIMG2D_INT_EN (1 << 0)
+
+/* INTC_PEND_REG */
+#define FIMG2D_INTP_CMD_FIN (1 << 0)
+
+/* FIFO_STAT_REG */
+#define FIMG2D_CMD_FIN (1 << 0)
+
+/* CACHECTL_REG */
+#define FIMG2D_PATCACHE_CLEAR (1 << 2)
+#define FIMG2D_SRCBUFFER_CLEAR (1 << 1)
+#define FIMG2D_MASKBUFFER_CLEAR (1 << 0)
+
+/* BITBLT_START_REG */
+#define FIMG2D_START_BITBLT (1 << 0)
+
+/* BITBLT_COMMAND_REG */
+#define FIMG2D_NONPREBLEND_DISABLE (0 << 22)
+#define FIMG2D_NONPREBLEND_CONSTANT (1 << 22)
+#define FIMG2D_NONPREBLEND_PERPIXEL (2 << 22)
+#define FIMG2D_NONPREBLEND_MASK (3 << 22)
+
+#define FIMG2D_ALPHA_MODE_NONE (0 << 20)
+#define FIMG2D_ALPHA_MODE_ALPHA (1 << 20)
+#define FIMG2D_ALPHA_MODE_FADING (2 << 20)
+#define FIMG2D_ALPHA_MODE_MASK (3 << 20)
+
+#define FIMG2D_ENABLE_CW (1 << 8)
+#define FIMG2D_ENABLE_STRETCH (1 << 4)
+#define FIMG2D_ENABLE_MASK (1 << 0)
+
+/* ROTATE_REG */
+#define FIMG2D_ROTATE_90_ENABLE (1 << 0)
+
+/* SRC_MSK_DIRECT_REG */
+#define FIMG2D_MSK_X_DIR_NEGATIVE (1 << 4)
+#define FIMG2D_MSK_Y_DIR_NEGATIVE (1 << 5)
+#define FIMG2D_MSK_DIR_MASK (3 << 4)
+
+#define FIMG2D_SRC_X_DIR_NEGATIVE (1 << 0)
+#define FIMG2D_SRC_Y_DIR_NEGATIVE (1 << 1)
+#define FIMG2D_SRC_DIR_MASK (3 << 0)
+
+/* DST_PAT_DIRECT_REG */
+#define FIMG2D_PAT_X_DIR_NEGATIVE (1 << 4)
+#define FIMG2D_PAT_Y_DIR_NEGATIVE (1 << 5)
+#define FIMG2D_PAT_DIR_MASK (3 << 4)
+
+#define FIMG2D_DST_X_DIR_NEGATIVE (1 << 0)
+#define FIMG2D_DST_Y_DIR_NEGATIVE (1 << 1)
+#define FIMG2D_DST_DIR_MASK (3 << 0)
+
+/* XXX_SELECT_REG */
+#define FIMG2D_IMG_TYPE_MEMORY (0 << 0)
+#define FIMG2D_IMG_TYPE_FGCOLOR (1 << 0)
+#define FIMG2D_IMG_TYPE_BGCOLOR (2 << 0)
+#define FIMG2D_IMG_TYPE_MASK (3 << 0)
+
+/* XXX_COLOR_MODE_REG */
+#define FIMG2D_CHANNEL_ORDER_SHIFT (4)
+#define FIMG2D_COLOR_FORMAT_SHIFT (0)
+
+/* XXX_LEFT_TOP_REG & XXX_RIGHT_BOTTOM_REG */
+#define FIMG2D_COORD_TOP_Y_SHIFT (16)
+#define FIMG2D_COORD_LEFT_X_SHIFT (0)
+#define FIMG2D_COORD_BOTTOM_Y_SHIFT (16)
+#define FIMG2D_COORD_RIGHT_X_SHIFT (0)
+
+/* THIRD_OPERAND_REG */
+#define FIMG2D_MASKED_OPR3_PATTERN (0 << 4)
+#define FIMG2D_MASKED_OPR3_FGCOLOR (1 << 4)
+#define FIMG2D_MASKED_OPR3_BGCOLOR (2 << 4)
+#define FIMG2D_MASKED_OPR3_MASK (3 << 4)
+
+#define FIMG2D_UNMASKED_OPR3_PATTERN (0 << 0)
+#define FIMG2D_UNMASKED_OPR3_FGCOLOR (1 << 0)
+#define FIMG2D_UNMASKED_OPR3_BGCOLOR (2 << 0)
+#define FIMG2D_UNMASKED_OPR3_MASK (3 << 0)
+
+/* ROP4_REG */
+#define FIMG2D_MASKED_ROP3_SHIFT (8)
+#define FIMG2D_UNMASKED_ROP3_SHIFT (0)
+
+/* ALPHA_REG */
+#define FIMG2D_FADING_OFFSET_SHIFT (8)
+#define FIMG2D_FADING_OFFSET_MASK (0xff)
+#define FIMG2D_ALPHA_VALUE_SHIFT (0)
+#define FIMG2D_ALPHA_VALUE_MASK (0xff)
+
+#endif /* __ASM_MACH_REGS_FIMG2D3X_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-gpio.h b/arch/arm/mach-exynos/include/mach/regs-gpio.h
new file mode 100644
index 0000000..b03f2d3
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-gpio.h
@@ -0,0 +1,53 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - GPIO (including EINT) register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#define EINT_BASE_ADD S5P_VA_GPIO2
+#define EINT_GPIO_0(x) EXYNOS4_GPX0(x)
+#define EINT_GPIO_1(x) EXYNOS4_GPX1(x)
+#define EINT_GPIO_2(x) EXYNOS4_GPX2(x)
+#define EINT_GPIO_3(x) EXYNOS4_GPX3(x)
+
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#define EINT_BASE_ADD S5P_VA_GPIO1
+#define EINT_GPIO_0(x) EXYNOS5_GPX0(x)
+#define EINT_GPIO_1(x) EXYNOS5_GPX1(x)
+#define EINT_GPIO_2(x) EXYNOS5_GPX2(x)
+#define EINT_GPIO_3(x) EXYNOS5_GPX3(x)
+#else
+#error "ARCH_EXYNOS* is not defined"
+#endif
+
+#define EXYNOS_EINT40CON (EINT_BASE_ADD + 0xE00)
+#define S5P_EINT_CON(x) (EXYNOS_EINT40CON + ((x) * 0x4))
+
+#define EXYNOS_EINT40FLTCON0 (EINT_BASE_ADD + 0xE80)
+#define S5P_EINT_FLTCON(x) (EXYNOS_EINT40FLTCON0 + ((x) * 0x4))
+
+#define EXYNOS_EINT40MASK (EINT_BASE_ADD + 0xF00)
+#define S5P_EINT_MASK(x) (EXYNOS_EINT40MASK + ((x) * 0x4))
+
+#define EXYNOS_EINT40PEND (EINT_BASE_ADD + 0xF40)
+#define S5P_EINT_PEND(x) (EXYNOS_EINT40PEND + ((x) * 0x4))
+
+#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
+
+#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
+
+#define EINT_MODE S3C_GPIO_SFN(0xf)
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-hdmi.h b/arch/arm/mach-exynos/include/mach/regs-hdmi.h
new file mode 100644
index 0000000..6a9df06
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-hdmi.h
@@ -0,0 +1,1787 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-hdmi.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * HDMI register header file for Samsung TVOUT driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ARCH_ARM_REGS_HDMI_H
+#define __ARCH_ARM_REGS_HDMI_H
+
+/*
+ * Register part
+*/
+
+#ifdef CONFIG_HDMI_14A_3D
+
+#define S5P_HDMI_I2C_PHY_BASE(x) (x)
+
+#define HDMI_I2C_CON S5P_HDMI_I2C_PHY_BASE(0x0000)
+#define HDMI_I2C_STAT S5P_HDMI_I2C_PHY_BASE(0x0004)
+#define HDMI_I2C_ADD S5P_HDMI_I2C_PHY_BASE(0x0008)
+#define HDMI_I2C_DS S5P_HDMI_I2C_PHY_BASE(0x000c)
+#define HDMI_I2C_LC S5P_HDMI_I2C_PHY_BASE(0x0010)
+
+#define S5P_HDMI_CTRL_BASE(x) (x)
+#define S5P_HDMI_BASE(x) ((x) + 0x00010000)
+#define S5P_HDMI_SPDIF_BASE(x) ((x) + 0x00030000)
+#define S5P_HDMI_I2S_BASE(x) ((x) + 0x00040000)
+#define S5P_HDMI_TG_BASE(x) ((x) + 0x00050000)
+#define S5P_HDMI_EFUSE_BASE(x) ((x) + 0x00060000)
+
+/* HDMIControlRegister */
+#define S5P_HDMI_INTC_CON0 S5P_HDMI_CTRL_BASE(0x000)
+#define S5P_HDMI_INTC_FLAG0 S5P_HDMI_CTRL_BASE(0x004)
+#define S5P_HDMI_AES_KEY_LOAD S5P_HDMI_CTRL_BASE(0x008)
+#define S5P_HDMI_HPD_STATUS S5P_HDMI_CTRL_BASE(0x00C)
+
+#define S5P_HDMI_INTC_CON1 S5P_HDMI_CTRL_BASE(0x010)
+#define S5P_HDMI_INTC_FLAG1 S5P_HDMI_CTRL_BASE(0x014)
+#define S5P_HDMI_PHY_STATUS0 S5P_HDMI_CTRL_BASE(0x020)
+#define S5P_HDMI_PHY_STATUS_PLL S5P_HDMI_CTRL_BASE(0x028)
+#define S5P_HDMI_PHY_CON_0 S5P_HDMI_CTRL_BASE(0x030)
+
+#define S5P_HDMI_HPD_CTRL S5P_HDMI_CTRL_BASE(0x040)
+#define S5P_HDMI_HPD_th_0 S5P_HDMI_CTRL_BASE(0x050)
+#define S5P_HDMI_HPD_th_1 S5P_HDMI_CTRL_BASE(0x054)
+#define S5P_HDMI_HPD_th_2 S5P_HDMI_CTRL_BASE(0x058)
+#define S5P_HDMI_HPD_th_3 S5P_HDMI_CTRL_BASE(0x05C)
+
+#define S5P_HDMI_AUDIO_CLKSEL S5P_HDMI_CTRL_BASE(0x070)
+#define S5P_HDMI_PHY_RSTOUT S5P_HDMI_CTRL_BASE(0x074)
+#define S5P_HDMI_PHY_VPLL S5P_HDMI_CTRL_BASE(0x078)
+#define S5P_HDMI_PHY_CMU S5P_HDMI_CTRL_BASE(0x07C)
+#define S5P_HDMI_CORE_RSTOUT S5P_HDMI_CTRL_BASE(0x080)
+
+/* HDMICoreRegister */
+#define S5P_HDMI_CON_0 S5P_HDMI_BASE(0x000)
+#define S5P_HDMI_CON_1 S5P_HDMI_BASE(0x004)
+#define S5P_HDMI_CON_2 S5P_HDMI_BASE(0x008)
+#define S5P_HDMI_SIM_MODE S5P_HDMI_BASE(0x00C)
+#define S5P_HDMI_SYS_STATUS S5P_HDMI_BASE(0x010)
+#define S5P_HDMI_PHY_STATUS S5P_HDMI_BASE(0x014)
+#define S5P_HDMI_STATUS_EN S5P_HDMI_BASE(0x020)
+#define S5P_HDMI_HPD S5P_HDMI_BASE(0x030)
+#define S5P_HDMI_MODE_SEL S5P_HDMI_BASE(0x040)
+#define S5P_HDMI_ENC_EN S5P_HDMI_BASE(0x044)
+
+#define S5P_HDMI_YMAX S5P_HDMI_BASE(0x060)
+#define S5P_HDMI_YMIN S5P_HDMI_BASE(0x064)
+#define S5P_HDMI_CMAX S5P_HDMI_BASE(0x068)
+#define S5P_HDMI_CMIN S5P_HDMI_BASE(0x06c)
+
+#define S5P_HDMI_DI_PREFIX S5P_HDMI_BASE(0x078)
+#define S5P_HDMI_VBI_ST_MG S5P_HDMI_BASE(0x080)
+#define S5P_HDMI_END_MG S5P_HDMI_BASE(0x084)
+
+#define S5P_HDMI_AUTH_ST_MG0 S5P_HDMI_BASE(0x090)
+#define S5P_HDMI_AUTH_ST_MG1 S5P_HDMI_BASE(0x094)
+#define S5P_HDMI_AUTH_END_MG0 S5P_HDMI_BASE(0x098)
+#define S5P_HDMI_AUTH_END_MG1 S5P_HDMI_BASE(0x09C)
+
+#define S5P_HDMI_H_BLANK_0 S5P_HDMI_BASE(0x0a0)
+#define S5P_HDMI_H_BLANK_1 S5P_HDMI_BASE(0x0a4)
+
+#define S5P_HDMI_V2_BLANK_0 S5P_HDMI_BASE(0x0b0)
+#define S5P_HDMI_V2_BLANK_1 S5P_HDMI_BASE(0x0b4)
+#define S5P_HDMI_V1_BLANK_0 S5P_HDMI_BASE(0x0b8)
+#define S5P_HDMI_V1_BLANK_1 S5P_HDMI_BASE(0x0bC)
+
+#define S5P_HDMI_V_LINE_0 S5P_HDMI_BASE(0x0c0)
+#define S5P_HDMI_V_LINE_1 S5P_HDMI_BASE(0x0c4)
+#define S5P_HDMI_H_LINE_0 S5P_HDMI_BASE(0x0c8)
+#define S5P_HDMI_H_LINE_1 S5P_HDMI_BASE(0x0cC)
+#define S5P_HDMI_HSYNC_POL S5P_HDMI_BASE(0x0E0)
+
+#define S5P_HDMI_VSYNC_POL S5P_HDMI_BASE(0x0e4)
+#define S5P_HDMI_INT_PRO_MODE S5P_HDMI_BASE(0x0e8)
+
+#define S5P_HDMI_V_BLANK_F0_0 S5P_HDMI_BASE(0x110)
+#define S5P_HDMI_V_BLANK_F0_1 S5P_HDMI_BASE(0x114)
+#define S5P_HDMI_V_BLANK_F1_0 S5P_HDMI_BASE(0x118)
+#define S5P_HDMI_V_BLANK_F1_1 S5P_HDMI_BASE(0x11C)
+
+#define S5P_HDMI_H_SYNC_START_0 S5P_HDMI_BASE(0x120)
+#define S5P_HDMI_H_SYNC_START_1 S5P_HDMI_BASE(0x124)
+#define S5P_HDMI_H_SYNC_END_0 S5P_HDMI_BASE(0x128)
+#define S5P_HDMI_H_SYNC_END_1 S5P_HDMI_BASE(0x12C)
+
+#define S5P_HDMI_V_SYNC_LINE_BEF_2_0 S5P_HDMI_BASE(0x130)
+#define S5P_HDMI_V_SYNC_LINE_BEF_2_1 S5P_HDMI_BASE(0x134)
+#define S5P_HDMI_V_SYNC_LINE_BEF_1_0 S5P_HDMI_BASE(0x138)
+#define S5P_HDMI_V_SYNC_LINE_BEF_1_1 S5P_HDMI_BASE(0x13C)
+
+#define S5P_HDMI_V_SYNC_LINE_AFT_2_0 S5P_HDMI_BASE(0x140)
+#define S5P_HDMI_V_SYNC_LINE_AFT_2_1 S5P_HDMI_BASE(0x144)
+#define S5P_HDMI_V_SYNC_LINE_AFT_1_0 S5P_HDMI_BASE(0x148)
+#define S5P_HDMI_V_SYNC_LINE_AFT_1_1 S5P_HDMI_BASE(0x14C)
+
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_2_0 S5P_HDMI_BASE(0x150)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_2_1 S5P_HDMI_BASE(0x154)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_1_0 S5P_HDMI_BASE(0x158)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_1_1 S5P_HDMI_BASE(0x15C)
+
+#define S5P_HDMI_V_BLANK_F2_0 S5P_HDMI_BASE(0x160)
+#define S5P_HDMI_V_BLANK_F2_1 S5P_HDMI_BASE(0x164)
+#define S5P_HDMI_V_BLANK_F3_0 S5P_HDMI_BASE(0x168)
+#define S5P_HDMI_V_BLANK_F3_1 S5P_HDMI_BASE(0x16C)
+#define S5P_HDMI_V_BLANK_F4_0 S5P_HDMI_BASE(0x170)
+#define S5P_HDMI_V_BLANK_F4_1 S5P_HDMI_BASE(0x174)
+#define S5P_HDMI_V_BLANK_F5_0 S5P_HDMI_BASE(0x178)
+#define S5P_HDMI_V_BLANK_F5_1 S5P_HDMI_BASE(0x17C)
+
+#define S5P_HDMI_V_SYNC_LINE_AFT_3_0 S5P_HDMI_BASE(0x180)
+#define S5P_HDMI_V_SYNC_LINE_AFT_3_1 S5P_HDMI_BASE(0x184)
+#define S5P_HDMI_V_SYNC_LINE_AFT_4_0 S5P_HDMI_BASE(0x188)
+#define S5P_HDMI_V_SYNC_LINE_AFT_4_1 S5P_HDMI_BASE(0x18C)
+#define S5P_HDMI_V_SYNC_LINE_AFT_5_0 S5P_HDMI_BASE(0x190)
+#define S5P_HDMI_V_SYNC_LINE_AFT_5_1 S5P_HDMI_BASE(0x194)
+#define S5P_HDMI_V_SYNC_LINE_AFT_6_0 S5P_HDMI_BASE(0x198)
+#define S5P_HDMI_V_SYNC_LINE_AFT_6_1 S5P_HDMI_BASE(0x19C)
+
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_3_0 S5P_HDMI_BASE(0x1A0)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_3_1 S5P_HDMI_BASE(0x1A4)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_4_0 S5P_HDMI_BASE(0x1A8)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_4_1 S5P_HDMI_BASE(0x1AC)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_5_0 S5P_HDMI_BASE(0x1B0)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_5_1 S5P_HDMI_BASE(0x1B4)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_6_0 S5P_HDMI_BASE(0x1B8)
+#define S5P_HDMI_V_SYNC_LINE_AFT_PXL_6_1 S5P_HDMI_BASE(0x1BC)
+
+#define S5P_HDMI_VACT_SPACE_1_0 S5P_HDMI_BASE(0x1C0)
+#define S5P_HDMI_VACT_SPACE_1_1 S5P_HDMI_BASE(0x1C4)
+#define S5P_HDMI_VACT_SPACE_2_0 S5P_HDMI_BASE(0x1C8)
+#define S5P_HDMI_VACT_SPACE_2_1 S5P_HDMI_BASE(0x1CC)
+#define S5P_HDMI_VACT_SPACE_3_0 S5P_HDMI_BASE(0x1D0)
+#define S5P_HDMI_VACT_SPACE_3_1 S5P_HDMI_BASE(0x1D4)
+#define S5P_HDMI_VACT_SPACE_4_0 S5P_HDMI_BASE(0x1D8)
+#define S5P_HDMI_VACT_SPACE_4_1 S5P_HDMI_BASE(0x1DC)
+#define S5P_HDMI_VACT_SPACE_5_0 S5P_HDMI_BASE(0x1E0)
+#define S5P_HDMI_VACT_SPACE_5_1 S5P_HDMI_BASE(0x1E4)
+#define S5P_HDMI_VACT_SPACE_6_0 S5P_HDMI_BASE(0x1E8)
+#define S5P_HDMI_VACT_SPACE_6_1 S5P_HDMI_BASE(0x1EC)
+#define S5P_HDMI_CSC_MUX S5P_HDMI_BASE(0x1F0)
+#define S5P_HDMI_SYNC_GEN_MUX S5P_HDMI_BASE(0x1F4)
+
+#define S5P_HDMI_GCP_CON S5P_HDMI_BASE(0x200)
+#define S5P_HDMI_GCP_CON_EX S5P_HDMI_BASE(0x204)
+#define S5P_HDMI_GCP_BYTE1 S5P_HDMI_BASE(0x210)
+#define S5P_HDMI_GCP_BYTE2 S5P_HDMI_BASE(0x214)
+#define S5P_HDMI_GCP_BYTE3 S5P_HDMI_BASE(0x218)
+
+#define S5P_HDMI_ASP_CON S5P_HDMI_BASE(0x300)
+#define S5P_HDMI_ASP_SP_FLAT S5P_HDMI_BASE(0x304)
+#define S5P_HDMI_ASP_CHCFG0 S5P_HDMI_BASE(0x310)
+#define S5P_HDMI_ASP_CHCFG1 S5P_HDMI_BASE(0x314)
+#define S5P_HDMI_ASP_CHCFG2 S5P_HDMI_BASE(0x318)
+#define S5P_HDMI_ASP_CHCFG3 S5P_HDMI_BASE(0x31c)
+
+#define S5P_HDMI_ACR_CON S5P_HDMI_BASE(0x400)
+#define S5P_HDMI_ACR_MCTS0 S5P_HDMI_BASE(0x410)
+#define S5P_HDMI_ACR_MCTS1 S5P_HDMI_BASE(0x414)
+#define S5P_HDMI_ACR_MCTS2 S5P_HDMI_BASE(0x418)
+#define S5P_HDMI_ACR_CTS0 S5P_HDMI_BASE(0x420)
+#define S5P_HDMI_ACR_CTS1 S5P_HDMI_BASE(0x424)
+#define S5P_HDMI_ACR_CTS2 S5P_HDMI_BASE(0x428)
+#define S5P_HDMI_ACR_N0 S5P_HDMI_BASE(0x430)
+#define S5P_HDMI_ACR_N1 S5P_HDMI_BASE(0x434)
+#define S5P_HDMI_ACR_N2 S5P_HDMI_BASE(0x438)
+#define S5P_HDMI_ACR_LSB2 S5P_HDMI_BASE(0x440)
+#define S5P_HDMI_ACR_TXCNT S5P_HDMI_BASE(0x444)
+#define S5P_HDMI_ACR_TXINTERNAL S5P_HDMI_BASE(0x448)
+#define S5P_HDMI_ACR_CTS_OFFSET S5P_HDMI_BASE(0x44c)
+
+#define S5P_HDMI_ACP_CON S5P_HDMI_BASE(0x500)
+#define S5P_HDMI_ACP_TYPE S5P_HDMI_BASE(0x514)
+#define S5P_HDMI_ACP_DATA00 S5P_HDMI_BASE(0x520)
+#define S5P_HDMI_ACP_DATA01 S5P_HDMI_BASE(0x524)
+#define S5P_HDMI_ACP_DATA02 S5P_HDMI_BASE(0x528)
+#define S5P_HDMI_ACP_DATA03 S5P_HDMI_BASE(0x52C)
+#define S5P_HDMI_ACP_DATA04 S5P_HDMI_BASE(0x530)
+#define S5P_HDMI_ACP_DATA05 S5P_HDMI_BASE(0x534)
+#define S5P_HDMI_ACP_DATA06 S5P_HDMI_BASE(0x538)
+#define S5P_HDMI_ACP_DATA07 S5P_HDMI_BASE(0x53c)
+#define S5P_HDMI_ACP_DATA08 S5P_HDMI_BASE(0x540)
+#define S5P_HDMI_ACP_DATA09 S5P_HDMI_BASE(0x544)
+#define S5P_HDMI_ACP_DATA10 S5P_HDMI_BASE(0x548)
+#define S5P_HDMI_ACP_DATA11 S5P_HDMI_BASE(0x54c)
+#define S5P_HDMI_ACP_DATA12 S5P_HDMI_BASE(0x550)
+#define S5P_HDMI_ACP_DATA13 S5P_HDMI_BASE(0x554)
+#define S5P_HDMI_ACP_DATA14 S5P_HDMI_BASE(0x558)
+#define S5P_HDMI_ACP_DATA15 S5P_HDMI_BASE(0x55c)
+#define S5P_HDMI_ACP_DATA16 S5P_HDMI_BASE(0x560)
+
+#define S5P_HDMI_ISRC_CON S5P_HDMI_BASE(0x600)
+#define S5P_HDMI_ISRC1_HEADER1 S5P_HDMI_BASE(0x614)
+#define S5P_HDMI_ISRC1_DATA00 S5P_HDMI_BASE(0x620)
+#define S5P_HDMI_ISRC1_DATA01 S5P_HDMI_BASE(0x624)
+#define S5P_HDMI_ISRC1_DATA02 S5P_HDMI_BASE(0x628)
+#define S5P_HDMI_ISRC1_DATA03 S5P_HDMI_BASE(0x62c)
+#define S5P_HDMI_ISRC1_DATA04 S5P_HDMI_BASE(0x630)
+#define S5P_HDMI_ISRC1_DATA05 S5P_HDMI_BASE(0x634)
+#define S5P_HDMI_ISRC1_DATA06 S5P_HDMI_BASE(0x638)
+#define S5P_HDMI_ISRC1_DATA07 S5P_HDMI_BASE(0x63c)
+#define S5P_HDMI_ISRC1_DATA08 S5P_HDMI_BASE(0x640)
+#define S5P_HDMI_ISRC1_DATA09 S5P_HDMI_BASE(0x644)
+#define S5P_HDMI_ISRC1_DATA10 S5P_HDMI_BASE(0x648)
+#define S5P_HDMI_ISRC1_DATA11 S5P_HDMI_BASE(0x64c)
+#define S5P_HDMI_ISRC1_DATA12 S5P_HDMI_BASE(0x650)
+#define S5P_HDMI_ISRC1_DATA13 S5P_HDMI_BASE(0x654)
+#define S5P_HDMI_ISRC1_DATA14 S5P_HDMI_BASE(0x658)
+#define S5P_HDMI_ISRC1_DATA15 S5P_HDMI_BASE(0x65c)
+#define S5P_HDMI_ISRC2_DATA00 S5P_HDMI_BASE(0x6A0)
+#define S5P_HDMI_ISRC2_DATA01 S5P_HDMI_BASE(0x6A4)
+#define S5P_HDMI_ISRC2_DATA02 S5P_HDMI_BASE(0x6A8)
+#define S5P_HDMI_ISRC2_DATA03 S5P_HDMI_BASE(0x6Ac)
+#define S5P_HDMI_ISRC2_DATA04 S5P_HDMI_BASE(0x6B0)
+#define S5P_HDMI_ISRC2_DATA05 S5P_HDMI_BASE(0x6B4)
+#define S5P_HDMI_ISRC2_DATA06 S5P_HDMI_BASE(0x6B8)
+#define S5P_HDMI_ISRC2_DATA07 S5P_HDMI_BASE(0x6Bc)
+#define S5P_HDMI_ISRC2_DATA08 S5P_HDMI_BASE(0x6C0)
+#define S5P_HDMI_ISRC2_DATA09 S5P_HDMI_BASE(0x6C4)
+#define S5P_HDMI_ISRC2_DATA10 S5P_HDMI_BASE(0x6C8)
+#define S5P_HDMI_ISRC2_DATA11 S5P_HDMI_BASE(0x6Cc)
+#define S5P_HDMI_ISRC2_DATA12 S5P_HDMI_BASE(0x6D0)
+#define S5P_HDMI_ISRC2_DATA13 S5P_HDMI_BASE(0x6D4)
+#define S5P_HDMI_ISRC2_DATA14 S5P_HDMI_BASE(0x6D8)
+#define S5P_HDMI_ISRC2_DATA15 S5P_HDMI_BASE(0x6Dc)
+
+#define S5P_HDMI_AVI_CON S5P_HDMI_BASE(0x700)
+#define S5P_HDMI_AVI_HEADER0 S5P_HDMI_BASE(0x710)
+#define S5P_HDMI_AVI_HEADER1 S5P_HDMI_BASE(0x714)
+#define S5P_HDMI_AVI_HEADER2 S5P_HDMI_BASE(0x718)
+#define S5P_HDMI_AVI_CHECK_SUM S5P_HDMI_BASE(0x71C)
+#define S5P_HDMI_AVI_BYTE1 S5P_HDMI_BASE(0x720)
+#define S5P_HDMI_AVI_BYTE2 S5P_HDMI_BASE(0x724)
+#define S5P_HDMI_AVI_BYTE3 S5P_HDMI_BASE(0x728)
+#define S5P_HDMI_AVI_BYTE4 S5P_HDMI_BASE(0x72c)
+#define S5P_HDMI_AVI_BYTE5 S5P_HDMI_BASE(0x730)
+#define S5P_HDMI_AVI_BYTE6 S5P_HDMI_BASE(0x734)
+#define S5P_HDMI_AVI_BYTE7 S5P_HDMI_BASE(0x738)
+#define S5P_HDMI_AVI_BYTE8 S5P_HDMI_BASE(0x73c)
+#define S5P_HDMI_AVI_BYTE9 S5P_HDMI_BASE(0x740)
+#define S5P_HDMI_AVI_BYTE10 S5P_HDMI_BASE(0x744)
+#define S5P_HDMI_AVI_BYTE11 S5P_HDMI_BASE(0x748)
+#define S5P_HDMI_AVI_BYTE12 S5P_HDMI_BASE(0x74c)
+#define S5P_HDMI_AVI_BYTE13 S5P_HDMI_BASE(0x750)
+
+#define S5P_HDMI_AUI_CON S5P_HDMI_BASE(0x800)
+#define S5P_HDMI_AUI_HEADER0 S5P_HDMI_BASE(0x810)
+#define S5P_HDMI_AUI_HEADER1 S5P_HDMI_BASE(0x814)
+#define S5P_HDMI_AUI_HEADER2 S5P_HDMI_BASE(0x818)
+#define S5P_HDMI_AUI_CHECK_SUM S5P_HDMI_BASE(0x81C)
+#define S5P_HDMI_AUI_BYTE1 S5P_HDMI_BASE(0x820)
+#define S5P_HDMI_AUI_BYTE2 S5P_HDMI_BASE(0x824)
+#define S5P_HDMI_AUI_BYTE3 S5P_HDMI_BASE(0x828)
+#define S5P_HDMI_AUI_BYTE4 S5P_HDMI_BASE(0x82c)
+#define S5P_HDMI_AUI_BYTE5 S5P_HDMI_BASE(0x830)
+#define S5P_HDMI_AUI_BYTE6 S5P_HDMI_BASE(0x834)
+#define S5P_HDMI_AUI_BYTE7 S5P_HDMI_BASE(0x838)
+#define S5P_HDMI_AUI_BYTE8 S5P_HDMI_BASE(0x83C)
+#define S5P_HDMI_AUI_BYTE9 S5P_HDMI_BASE(0x840)
+#define S5P_HDMI_AUI_BYTE10 S5P_HDMI_BASE(0x844)
+#define S5P_HDMI_AUI_BYTE11 S5P_HDMI_BASE(0x848)
+#define S5P_HDMI_AUI_BYTE12 S5P_HDMI_BASE(0x84C)
+
+#define S5P_HDMI_MPG_CON S5P_HDMI_BASE(0x900)
+#define S5P_HDMI_MPG_CHECK_SUM S5P_HDMI_BASE(0x91C)
+#define S5P_HDMI_MPG_BYTE1 S5P_HDMI_BASE(0x920)
+#define S5P_HDMI_MPG_BYTE2 S5P_HDMI_BASE(0x924)
+#define S5P_HDMI_MPG_BYTE3 S5P_HDMI_BASE(0x928)
+#define S5P_HDMI_MPG_BYTE4 S5P_HDMI_BASE(0x92c)
+#define S5P_HDMI_MPG_BYTE5 S5P_HDMI_BASE(0x930)
+#define S5P_HDMI_MPG_BYTE6 S5P_HDMI_BASE(0x934)
+
+#define S5P_HDMI_SPD_CON S5P_HDMI_BASE(0xA00)
+#define S5P_HDMI_SPD_HEADER0 S5P_HDMI_BASE(0xA10)
+#define S5P_HDMI_SPD_HEADER1 S5P_HDMI_BASE(0xA14)
+#define S5P_HDMI_SPD_HEADER2 S5P_HDMI_BASE(0xA18)
+#define S5P_HDMI_SPD_DATA00 S5P_HDMI_BASE(0xA20)
+#define S5P_HDMI_SPD_DATA01 S5P_HDMI_BASE(0xA24)
+#define S5P_HDMI_SPD_DATA02 S5P_HDMI_BASE(0xA28)
+#define S5P_HDMI_SPD_DATA03 S5P_HDMI_BASE(0xA2c)
+#define S5P_HDMI_SPD_DATA04 S5P_HDMI_BASE(0xA30)
+#define S5P_HDMI_SPD_DATA05 S5P_HDMI_BASE(0xA34)
+#define S5P_HDMI_SPD_DATA06 S5P_HDMI_BASE(0xA38)
+#define S5P_HDMI_SPD_DATA07 S5P_HDMI_BASE(0xA3c)
+#define S5P_HDMI_SPD_DATA08 S5P_HDMI_BASE(0xA40)
+#define S5P_HDMI_SPD_DATA09 S5P_HDMI_BASE(0xA44)
+#define S5P_HDMI_SPD_DATA10 S5P_HDMI_BASE(0xA48)
+#define S5P_HDMI_SPD_DATA11 S5P_HDMI_BASE(0xA4c)
+#define S5P_HDMI_SPD_DATA12 S5P_HDMI_BASE(0xA50)
+#define S5P_HDMI_SPD_DATA13 S5P_HDMI_BASE(0xA54)
+#define S5P_HDMI_SPD_DATA14 S5P_HDMI_BASE(0xA58)
+#define S5P_HDMI_SPD_DATA15 S5P_HDMI_BASE(0xA5c)
+#define S5P_HDMI_SPD_DATA16 S5P_HDMI_BASE(0xA60)
+#define S5P_HDMI_SPD_DATA17 S5P_HDMI_BASE(0xA64)
+#define S5P_HDMI_SPD_DATA18 S5P_HDMI_BASE(0xA68)
+#define S5P_HDMI_SPD_DATA19 S5P_HDMI_BASE(0xA6c)
+#define S5P_HDMI_SPD_DATA20 S5P_HDMI_BASE(0xA70)
+#define S5P_HDMI_SPD_DATA21 S5P_HDMI_BASE(0xA74)
+#define S5P_HDMI_SPD_DATA22 S5P_HDMI_BASE(0xA78)
+#define S5P_HDMI_SPD_DATA23 S5P_HDMI_BASE(0xA7c)
+#define S5P_HDMI_SPD_DATA24 S5P_HDMI_BASE(0xA80)
+#define S5P_HDMI_SPD_DATA25 S5P_HDMI_BASE(0xA84)
+#define S5P_HDMI_SPD_DATA26 S5P_HDMI_BASE(0xA88)
+#define S5P_HDMI_SPD_DATA27 S5P_HDMI_BASE(0xA8c)
+
+#define S5P_HDMI_GAMUT_CON S5P_HDMI_BASE(0xB00)
+#define S5P_HDMI_GAMUT_HEADER0 S5P_HDMI_BASE(0xB10)
+#define S5P_HDMI_GAMUT_HEADER1 S5P_HDMI_BASE(0xB14)
+#define S5P_HDMI_GAMUT_HEADER2 S5P_HDMI_BASE(0xB18)
+#define S5P_HDMI_GAMUT_DATA00 S5P_HDMI_BASE(0xB20)
+#define S5P_HDMI_GAMUT_DATA01 S5P_HDMI_BASE(0xB24)
+#define S5P_HDMI_GAMUT_DATA02 S5P_HDMI_BASE(0xB28)
+#define S5P_HDMI_GAMUT_DATA03 S5P_HDMI_BASE(0xB2c)
+#define S5P_HDMI_GAMUT_DATA04 S5P_HDMI_BASE(0xB30)
+#define S5P_HDMI_GAMUT_DATA05 S5P_HDMI_BASE(0xB34)
+#define S5P_HDMI_GAMUT_DATA06 S5P_HDMI_BASE(0xB38)
+#define S5P_HDMI_GAMUT_DATA07 S5P_HDMI_BASE(0xB3c)
+#define S5P_HDMI_GAMUT_DATA08 S5P_HDMI_BASE(0xB40)
+#define S5P_HDMI_GAMUT_DATA09 S5P_HDMI_BASE(0xB44)
+#define S5P_HDMI_GAMUT_DATA10 S5P_HDMI_BASE(0xB48)
+#define S5P_HDMI_GAMUT_DATA11 S5P_HDMI_BASE(0xB4c)
+#define S5P_HDMI_GAMUT_DATA12 S5P_HDMI_BASE(0xB50)
+#define S5P_HDMI_GAMUT_DATA13 S5P_HDMI_BASE(0xB54)
+#define S5P_HDMI_GAMUT_DATA14 S5P_HDMI_BASE(0xB58)
+#define S5P_HDMI_GAMUT_DATA15 S5P_HDMI_BASE(0xB5c)
+#define S5P_HDMI_GAMUT_DATA16 S5P_HDMI_BASE(0xB60)
+#define S5P_HDMI_GAMUT_DATA17 S5P_HDMI_BASE(0xB64)
+#define S5P_HDMI_GAMUT_DATA18 S5P_HDMI_BASE(0xB68)
+#define S5P_HDMI_GAMUT_DATA19 S5P_HDMI_BASE(0xB6c)
+#define S5P_HDMI_GAMUT_DATA20 S5P_HDMI_BASE(0xB70)
+#define S5P_HDMI_GAMUT_DATA21 S5P_HDMI_BASE(0xB74)
+#define S5P_HDMI_GAMUT_DATA22 S5P_HDMI_BASE(0xB78)
+#define S5P_HDMI_GAMUT_DATA23 S5P_HDMI_BASE(0xB7c)
+#define S5P_HDMI_GAMUT_DATA24 S5P_HDMI_BASE(0xB80)
+#define S5P_HDMI_GAMUT_DATA25 S5P_HDMI_BASE(0xB84)
+#define S5P_HDMI_GAMUT_DATA26 S5P_HDMI_BASE(0xB88)
+#define S5P_HDMI_GAMUT_DATA27 S5P_HDMI_BASE(0xB8c)
+
+#define S5P_HDMI_VSI_CON S5P_HDMI_BASE(0xC00)
+#define S5P_HDMI_VSI_HEADER0 S5P_HDMI_BASE(0xC10)
+#define S5P_HDMI_VSI_HEADER1 S5P_HDMI_BASE(0xC14)
+#define S5P_HDMI_VSI_HEADER2 S5P_HDMI_BASE(0xC18)
+#define S5P_HDMI_VSI_DATA00 S5P_HDMI_BASE(0xC20)
+#define S5P_HDMI_VSI_DATA01 S5P_HDMI_BASE(0xC24)
+#define S5P_HDMI_VSI_DATA02 S5P_HDMI_BASE(0xC28)
+#define S5P_HDMI_VSI_DATA03 S5P_HDMI_BASE(0xC2c)
+#define S5P_HDMI_VSI_DATA04 S5P_HDMI_BASE(0xC30)
+#define S5P_HDMI_VSI_DATA05 S5P_HDMI_BASE(0xC34)
+#define S5P_HDMI_VSI_DATA06 S5P_HDMI_BASE(0xC38)
+#define S5P_HDMI_VSI_DATA07 S5P_HDMI_BASE(0xC3c)
+#define S5P_HDMI_VSI_DATA08 S5P_HDMI_BASE(0xC40)
+#define S5P_HDMI_VSI_DATA09 S5P_HDMI_BASE(0xC44)
+#define S5P_HDMI_VSI_DATA10 S5P_HDMI_BASE(0xC48)
+#define S5P_HDMI_VSI_DATA11 S5P_HDMI_BASE(0xC4c)
+#define S5P_HDMI_VSI_DATA12 S5P_HDMI_BASE(0xC50)
+#define S5P_HDMI_VSI_DATA13 S5P_HDMI_BASE(0xC54)
+#define S5P_HDMI_VSI_DATA14 S5P_HDMI_BASE(0xC58)
+#define S5P_HDMI_VSI_DATA15 S5P_HDMI_BASE(0xC5c)
+#define S5P_HDMI_VSI_DATA16 S5P_HDMI_BASE(0xC60)
+#define S5P_HDMI_VSI_DATA17 S5P_HDMI_BASE(0xC64)
+#define S5P_HDMI_VSI_DATA18 S5P_HDMI_BASE(0xC68)
+#define S5P_HDMI_VSI_DATA19 S5P_HDMI_BASE(0xC6c)
+#define S5P_HDMI_VSI_DATA20 S5P_HDMI_BASE(0xC70)
+#define S5P_HDMI_VSI_DATA21 S5P_HDMI_BASE(0xC74)
+#define S5P_HDMI_VSI_DATA22 S5P_HDMI_BASE(0xC78)
+#define S5P_HDMI_VSI_DATA23 S5P_HDMI_BASE(0xC7c)
+#define S5P_HDMI_VSI_DATA24 S5P_HDMI_BASE(0xC80)
+#define S5P_HDMI_VSI_DATA25 S5P_HDMI_BASE(0xC84)
+#define S5P_HDMI_VSI_DATA26 S5P_HDMI_BASE(0xC88)
+#define S5P_HDMI_VSI_DATA27 S5P_HDMI_BASE(0xC8c)
+
+#define S5P_HDMI_DC_CONTROL S5P_HDMI_BASE(0xD00)
+#define S5P_HDMI_VIDEO_PATTERN_GEN S5P_HDMI_BASE(0xD04)
+#define S5P_HDMI_HPD_GEN0 S5P_HDMI_BASE(0xD08)
+#define S5P_HDMI_HPD_GEN1 S5P_HDMI_BASE(0xD0C)
+#define S5P_HDMI_HPD_GEN2 S5P_HDMI_BASE(0xD10)
+#define S5P_HDMI_HPD_GEN3 S5P_HDMI_BASE(0xD14)
+
+#define S5P_HDMI_DIM_CON S5P_HDMI_BASE(0xD30)
+
+#define S5P_HDMI_HDCP_RX_SHA1_0_0 S5P_HDMI_BASE(0x7000)
+#define S5P_HDMI_HDCP_RX_SHA1_0_1 S5P_HDMI_BASE(0x7004)
+#define S5P_HDMI_HDCP_RX_SHA1_0_2 S5P_HDMI_BASE(0x7008)
+#define S5P_HDMI_HDCP_RX_SHA1_0_3 S5P_HDMI_BASE(0x700c)
+#define S5P_HDMI_HDCP_RX_SHA1_1_0 S5P_HDMI_BASE(0x7010)
+#define S5P_HDMI_HDCP_RX_SHA1_1_1 S5P_HDMI_BASE(0x7014)
+#define S5P_HDMI_HDCP_RX_SHA1_1_2 S5P_HDMI_BASE(0x7018)
+#define S5P_HDMI_HDCP_RX_SHA1_1_3 S5P_HDMI_BASE(0x701c)
+#define S5P_HDMI_HDCP_RX_SHA1_2_0 S5P_HDMI_BASE(0x7020)
+#define S5P_HDMI_HDCP_RX_SHA1_2_1 S5P_HDMI_BASE(0x7024)
+#define S5P_HDMI_HDCP_RX_SHA1_2_2 S5P_HDMI_BASE(0x7028)
+#define S5P_HDMI_HDCP_RX_SHA1_2_3 S5P_HDMI_BASE(0x702c)
+#define S5P_HDMI_HDCP_RX_SHA1_3_0 S5P_HDMI_BASE(0x7030)
+#define S5P_HDMI_HDCP_RX_SHA1_3_1 S5P_HDMI_BASE(0x7034)
+#define S5P_HDMI_HDCP_RX_SHA1_3_2 S5P_HDMI_BASE(0x7038)
+#define S5P_HDMI_HDCP_RX_SHA1_3_3 S5P_HDMI_BASE(0x703c)
+#define S5P_HDMI_HDCP_RX_SHA1_4_0 S5P_HDMI_BASE(0x7040)
+#define S5P_HDMI_HDCP_RX_SHA1_4_1 S5P_HDMI_BASE(0x7044)
+#define S5P_HDMI_HDCP_RX_SHA1_4_2 S5P_HDMI_BASE(0x7048)
+#define S5P_HDMI_HDCP_RX_SHA1_4_3 S5P_HDMI_BASE(0x704c)
+
+#define S5P_HDMI_HDCP_RX_KSV_0_0 S5P_HDMI_BASE(0x7050)
+#define S5P_HDMI_HDCP_RX_KSV_0_1 S5P_HDMI_BASE(0x7054)
+#define S5P_HDMI_HDCP_RX_KSV_0_2 S5P_HDMI_BASE(0x7058)
+#define S5P_HDMI_HDCP_RX_KSV_0_3 S5P_HDMI_BASE(0x705c)
+#define S5P_HDMI_HDCP_RX_KSV_0_4 S5P_HDMI_BASE(0x7060)
+
+#define S5P_HDMI_HDCP_KSV_LIST_CON S5P_HDMI_BASE(0x7064)
+#define S5P_HDMI_HDCP_SHA_RESULT S5P_HDMI_BASE(0x7070)
+#define S5P_HDMI_HDCP_CTRL1 S5P_HDMI_BASE(0x7080)
+#define S5P_HDMI_HDCP_CTRL2 S5P_HDMI_BASE(0x7084)
+#define S5P_HDMI_HDCP_CHECK_RESULT S5P_HDMI_BASE(0x7090)
+
+#define S5P_HDMI_HDCP_BKSV_0_0 S5P_HDMI_BASE(0x70a0)
+#define S5P_HDMI_HDCP_BKSV_0_1 S5P_HDMI_BASE(0x70a4)
+#define S5P_HDMI_HDCP_BKSV_0_2 S5P_HDMI_BASE(0x70a8)
+#define S5P_HDMI_HDCP_BKSV_0_3 S5P_HDMI_BASE(0x70ac)
+#define S5P_HDMI_HDCP_BKSV_1 S5P_HDMI_BASE(0x70b0)
+
+#define S5P_HDMI_HDCP_AKSV_0_0 S5P_HDMI_BASE(0x70c0)
+#define S5P_HDMI_HDCP_AKSV_0_1 S5P_HDMI_BASE(0x70c4)
+#define S5P_HDMI_HDCP_AKSV_0_2 S5P_HDMI_BASE(0x70c8)
+#define S5P_HDMI_HDCP_AKSV_0_3 S5P_HDMI_BASE(0x70cc)
+#define S5P_HDMI_HDCP_AKSV_1 S5P_HDMI_BASE(0x70d0)
+
+#define S5P_HDMI_HDCP_An_0_0 S5P_HDMI_BASE(0x70e0)
+#define S5P_HDMI_HDCP_An_0_1 S5P_HDMI_BASE(0x70e4)
+#define S5P_HDMI_HDCP_An_0_2 S5P_HDMI_BASE(0x70e8)
+#define S5P_HDMI_HDCP_An_0_3 S5P_HDMI_BASE(0x70ec)
+#define S5P_HDMI_HDCP_An_1_0 S5P_HDMI_BASE(0x70f0)
+#define S5P_HDMI_HDCP_An_1_1 S5P_HDMI_BASE(0x70f4)
+#define S5P_HDMI_HDCP_An_1_2 S5P_HDMI_BASE(0x70f8)
+#define S5P_HDMI_HDCP_An_1_3 S5P_HDMI_BASE(0x70fc)
+
+#define S5P_HDMI_HDCP_BCAPS S5P_HDMI_BASE(0x7100)
+#define S5P_HDMI_HDCP_BSTATUS_0 S5P_HDMI_BASE(0x7110)
+#define S5P_HDMI_HDCP_BSTATUS_1 S5P_HDMI_BASE(0x7114)
+#define S5P_HDMI_HDCP_Ri_0 S5P_HDMI_BASE(0x7140)
+#define S5P_HDMI_HDCP_Ri_1 S5P_HDMI_BASE(0x7144)
+#define S5P_HDMI_HDCP_I2C_INT S5P_HDMI_BASE(0x7180)
+#define S5P_HDMI_HDCP_AN_INT S5P_HDMI_BASE(0x7190)
+#define S5P_HDMI_HDCP_WDT_INT S5P_HDMI_BASE(0x71a0)
+#define S5P_HDMI_HDCP_RI_INT S5P_HDMI_BASE(0x71b0)
+
+#define S5P_HDMI_HDCP_RI_COMPARE_0 S5P_HDMI_BASE(0x71d0)
+#define S5P_HDMI_HDCP_RI_COMPARE_1 S5P_HDMI_BASE(0x71d4)
+#define S5P_HDMI_HDCP_FRAME_COUNT S5P_HDMI_BASE(0x71e0)
+
+#define S5P_HDMI_RGB_ROUND_EN S5P_HDMI_BASE(0xD500)
+
+#define S5P_HDMI_VACT_SPACE_R_0 S5P_HDMI_BASE(0xD504)
+#define S5P_HDMI_VACT_SPACE_R_1 S5P_HDMI_BASE(0xD508)
+
+#define S5P_HDMI_VACT_SPACE_G_0 S5P_HDMI_BASE(0xD50C)
+#define S5P_HDMI_VACT_SPACE_G_1 S5P_HDMI_BASE(0xD510)
+
+#define S5P_HDMI_VACT_SPACE_B_0 S5P_HDMI_BASE(0xD514)
+#define S5P_HDMI_VACT_SPACE_B_1 S5P_HDMI_BASE(0xD518)
+
+#define S5P_HDMI_BLUE_SCREEN_B_0 S5P_HDMI_BASE(0xD520)
+#define S5P_HDMI_BLUE_SCREEN_B_1 S5P_HDMI_BASE(0xD524)
+#define S5P_HDMI_BLUE_SCREEN_G_0 S5P_HDMI_BASE(0xD528)
+#define S5P_HDMI_BLUE_SCREEN_G_1 S5P_HDMI_BASE(0xD52C)
+#define S5P_HDMI_BLUE_SCREEN_R_0 S5P_HDMI_BASE(0xD530)
+#define S5P_HDMI_BLUE_SCREEN_R_1 S5P_HDMI_BASE(0xD534)
+
+/* HDMISPDIFregister */
+#define S5P_HDMI_SPDIFIN_CLK_CTRL S5P_HDMI_SPDIF_BASE(0x0000)
+#define S5P_HDMI_SPDIFIN_OP_CTRL S5P_HDMI_SPDIF_BASE(0x0004)
+#define S5P_HDMI_SPDIFIN_IRQ_MASK S5P_HDMI_SPDIF_BASE(0x0008)
+#define S5P_HDMI_SPDIFIN_IRQ_STATUS S5P_HDMI_SPDIF_BASE(0x000C)
+#define S5P_HDMI_SPDIFIN_CONFIG_1 S5P_HDMI_SPDIF_BASE(0x0010)
+#define S5P_HDMI_SPDIFIN_CONFIG_2 S5P_HDMI_SPDIF_BASE(0x0014)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_1 S5P_HDMI_SPDIF_BASE(0x0020)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_2 S5P_HDMI_SPDIF_BASE(0x0024)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_3 S5P_HDMI_SPDIF_BASE(0x0028)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_4 S5P_HDMI_SPDIF_BASE(0x002C)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_1 S5P_HDMI_SPDIF_BASE(0x0030)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_2 S5P_HDMI_SPDIF_BASE(0x0034)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_3 S5P_HDMI_SPDIF_BASE(0x0038)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_4 S5P_HDMI_SPDIF_BASE(0x003C)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_1 S5P_HDMI_SPDIF_BASE(0x0040)
+#define S5P_HDMI_SPDIFIN_FRAME_PERIOD_1 S5P_HDMI_SPDIF_BASE(0x0048)
+#define S5P_HDMI_SPDIFIN_FRAME_PERIOD_2 S5P_HDMI_SPDIF_BASE(0x004C)
+#define S5P_HDMI_SPDIFIN_Pc_INFO_1 S5P_HDMI_SPDIF_BASE(0x0050)
+#define S5P_HDMI_SPDIFIN_Pc_INFO_2 S5P_HDMI_SPDIF_BASE(0x0054)
+#define S5P_HDMI_SPDIFIN_Pd_INFO_1 S5P_HDMI_SPDIF_BASE(0x0058)
+#define S5P_HDMI_SPDIFIN_Pd_INFO_2 S5P_HDMI_SPDIF_BASE(0x005C)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_0_1 S5P_HDMI_SPDIF_BASE(0x0060)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_0_2 S5P_HDMI_SPDIF_BASE(0x0064)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_0_3 S5P_HDMI_SPDIF_BASE(0x0068)
+#define S5P_HDMI_SPDIFIN_USER_BUF_0 S5P_HDMI_SPDIF_BASE(0x006C)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_1_1 S5P_HDMI_SPDIF_BASE(0x0070)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_1_2 S5P_HDMI_SPDIF_BASE(0x0074)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_1_3 S5P_HDMI_SPDIF_BASE(0x0078)
+#define S5P_HDMI_SPDIFIN_USER_BUF_1 S5P_HDMI_SPDIF_BASE(0x007C)
+
+/* HDMII2Sregister */
+#define S5P_HDMI_I2S_CLK_CON S5P_HDMI_I2S_BASE(0x000)
+#define S5P_HDMI_I2S_CON_1 S5P_HDMI_I2S_BASE(0x004)
+#define S5P_HDMI_I2S_CON_2 S5P_HDMI_I2S_BASE(0x008)
+#define S5P_HDMI_I2S_PIN_SEL_0 S5P_HDMI_I2S_BASE(0x00c)
+#define S5P_HDMI_I2S_PIN_SEL_1 S5P_HDMI_I2S_BASE(0x010)
+#define S5P_HDMI_I2S_PIN_SEL_2 S5P_HDMI_I2S_BASE(0x014)
+#define S5P_HDMI_I2S_PIN_SEL_3 S5P_HDMI_I2S_BASE(0x018)
+#define S5P_HDMI_I2S_DSD_CON S5P_HDMI_I2S_BASE(0x01c)
+#define S5P_HDMI_I2S_MUX_CON S5P_HDMI_I2S_BASE(0x020)
+#define S5P_HDMI_I2S_CH_ST_CON S5P_HDMI_I2S_BASE(0x024)
+#define S5P_HDMI_I2S_CH_ST_0 S5P_HDMI_I2S_BASE(0x028)
+#define S5P_HDMI_I2S_CH_ST_1 S5P_HDMI_I2S_BASE(0x02c)
+#define S5P_HDMI_I2S_CH_ST_2 S5P_HDMI_I2S_BASE(0x030)
+#define S5P_HDMI_I2S_CH_ST_3 S5P_HDMI_I2S_BASE(0x034)
+#define S5P_HDMI_I2S_CH_ST_4 S5P_HDMI_I2S_BASE(0x038)
+#define S5P_HDMI_I2S_CH_ST_SH_0 S5P_HDMI_I2S_BASE(0x03c)
+#define S5P_HDMI_I2S_CH_ST_SH_1 S5P_HDMI_I2S_BASE(0x040)
+#define S5P_HDMI_I2S_CH_ST_SH_2 S5P_HDMI_I2S_BASE(0x044)
+#define S5P_HDMI_I2S_CH_ST_SH_3 S5P_HDMI_I2S_BASE(0x048)
+#define S5P_HDMI_I2S_CH_ST_SH_4 S5P_HDMI_I2S_BASE(0x04c)
+#define S5P_HDMI_I2S_VD_DATA S5P_HDMI_I2S_BASE(0x050)
+#define S5P_HDMI_I2S_MUX_CH S5P_HDMI_I2S_BASE(0x054)
+#define S5P_HDMI_I2S_MUX_CUV S5P_HDMI_I2S_BASE(0x058)
+#define S5P_HDMI_I2S_IRQ_MASK S5P_HDMI_I2S_BASE(0x05c)
+#define S5P_HDMI_I2S_IRQ_STATUS S5P_HDMI_I2S_BASE(0x060)
+
+/* HDMITGregister */
+#define S5P_HDMI_TG_CMD S5P_HDMI_TG_BASE(0x000)
+#define S5P_HDMI_TG_CFG S5P_HDMI_TG_BASE(0x004)
+#define S5P_HDMI_TG_CB_SZ S5P_HDMI_TG_BASE(0x008)
+#define S5P_HDMI_TG_INDELAY_L S5P_HDMI_TG_BASE(0x00c)
+#define S5P_HDMI_TG_INDELAY_H S5P_HDMI_TG_BASE(0x010)
+#define S5P_HDMI_TG_POL_CTRL S5P_HDMI_TG_BASE(0x014)
+#define S5P_HDMI_TG_H_FSZ_L S5P_HDMI_TG_BASE(0x018)
+#define S5P_HDMI_TG_H_FSZ_H S5P_HDMI_TG_BASE(0x01c)
+#define S5P_HDMI_TG_HACT_ST_L S5P_HDMI_TG_BASE(0x020)
+#define S5P_HDMI_TG_HACT_ST_H S5P_HDMI_TG_BASE(0x024)
+#define S5P_HDMI_TG_HACT_SZ_L S5P_HDMI_TG_BASE(0x028)
+#define S5P_HDMI_TG_HACT_SZ_H S5P_HDMI_TG_BASE(0x02c)
+#define S5P_HDMI_TG_V_FSZ_L S5P_HDMI_TG_BASE(0x030)
+#define S5P_HDMI_TG_V_FSZ_H S5P_HDMI_TG_BASE(0x034)
+#define S5P_HDMI_TG_VSYNC_L S5P_HDMI_TG_BASE(0x038)
+#define S5P_HDMI_TG_VSYNC_H S5P_HDMI_TG_BASE(0x03c)
+#define S5P_HDMI_TG_VSYNC2_L S5P_HDMI_TG_BASE(0x040)
+#define S5P_HDMI_TG_VSYNC2_H S5P_HDMI_TG_BASE(0x044)
+#define S5P_HDMI_TG_VACT_ST_L S5P_HDMI_TG_BASE(0x048)
+#define S5P_HDMI_TG_VACT_ST_H S5P_HDMI_TG_BASE(0x04c)
+#define S5P_HDMI_TG_VACT_SZ_L S5P_HDMI_TG_BASE(0x050)
+#define S5P_HDMI_TG_VACT_SZ_H S5P_HDMI_TG_BASE(0x054)
+#define S5P_HDMI_TG_FIELD_CHG_L S5P_HDMI_TG_BASE(0x058)
+#define S5P_HDMI_TG_FIELD_CHG_H S5P_HDMI_TG_BASE(0x05c)
+#define S5P_HDMI_TG_VACT_ST2_L S5P_HDMI_TG_BASE(0x060)
+#define S5P_HDMI_TG_VACT_ST2_H S5P_HDMI_TG_BASE(0x064)
+
+#define S5P_HDMI_TG_VACT_ST3_L S5P_HDMI_TG_BASE(0x068)
+#define S5P_HDMI_TG_VACT_ST3_H S5P_HDMI_TG_BASE(0x06c)
+#define S5P_HDMI_TG_VACT_ST4_L S5P_HDMI_TG_BASE(0x070)
+#define S5P_HDMI_TG_VACT_ST4_H S5P_HDMI_TG_BASE(0x074)
+
+#define S5P_HDMI_TG_VSYNC_TOP_HDMI_L S5P_HDMI_TG_BASE(0x078)
+#define S5P_HDMI_TG_VSYNC_TOP_HDMI_H S5P_HDMI_TG_BASE(0x07c)
+#define S5P_HDMI_TG_VSYNC_BOT_HDMI_L S5P_HDMI_TG_BASE(0x080)
+#define S5P_HDMI_TG_VSYNC_BOT_HDMI_H S5P_HDMI_TG_BASE(0x084)
+#define S5P_HDMI_TG_FIELD_TOP_HDMI_L S5P_HDMI_TG_BASE(0x088)
+#define S5P_HDMI_TG_FIELD_TOP_HDMI_H S5P_HDMI_TG_BASE(0x08c)
+#define S5P_HDMI_TG_FIELD_BOT_HDMI_L S5P_HDMI_TG_BASE(0x090)
+#define S5P_HDMI_TG_FIELD_BOT_HDMI_H S5P_HDMI_TG_BASE(0x094)
+
+#define S5P_HDMI_TG_3D S5P_HDMI_TG_BASE(0x0F0)
+
+#define S5P_HDMI_MHL_HSYNC_WIDTH S5P_HDMI_TG_BASE(0x17C)
+#define S5P_HDMI_MHL_VSYNC_WIDTH S5P_HDMI_TG_BASE(0x180)
+#define S5P_HDMI_MHL_CLK_INV S5P_HDMI_TG_BASE(0x184)
+
+/* HDMIE-FUSEregiseter */
+#define S5P_HDMI_EFUSE_CTRL S5P_HDMI_EFUSE_BASE(0x000)
+#define S5P_HDMI_EFUSE_STATUS S5P_HDMI_EFUSE_BASE(0x004)
+#define S5P_HDMI_EFUSE_ADDR_WIDTH S5P_HDMI_EFUSE_BASE(0x008)
+#define S5P_HDMI_EFUSE_SIGDEV_ASSERT S5P_HDMI_EFUSE_BASE(0x00c)
+#define S5P_HDMI_EFUSE_SIGDEV_DEASSERT S5P_HDMI_EFUSE_BASE(0x010)
+#define S5P_HDMI_EFUSE_PRCHG_ASSERT S5P_HDMI_EFUSE_BASE(0x014)
+#define S5P_HDMI_EFUSE_PRCHG_DEASSERT S5P_HDMI_EFUSE_BASE(0x018)
+#define S5P_HDMI_EFUSE_FSET_ASSERT S5P_HDMI_EFUSE_BASE(0x01c)
+#define S5P_HDMI_EFUSE_FSET_DEASSERT S5P_HDMI_EFUSE_BASE(0x020)
+#define S5P_HDMI_EFUSE_SENSING S5P_HDMI_EFUSE_BASE(0x024)
+#define S5P_HDMI_EFUSE_SCK_ASSERT S5P_HDMI_EFUSE_BASE(0x028)
+#define S5P_HDMI_EFUSE_SCK_DEASSERT S5P_HDMI_EFUSE_BASE(0x02c)
+#define S5P_HDMI_EFUSE_SDOUT_OFFSET S5P_HDMI_EFUSE_BASE(0x030)
+#define S5P_HDMI_EFUSE_READ_OFFSET S5P_HDMI_EFUSE_BASE(0x034)
+#else
+
+#define S5P_HDMI_I2C_PHY_BASE(x) (x)
+
+#define HDMI_I2C_CON S5P_HDMI_I2C_PHY_BASE(0x0000)
+#define HDMI_I2C_STAT S5P_HDMI_I2C_PHY_BASE(0x0004)
+#define HDMI_I2C_ADD S5P_HDMI_I2C_PHY_BASE(0x0008)
+#define HDMI_I2C_DS S5P_HDMI_I2C_PHY_BASE(0x000c)
+#define HDMI_I2C_LC S5P_HDMI_I2C_PHY_BASE(0x0010)
+
+#define S5P_HDMI_CTRL_BASE(x) (x)
+#define S5P_HDMI_BASE(x) ((x) + 0x00010000)
+#define S5P_HDMI_SPDIF_BASE(x) ((x) + 0x00030000)
+#define S5P_HDMI_I2S_BASE(x) ((x) + 0x00040000)
+#define S5P_HDMI_TG_BASE(x) ((x) + 0x00050000)
+#define S5P_HDMI_EFUSE_BASE(x) ((x) + 0x00060000)
+
+#define S5P_HDMI_INTC_CON S5P_HDMI_CTRL_BASE(0x0000)
+#define S5P_HDMI_INTC_FLAG S5P_HDMI_CTRL_BASE(0x0004)
+#define S5P_HDMI_HDCP_KEY_LOAD S5P_HDMI_CTRL_BASE(0x0008)
+#define S5P_HDMI_HPD_STATUS S5P_HDMI_CTRL_BASE(0x000C)
+#define S5P_HDMI_AUDIO_CLKSEL S5P_HDMI_CTRL_BASE(0x0010)
+#define S5P_HDMI_PHY_RSTOUT S5P_HDMI_CTRL_BASE(0x0014)
+#define S5P_HDMI_PHY_VPLL S5P_HDMI_CTRL_BASE(0x0018)
+#define S5P_HDMI_PHY_CMU S5P_HDMI_CTRL_BASE(0x001C)
+#define S5P_HDMI_CORE_RSTOUT S5P_HDMI_CTRL_BASE(0x0020)
+
+#define S5P_HDMI_CON_0 S5P_HDMI_BASE(0x0000)
+#define S5P_HDMI_CON_1 S5P_HDMI_BASE(0x0004)
+#define S5P_HDMI_CON_2 S5P_HDMI_BASE(0x0008)
+#define S5P_HDMI_SYS_STATUS S5P_HDMI_BASE(0x0010)
+#define S5P_HDMI_PHY_STATUS S5P_HDMI_BASE(0x0014)
+#define S5P_HDMI_STATUS_EN S5P_HDMI_BASE(0x0020)
+#define S5P_HDMI_HPD S5P_HDMI_BASE(0x0030)
+#define S5P_HDMI_MODE_SEL S5P_HDMI_BASE(0x0040)
+#define S5P_HDMI_ENC_EN S5P_HDMI_BASE(0x0044)
+
+#define S5P_HDMI_BLUE_SCREEN_0 S5P_HDMI_BASE(0x0050)
+#define S5P_HDMI_BLUE_SCREEN_1 S5P_HDMI_BASE(0x0054)
+#define S5P_HDMI_BLUE_SCREEN_2 S5P_HDMI_BASE(0x0058)
+
+#define S5P_HDMI_YMAX S5P_HDMI_BASE(0x0060)
+#define S5P_HDMI_YMIN S5P_HDMI_BASE(0x0064)
+#define S5P_HDMI_CMAX S5P_HDMI_BASE(0x0068)
+#define S5P_HDMI_CMIN S5P_HDMI_BASE(0x006C)
+
+#define S5P_HDMI_H_BLANK_0 S5P_HDMI_BASE(0x00A0)
+#define S5P_HDMI_H_BLANK_1 S5P_HDMI_BASE(0x00A4)
+#define S5P_HDMI_V_BLANK_0 S5P_HDMI_BASE(0x00B0)
+#define S5P_HDMI_V_BLANK_1 S5P_HDMI_BASE(0x00B4)
+#define S5P_HDMI_V_BLANK_2 S5P_HDMI_BASE(0x00B8)
+#define S5P_HDMI_H_V_LINE_0 S5P_HDMI_BASE(0x00C0)
+#define S5P_HDMI_H_V_LINE_1 S5P_HDMI_BASE(0x00C4)
+#define S5P_HDMI_H_V_LINE_2 S5P_HDMI_BASE(0x00C8)
+
+#define S5P_HDMI_SYNC_MODE S5P_HDMI_BASE(0x00E4)
+#define S5P_HDMI_INT_PRO_MODE S5P_HDMI_BASE(0x00E8)
+
+#define S5P_HDMI_V_BLANK_F_0 S5P_HDMI_BASE(0x0110)
+#define S5P_HDMI_V_BLANK_F_1 S5P_HDMI_BASE(0x0114)
+#define S5P_HDMI_V_BLANK_F_2 S5P_HDMI_BASE(0x0118)
+#define S5P_HDMI_H_SYNC_GEN_0 S5P_HDMI_BASE(0x0120)
+#define S5P_HDMI_H_SYNC_GEN_1 S5P_HDMI_BASE(0x0124)
+#define S5P_HDMI_H_SYNC_GEN_2 S5P_HDMI_BASE(0x0128)
+#define S5P_HDMI_V_SYNC_GEN_1_0 S5P_HDMI_BASE(0x0130)
+#define S5P_HDMI_V_SYNC_GEN_1_1 S5P_HDMI_BASE(0x0134)
+#define S5P_HDMI_V_SYNC_GEN_1_2 S5P_HDMI_BASE(0x0138)
+#define S5P_HDMI_V_SYNC_GEN_2_0 S5P_HDMI_BASE(0x0140)
+#define S5P_HDMI_V_SYNC_GEN_2_1 S5P_HDMI_BASE(0x0144)
+#define S5P_HDMI_V_SYNC_GEN_2_2 S5P_HDMI_BASE(0x0148)
+#define S5P_HDMI_V_SYNC_GEN_3_0 S5P_HDMI_BASE(0x0150)
+#define S5P_HDMI_V_SYNC_GEN_3_1 S5P_HDMI_BASE(0x0154)
+#define S5P_HDMI_V_SYNC_GEN_3_2 S5P_HDMI_BASE(0x0158)
+
+#define S5P_HDMI_ASP_CON S5P_HDMI_BASE(0x0160)
+#define S5P_HDMI_ASP_SP_FLAT S5P_HDMI_BASE(0x0164)
+#define S5P_HDMI_ASP_CHCFG0 S5P_HDMI_BASE(0x0170)
+#define S5P_HDMI_ASP_CHCFG1 S5P_HDMI_BASE(0x0174)
+#define S5P_HDMI_ASP_CHCFG2 S5P_HDMI_BASE(0x0178)
+#define S5P_HDMI_ASP_CHCFG3 S5P_HDMI_BASE(0x017C)
+
+#define S5P_HDMI_ACR_CON S5P_HDMI_BASE(0x0180)
+#define S5P_HDMI_ACR_MCTS0 S5P_HDMI_BASE(0x0184)
+#define S5P_HDMI_ACR_MCTS1 S5P_HDMI_BASE(0x0188)
+#define S5P_HDMI_ACR_MCTS2 S5P_HDMI_BASE(0x018C)
+#define S5P_HDMI_ACR_CTS0 S5P_HDMI_BASE(0x0190)
+#define S5P_HDMI_ACR_CTS1 S5P_HDMI_BASE(0x0194)
+#define S5P_HDMI_ACR_CTS2 S5P_HDMI_BASE(0x0198)
+#define S5P_HDMI_ACR_N0 S5P_HDMI_BASE(0x01A0)
+#define S5P_HDMI_ACR_N1 S5P_HDMI_BASE(0x01A4)
+#define S5P_HDMI_ACR_N2 S5P_HDMI_BASE(0x01A8)
+#define S5P_HDMI_ACR_LSB2 S5P_HDMI_BASE(0x01B0)
+#define S5P_HDMI_ACR_TXCNT S5P_HDMI_BASE(0x01B4)
+#define S5P_HDMI_ACR_TXINTERVAL S5P_HDMI_BASE(0x01B8)
+#define S5P_HDMI_ACR_CTS_OFFSET S5P_HDMI_BASE(0x01BC)
+
+#define S5P_HDMI_GCP_CON S5P_HDMI_BASE(0x01C0)
+#define S5P_HDMI_GCP_BYTE1 S5P_HDMI_BASE(0x01D0)
+#define S5P_HDMI_GCP_BYTE2 S5P_HDMI_BASE(0x01D4)
+#define S5P_HDMI_GCP_BYTE3 S5P_HDMI_BASE(0x01D8)
+
+#define S5P_HDMI_ACP_CON S5P_HDMI_BASE(0x01E0)
+#define S5P_HDMI_ACP_TYPE S5P_HDMI_BASE(0x01E4)
+#define S5P_HDMI_ACP_DATA S5P_HDMI_BASE(0x0200)
+
+#define S5P_HDMI_ISRC_CON S5P_HDMI_BASE(0x0250)
+#define S5P_HDMI_ISRC1_HEADER1 S5P_HDMI_BASE(0x0264)
+#define S5P_HDMI_ISRC1_DATA S5P_HDMI_BASE(0x0270)
+#define S5P_HDMI_ISRC2_DATA S5P_HDMI_BASE(0x02b0)
+
+#define S5P_HDMI_AVI_CON S5P_HDMI_BASE(0x0300)
+#define S5P_HDMI_AVI_CHECK_SUM S5P_HDMI_BASE(0x0310)
+#define S5P_HDMI_AVI_DATA S5P_HDMI_BASE(0x0320)
+
+#define S5P_HDMI_AUI_CON S5P_HDMI_BASE(0x0360)
+#define S5P_HDMI_AUI_CHECK_SUM S5P_HDMI_BASE(0x0370)
+
+#define S5P_HDMI_AUI_BYTE1 S5P_HDMI_BASE(0x0380)
+#define S5P_HDMI_AUI_BYTE2 S5P_HDMI_BASE(0x0384)
+#define S5P_HDMI_AUI_BYTE3 S5P_HDMI_BASE(0x0388)
+#define S5P_HDMI_AUI_BYTE4 S5P_HDMI_BASE(0x038c)
+#define S5P_HDMI_AUI_BYTE5 S5P_HDMI_BASE(0x0390)
+
+#define S5P_HDMI_MPG_CON S5P_HDMI_BASE(0x03A0)
+#define S5P_HDMI_MPG_CHECK_SUM S5P_HDMI_BASE(0x03B0)
+#define S5P_HDMI_MPG_DATA S5P_HDMI_BASE(0x03c0)
+
+#define S5P_HDMI_SPD_CON S5P_HDMI_BASE(0x0400)
+#define S5P_HDMI_SPD_HEADER S5P_HDMI_BASE(0x0410)
+#define S5P_HDMI_SPD_DATA S5P_HDMI_BASE(0x0420)
+
+#define S5P_HDMI_HDCP_RX_SHA1_0_0 S5P_HDMI_BASE(0x0600)
+#define S5P_HDMI_HDCP_RX_SHA1_0_1 S5P_HDMI_BASE(0x0604)
+#define S5P_HDMI_HDCP_RX_SHA1_0_2 S5P_HDMI_BASE(0x0608)
+#define S5P_HDMI_HDCP_RX_SHA1_0_3 S5P_HDMI_BASE(0x060C)
+#define S5P_HDMI_HDCP_RX_SHA1_1_0 S5P_HDMI_BASE(0x0610)
+#define S5P_HDMI_HDCP_RX_SHA1_1_1 S5P_HDMI_BASE(0x0614)
+#define S5P_HDMI_HDCP_RX_SHA1_1_2 S5P_HDMI_BASE(0x0618)
+#define S5P_HDMI_HDCP_RX_SHA1_1_3 S5P_HDMI_BASE(0x061C)
+#define S5P_HDMI_HDCP_RX_SHA1_2_0 S5P_HDMI_BASE(0x0620)
+#define S5P_HDMI_HDCP_RX_SHA1_2_1 S5P_HDMI_BASE(0x0624)
+#define S5P_HDMI_HDCP_RX_SHA1_2_2 S5P_HDMI_BASE(0x0628)
+#define S5P_HDMI_HDCP_RX_SHA1_2_3 S5P_HDMI_BASE(0x062C)
+#define S5P_HDMI_HDCP_RX_SHA1_3_0 S5P_HDMI_BASE(0x0630)
+#define S5P_HDMI_HDCP_RX_SHA1_3_1 S5P_HDMI_BASE(0x0634)
+#define S5P_HDMI_HDCP_RX_SHA1_3_2 S5P_HDMI_BASE(0x0638)
+#define S5P_HDMI_HDCP_RX_SHA1_3_3 S5P_HDMI_BASE(0x063C)
+#define S5P_HDMI_HDCP_RX_SHA1_4_0 S5P_HDMI_BASE(0x0640)
+#define S5P_HDMI_HDCP_RX_SHA1_4_1 S5P_HDMI_BASE(0x0644)
+#define S5P_HDMI_HDCP_RX_SHA1_4_2 S5P_HDMI_BASE(0x0648)
+#define S5P_HDMI_HDCP_RX_SHA1_4_3 S5P_HDMI_BASE(0x064C)
+
+#define S5P_HDMI_HDCP_RX_KSV_0_0 S5P_HDMI_BASE(0x0650)
+#define S5P_HDMI_HDCP_RX_KSV_0_1 S5P_HDMI_BASE(0x0654)
+#define S5P_HDMI_HDCP_RX_KSV_0_2 S5P_HDMI_BASE(0x0658)
+#define S5P_HDMI_HDCP_RX_KSV_0_3 S5P_HDMI_BASE(0x065C)
+#define S5P_HDMI_HDCP_RX_KSV_0_4 S5P_HDMI_BASE(0x0660)
+
+#define S5P_HDMI_HDCP_KSV_LIST_CON S5P_HDMI_BASE(0x0664)
+#define S5P_HDMI_HDCP_SHA_RESULT S5P_HDMI_BASE(0x0670)
+#define S5P_HDMI_HDCP_CTRL1 S5P_HDMI_BASE(0x0680)
+#define S5P_HDMI_HDCP_CTRL2 S5P_HDMI_BASE(0x0684)
+#define S5P_HDMI_HDCP_CHECK_RESULT S5P_HDMI_BASE(0x0690)
+
+#define S5P_HDMI_HDCP_BKSV_0_0 S5P_HDMI_BASE(0x06A0)
+#define S5P_HDMI_HDCP_BKSV_0_1 S5P_HDMI_BASE(0x06A4)
+#define S5P_HDMI_HDCP_BKSV_0_2 S5P_HDMI_BASE(0x06A8)
+#define S5P_HDMI_HDCP_BKSV_0_3 S5P_HDMI_BASE(0x06AC)
+#define S5P_HDMI_HDCP_BKSV_1 S5P_HDMI_BASE(0x06B0)
+
+#define S5P_HDMI_HDCP_AKSV_0_0 S5P_HDMI_BASE(0x06C0)
+#define S5P_HDMI_HDCP_AKSV_0_1 S5P_HDMI_BASE(0x06C4)
+#define S5P_HDMI_HDCP_AKSV_0_2 S5P_HDMI_BASE(0x06C8)
+#define S5P_HDMI_HDCP_AKSV_0_3 S5P_HDMI_BASE(0x06CC)
+#define S5P_HDMI_HDCP_AKSV_1 S5P_HDMI_BASE(0x06D0)
+
+#define S5P_HDMI_HDCP_An_0_0 S5P_HDMI_BASE(0x06E0)
+#define S5P_HDMI_HDCP_An_0_1 S5P_HDMI_BASE(0x06E4)
+#define S5P_HDMI_HDCP_An_0_2 S5P_HDMI_BASE(0x06E8)
+#define S5P_HDMI_HDCP_An_0_3 S5P_HDMI_BASE(0x06EC)
+#define S5P_HDMI_HDCP_An_1_0 S5P_HDMI_BASE(0x06F0)
+#define S5P_HDMI_HDCP_An_1_1 S5P_HDMI_BASE(0x06F4)
+#define S5P_HDMI_HDCP_An_1_2 S5P_HDMI_BASE(0x06F8)
+#define S5P_HDMI_HDCP_An_1_3 S5P_HDMI_BASE(0x06FC)
+
+#define S5P_HDMI_HDCP_BCAPS S5P_HDMI_BASE(0x0700)
+#define S5P_HDMI_HDCP_BSTATUS_0 S5P_HDMI_BASE(0x0710)
+#define S5P_HDMI_HDCP_BSTATUS_1 S5P_HDMI_BASE(0x0714)
+#define S5P_HDMI_HDCP_Ri_0 S5P_HDMI_BASE(0x0740)
+#define S5P_HDMI_HDCP_Ri_1 S5P_HDMI_BASE(0x0744)
+
+#define S5P_HDMI_HDCP_I2C_INT S5P_HDMI_BASE(0x0780)
+#define S5P_HDMI_HDCP_AN_INT S5P_HDMI_BASE(0x0790)
+#define S5P_HDMI_HDCP_WDT_INT S5P_HDMI_BASE(0x07a0)
+#define S5P_HDMI_HDCP_RI_INT S5P_HDMI_BASE(0x07b0)
+
+#define S5P_HDMI_HDCP_RI_COMPARE_0 S5P_HDMI_BASE(0x07d0)
+#define S5P_HDMI_HDCP_RI_COMPARE_1 S5P_HDMI_BASE(0x07d4)
+#define S5P_HDMI_HDCP_FRAME_COUNT S5P_HDMI_BASE(0x07e0)
+
+#define S5P_HDMI_GAMUT_CON S5P_HDMI_BASE(0x0500)
+#define S5P_HDMI_GAMUT_HEADER0 S5P_HDMI_BASE(0x0504)
+#define S5P_HDMI_GAMUT_HEADER1 S5P_HDMI_BASE(0x0508)
+#define S5P_HDMI_GAMUT_HEADER2 S5P_HDMI_BASE(0x050c)
+#define S5P_HDMI_GAMUT_DATA S5P_HDMI_BASE(0x0510)
+
+#define S5P_HDMI_DC_CONTROL S5P_HDMI_BASE(0x05C0)
+#define S5P_HDMI_VIDEO_PATTERN_GEN S5P_HDMI_BASE(0x05C4)
+#define S5P_HDMI_HPD_GEN S5P_HDMI_BASE(0x05C8)
+
+#define S5P_HDMI_SPDIFIN_CLK_CTRL S5P_HDMI_SPDIF_BASE(0x0000)
+#define S5P_HDMI_SPDIFIN_OP_CTRL S5P_HDMI_SPDIF_BASE(0x0004)
+#define S5P_HDMI_SPDIFIN_IRQ_MASK S5P_HDMI_SPDIF_BASE(0x0008)
+#define S5P_HDMI_SPDIFIN_IRQ_STATUS S5P_HDMI_SPDIF_BASE(0x000C)
+#define S5P_HDMI_SPDIFIN_CONFIG_1 S5P_HDMI_SPDIF_BASE(0x0010)
+#define S5P_HDMI_SPDIFIN_CONFIG_2 S5P_HDMI_SPDIF_BASE(0x0014)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_1 S5P_HDMI_SPDIF_BASE(0x0020)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_2 S5P_HDMI_SPDIF_BASE(0x0024)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_3 S5P_HDMI_SPDIF_BASE(0x0028)
+#define S5P_HDMI_SPDIFIN_USER_VALUE_4 S5P_HDMI_SPDIF_BASE(0x002C)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_1 S5P_HDMI_SPDIF_BASE(0x0030)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_2 S5P_HDMI_SPDIF_BASE(0x0034)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_3 S5P_HDMI_SPDIF_BASE(0x0038)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_0_4 S5P_HDMI_SPDIF_BASE(0x003C)
+#define S5P_HDMI_SPDIFIN_CH_STATUS_1 S5P_HDMI_SPDIF_BASE(0x0040)
+#define S5P_HDMI_SPDIFIN_FRAME_PERIOD_1 S5P_HDMI_SPDIF_BASE(0x0048)
+#define S5P_HDMI_SPDIFIN_FRAME_PERIOD_2 S5P_HDMI_SPDIF_BASE(0x004C)
+#define S5P_HDMI_SPDIFIN_Pc_INFO_1 S5P_HDMI_SPDIF_BASE(0x0050)
+#define S5P_HDMI_SPDIFIN_Pc_INFO_2 S5P_HDMI_SPDIF_BASE(0x0054)
+#define S5P_HDMI_SPDIFIN_Pd_INFO_1 S5P_HDMI_SPDIF_BASE(0x0058)
+#define S5P_HDMI_SPDIFIN_Pd_INFO_2 S5P_HDMI_SPDIF_BASE(0x005C)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_0_1 S5P_HDMI_SPDIF_BASE(0x0060)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_0_2 S5P_HDMI_SPDIF_BASE(0x0064)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_0_3 S5P_HDMI_SPDIF_BASE(0x0068)
+#define S5P_HDMI_SPDIFIN_USER_BUF_0 S5P_HDMI_SPDIF_BASE(0x006C)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_1_1 S5P_HDMI_SPDIF_BASE(0x0070)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_1_2 S5P_HDMI_SPDIF_BASE(0x0074)
+#define S5P_HDMI_SPDIFIN_DATA_BUF_1_3 S5P_HDMI_SPDIF_BASE(0x0078)
+#define S5P_HDMI_SPDIFIN_USER_BUF_1 S5P_HDMI_SPDIF_BASE(0x007C)
+
+#define S5P_HDMI_I2S_CLK_CON S5P_HDMI_I2S_BASE(0x0000)
+#define S5P_HDMI_I2S_CON_1 S5P_HDMI_I2S_BASE(0x0004)
+#define S5P_HDMI_I2S_CON_2 S5P_HDMI_I2S_BASE(0x0008)
+#define S5P_HDMI_I2S_PIN_SEL_0 S5P_HDMI_I2S_BASE(0x000C)
+#define S5P_HDMI_I2S_PIN_SEL_1 S5P_HDMI_I2S_BASE(0x0010)
+#define S5P_HDMI_I2S_PIN_SEL_2 S5P_HDMI_I2S_BASE(0x0014)
+#define S5P_HDMI_I2S_PIN_SEL_3 S5P_HDMI_I2S_BASE(0x0018)
+#define S5P_HDMI_I2S_DSD_CON S5P_HDMI_I2S_BASE(0x001C)
+#define S5P_HDMI_I2S_MUX_CON S5P_HDMI_I2S_BASE(0x0020)
+#define S5P_HDMI_I2S_CH_ST_CON S5P_HDMI_I2S_BASE(0x0024)
+#define S5P_HDMI_I2S_CH_ST_0 S5P_HDMI_I2S_BASE(0x0028)
+#define S5P_HDMI_I2S_CH_ST_1 S5P_HDMI_I2S_BASE(0x002C)
+#define S5P_HDMI_I2S_CH_ST_2 S5P_HDMI_I2S_BASE(0x0030)
+#define S5P_HDMI_I2S_CH_ST_3 S5P_HDMI_I2S_BASE(0x0034)
+#define S5P_HDMI_I2S_CH_ST_4 S5P_HDMI_I2S_BASE(0x0038)
+#define S5P_HDMI_I2S_CH_ST_SH_0 S5P_HDMI_I2S_BASE(0x003C)
+#define S5P_HDMI_I2S_CH_ST_SH_1 S5P_HDMI_I2S_BASE(0x0040)
+#define S5P_HDMI_I2S_CH_ST_SH_2 S5P_HDMI_I2S_BASE(0x0044)
+#define S5P_HDMI_I2S_CH_ST_SH_3 S5P_HDMI_I2S_BASE(0x0048)
+#define S5P_HDMI_I2S_CH_ST_SH_4 S5P_HDMI_I2S_BASE(0x004C)
+#define S5P_HDMI_I2S_VD_DATA S5P_HDMI_I2S_BASE(0x0050)
+#define S5P_HDMI_I2S_MUX_CH S5P_HDMI_I2S_BASE(0x0054)
+#define S5P_HDMI_I2S_MUX_CUV S5P_HDMI_I2S_BASE(0x0058)
+#define S5P_HDMI_I2S_IRQ_MASK S5P_HDMI_I2S_BASE(0x005C)
+#define S5P_HDMI_I2S_IRQ_STATUS S5P_HDMI_I2S_BASE(0x0060)
+#define S5P_HDMI_I2S_CH0_L_0 S5P_HDMI_I2S_BASE(0x0064)
+#define S5P_HDMI_I2S_CH0_L_1 S5P_HDMI_I2S_BASE(0x0068)
+#define S5P_HDMI_I2S_CH0_L_2 S5P_HDMI_I2S_BASE(0x006C)
+#define S5P_HDMI_I2S_CH0_L_3 S5P_HDMI_I2S_BASE(0x0070)
+#define S5P_HDMI_I2S_CH0_R_0 S5P_HDMI_I2S_BASE(0x0074)
+#define S5P_HDMI_I2S_CH0_R_1 S5P_HDMI_I2S_BASE(0x0078)
+#define S5P_HDMI_I2S_CH0_R_2 S5P_HDMI_I2S_BASE(0x007C)
+#define S5P_HDMI_I2S_CH0_R_3 S5P_HDMI_I2S_BASE(0x0080)
+#define S5P_HDMI_I2S_CH1_L_0 S5P_HDMI_I2S_BASE(0x0084)
+#define S5P_HDMI_I2S_CH1_L_1 S5P_HDMI_I2S_BASE(0x0088)
+#define S5P_HDMI_I2S_CH1_L_2 S5P_HDMI_I2S_BASE(0x008C)
+#define S5P_HDMI_I2S_CH1_L_3 S5P_HDMI_I2S_BASE(0x0090)
+#define S5P_HDMI_I2S_CH1_R_0 S5P_HDMI_I2S_BASE(0x0094)
+#define S5P_HDMI_I2S_CH1_R_1 S5P_HDMI_I2S_BASE(0x0098)
+#define S5P_HDMI_I2S_CH1_R_2 S5P_HDMI_I2S_BASE(0x009C)
+#define S5P_HDMI_I2S_CH1_R_3 S5P_HDMI_I2S_BASE(0x00A0)
+#define S5P_HDMI_I2S_CH2_L_0 S5P_HDMI_I2S_BASE(0x00A4)
+#define S5P_HDMI_I2S_CH2_L_1 S5P_HDMI_I2S_BASE(0x00A8)
+#define S5P_HDMI_I2S_CH2_L_2 S5P_HDMI_I2S_BASE(0x00AC)
+#define S5P_HDMI_I2S_CH2_L_3 S5P_HDMI_I2S_BASE(0x00B0)
+#define S5P_HDMI_I2S_CH2_R_0 S5P_HDMI_I2S_BASE(0x00B4)
+#define S5P_HDMI_I2S_CH2_R_1 S5P_HDMI_I2S_BASE(0x00B8)
+#define S5P_HDMI_I2S_CH2_R_2 S5P_HDMI_I2S_BASE(0x00BC)
+#define S5P_HDMI_I2S_Ch2_R_3 S5P_HDMI_I2S_BASE(0x00C0)
+#define S5P_HDMI_I2S_CH3_L_0 S5P_HDMI_I2S_BASE(0x00C4)
+#define S5P_HDMI_I2S_CH3_L_1 S5P_HDMI_I2S_BASE(0x00C8)
+#define S5P_HDMI_I2S_CH3_L_2 S5P_HDMI_I2S_BASE(0x00CC)
+#define S5P_HDMI_I2S_CH3_R_0 S5P_HDMI_I2S_BASE(0x00D0)
+#define S5P_HDMI_I2S_CH3_R_1 S5P_HDMI_I2S_BASE(0x00D4)
+#define S5P_HDMI_I2S_CH3_R_2 S5P_HDMI_I2S_BASE(0x00D8)
+#define S5P_HDMI_I2S_CUV_L_R S5P_HDMI_I2S_BASE(0x00DC)
+
+#define S5P_HDMI_TG_CMD S5P_HDMI_TG_BASE(0x0000)
+#define S5P_HDMI_TG_H_FSZ_L S5P_HDMI_TG_BASE(0x0018)
+#define S5P_HDMI_TG_H_FSZ_H S5P_HDMI_TG_BASE(0x001C)
+#define S5P_HDMI_TG_HACT_ST_L S5P_HDMI_TG_BASE(0x0020)
+#define S5P_HDMI_TG_HACT_ST_H S5P_HDMI_TG_BASE(0x0024)
+#define S5P_HDMI_TG_HACT_SZ_L S5P_HDMI_TG_BASE(0x0028)
+#define S5P_HDMI_TG_HACT_SZ_H S5P_HDMI_TG_BASE(0x002C)
+#define S5P_HDMI_TG_V_FSZ_L S5P_HDMI_TG_BASE(0x0030)
+#define S5P_HDMI_TG_V_FSZ_H S5P_HDMI_TG_BASE(0x0034)
+#define S5P_HDMI_TG_VSYNC_L S5P_HDMI_TG_BASE(0x0038)
+#define S5P_HDMI_TG_VSYNC_H S5P_HDMI_TG_BASE(0x003C)
+#define S5P_HDMI_TG_VSYNC2_L S5P_HDMI_TG_BASE(0x0040)
+#define S5P_HDMI_TG_VSYNC2_H S5P_HDMI_TG_BASE(0x0044)
+#define S5P_HDMI_TG_VACT_ST_L S5P_HDMI_TG_BASE(0x0048)
+#define S5P_HDMI_TG_VACT_ST_H S5P_HDMI_TG_BASE(0x004C)
+#define S5P_HDMI_TG_VACT_SZ_L S5P_HDMI_TG_BASE(0x0050)
+#define S5P_HDMI_TG_VACT_SZ_H S5P_HDMI_TG_BASE(0x0054)
+#define S5P_HDMI_TG_FIELD_CHG_L S5P_HDMI_TG_BASE(0x0058)
+#define S5P_HDMI_TG_FIELD_CHG_H S5P_HDMI_TG_BASE(0x005C)
+#define S5P_HDMI_TG_VACT_ST2_L S5P_HDMI_TG_BASE(0x0060)
+#define S5P_HDMI_TG_VACT_ST2_H S5P_HDMI_TG_BASE(0x0064)
+
+#define S5P_HDMI_TG_VSYNC_TOP_HDMI_L S5P_HDMI_TG_BASE(0x0078)
+#define S5P_HDMI_TG_VSYNC_TOP_HDMI_H S5P_HDMI_TG_BASE(0x007C)
+#define S5P_HDMI_TG_VSYNC_BOT_HDMI_L S5P_HDMI_TG_BASE(0x0080)
+#define S5P_HDMI_TG_VSYNC_BOT_HDMI_H S5P_HDMI_TG_BASE(0x0084)
+#define S5P_HDMI_TG_FIELD_TOP_HDMI_L S5P_HDMI_TG_BASE(0x0088)
+#define S5P_HDMI_TG_FIELD_TOP_HDMI_H S5P_HDMI_TG_BASE(0x008C)
+#define S5P_HDMI_TG_FIELD_BOT_HDMI_L S5P_HDMI_TG_BASE(0x0090)
+#define S5P_HDMI_TG_FIELD_BOT_HDMI_H S5P_HDMI_TG_BASE(0x0094)
+
+#define S5P_HDMI_EFUSE_CTRL S5P_HDMI_EFUSE_BASE(0x0000)
+#define S5P_HDMI_EFUSE_STATUS S5P_HDMI_EFUSE_BASE(0x0004)
+#define S5P_HDMI_EFUSE_ADDR_WIDTH S5P_HDMI_EFUSE_BASE(0x0008)
+#define S5P_HDMI_EFUSE_SIGDEV_ASSERT S5P_HDMI_EFUSE_BASE(0x000c)
+#define S5P_HDMI_EFUSE_SIGDEV_DEASSERT S5P_HDMI_EFUSE_BASE(0x0010)
+#define S5P_HDMI_EFUSE_PRCHG_ASSERT S5P_HDMI_EFUSE_BASE(0x0014)
+#define S5P_HDMI_EFUSE_PRCHG_DEASSERT S5P_HDMI_EFUSE_BASE(0x0018)
+#define S5P_HDMI_EFUSE_FSET_ASSERT S5P_HDMI_EFUSE_BASE(0x001c)
+#define S5P_HDMI_EFUSE_FSET_DEASSERT S5P_HDMI_EFUSE_BASE(0x0020)
+#define S5P_HDMI_EFUSE_SENSING S5P_HDMI_EFUSE_BASE(0x0024)
+#define S5P_HDMI_EFUSE_SCK_ASSERT S5P_HDMI_EFUSE_BASE(0x0028)
+#define S5P_HDMI_EFUSE_SCK_DEASSERT S5P_HDMI_EFUSE_BASE(0x002c)
+#define S5P_HDMI_EFUSE_SDOUT_OFFSET S5P_HDMI_EFUSE_BASE(0x0030)
+#define S5P_HDMI_EFUSE_READ_OFFSET S5P_HDMI_EFUSE_BASE(0x0034)
+#endif
+
+#define S5P_HDMI_AUI_SZ 5
+#define S5P_HDMI_GCP_SZ 3
+#define S5P_HDMI_SPD_SZ 28
+#define S5P_HDMI_AVI_SZ 13
+#define S5P_HDMI_MPG_SZ 5
+#define S5P_HDMI_GMU_SX 28
+#define S5P_HDMI_ISRC_SZ 16
+#define S5P_HDMI_ACP_SZ 17
+
+/*
+ * Bit definition part
+ */
+
+/* Control Register */
+
+/* INTC_CON */
+#define S5P_HDMI_INTC_ACT_HI (1 << 7)
+#define S5P_HDMI_INTC_ACT_LOW (0 << 7)
+#define S5P_HDMI_INTC_EN_GLOBAL (1 << 6)
+#define S5P_HDMI_INTC_DIS_GLOBAL (0 << 6)
+#define S5P_HDMI_INTC_EN_I2S (1 << 5)
+#define S5P_HDMI_INTC_DIS_I2S (0 << 5)
+#define S5P_HDMI_INTC_EN_CEC (1 << 4)
+#define S5P_HDMI_INTC_DIS_CEC (0 << 4)
+#define S5P_HDMI_INTC_EN_HPD_PLUG (1 << 3)
+#define S5P_HDMI_INTC_DIS_HPD_PLUG (0 << 3)
+#define S5P_HDMI_INTC_EN_HPD_UNPLUG (1 << 2)
+#define S5P_HDMI_INTC_DIS_HPD_UNPLUG (0 << 2)
+#define S5P_HDMI_INTC_EN_SPDIF (1 << 1)
+#define S5P_HDMI_INTC_DIS_SPDIF (0 << 1)
+#define S5P_HDMI_INTC_EN_HDCP (1 << 0)
+#define S5P_HDMI_INTC_DIS_HDCP (0 << 0)
+
+/* INTC_FLAG */
+#define S5P_HDMI_INTC_FLAG_I2S (1 << 5)
+#define S5P_HDMI_INTC_FLAG_CEC (1 << 4)
+#define S5P_HDMI_INTC_FLAG_HPD_PLUG (1 << 3)
+#define S5P_HDMI_INTC_FLAG_HPD_UNPLUG (1 << 2)
+#define S5P_HDMI_INTC_FLAG_SPDIF (1 << 1)
+#define S5P_HDMI_INTC_FLAG_HDCP (1 << 0)
+
+/* HDCP_KEY_LOAD_DONE */
+#define S5P_HDMI_HDCP_KEY_LOAD_DONE (1 << 0)
+
+/* HPD_STATUS */
+#define S5P_HDMI_HPD_PLUGED (1 << 0)
+
+/* AUDIO_CLKSEL */
+#define S5P_HDMI_AUDIO_SPDIF_CLK (1 << 0)
+#define S5P_HDMI_AUDIO_PCLK (0 << 0)
+
+/* HDMI_PHY_RSTOUT */
+#define S5P_HDMI_PHY_SW_RSTOUT (1 << 0)
+
+/* HDMI_PHY_VPLL */
+#define S5P_HDMI_PHY_VPLL_LOCK (1 << 7)
+#define S5P_HDMI_PHY_VPLL_CODE_MASK (0x7 << 0)
+
+/* HDMI_PHY_CMU */
+#define S5P_HDMI_PHY_CMU_LOCK (1 << 7)
+#define S5P_HDMI_PHY_CMU_CODE_MASK (0x7 << 0)
+
+/* HDMI_CORE_RSTOUT */
+#define S5P_HDMI_CORE_SW_RSTOUT (1 << 0)
+
+/* Core Register */
+
+/* HDMI_CON_0 */
+#define S5P_HDMI_BLUE_SCR_EN (1 << 5)
+#define S5P_HDMI_BLUE_SCR_DIS (0 << 5)
+#define S5P_HDMI_ENC_OPTION (1 << 4)
+#define S5P_HDMI_ASP_EN (1 << 2)
+#define S5P_HDMI_ASP_DIS (0 << 2)
+#define S5P_HDMI_PWDN_ENB_NORMAL (1 << 1)
+#define S5P_HDMI_PWDN_ENB_PD (0 << 1)
+#define S5P_HDMI_EN (1 << 0)
+#define S5P_HDMI_DIS (~(1 << 0))
+
+/* HDMI_CON_1 */
+#define S5P_HDMI_PX_LMT_CTRL_BYPASS (0 << 5)
+#define S5P_HDMI_PX_LMT_CTRL_RGB (1 << 5)
+#define S5P_HDMI_PX_LMT_CTRL_YPBPR (2 << 5)
+#define S5P_HDMI_PX_LMT_CTRL_RESERVED (3 << 5)
+#define S5P_HDMI_CON_PXL_REP_RATIO_MASK (1 << 1 | 1 << 0)
+#define S5P_HDMI_DOUBLE_PIXEL_REPETITION (0x01)
+
+/* HDMI_CON_2 */
+#define S5P_HDMI_VID_PREAMBLE_EN (0 << 5)
+#define S5P_HDMI_VID_PREAMBLE_DIS (1 << 5)
+#define S5P_HDMI_GUARD_BAND_EN (0 << 1)
+#define S5P_HDMI_GUARD_BAND_DIS (1 << 1)
+
+/* STATUS */
+#define S5P_HDMI_AUTHEN_ACK_AUTH (1 << 7)
+#define S5P_HDMI_AUTHEN_ACK_NOT (0 << 7)
+#define S5P_HDMI_AUD_FIFO_OVF_FULL (1 << 6)
+#define S5P_HDMI_AUD_FIFO_OVF_NOT (0 << 6)
+#define S5P_HDMI_UPDATE_RI_INT_OCC (1 << 4)
+#define S5P_HDMI_UPDATE_RI_INT_NOT (0 << 4)
+#define S5P_HDMI_UPDATE_RI_INT_CLEAR (1 << 4)
+#define S5P_HDMI_UPDATE_PJ_INT_OCC (1 << 3)
+#define S5P_HDMI_UPDATE_PJ_INT_NOT (0 << 3)
+#define S5P_HDMI_UPDATE_PJ_INT_CLEAR (1 << 3)
+#define S5P_HDMI_WRITE_INT_OCC (1 << 2)
+#define S5P_HDMI_WRITE_INT_NOT (0 << 2)
+#define S5P_HDMI_WRITE_INT_CLEAR (1 << 2)
+#define S5P_HDMI_WATCHDOG_INT_OCC (1 << 1)
+#define S5P_HDMI_WATCHDOG_INT_NOT (0 << 1)
+#define S5P_HDMI_WATCHDOG_INT_CLEAR (1 << 1)
+#define S5P_HDMI_WTFORACTIVERX_INT_OCC (1)
+#define S5P_HDMI_WTFORACTIVERX_INT_NOT (0)
+#define S5P_HDMI_WTFORACTIVERX_INT_CLEAR (1)
+
+/* PHY_STATUS */
+#define S5P_HDMI_PHY_STATUS_READY (1)
+
+/* STATUS_EN */
+#define S5P_HDMI_AUD_FIFO_OVF_EN (1 << 6)
+#define S5P_HDMI_AUD_FIFO_OVF_DIS (0 << 6)
+#define S5P_HDMI_UPDATE_RI_INT_EN (1 << 4)
+#define S5P_HDMI_UPDATE_RI_INT_DIS (0 << 4)
+#define S5P_HDMI_UPDATE_PJ_INT_EN (1 << 3)
+#define S5P_HDMI_UPDATE_PJ_INT_DIS (0 << 3)
+#define S5P_HDMI_WRITE_INT_EN (1 << 2)
+#define S5P_HDMI_WRITE_INT_DIS (0 << 2)
+#define S5P_HDMI_WATCHDOG_INT_EN (1 << 1)
+#define S5P_HDMI_WATCHDOG_INT_DIS (0 << 1)
+#define S5P_HDMI_WTFORACTIVERX_INT_EN (1)
+#define S5P_HDMI_WTFORACTIVERX_INT_DIS (0)
+#define S5P_HDMI_INT_EN_ALL (S5P_HDMI_UPDATE_RI_INT_EN|\
+ S5P_HDMI_UPDATE_PJ_INT_DIS|\
+ S5P_HDMI_WRITE_INT_EN|\
+ S5P_HDMI_WATCHDOG_INT_EN|\
+ S5P_HDMI_WTFORACTIVERX_INT_EN)
+#define S5P_HDMI_INT_DIS_ALL (~0x1F)
+
+/* HPD */
+#define S5P_HDMI_SW_HPD_PLUGGED (1 << 1)
+#define S5P_HDMI_SW_HPD_UNPLUGGED (0 << 1)
+#define S5P_HDMI_HPD_SEL_I_HPD (1)
+#define S5P_HDMI_HPD_SEL_SW_HPD (0)
+
+/* MODE_SEL */
+#define S5P_HDMI_MODE_EN (1 << 1)
+#define S5P_HDMI_MODE_DIS (0 << 1)
+#define S5P_HDMI_DVI_MODE_EN (1)
+#define S5P_HDMI_DVI_MODE_DIS (0)
+
+/* ENC_EN */
+#define S5P_HDMI_HDCP_ENC_ENABLE (1)
+#define S5P_HDMI_HDCP_ENC_DISABLE (0)
+
+/* Video Related Register */
+
+/* BLUESCREEN_0/1/2 */
+
+/* HDMI_YMAX/YMIN/CMAX/CMIN */
+
+/* H_BLANK_0/1 */
+
+/* V_BLANK_0/1/2 */
+
+/* H_V_LINE_0/1/2 */
+
+/* VSYNC_POL */
+#define S5P_HDMI_V_SYNC_POL_ACT_LOW (1)
+#define S5P_HDMI_V_SYNC_POL_ACT_HIGH (0)
+
+/* INT_PRO_MODE */
+#define S5P_HDMI_INTERLACE_MODE (1)
+#define S5P_HDMI_PROGRESSIVE_MODE (0)
+
+/* V_BLANK_F_0/1/2 */
+
+/* H_SYNC_GEN_0/1/2 */
+
+/* V_SYNC_GEN1_0/1/2 */
+
+/* V_SYNC_GEN2_0/1/2 */
+
+/* V_SYNC_GEN3_0/1/2 */
+
+/* Audio Related Packet Register */
+
+/* ASP_CON */
+#define S5P_HDMI_AUD_DST_DOUBLE (1 << 7)
+#define S5P_HDMI_AUD_NO_DST_DOUBLE (0 << 7)
+#define S5P_HDMI_AUD_TYPE_SAMPLE (0 << 5)
+#define S5P_HDMI_AUD_TYPE_ONE_BIT (1 << 5)
+#define S5P_HDMI_AUD_TYPE_HBR (2 << 5)
+#define S5P_HDMI_AUD_TYPE_DST (3 << 5)
+#define S5P_HDMI_AUD_MODE_TWO_CH (0 << 4)
+#define S5P_HDMI_AUD_MODE_MULTI_CH (1 << 4)
+#define S5P_HDMI_AUD_SP_AUD3_EN (1 << 3)
+#define S5P_HDMI_AUD_SP_AUD2_EN (1 << 2)
+#define S5P_HDMI_AUD_SP_AUD1_EN (1 << 1)
+#define S5P_HDMI_AUD_SP_AUD0_EN (1 << 0)
+#define S5P_HDMI_AUD_SP_ALL_DIS (0 << 0)
+
+#define S5P_HDMI_AUD_SET_SP_PRE(x) ((x) & 0xF)
+
+/* ASP_SP_FLAT */
+#define S5P_HDMI_ASP_SP_FLAT_AUD_SAMPLE (0)
+
+/* ASP_CHCFG0/1/2/3 */
+#define S5P_HDMI_SPK3R_SEL_I_PCM0L (0 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM0R (1 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM1L (2 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM1R (3 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM2L (4 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM2R (5 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM3L (6 << 27)
+#define S5P_HDMI_SPK3R_SEL_I_PCM3R (7 << 27)
+#define S5P_HDMI_SPK3L_SEL_I_PCM0L (0 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM0R (1 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM1L (2 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM1R (3 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM2L (4 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM2R (5 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM3L (6 << 24)
+#define S5P_HDMI_SPK3L_SEL_I_PCM3R (7 << 24)
+#define S5P_HDMI_SPK2R_SEL_I_PCM0L (0 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM0R (1 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM1L (2 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM1R (3 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM2L (4 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM2R (5 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM3L (6 << 19)
+#define S5P_HDMI_SPK2R_SEL_I_PCM3R (7 << 19)
+#define S5P_HDMI_SPK2L_SEL_I_PCM0L (0 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM0R (1 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM1L (2 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM1R (3 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM2L (4 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM2R (5 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM3L (6 << 16)
+#define S5P_HDMI_SPK2L_SEL_I_PCM3R (7 << 16)
+#define S5P_HDMI_SPK1R_SEL_I_PCM0L (0 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM0R (1 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM1L (2 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM1R (3 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM2L (4 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM2R (5 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM3L (6 << 11)
+#define S5P_HDMI_SPK1R_SEL_I_PCM3R (7 << 11)
+#define S5P_HDMI_SPK1L_SEL_I_PCM0L (0 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM0R (1 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM1L (2 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM1R (3 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM2L (4 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM2R (5 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM3L (6 << 8)
+#define S5P_HDMI_SPK1L_SEL_I_PCM3R (7 << 8)
+#define S5P_HDMI_SPK0R_SEL_I_PCM0L (0 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM0R (1 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM1L (2 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM1R (3 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM2L (4 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM2R (5 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM3L (6 << 3)
+#define S5P_HDMI_SPK0R_SEL_I_PCM3R (7 << 3)
+#define S5P_HDMI_SPK0L_SEL_I_PCM0L (0)
+#define S5P_HDMI_SPK0L_SEL_I_PCM0R (1)
+#define S5P_HDMI_SPK0L_SEL_I_PCM1L (2)
+#define S5P_HDMI_SPK0L_SEL_I_PCM1R (3)
+#define S5P_HDMI_SPK0L_SEL_I_PCM2L (4)
+#define S5P_HDMI_SPK0L_SEL_I_PCM2R (5)
+#define S5P_HDMI_SPK0L_SEL_I_PCM3L (6)
+#define S5P_HDMI_SPK0L_SEL_I_PCM3R (7)
+
+/* ACR_CON */
+#define S5P_HDMI_ALT_CTS_RATE_CTS_1 (0 << 3)
+#define S5P_HDMI_ALT_CTS_RATE_CTS_11 (1 << 3)
+#define S5P_HDMI_ALT_CTS_RATE_CTS_21 (2 << 3)
+#define S5P_HDMI_ALT_CTS_RATE_CTS_31 (3 << 3)
+#define S5P_HDMI_ACR_TX_MODE_NO_TX (0)
+#define S5P_HDMI_ACR_TX_MODE_TX_ONCE (1)
+#define S5P_HDMI_ACR_TX_MODE_TXCNT_VBI (2)
+#define S5P_HDMI_ACR_TX_MODE_TX_VPC (3)
+#define S5P_HDMI_ACR_TX_MODE_MESURE_CTS (4)
+
+/* ACR_MCTS0/1/2 */
+
+/* ACR_CTS0/1/2 */
+
+/* ACR_N0/1/2 */
+
+/* ACR_LSB2 */
+#define S5P_HDMI_ACR_LSB2_MASK (0xFF)
+
+/* ACR_TXCNT */
+#define S5P_HDMI_ACR_TXCNT_MASK (0x1F)
+
+/* ACR_TXINTERNAL */
+#define S5P_HDMI_ACR_TX_INTERNAL_MASK (0xFF)
+
+/* ACR_CTS_OFFSET */
+#define S5P_HDMI_ACR_CTS_OFFSET_MASK (0xFF)
+
+/* GCP_CON */
+#define S5P_HDMI_GCP_CON_EN_1ST_VSYNC (1 << 3)
+#define S5P_HDMI_GCP_CON_EN_2ST_VSYNC (1 << 2)
+#define S5P_HDMI_GCP_CON_TRANS_EVERY_VSYNC (2)
+#define S5P_HDMI_GCP_CON_NO_TRAN (0)
+#define S5P_HDMI_GCP_CON_TRANS_ONCE (1)
+#define S5P_HDMI_GCP_CON_TRANS_EVERY_VSYNC (2)
+
+/* GCP_BYTE1 */
+#define S5P_HDMI_GCP_BYTE1_MASK (0xFF)
+
+/* GCP_BYTE2 */
+#define S5P_HDMI_GCP_BYTE2_PP_MASK (0xF << 4)
+#define S5P_HDMI_GCP_24BPP (1 << 2)
+#define S5P_HDMI_GCP_30BPP (1 << 0 | 1 << 2)
+#define S5P_HDMI_GCP_36BPP (1 << 1 | 1 << 2)
+#define S5P_HDMI_GCP_48BPP (1 << 0 | 1 << 1 | 1 << 2)
+
+/* GCP_BYTE3 */
+#define S5P_HDMI_GCP_BYTE3_MASK (0xFF)
+
+/* ACP Packet Register */
+
+/* ACP_CON */
+#define S5P_HDMI_ACP_FR_RATE_MASK (0x1F << 3)
+#define S5P_HDMI_ACP_CON_NO_TRAN (0)
+#define S5P_HDMI_ACP_CON_TRANS_ONCE (1)
+#define S5P_HDMI_ACP_CON_TRANS_EVERY_VSYNC (2)
+
+/* ACP_TYPE */
+#define S5P_HDMI_ACP_TYPE_MASK (0xFF)
+
+/* ACP_DATA00~16 */
+#define S5P_HDMI_ACP_DATA_MASK (0xFF)
+
+/* ISRC1/2 Packet Register */
+
+/* ISRC_CON */
+#define S5P_HDMI_ISRC_FR_RATE_MASK (0x1F << 3)
+#define S5P_HDMI_ISRC_EN (1 << 2)
+#define S5P_HDMI_ISRC_DIS (0 << 2)
+
+/* ISRC1_HEADER1 */
+#define S5P_HDMI_ISRC1_HEADER_MASK (0xFF)
+
+/* ISRC1_DATA 00~15 */
+#define S5P_HDMI_ISRC1_DATA_MASK (0xFF)
+
+/* ISRC2_DATA 00~15 */
+#define S5P_HDMI_ISRC2_DATA_MASK (0xFF)
+
+/* AVI InfoFrame Register */
+
+/* AVI_CON */
+
+/* AVI_CHECK_SUM */
+
+/* AVI_DATA01~13 */
+#define S5P_HDMI_AVI_PIXEL_REPETITION_DOUBLE (1<<0)
+#define S5P_HDMI_AVI_PICTURE_ASPECT_4_3 (1<<4)
+#define S5P_HDMI_AVI_PICTURE_ASPECT_16_9 (1<<5)
+
+/* Audio InfoFrame Register */
+
+/* AUI_CON */
+
+/* AUI_CHECK_SUM */
+
+/* AUI_DATA1~5 */
+
+/* MPEG Source InfoFrame registers */
+
+/* MPG_CON */
+
+/* HDMI_MPG_CHECK_SUM */
+
+/* MPG_DATA1~5 */
+
+/* Source Product Descriptor Infoframe registers */
+
+/* SPD_CON */
+
+/* SPD_HEADER0/1/2 */
+
+/* SPD_DATA0~27 */
+
+/* HDCP Register */
+
+/* HDCP_SHA1_00~19 */
+
+/* HDCP_KSV_LIST_0~4 */
+
+/* HDCP_KSV_LIST_CON */
+#define S5P_HDMI_HDCP_KSV_WRITE_DONE (0x1 << 3)
+#define S5P_HDMI_HDCP_KSV_LIST_EMPTY (0x1 << 2)
+#define S5P_HDMI_HDCP_KSV_END (0x1 << 1)
+#define S5P_HDMI_HDCP_KSV_READ (0x1 << 0)
+
+/* HDCP_CTRL1 */
+#define S5P_HDMI_HDCP_EN_PJ_EN (1 << 4)
+#define S5P_HDMI_HDCP_EN_PJ_DIS (~(1 << 4))
+#define S5P_HDMI_HDCP_SET_REPEATER_TIMEOUT (1 << 2)
+#define S5P_HDMI_HDCP_CLEAR_REPEATER_TIMEOUT (~(1 << 2))
+#define S5P_HDMI_HDCP_CP_DESIRED_EN (1 << 1)
+#define S5P_HDMI_HDCP_CP_DESIRED_DIS (~(1 << 1))
+#define S5P_HDMI_HDCP_ENABLE_1_1_FEATURE_EN (1)
+#define S5P_HDMI_HDCP_ENABLE_1_1_FEATURE_DIS (~(1))
+
+/* HDCP_CHECK_RESULT */
+#define S5P_HDMI_HDCP_Pi_MATCH_RESULT_Y ((0x1 << 3) | (0x1 << 2))
+#define S5P_HDMI_HDCP_Pi_MATCH_RESULT_N ((0x1 << 3) | (0x0 << 2))
+#define S5P_HDMI_HDCP_Ri_MATCH_RESULT_Y ((0x1 << 1) | (0x1 << 0))
+#define S5P_HDMI_HDCP_Ri_MATCH_RESULT_N ((0x1 << 1) | (0x0 << 0))
+#define S5P_HDMI_HDCP_CLR_ALL_RESULTS (0)
+
+/* HDCP_BKSV0~4 */
+/* HDCP_AKSV0~4 */
+
+/* HDCP_BCAPS */
+#define S5P_HDMI_HDCP_BCAPS_REPEATER (1 << 6)
+#define S5P_HDMI_HDCP_BCAPS_READY (1 << 5)
+#define S5P_HDMI_HDCP_BCAPS_FAST (1 << 4)
+#define S5P_HDMI_HDCP_BCAPS_1_1_FEATURES (1 << 1)
+#define S5P_HDMI_HDCP_BCAPS_FAST_REAUTH (1)
+
+/* HDCP_BSTATUS_0/1 */
+/* HDCP_Ri_0/1 */
+/* HDCP_I2C_INT */
+/* HDCP_AN_INT */
+/* HDCP_WATCHDOG_INT */
+/* HDCP_RI_INT/1 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_1 */
+/* HDCP_Frame_Count */
+
+/* Gamut Metadata Packet Register */
+
+/* GAMUT_CON */
+/* GAMUT_HEADER0 */
+/* GAMUT_HEADER1 */
+/* GAMUT_HEADER2 */
+/* GAMUT_METADATA0~27 */
+
+/* Video Mode Register */
+
+/* VIDEO_PATTERN_GEN */
+/* HPD_GEN */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+
+/* SPDIF Register */
+
+/* SPDIFIN_CLK_CTRL */
+#define S5P_HDMI_SPDIFIN_READY_CLK_DOWN (1 << 1)
+#define S5P_HDMI_SPDIFIN_CLK_ON (1)
+
+/* SPDIFIN_OP_CTRL */
+#define S5P_HDMI_SPDIFIN_SW_RESET (0)
+#define S5P_HDMI_SPDIFIN_STATUS_CHECK_MODE (1)
+#define S5P_HDMI_SPDIFIN_STATUS_CHK_OP_MODE (3)
+
+/* SPDIFIN_IRQ_MASK */
+
+/* SPDIFIN_IRQ_STATUS */
+#define S5P_HDMI_SPDIFIN_IRQ_OVERFLOW_EN (1 << 7)
+#define S5P_HDMI_SPDIFIN_IRQ_ABNORMAL_PD_EN (1 << 6)
+#define S5P_HDMI_SPDIFIN_IRQ_SH_NOT_DETECTED_RIGHTTIME_EN (1 << 5)
+#define S5P_HDMI_SPDIFIN_IRQ_SH_DETECTED_EN (1 << 4)
+#define S5P_HDMI_SPDIFIN_IRQ_SH_NOT_DETECTED_EN (1 << 3)
+#define S5P_HDMI_SPDIFIN_IRQ_WRONG_PREAMBLE_EN (1 << 2)
+#define S5P_HDMI_SPDIFIN_IRQ_CH_STATUS_RECOVERED_EN (1 << 1)
+#define S5P_HDMI_SPDIFIN_IRQ_WRONG_SIG_EN (1 << 0)
+
+/* SPDIFIN_CONFIG_1 */
+#define S5P_HDMI_SPDIFIN_CFG_FILTER_3_SAMPLE (0 << 6)
+#define S5P_HDMI_SPDIFIN_CFG_FILTER_2_SAMPLE (1 << 6)
+#define S5P_HDMI_SPDIFIN_CFG_LINEAR_PCM_TYPE (0 << 5)
+#define S5P_HDMI_SPDIFIN_CFG_NO_LINEAR_PCM_TYPE (1 << 5)
+#define S5P_HDMI_SPDIFIN_CFG_PCPD_AUTO_SET (0 << 4)
+#define S5P_HDMI_SPDIFIN_CFG_PCPD_MANUAL_SET (1 << 4)
+#define S5P_HDMI_SPDIFIN_CFG_WORD_LENGTH_A_SET (0 << 3)
+#define S5P_HDMI_SPDIFIN_CFG_WORD_LENGTH_M_SET (1 << 3)
+#define S5P_HDMI_SPDIFIN_CFG_U_V_C_P_NEGLECT (0 << 2)
+#define S5P_HDMI_SPDIFIN_CFG_U_V_C_P_REPORT (1 << 2)
+#define S5P_HDMI_SPDIFIN_CFG_BURST_SIZE_1 (0 << 1)
+#define S5P_HDMI_SPDIFIN_CFG_BURST_SIZE_2 (1 << 1)
+#define S5P_HDMI_SPDIFIN_CFG_DATA_ALIGN_16BIT (0 << 0)
+#define S5P_HDMI_SPDIFIN_CFG_DATA_ALIGN_32BIT (1 << 0)
+
+/* SPDIFIN_CONFIG_2 */
+#define S5P_HDMI_SPDIFIN_CFG2_NO_CLK_DIV (0)
+
+/* SPDIFIN_USER_VALUE_1 */
+/* SPDIFIN_USER_VALUE_2 */
+/* SPDIFIN_USER_VALUE_3 */
+/* SPDIFIN_USER_VALUE_4 */
+/* SPDIFIN_CH_STATUS_0_1 */
+/* SPDIFIN_CH_STATUS_0_2 */
+/* SPDIFIN_CH_STATUS_0_3 */
+/* SPDIFIN_CH_STATUS_0_4 */
+/* SPDIFIN_CH_STATUS_1 */
+/* SPDIFIN_FRAME_PERIOD_1 */
+/* SPDIFIN_FRAME_PERIOD_2 */
+/* SPDIFIN_PC_INFO_1 */
+/* SPDIFIN_PC_INFO_2 */
+/* SPDIFIN_PD_INFO_1 */
+/* SPDIFIN_PD_INFO_2 */
+/* SPDIFIN_DATA_BUF_0_1 */
+/* SPDIFIN_DATA_BUF_0_2 */
+/* SPDIFIN_DATA_BUF_0_3 */
+/* SPDIFIN_USER_BUF_0 */
+/* SPDIFIN_USER_BUF_1_1 */
+/* SPDIFIN_USER_BUF_1_2 */
+/* SPDIFIN_USER_BUF_1_3 */
+/* SPDIFIN_USER_BUF_1 */
+
+/* I2S Register */
+
+/* I2S_CLK_CON */
+#define S5P_HDMI_I2S_CLK_DIS (0)
+#define S5P_HDMI_I2S_CLK_EN (1)
+
+/* I2S_CON_1 */
+#define S5P_HDMI_I2S_SCLK_FALLING_EDGE (0 << 1)
+#define S5P_HDMI_I2S_SCLK_RISING_EDGE (1 << 1)
+#define S5P_HDMI_I2S_L_CH_LOW_POL (0)
+#define S5P_HDMI_I2S_L_CH_HIGH_POL (1)
+
+/* I2S_CON_2 */
+#define S5P_HDMI_I2S_MSB_FIRST_MODE (0 << 6)
+#define S5P_HDMI_I2S_LSB_FIRST_MODE (1 << 6)
+#define S5P_HDMI_I2S_BIT_CH_32FS (0 << 4)
+#define S5P_HDMI_I2S_BIT_CH_48FS (1 << 4)
+#define S5P_HDMI_I2S_BIT_CH_RESERVED (2 << 4)
+#define S5P_HDMI_I2S_SDATA_16BIT (1 << 2)
+#define S5P_HDMI_I2S_SDATA_20BIT (2 << 2)
+#define S5P_HDMI_I2S_SDATA_24BIT (3 << 2)
+#define S5P_HDMI_I2S_BASIC_FORMAT (0)
+#define S5P_HDMI_I2S_L_JUST_FORMAT (2)
+#define S5P_HDMI_I2S_R_JUST_FORMAT (3)
+#define S5P_HDMI_I2S_CON_2_CLR (~(0xFF))
+#define S5P_HDMI_I2S_SET_BIT_CH(x) (((x) & 0x7) << 4)
+#define S5P_HDMI_I2S_SET_SDATA_BIT(x) (((x) & 0x7) << 2)
+
+/* I2S_PIN_SEL_0 */
+#define S5P_HDMI_I2S_SEL_SCLK(x) (((x) & 0x7) << 4)
+#define S5P_HDMI_I2S_SEL_SCLK_DEFAULT_1 (0x7 << 4)
+#define S5P_HDMI_I2S_SEL_LRCK(x) ((x) & 0x7)
+#define S5P_HDMI_I2S_SEL_LRCK_DEFAULT_0 (0x7)
+
+/* I2S_PIN_SEL_1 */
+#define S5P_HDMI_I2S_SEL_SDATA1(x) (((x) & 0x7) << 4)
+#define S5P_HDMI_I2S_SEL_SDATA1_DEFAULT_3 (0x7 << 4)
+#define S5P_HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7)
+#define S5P_HDMI_I2S_SEL_SDATA2_DEFAULT_2 (0x7)
+
+/* I2S_PIN_SEL_2 */
+#define S5P_HDMI_I2S_SEL_SDATA3(x) (((x) & 0x7) << 4)
+#define S5P_HDMI_I2S_SEL_SDATA3_DEFAULT_5 (0x7 << 4)
+#define S5P_HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7)
+#define S5P_HDMI_I2S_SEL_SDATA2_DEFAULT_4 (0x7)
+
+/* I2S_PIN_SEL_3 */
+#define S5P_HDMI_I2S_SEL_DSD(x) ((x) & 0x7)
+#define S5P_HDMI_I2S_SEL_DSD_DEFAULT_6 (0x7)
+
+/* I2S_DSD_CON */
+#define S5P_HDMI_I2S_DSD_CLK_RI_EDGE (1 << 1)
+#define S5P_HDMI_I2S_DSD_CLK_FA_EDGE (0 << 1)
+#define S5P_HDMI_I2S_DSD_ENABLE (1)
+#define S5P_HDMI_I2S_DSD_DISABLE (0)
+
+/* I2S_MUX_CON */
+#define S5P_HDMI_I2S_NOISE_FILTER_ZERO (0 << 5)
+#define S5P_HDMI_I2S_NOISE_FILTER_2_STAGE (1 << 5)
+#define S5P_HDMI_I2S_NOISE_FILTER_3_STAGE (2 << 5)
+#define S5P_HDMI_I2S_NOISE_FILTER_4_STAGE (3 << 5)
+#define S5P_HDMI_I2S_NOISE_FILTER_5_STAGE (4 << 5)
+#define S5P_HDMI_I2S_IN_DISABLE (1 << 4)
+#define S5P_HDMI_I2S_IN_ENABLE (0 << 4)
+#define S5P_HDMI_I2S_AUD_SPDIF (0 << 2)
+#define S5P_HDMI_I2S_AUD_I2S (1 << 2)
+#define S5P_HDMI_I2S_AUD_DSD (2 << 2)
+#define S5P_HDMI_I2S_CUV_SPDIF_ENABLE (0 << 1)
+#define S5P_HDMI_I2S_CUV_I2S_ENABLE (1 << 1)
+#define S5P_HDMI_I2S_MUX_DISABLE (0)
+#define S5P_HDMI_I2S_MUX_ENABLE (1)
+#define S5P_HDMI_I2S_MUX_CON_CLR (~(0xFF))
+
+/* I2S_CH_ST_CON */
+#define S5P_HDMI_I2S_CH_STATUS_RELOAD (1)
+#define S5P_HDMI_I2S_CH_ST_CON_CLR (~(1))
+
+/* I2S_CH_ST_0 / I2S_CH_ST_SH_0 */
+#define S5P_HDMI_I2S_CH_STATUS_MODE_0 (0 << 6)
+#define S5P_HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH (0 << 3)
+#define S5P_HDMI_I2S_2AUD_CH_WITH_PREEMPH (1 << 3)
+#define S5P_HDMI_I2S_DEFAULT_EMPHASIS (0 << 3)
+#define S5P_HDMI_I2S_COPYRIGHT (0 << 2)
+#define S5P_HDMI_I2S_NO_COPYRIGHT (1 << 2)
+#define S5P_HDMI_I2S_LINEAR_PCM (0 << 1)
+#define S5P_HDMI_I2S_NO_LINEAR_PCM (1 << 1)
+#define S5P_HDMI_I2S_CONSUMER_FORMAT (0)
+#define S5P_HDMI_I2S_PROF_FORMAT (1)
+#define S5P_HDMI_I2S_CH_ST_0_CLR (~(0xFF))
+
+/* I2S_CH_ST_1 / I2S_CH_ST_SH_1 */
+#define S5P_HDMI_I2S_CD_PLAYER (0x00)
+#define S5P_HDMI_I2S_DAT_PLAYER (0x03)
+#define S5P_HDMI_I2S_DCC_PLAYER (0x43)
+#define S5P_HDMI_I2S_MINI_DISC_PLAYER (0x49)
+
+/* I2S_CH_ST_2 / I2S_CH_ST_SH_2 */
+#define S5P_HDMI_I2S_CHANNEL_NUM_MASK (0xF << 4)
+#define S5P_HDMI_I2S_SOURCE_NUM_MASK (0xF)
+#define S5P_HDMI_I2S_SET_CHANNEL_NUM(x) (((x) & (0xF)) << 4)
+#define S5P_HDMI_I2S_SET_SOURCE_NUM(x) ((x) & (0xF))
+
+/* I2S_CH_ST_3 / I2S_CH_ST_SH_3 */
+#define S5P_HDMI_I2S_CLK_ACCUR_LEVEL_1 (1 << 4)
+#define S5P_HDMI_I2S_CLK_ACCUR_LEVEL_2 (0 << 4)
+#define S5P_HDMI_I2S_CLK_ACCUR_LEVEL_3 (2 << 4)
+#define S5P_HDMI_I2S_SAMPLING_FREQ_44_1 (0x0)
+#define S5P_HDMI_I2S_SAMPLING_FREQ_48 (0x2)
+#define S5P_HDMI_I2S_SAMPLING_FREQ_32 (0x3)
+#define S5P_HDMI_I2S_SAMPLING_FREQ_96 (0xA)
+#define S5P_HDMI_I2S_SET_SAMPLING_FREQ(x) ((x) & (0xF))
+
+/* I2S_CH_ST_4 / I2S_CH_ST_SH_4 */
+#define S5P_HDMI_I2S_ORG_SAMPLING_FREQ_44_1 (0xF << 4)
+#define S5P_HDMI_I2S_ORG_SAMPLING_FREQ_88_2 (0x7 << 4)
+#define S5P_HDMI_I2S_ORG_SAMPLING_FREQ_22_05 (0xB << 4)
+#define S5P_HDMI_I2S_ORG_SAMPLING_FREQ_176_4 (0x3 << 4)
+#define S5P_HDMI_I2S_WORD_LENGTH_NOT_DEFINE (0x0 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX24_20BITS (0x1 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX24_22BITS (0x2 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX24_23BITS (0x4 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX24_24BITS (0x5 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX24_21BITS (0x6 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX20_16BITS (0x1 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX20_18BITS (0x2 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX20_19BITS (0x4 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX20_20BITS (0x5 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX20_17BITS (0x6 << 1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX_24BITS (1)
+#define S5P_HDMI_I2S_WORD_LENGTH_MAX_20BITS (0)
+
+/* I2S_VD_DATA */
+#define S5P_HDMI_I2S_VD_AUD_SAMPLE_RELIABLE (0)
+#define S5P_HDMI_I2S_VD_AUD_SAMPLE_UNRELIABLE (1)
+
+/* I2S_MUX_CH */
+#define S5P_HDMI_I2S_CH3_R_EN (1 << 7)
+#define S5P_HDMI_I2S_CH3_L_EN (1 << 6)
+#define S5P_HDMI_I2S_CH3_EN (3 << 6)
+#define S5P_HDMI_I2S_CH2_R_EN (1 << 5)
+#define S5P_HDMI_I2S_CH2_L_EN (1 << 4)
+#define S5P_HDMI_I2S_CH2_EN (3 << 4)
+#define S5P_HDMI_I2S_CH1_R_EN (1 << 3)
+#define S5P_HDMI_I2S_CH1_L_EN (1 << 2)
+#define S5P_HDMI_I2S_CH1_EN (3 << 2)
+#define S5P_HDMI_I2S_CH0_R_EN (1 << 1)
+#define S5P_HDMI_I2S_CH0_L_EN (1)
+#define S5P_HDMI_I2S_CH0_EN (3)
+#define S5P_HDMI_I2S_CH_ALL_EN (0xFF)
+#define S5P_HDMI_I2S_MUX_CH_CLR (~S5P_HDMI_I2S_CH_ALL_EN)
+
+/* I2S_MUX_CUV */
+#define S5P_HDMI_I2S_CUV_R_EN (1 << 1)
+#define S5P_HDMI_I2S_CUV_L_EN (1)
+#define S5P_HDMI_I2S_CUV_RL_EN (0x03)
+
+/* I2S_IRQ_MASK */
+#define S5P_HDMI_I2S_INT2_DIS (0 << 1)
+#define S5P_HDMI_I2S_INT2_EN (1 << 1)
+
+/* I2S_IRQ_STATUS */
+#define S5P_HDMI_I2S_INT2_STATUS (1 << 1)
+
+/* I2S_CH0_L_0 */
+/* I2S_CH0_L_1 */
+/* I2S_CH0_L_2 */
+/* I2S_CH0_L_3 */
+/* I2S_CH0_R_0 */
+/* I2S_CH0_R_1 */
+/* I2S_CH0_R_2 */
+/* I2S_CH0_R_3 */
+/* I2S_CH1_L_0 */
+/* I2S_CH1_L_1 */
+/* I2S_CH1_L_2 */
+/* I2S_CH1_L_3 */
+/* I2S_CH1_R_0 */
+/* I2S_CH1_R_1 */
+/* I2S_CH1_R_2 */
+/* I2S_CH1_R_3 */
+/* I2S_CH2_L_0 */
+/* I2S_CH2_L_1 */
+/* I2S_CH2_L_2 */
+/* I2S_CH2_L_3 */
+/* I2S_CH2_R_0 */
+/* I2S_CH2_R_1 */
+/* I2S_CH2_R_2 */
+/* I2S_Ch2_R_3 */
+/* I2S_CH3_L_0 */
+/* I2S_CH3_L_1 */
+/* I2S_CH3_L_2 */
+/* I2S_CH3_R_0 */
+/* I2S_CH3_R_1 */
+/* I2S_CH3_R_2 */
+
+/* I2S_CUV_L_R */
+#define S5P_HDMI_I2S_CUV_R_DATA_MASK (0x7 << 4)
+#define S5P_HDMI_I2S_CUV_L_DATA_MASK (0x7)
+
+/* Timing Generator Register */
+/* TG_CMD */
+#define S5P_HDMI_GETSYNC_TYPE (1 << 4)
+#define S5P_HDMI_GETSYNC (1 << 3)
+#define S5P_HDMI_FIELD (1 << 1)
+#define S5P_HDMI_TG (1)
+
+/* TG_CFG */
+/* TG_CB_SZ */
+/* TG_INDELAY_L */
+/* TG_INDELAY_H */
+/* TG_POL_CTRL */
+
+/* TG_H_FSZ_L */
+/* TG_H_FSZ_H */
+/* TG_HACT_ST_L */
+/* TG_HACT_ST_H */
+/* TG_HACT_SZ_L */
+/* TG_HACT_SZ_H */
+/* TG_V_FSZ_L */
+/* TG_V_FSZ_H */
+/* TG_VSYNC_L */
+/* TG_VSYNC_H */
+/* TG_VSYNC2_L */
+/* TG_VSYNC2_H */
+/* TG_VACT_ST_L */
+/* TG_VACT_ST_H */
+/* TG_VACT_SZ_L */
+/* TG_VACT_SZ_H */
+/* TG_FIELD_CHG_L */
+/* TG_FIELD_CHG_H */
+/* TG_VACT_ST2_L */
+/* TG_VACT_ST2_H */
+/* TG_VACT_SC_ST_L */
+/* TG_VACT_SC_ST_H */
+/* TG_VACT_SC_SZ_L */
+/* TG_VACT_SC_SZ_H */
+
+/* TG_VSYNC_TOP_HDMI_L */
+/* TG_VSYNC_TOP_HDMI_H */
+/* TG_VSYNC_BOT_HDMI_L */
+/* TG_VSYNC_BOT_HDMI_H */
+/* TG_FIELD_TOP_HDMI_L */
+/* TG_FIELD_TOP_HDMI_H */
+/* TG_FIELD_BOT_HDMI_L */
+/* TG_FIELD_BOT_HDMI_H */
+/* TG_HSYNC_HDOUT_ST_L */
+/* TG_HSYNC_HDOUT_ST_H */
+/* TG_HSYNC_HDOUT_END_L */
+/* TG_HSYNC_HDOUT_END_H */
+/* TG_VSYNC_HDOUT_ST_L */
+/* TG_VSYNC_HDOUT_ST_H */
+/* TG_VSYNC_HDOUT_END_L */
+/* TG_VSYNC_HDOUT_END_H */
+/* TG_VSYNC_HDOUT_DLY_L */
+/* TG_VSYNC_HDOUT_DLY_H */
+/* TG_BT_ERR_RANGE */
+/* TG_BT_ERR_RESULT */
+/* TG_COR_THR */
+/* TG_COR_NUM */
+/* TG_BT_CON */
+/* TG_BT_H_FSZ_L */
+/* TG_BT_H_FSZ_H */
+/* TG_BT_HSYNC_ST */
+/* TG_BT_HSYNC_SZ */
+/* TG_BT_FSZ_L */
+/* TG_BT_FSZ_H */
+/* TG_BT_VACT_T_ST_L */
+/* TG_BT_VACT_T_ST_H */
+/* TG_BT_VACT_B_ST_L */
+/* TG_BT_VACT_B_ST_H */
+/* TG_BT_VACT_SZ_L */
+/* TG_BT_VACT_SZ_H */
+/* TG_BT_VSYNC_SZ */
+
+/* HDCP E-FUSE Control Register */
+/* HDCP_E_FUSE_CTRL */
+#define S5P_HDMI_EFUSE_CTRL_HDCP_KEY_READ (1)
+
+/* HDCP_E_FUSE_STATUS */
+#define S5P_HDMI_EFUSE_ECC_FAIL (1 << 2)
+#define S5P_HDMI_EFUSE_ECC_BUSY (1 << 1)
+#define S5P_HDMI_EFUSE_ECC_DONE (1)
+
+/* EFUSE_ADDR_WIDTH */
+/* EFUSE_SIGDEV_ASSERT */
+/* EFUSE_SIGDEV_DE-ASSERT */
+/* EFUSE_PRCHG_ASSERT */
+/* EFUSE_PRCHG_DE-ASSERT */
+/* EFUSE_FSET_ASSERT */
+/* EFUSE_FSET_DE-ASSERT */
+/* EFUSE_SENSING */
+/* EFUSE_SCK_ASSERT */
+/* EFUSE_SCK_DEASSERT */
+/* EFUSE_SDOUT_OFFSET */
+/* EFUSE_READ_OFFSET */
+
+/* HDCP_SHA_RESULT */
+#define S5P_HDMI_HDCP_SHA_VALID_NO_RD (0 << 1)
+#define S5P_HDMI_HDCP_SHA_VALID_RD (1 << 1)
+#define S5P_HDMI_HDCP_SHA_VALID (1)
+#define S5P_HDMI_HDCP_SHA_NO_VALID (0)
+
+/* DC_CONTRAL */
+#define S5P_HDMI_DC_CTL_12 (1 << 1)
+#define S5P_HDMI_DC_CTL_8 (0)
+#define S5P_HDMI_DC_CTL_10 (1)
+#endif /* __ARCH_ARM_REGS_HDMI_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-iem.h b/arch/arm/mach-exynos/include/mach/regs-iem.h
new file mode 100644
index 0000000..d9bf177
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-iem.h
@@ -0,0 +1,27 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-iem.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - IEM(INTELLIGENT ENERGY MANAGEMENT) register discription
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IEM_H
+#define __ASM_ARCH_REGS_IEM_H __FILE__
+
+/* Register for IEC */
+#define EXYNOS4_IECDPCCR (0x00000)
+
+/* Register for APC */
+#define EXYNOS4_APC_CONTROL (0x10010)
+#define EXYNOS4_APC_PREDLYSEL (0x10024)
+#define EXYNOS4_APC_DBG_DLYCODE (0x100E0)
+
+#define APC_HPM_EN (1 << 4)
+#define IEC_EN (1 << 0)
+
+#endif /* __ASM_ARCH_REGS_IEM_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-irq.h b/arch/arm/mach-exynos/include/mach/regs-irq.h
index 9c7b4bf..d2653c1 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-irq.h
+++ b/arch/arm/mach-exynos/include/mach/regs-irq.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-irq.h
+/* linux/arch/arm/mach-exynos/include/mach/regs-irq.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos/include/mach/regs-mct.h
index ca9c843..96cf40a 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-mct.h
+++ b/arch/arm/mach-exynos/include/mach/regs-mct.h
@@ -1,4 +1,4 @@
-/* arch/arm/mach-exynos4/include/mach/regs-mct.h
+/* arch/arm/mach-exynos/include/mach/regs-mct.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -31,8 +31,9 @@
#define EXYNOS4_MCT_G_INT_ENB EXYNOS4_MCTREG(0x248)
#define EXYNOS4_MCT_G_WSTAT EXYNOS4_MCTREG(0x24C)
-#define EXYNOS4_MCT_L0_BASE EXYNOS4_MCTREG(0x300)
-#define EXYNOS4_MCT_L1_BASE EXYNOS4_MCTREG(0x400)
+#define _EXYNOS4_MCT_L_BASE EXYNOS4_MCTREG(0x300)
+#define EXYNOS4_MCT_L_BASE(x) (_EXYNOS4_MCT_L_BASE + (0x100 * x))
+#define EXYNOS4_MCT_L_MASK (0xffffff00)
#define MCT_L_TCNTB_OFFSET (0x00)
#define MCT_L_ICNTB_OFFSET (0x08)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mem.h b/arch/arm/mach-exynos/include/mach/regs-mem.h
index 0368b5a..23eb23c8 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-mem.h
+++ b/arch/arm/mach-exynos/include/mach/regs-mem.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-mem.h
+/* linux/arch/arm/mach-exynos/include/mach/regs-mem.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/regs-mfc.h b/arch/arm/mach-exynos/include/mach/regs-mfc.h
new file mode 100644
index 0000000..1fe42f0
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-mfc.h
@@ -0,0 +1,197 @@
+/*
+ * linux/arch/arm/mach-exynos/include/mach/regs-mfc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition for Samsung MFC (Multi Function Codec - FIMV) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __REGS_MFC_H
+#define __REGS_MFC_H __FILE__
+
+#define S5P_MFCREG(x) (x)
+
+#define MFC_START_ADDR S5P_MFCREG(0x0000)
+#define MFC_END_ADDR S5P_MFCREG(0xe008)
+
+#define MFC_SW_RESET S5P_MFCREG(0x0000)
+#define MFC_RISC_HOST_INT S5P_MFCREG(0x0008)
+
+/* Command from HOST to RISC */
+#define MFC_HOST2RISC_CMD S5P_MFCREG(0x0030)
+#define MFC_HOST2RISC_ARG1 S5P_MFCREG(0x0034)
+#define MFC_HOST2RISC_ARG2 S5P_MFCREG(0x0038)
+#define MFC_HOST2RISC_ARG3 S5P_MFCREG(0x003c)
+#define MFC_HOST2RISC_ARG4 S5P_MFCREG(0x0040)
+
+/* Command from RISC to HOST */
+#define MFC_RISC2HOST_CMD S5P_MFCREG(0x0044)
+#define MFC_RISC2HOST_ARG1 S5P_MFCREG(0x0048)
+#define MFC_RISC2HOST_ARG2 S5P_MFCREG(0x004c)
+#define MFC_RISC2HOST_ARG3 S5P_MFCREG(0x0050)
+#define MFC_RISC2HOST_ARG4 S5P_MFCREG(0x0054)
+
+#define MFC_FW_VERSION S5P_MFCREG(0x0058)
+#define MFC_SYS_MEM_SZ S5P_MFCREG(0x005c)
+#define MFC_FW_STATUS S5P_MFCREG(0x0080)
+
+/* Memory controller register */
+#define MFC_MC_DRAMBASE_ADR_A S5P_MFCREG(0x0508)
+#define MFC_MC_DRAMBASE_ADR_B S5P_MFCREG(0x050c)
+#define MFC_MC_STATUS S5P_MFCREG(0x0510)
+
+/* Common register */
+#define MFC_SYS_MEM_ADR S5P_MFCREG(0x0600) /* firmware buffer */
+#define MFC_CPB_BUF_ADR S5P_MFCREG(0x0604) /* stream buffer */
+#define MFC_DESC_BUF_ADR S5P_MFCREG(0x0608) /* descriptor buffer */
+#define MFC_LUMA_ADR S5P_MFCREG(0x0700) /* Luma0 ~ Luma18 */
+#define MFC_CHROMA_ADR S5P_MFCREG(0x0600) /* Chroma0 ~ Chroma18 */
+
+#define MFC_B_RECON_LUMA_ADR S5P_MFCREG(0x062c)
+#define MFC_B_RECON_CHROMA_ADR S5P_MFCREG(0x0630)
+
+/* H264 decoding */
+#define MFC_VERT_NB_MV_ADR S5P_MFCREG(0x068c) /* vertical neighbor motion vector */
+#define MFC_VERT_NB_IP_ADR S5P_MFCREG(0x0690) /* neighbor pixels for intra pred */
+#define MFC_MV_ADR S5P_MFCREG(0x0780) /* H264 motion vector */
+
+/* H263/MPEG4/MPEG2/VC-1 decoding */
+#define MFC_NB_DCAC_ADR S5P_MFCREG(0x068c) /* neighbor AC/DC coeff. buffer */
+#define MFC_UP_NB_MV_ADR S5P_MFCREG(0x0690) /* upper neighbor motion vector buffer */
+#define MFC_SA_MV_ADR S5P_MFCREG(0x0694) /* subseq. anchor motion vector buffer */
+#define MFC_OT_LINE_ADR S5P_MFCREG(0x0698) /* overlap transform line buffer */
+#define MFC_BITPLANE3_ADR S5P_MFCREG(0x069c) /* bitplane3 addr */
+#define MFC_BITPLANE2_ADR S5P_MFCREG(0x06a0) /* bitplane2 addr */
+#define MFC_BITPLANE1_ADR S5P_MFCREG(0x06a4) /* bitplane1 addr */
+#define MFC_SP_ADR S5P_MFCREG(0x06a8) /* syntax parser addr */
+
+/* Encoder register */
+#define MFC_UP_MV_ADR S5P_MFCREG(0x0600) /* upper motion vector addr */
+#define MFC_COLZERO_FLAG_ADR S5P_MFCREG(0x0610) /* direct colocaated zero flag addr */
+#define MFC_UP_INTRA_MD_ADR S5P_MFCREG(0x0608) /* upper intra MD addr */
+#define MFC_UP_INTRA_PRED_ADR S5P_MFCREG(0x0740) /* upper intra PRED addr */
+#define MFC_NBOR_INFO_ADR S5P_MFCREG(0x0604) /* entropy engine's neighbor inform and AC/DC coeff. */
+
+#define MFC_ENC_REF0_LUMA_ADR S5P_MFCREG(0x061c) /* ref0 Luma addr */
+#define MFC_ENC_REF0_CHROMA_ADR S5P_MFCREG(0x0700) /* ref0 Chroma addr */
+#define MFC_ENC_REF1_LUMA_ADR S5P_MFCREG(0x0620) /* ref1 Luma addr */
+#define MFC_ENC_REF1_CHROMA_ADR S5P_MFCREG(0x0704) /* ref1 Chroma addr */
+#define MFC_ENC_REF2_LUMA_ADR S5P_MFCREG(0x0710) /* ref2 Luma addr */
+#define MFC_ENC_REF2_CHROMA_ADR S5P_MFCREG(0x0708) /* ref2 Chroma addr */
+#define MFC_ENC_REF3_LUMA_ADR S5P_MFCREG(0x0714) /* ref3 Luma addr */
+#define MFC_ENC_REF3_CHROMA_ADR S5P_MFCREG(0x070c) /* ref3 Chroma addr */
+
+/* Codec common register */
+#define MFC_ENC_HSIZE_PX S5P_MFCREG(0x0818) /* frame width at encoder */
+#define MFC_ENC_VSIZE_PX S5P_MFCREG(0x081c) /* frame height at encoder */
+#define MFC_ENC_PROFILE S5P_MFCREG(0x0830) /* profile register */
+#define MFC_ENC_PIC_STRUCT S5P_MFCREG(0x083c) /* picture field/frame flag */
+#define MFC_ENC_LF_CTRL S5P_MFCREG(0x0848) /* loop filter control */
+#define MFC_ENC_ALPHA_OFF S5P_MFCREG(0x084c) /* loop filter alpha offset */
+#define MFC_ENC_BETA_OFF S5P_MFCREG(0x0850) /* loop filter beta offset */
+#define MFC_MR_BUSIF_CTRL S5P_MFCREG(0x0854) /* hidden, bus interface ctrl */
+#define MFC_ENC_PXL_CACHE_CTRL S5P_MFCREG(0x0a00) /* pixel cache control */
+
+/* Channel & stream interface register */
+#define MFC_SI_RTN_CHID S5P_MFCREG(0x2000) /* Return CH instance ID register */
+#define MFC_SI_CH1_INST_ID S5P_MFCREG(0x2040) /* codec instance ID */
+#define MFC_SI_CH2_INST_ID S5P_MFCREG(0x2080) /* codec instance ID */
+
+/* Decoder */
+#define MFC_SI_VRESOL S5P_MFCREG(0x2004) /* vertical resolution of decoder */
+#define MFC_SI_HRESOL S5P_MFCREG(0x2008) /* horizontal resolution of decoder */
+#define MFC_SI_BUF_NUMBER S5P_MFCREG(0x200c) /* number of frames in the decoded pic */
+#define MFC_SI_DISPLAY_Y_ADR S5P_MFCREG(0x2010) /* luma address of displayed pic */
+#define MFC_SI_DISPLAY_C_ADR S5P_MFCREG(0x2014) /* chroma address of displayed pic */
+#define MFC_SI_FRM_COUNT S5P_MFCREG(0x2018) /* the number of frames so far decoded */
+#define MFC_SI_DISPLAY_STATUS S5P_MFCREG(0x201c) /* Display status of decoded picture */
+#define MFC_SI_FRAME_TYPE S5P_MFCREG(0x2020) /* frame type such as skip/I/P/B */
+#define MFC_SI_DECODE_Y_ADR S5P_MFCREG(0x2024) /* luma address of decoded pic */
+#define MFC_SI_DECODE_C_ADR S5P_MFCREG(0x2028) /* chroma address of decoded pic */
+#define MFC_SI_DECODE_STATUS S5P_MFCREG(0x202c) /* decoded status */
+
+#define MFC_SI_CH1_ES_ADR S5P_MFCREG(0x2044) /* start addr of stream buf */
+#define MFC_SI_CH1_ES_SIZE S5P_MFCREG(0x2048) /* size of stream buf */
+#define MFC_SI_CH1_DESC_ADR S5P_MFCREG(0x204c) /* addr of descriptor buf */
+#define MFC_SI_CH1_CPB_SIZE S5P_MFCREG(0x2058) /* max size of coded pic. buf */
+#define MFC_SI_CH1_DESC_SIZE S5P_MFCREG(0x205c) /* max size of descriptor buf */
+#define MFC_SI_CH1_RELEASE_BUF S5P_MFCREG(0x2060) /* release buffer register */
+#define MFC_SI_CH1_HOST_WR_ADR S5P_MFCREG(0x2064) /* shared memory address */
+#define MFC_SI_CH1_DPB_CONF_CTRL S5P_MFCREG(0x2068) /* DPB Configuration Control Register */
+
+#define MFC_SI_CH2_ES_ADR S5P_MFCREG(0x2084) /* start addr of stream buf */
+#define MFC_SI_CH2_ES_SIZE S5P_MFCREG(0x2088) /* size of stream buf */
+#define MFC_SI_CH2_DESC_ADR S5P_MFCREG(0x208c) /* addr of descriptor buf */
+#define MFC_SI_CH2_CPB_SIZE S5P_MFCREG(0x2098) /* max size of coded pic. buf */
+#define MFC_SI_CH2_DESC_SIZE S5P_MFCREG(0x209c) /* max size of descriptor buf */
+#define MFC_SI_CH2_RELEASE_BUF S5P_MFCREG(0x20a0) /* release buffer register */
+#define MFC_SI_CH2_HOST_WR_ADR S5P_MFCREG(0x20a4) /* shared memory address */
+#define MFC_SI_CH2_DPB_CONF_CTRL S5P_MFCREG(0x20a8) /* DPB Configuration Control Register */
+
+#define MFC_SI_FIMV1_VRESOL S5P_MFCREG(0x2050) /* vertical resolution */
+#define MFC_SI_FIMV1_HRESOL S5P_MFCREG(0x2054) /* horizontal resolution */
+#define MFC_CRC_LUMA0 S5P_MFCREG(0x2030) /* luma crc data per frame(or top field) */
+#define MFC_CRC_CHROMA0 S5P_MFCREG(0x2034) /* chroma crc data per frame(or top field) */
+#define MFC_CRC_LUMA1 S5P_MFCREG(0x2038) /* luma crc data per bottom field */
+#define MFC_CRC_CHROMA1 S5P_MFCREG(0x203c) /* chroma crc data per bottom field */
+
+/* Encoder */
+#define MFC_ENC_SI_STRM_SIZE S5P_MFCREG(0x2004) /* stream size */
+#define MFC_ENC_SI_PIC_CNT S5P_MFCREG(0x2008) /* picture count */
+#define MFC_ENC_SI_WRITE_PTR S5P_MFCREG(0x200c) /* write pointer */
+#define MFC_ENC_SI_SLICE_TYPE S5P_MFCREG(0x2010) /* slice type(I/P/B/IDR) */
+#define MFC_ENCODED_Y_ADDR S5P_MFCREG(0x2014) /* the address of the encoded luminance picture */
+#define MFC_ENCODED_C_ADDR S5P_MFCREG(0x2018) /* the address of the encoded chrominance picture */
+
+#define MFC_ENC_SI_CH1_SB_ADR S5P_MFCREG(0x2044) /* addr of stream buf */
+#define MFC_ENC_SI_CH1_SB_SIZE S5P_MFCREG(0x204c) /* size of stream buf */
+#define MFC_ENC_SI_CH1_CUR_Y_ADR S5P_MFCREG(0x2050) /* current Luma addr */
+#define MFC_ENC_SI_CH1_CUR_C_ADR S5P_MFCREG(0x2054) /* current Chroma addr */
+#define MFC_ENC_SI_CH1_FRAME_INS S5P_MFCREG(0x2058) /* frame insertion control register */
+#define MFC_ENC_SI_CH1_INPUT_FLUSH S5P_MFCREG(0x2068) /* flusing input buffer */
+
+#define MFC_ENC_SI_CH2_SB_ADR S5P_MFCREG(0x2084) /* addr of stream buf */
+#define MFC_ENC_SI_CH2_SB_SIZE S5P_MFCREG(0x208c) /* size of stream buf */
+#define MFC_ENC_SI_CH2_CUR_Y_ADR S5P_MFCREG(0x2090) /* current Luma addr */
+#define MFC_ENC_SI_CH2_CUR_C_ADR S5P_MFCREG(0x2094) /* current Chroma addr */
+#define MFC_ENC_SI_CH2_FRAME_INS S5P_MFCREG(0x2098) /* frame insertion control register */
+#define MFC_ENC_SI_CH2_INPUT_FLUSH S5P_MFCREG(0x20A8) /* flusing input buffer */
+
+#define MFC_ENC_PIC_TYPE_CTRL S5P_MFCREG(0xc504) /* pic type level control */
+#define MFC_ENC_B_RECON_WRITE_ON S5P_MFCREG(0xc508) /* B frame recon data write cotrl */
+#define MFC_ENC_MSLICE_CTRL S5P_MFCREG(0xc50c) /* multi slice control */
+#define MFC_ENC_MSLICE_MB S5P_MFCREG(0xc510) /* MB number in the one slice */
+#define MFC_ENC_MSLICE_BIT S5P_MFCREG(0xc514) /* bit count number for one slice */
+#define MFC_ENC_CIR_CTRL S5P_MFCREG(0xc518) /* number of intra refresh MB */
+#define MFC_ENC_MAP_FOR_CUR S5P_MFCREG(0xc51c) /* linear or 64x32 tiled mode */
+#define MFC_ENC_PADDING_CTRL S5P_MFCREG(0xc520) /* padding control */
+
+#define MFC_ENC_NV21_SEL S5P_MFCREG(0xc548) /* chroma interleaving order */
+
+#define MFC_ENC_INTRA_BIAS S5P_MFCREG(0xc588) /* intra mode bias for the MB mode */
+#define MFC_ENC_BI_DIRECT_BIAS S5P_MFCREG(0xc58c) /* bi-directional mode bias for the MB mode */
+
+#define MFC_ENC_RC_CONFIG S5P_MFCREG(0xc5a0) /* RC config */
+#define MFC_ENC_RC_BIT_RATE S5P_MFCREG(0xc5a8) /* bit rate */
+#define MFC_ENC_RC_QBOUND S5P_MFCREG(0xc5ac) /* max/min QP */
+#define MFC_ENC_RC_RPARA S5P_MFCREG(0xc5b0) /* rate control reaction coeff. */
+#define MFC_ENC_RC_MB_CTRL S5P_MFCREG(0xc5b4) /* MB adaptive scaling */
+
+/* Encoder for H264 */
+#define MFC_ENC_H264_ENTRP_MODE S5P_MFCREG(0xd004) /* CAVLC or CABAC */
+#define MFC_ENC_H264_ALPHA_OFF S5P_MFCREG(0xd008) /* loop filter alpha offset */
+#define MFC_ENC_H264_BETA_OFF S5P_MFCREG(0xd00c) /* loop filter beta offset */
+#define MFC_ENC_H264_NUM_OF_REF S5P_MFCREG(0xd010) /* number of reference for P/B */
+#define MFC_ENC_H264_TRANS_FLAG S5P_MFCREG(0xd034) /* 8x8 transform flag in PPS & high profile */
+
+#define MFC_ENC_RC_FRAME_RATE S5P_MFCREG(0xd0d0) /* frame rate */
+
+/* Encoder for MPEG4 */
+#define MFC_ENC_MPEG4_QUART_PXL S5P_MFCREG(0xe008) /* quarter pel interpolation control */
+
+#endif /* __REGS_MFC_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-mixer.h b/arch/arm/mach-exynos/include/mach/regs-mixer.h
new file mode 100644
index 0000000..a9e905e
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-mixer.h
@@ -0,0 +1,216 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-mixer.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * Mixer register header file for Samsung TVOUT driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_REGS_MIXER_H
+#define __ARCH_ARM_REGS_MIXER_H
+
+/*
+ * Register part
+ */
+#define S5P_MXR_STATUS (0x0000)
+#define S5P_MXR_CFG (0x0004)
+#define S5P_MXR_INT_EN (0x0008)
+#define S5P_MXR_INT_STATUS (0x000C)
+#define S5P_MXR_LAYER_CFG (0x0010)
+#define S5P_MXR_VIDEO_CFG (0x0014)
+#define S5P_MXR_VIDEO_LIMITER_PARA_CFG (0x0018)
+#define S5P_MXR_GRAPHIC0_CFG (0x0020)
+#define S5P_MXR_GRAPHIC0_BASE (0x0024)
+#define S5P_MXR_GRAPHIC0_SPAN (0x0028)
+#define S5P_MXR_GRAPHIC0_SXY (0x002C)
+#define S5P_MXR_GRAPHIC0_WH (0x0030)
+#define S5P_MXR_GRAPHIC0_DXY (0x0034)
+#define S5P_MXR_GRAPHIC0_BLANK (0x0038)
+#define S5P_MXR_GRAPHIC1_CFG (0x0040)
+#define S5P_MXR_GRAPHIC1_BASE (0x0044)
+#define S5P_MXR_GRAPHIC1_SPAN (0x0048)
+#define S5P_MXR_GRAPHIC1_SXY (0x004C)
+#define S5P_MXR_GRAPHIC1_WH (0x0050)
+#define S5P_MXR_GRAPHIC1_DXY (0x0054)
+#define S5P_MXR_GRAPHIC1_BLANK (0x0058)
+#define S5P_MXR_BG_CFG (0x0060)
+#define S5P_MXR_BG_COLOR0 (0x0064)
+#define S5P_MXR_BG_COLOR1 (0x0068)
+#define S5P_MXR_BG_COLOR2 (0x006C)
+#define S5P_MXR_CM_COEFF_Y (0x0080)
+#define S5P_MXR_CM_COEFF_CB (0x0084)
+#define S5P_MXR_CM_COEFF_CR (0x0088)
+#define S5P_MXR_VER (0x0100)
+
+#define S5P_MXR_STATUS_S (0x2000)
+#define S5P_MXR_CFG_S (0x2004)
+#define S5P_MXR_LAYER_CFG_S (0x2010)
+#define S5P_MXR_VIDEO_CFG_S (0x2014)
+#define S5P_MXR_VIDEO_LIMITER_PARA_CFG_S (0x2018)
+#define S5P_MXR_GRAPHIC0_CFG_S (0x2020)
+#define S5P_MXR_GRAPHIC0_BASE_S (0x2024)
+#define S5P_MXR_GRAPHIC0_SPAN_S (0x2028)
+#define S5P_MXR_GRAPHIC0_SXY_S (0x202C)
+#define S5P_MXR_GRAPHIC0_WH_S (0x2030)
+#define S5P_MXR_GRAPHIC0_DXY_S (0x2034)
+#define S5P_MXR_GRAPHIC0_BLANK_PIXEL_S (0x2038)
+#define S5P_MXR_GRAPHIC1_CFG_S (0x2040)
+#define S5P_MXR_GRAPHIC1_BASE_S (0x2044)
+#define S5P_MXR_GRAPHIC1_SPAN_S (0x2048)
+#define S5P_MXR_GRAPHIC1_SXY_S (0x204C)
+#define S5P_MXR_GRAPHIC1_WH_S (0x2050)
+#define S5P_MXR_GRAPHIC1_DXY_S (0x2054)
+#define S5P_MXR_GRAPHIC1_BLANK_PIXEL_S (0x2058)
+#define S5P_MXR_BG_COLOR0_S (0x2064)
+#define S5P_MXR_BG_COLOR1_S (0x2068)
+#define S5P_MXR_BG_COLOR2_S (0x206C)
+
+/*
+ * Bit definition part
+ */
+/* MIXER_STATUS */
+#define S5P_MXR_STATUS_16_BURST (1 << 7)
+#define S5P_MXR_STATUS_8_BURST (0 << 7)
+#define S5P_MXR_STATUS_LITTLE_ENDIAN (0 << 3)
+#define S5P_MXR_STATUS_BIG_ENDIAN (1 << 3)
+#define S5P_MXR_STATUS_SYNC_DISABLE (0 << 2)
+#define S5P_MXR_STATUS_SYNC_ENABLE (1 << 2)
+#define S5P_MXR_STATUS_OPERATING (0 << 1)
+#define S5P_MXR_STATUS_IDLE_MODE (1 << 1)
+#define S5P_MXR_STATUS_STOP (0 << 0)
+#define S5P_MXR_STATUS_RUN (1 << 0)
+
+/* MIXER_CGF */
+#define S5P_MXR_CFG_TV_OUT (~(1 << 7))
+#define S5P_MXR_CFG_HDMI_OUT (1 << 7)
+#define S5P_MXR_CFG_HD_720P (0 << 6)
+#define S5P_MXR_CFG_HD_1080I (1 << 6)
+#define S5P_MXR_CFG_HD_1080P (1 << 6)
+#define S5P_MXR_CFG_GRAPHIC1_DISABLE (0 << 5)
+#define S5P_MXR_CFG_GRAPHIC1_ENABLE (1 << 5)
+#define S5P_MXR_CFG_GRAPHIC0_DISABLE (0 << 4)
+#define S5P_MXR_CFG_GRAPHIC0_ENABLE (1 << 4)
+#define S5P_MXR_CFG_VIDEO_DISABLE (0 << 3)
+#define S5P_MXR_CFG_VIDEO_ENABLE (1 << 3)
+#define S5P_MXR_CFG_INTERLACE (~(1 << 2))
+#define S5P_MXR_CFG_PROGRASSIVE (1 << 2)
+#define S5P_MXR_CFG_NTSC (0 << 1)
+#define S5P_MXR_CFG_PAL (1 << 1)
+#define S5P_MXR_CFG_SD (0 << 0)
+#define S5P_MXR_CFG_HD (1 << 0)
+#define S5P_MXR_CFG_RGB_FORMAT_MASK (0xFF << 9)
+
+/* MIXER_INT_EN */
+#define S5P_MXR_INT_EN_VSYNC_ENABLE (1 << 11)
+#define S5P_MXR_INT_EN_VP_DISABLE (0 << 10)
+#define S5P_MXR_INT_EN_VP_ENABLE (1 << 10)
+#define S5P_MXR_INT_EN_GRP1_DISABLE (0 << 9)
+#define S5P_MXR_INT_EN_GRP1_ENABLE (1 << 9)
+#define S5P_MXR_INT_EN_GRP0_DISABLE (0 << 8)
+#define S5P_MXR_INT_EN_GRP0_ENABLE (1 << 8)
+
+/* MIXER_INT_STATUS */
+#define S5P_MXR_INT_STATUS_VSYNC_CLEARED (1 << 11)
+#define S5P_MXR_INT_STATUS_VP_N_FIRED (0 << 10)
+#define S5P_MXR_INT_STATUS_VP_FIRED (1 << 10)
+#define S5P_MXR_INT_STATUS_GRP1_N_FIRED (0 << 9)
+#define S5P_MXR_INT_STATUS_GRP1_FIRED (1 << 9)
+#define S5P_MXR_INT_STATUS_GRP0_N_FIRED (0 << 8)
+#define S5P_MXR_INT_STATUS_GRP0_FIRED (1 << 8)
+#define S5P_MXR_INT_STATUS_INT_FIRED (1 << 0)
+
+/* MIXER_LAYER_CFG */
+#define S5P_MXR_LAYER_CFG_GRP1_HIDE (0 << 8)
+#define S5P_MXR_LAYER_CFG_GRP1_PRIORITY(x) (((x) & 0xF) << 8)
+#define S5P_MXR_LAYER_CFG_GRP1_PRIORITY_CLR(x) ((x) & (~(0xF << 8)))
+#define S5P_MXR_LAYER_CFG_GRP1_PRIORITY_INFO(x) ((x) & (0xF << 8))
+#define S5P_MXR_LAYER_CFG_GRP0_HIDE (0 << 4)
+#define S5P_MXR_LAYER_CFG_GRP0_PRIORITY(x) (((x) & 0xF) << 4)
+#define S5P_MXR_LAYER_CFG_GRP0_PRIORITY_CLR(x) ((x) & (~(0xF << 4)))
+#define S5P_MXR_LAYER_CFG_GRP0_PRIORITY_INFO(x) ((x) & (0xF << 4))
+#define S5P_MXR_LAYER_CFG_VID_HIDE (0 << 0)
+#define S5P_MXR_LAYER_CFG_VID_PRIORITY(x) (((x) & 0xF) << 0)
+#define S5P_MXR_LAYER_CFG_VID_PRIORITY_CLR(x) ((x) & (~(0xF << 0)))
+#define S5P_MXR_LAYER_CFG_VID_PRIORITY_INFO(x) ((x) & (0xF << 0))
+
+/* MIXER_VIDEO_CFG */
+#define S5P_MXR_VIDEO_CFG_LIMITER_DIS (0 << 17)
+#define S5P_MXR_VIDEO_CFG_LIMITER_EN (1 << 17)
+#define S5P_MXR_VIDEO_CFG_BLEND_DIS (0 << 16)
+#define S5P_MXR_VIDEO_CFG_BLEND_EN (1 << 16)
+#define S5P_MXR_VIDEO_CFG_ALPHA_MASK (0xFF)
+#define S5P_MXR_VIDEO_CFG_ALPHA_VALUE(x) (((x) & 0xFF) << 0)
+#define S5P_MXR_VIDEO_CFG_ALPHA_VALUE_CLR(x) ((x) & (~(0xFF << 0)))
+
+/* MIXER_VIDEO_LIMITER_PARA_CFG */
+#define S5P_MXR_VIDEO_LIMITER_PARA_Y_UPPER(x) (((x) & 0xFF) << 24)
+#define S5P_MXR_VIDEO_LIMITER_PARA_Y_LOWER(x) (((x) & 0xFF) << 16)
+#define S5P_MXR_VIDEO_LIMITER_PARA_C_UPPER(x) (((x) & 0xFF) << 8)
+#define S5P_MXR_VIDEO_LIMITER_PARA_C_LOWER(x) (((x) & 0xFF) << 0)
+
+/* MIXER_GRAPHIC0_CFG */
+/* MIXER_GRAPHIC1_CFG */
+#define S5P_MXR_BLANK_CHANGE_NEW_PIXEL (1 << 21)
+#define S5P_MXR_BLANK_NOT_CHANGE_NEW_PIXEL (0 << 21)
+#define S5P_MXR_PRE_MUL_MODE (1 << 20)
+#define S5P_MXR_NORMAL_MODE (0 << 20)
+#define S5P_MXR_WIN_BLEND_ENABLE (1 << 17)
+#define S5P_MXR_WIN_BLEND_DISABLE (0 << 17)
+#define S5P_MXR_PIXEL_BLEND_ENABLE (1 << 16)
+#define S5P_MXR_PIXEL_BLEND_DISABLE (0 << 16)
+#define S5P_MXR_EG_COLOR_FORMAT(x) (((x) & 0xF) << 8)
+#define S5P_MXR_EG_COLOR_FORMAT_CLEAR(x) ((x) & (~(0xF << 8)))
+#define S5P_MXR_GRP_ALPHA_VALUE(x) (((x) & 0xFF) << 0)
+#define S5P_MXR_GRP_ALPHA_VALUE_CLEAR(x) ((x) & (~(0xFF << 0)))
+
+/* MIXER_GRAPHIC0_BASE */
+/* MIXER_GRAPHIC1_BASE */
+#define S5P_MXR_GPR_BASE(x) ((x) & 0xFFFFFFFF)
+#define S5P_MXR_GRP_ADDR_ILLEGAL(x) ((x) & 0x3)
+
+/* MIXER_GRAPHIC0_SPAN */
+#define S5P_MXR_GRP_SPAN(x) ((x) & 0x7FFF)
+
+/* MIXER_GRAPHIC0_WH */
+#define S5P_MXR_GRP_H_SCALE(x) (((x) & 0x1) << 28)
+#define S5P_MXR_GRP_V_SCALE(x) (((x) & 0x1) << 12)
+#define S5P_MXR_GRP_WIDTH(x) (((x) & 0x7FF) << 16)
+#define S5P_MXR_GRP_HEIGHT(x) (((x) & 0x7FF) << 0)
+
+/* MIXER_GRAPHIC0_XY */
+#define S5P_MXR_GRP_STARTX(x) (((x) & 0x7FF) << 16)
+#define S5P_MXR_GRP_STARTY(x) (((x) & 0x7FF) << 0)
+
+/* MIXER_GRAPHIC0_DXY */
+#define S5P_MXR_GRP_DESTX(x) (((x) & 0x7FF) << 16)
+#define S5P_MXR_GRP_DESTY(x) (((x) & 0x7FF) << 0)
+
+/* MIXER_GRAPHIC0_BLANK */
+#define S5P_MXR_GPR_BLANK_COLOR(x) ((x) & 0xFFFFFFFF)
+
+/* MIXER_BG_CFG */
+#define S5P_MXR_BG_CR_DIHER_EN (1 << 19) /* Not support in S5PV210 */
+#define S5P_MXR_BG_CB_DIHER_EN (1 << 18) /* Not support in S5PV210 */
+#define S5P_MXR_BG_Y_DIHER_EN (1 << 17) /* Not support in S5PV210 */
+
+/* MIXER_BG_COLOR0/1/2 */
+#define S5P_MXR_BG_COEFF_0(x) (((x) & 0x3F) << 20)
+#define S5P_MXR_BG_COEFF_1(x) (((x) & 0x3F) << 10)
+#define S5P_MXR_BG_COEFF_2(x) (((x) & 0x3F) << 0)
+
+/* MIXER_CM_COEFF_Y */
+#define S5P_MXR_BG_COLOR_WIDE (1 << 30)
+#define S5P_MXR_BG_COLOR_NARROW (0 << 30)
+#define S5P_MXR_BG_COLOR_Y(x) (((x) & 0xFF) << 16)
+
+/* MIXER_CM_COEFF_CB */
+#define S5P_MXR_BG_COLOR_CB(x) (((x) & 0xFF) << 8)
+
+/* MIXER_CM_COEFF_Cr */
+#define S5P_MXR_BG_COLOR_CR(x) (((x) & 0xFF) << 0)
+#endif /* __ARCH_ARM_REGS_MIXER_H */
+
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu-4210.h b/arch/arm/mach-exynos/include/mach/regs-pmu-4210.h
new file mode 100644
index 0000000..0fc1da0
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu-4210.h
@@ -0,0 +1,32 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-pmu-4210.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - 4210 Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU_4210_H
+#define __ASM_ARCH_REGS_PMU_4210_H __FILE__
+
+#define S5P_USBOTG_PHY_CONTROL S5P_PMUREG(0x0704)
+#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708)
+#define S5P_USBOTG_PHY_ENABLE (1 << 0)
+#define S5P_USBHOST_PHY_ENABLE (1 << 0)
+
+#define S5P_PMU_SATA_PHY_CONTROL S5P_PMUREG(0x0720)
+
+#define S5P_CMU_CLKSTOP_LCD1_SYS S5P_PMUREG(0x1154)
+#define S5P_CMU_RESET_LCD1_SYS S5P_PMUREG(0x1174)
+#define S5P_MODIMIF_MEM_SYS S5P_PMUREG(0x11C4)
+#define S5P_PCIE_MEM_SYS S5P_PMUREG(0x11E0)
+#define S5P_SATA_MEM_SYS S5P_PMUREG(0x11E4)
+#define S5P_LCD1_SYS S5P_PMUREG(0x1394)
+
+#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
+
+#endif /* __ASM_ARCH_REGS_PMU_4210_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu-4212.h b/arch/arm/mach-exynos/include/mach/regs-pmu-4212.h
new file mode 100644
index 0000000..0c0d90c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu-4212.h
@@ -0,0 +1,134 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-pmu-4212.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - 4212 Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU_4212_H
+#define __ASM_ARCH_REGS_PMU_4212_H __FILE__
+
+#define S5P_LPI_MASK0 S5P_PMUREG(0x0004)
+#define S5P_LPI_MASK1 S5P_PMUREG(0x0008)
+#define S5P_LPI_MASK2 S5P_PMUREG(0x000C)
+
+#define S5P_LPI_DENIAL_MASK0 S5P_PMUREG(0x0018)
+#define S5P_LPI_DENIAL_MASK1 S5P_PMUREG(0x001C)
+#define S5P_LPI_DENIAL_MASK2 S5P_PMUREG(0x0020)
+
+#define S5P_C2C_CTRL S5P_PMUREG(0x0024)
+
+#define S5P_CENTRAL_SEQ_CONFIGURATION_COREBLK S5P_PMUREG(0x0240)
+
+#define S5P_CENTRAL_SEQ_COREBLK_CONF (0x1 << 16)
+
+#define S5P_SYS_WDTRESET (0x1 << 20)
+#define S5P_AUTOMATIC_WDT_RESET_DISABLE S5P_PMUREG(0x0408)
+#define S5P_MASK_WDT_RESET_REQUEST S5P_PMUREG(0x040C)
+
+#define S5P_WAKEUP_STAT_COREBLK S5P_PMUREG(0x0620)
+#define S5P_WAKEUP_MASK_COREBLK S5P_PMUREG(0x0628)
+
+#define S5P_USB_PHY_CONTROL S5P_PMUREG(0x0704)
+#define S5P_HSIC_1_PHY_CONTROL S5P_PMUREG(0x0708)
+#define S5P_HSIC_2_PHY_CONTROL S5P_PMUREG(0x070C)
+#define S5P_USB_PHY_ENABLE (0x1 << 0)
+#define S5P_HSIC_1_PHY_ENABLE (0x1 << 0)
+#define S5P_HSIC_2_PHY_ENABLE (0x1 << 0)
+
+#define S5P_ABB_INT S5P_PMUREG(0x0780)
+#define S5P_ABB_MIF S5P_PMUREG(0x0784)
+#define S5P_ABB_G3D S5P_PMUREG(0x0788)
+#define S5P_ABB_ARM S5P_PMUREG(0x078C)
+
+#define S5P_ABB_MEMBER(_nr) (S5P_ABB_INT + (_nr * 0x4))
+
+#define ABB_MODE_060V 0
+#define ABB_MODE_065V 1
+#define ABB_MODE_070V 2
+#define ABB_MODE_075V 3
+#define ABB_MODE_080V 4
+#define ABB_MODE_085V 5
+#define ABB_MODE_090V 6
+#define ABB_MODE_095V 7
+#define ABB_MODE_100V 8
+#define ABB_MODE_105V 9
+#define ABB_MODE_110V 10
+#define ABB_MODE_115V 11
+#define ABB_MODE_120V 12
+#define ABB_MODE_125V 13
+#define ABB_MODE_130V 14
+#define ABB_MODE_135V 15
+#define ABB_MODE_140V 16
+#define ABB_MODE_145V 17
+#define ABB_MODE_150V 18
+#define ABB_MODE_155V 19
+#define ABB_MODE_160V 20
+#define ABB_MODE_BYPASS 255
+
+#define S5P_ABB_INIT (0x80000080)
+#define S5P_ABB_INIT_BYPASS (0x80000000)
+
+/* SYS_PWR registers */
+#define S5P_ARM_CORE2_SYS S5P_PMUREG(0x1020)
+#define S5P_DIS_IRQ_ARM_CORE2_LOCAL_SYS S5P_PMUREG(0x1024)
+#define S5P_DIS_IRQ_ARM_CORE2_CENTRAL_SYS S5P_PMUREG(0x1028)
+#define S5P_ARM_CORE3_SYS S5P_PMUREG(0x1030)
+#define S5P_DIS_IRQ_ARM_CORE3_LOCAL_SYS S5P_PMUREG(0x1034)
+#define S5P_DIS_IRQ_ARM_CORE3_CENTRAL_SYS S5P_PMUREG(0x1038)
+#define S5P_ISP_ARM_SYS S5P_PMUREG(0x1050)
+#define S5P_DIS_IRQ_ISP_ARM_LOCAL_SYS S5P_PMUREG(0x1054)
+#define S5P_DIS_IRQ_ISP_ARM_CENTRAL_SYS S5P_PMUREG(0x1058)
+#define S5P_CMU_ACLKSTOP_COREBLK_SYS S5P_PMUREG(0x1110)
+#define S5P_CMU_SCLKSTOP_COREBLK_SYS S5P_PMUREG(0x1114)
+#define S5P_CMU_RESET_COREBLK_SYS S5P_PMUREG(0x111C)
+#define S5P_MPLLUSER_SYSCLK_SYS S5P_PMUREG(0x1130)
+#define S5P_CMU_CLKSTOP_ISP_SYS S5P_PMUREG(0x1154)
+#define S5P_CMU_RESET_ISP_SYS S5P_PMUREG(0x1174)
+#define S5P_TOP_BUS_COREBLK_SYS S5P_PMUREG(0x1190)
+#define S5P_TOP_RETENTION_COREBLK_SYS S5P_PMUREG(0x1194)
+#define S5P_TOP_PWR_COREBLK_SYS S5P_PMUREG(0x1198)
+#define S5P_OSCCLK_GATE_SYS S5P_PMUREG(0x11A4)
+#define S5P_LOGIC_RESET_COREBLK_SYS S5P_PMUREG(0x11B0)
+#define S5P_OSCCLK_GATE_COREBLK_SYS S5P_PMUREG(0x11B4)
+#define S5P_HSI_MEM_SYS S5P_PMUREG(0x11C4)
+#define S5P_ROTATOR_MEM_SYS S5P_PMUREG(0x11DC)
+#define S5P_PAD_RETENTION_GPIO_COREBLK_SYS S5P_PMUREG(0x123C)
+#define S5P_PAD_ISOLATION_COREBLK_SYS S5P_PMUREG(0x1250)
+#define S5P_GPIO_MODE_COREBLK_SYS S5P_PMUREG(0x1320)
+#define S5P_TOP_ASB_RESET_SYS S5P_PMUREG(0x1344)
+#define S5P_TOP_ASB_ISOLATION_SYS S5P_PMUREG(0x1348)
+#define S5P_ISP_SYS S5P_PMUREG(0x1394)
+#define S5P_DRAM_FREQ_DOWN_SYS S5P_PMUREG(0x13B0)
+#define S5P_DDRPHY_DLLOFF_SYS S5P_PMUREG(0x13B4)
+#define S5P_CMU_SYSCLK_ISP_SYS S5P_PMUREG(0x13B8)
+#define S5P_CMU_SYSCLK_GPS_SYS S5P_PMUREG(0x13BC)
+#define S5P_LPDDR_PHY_DLL_LOCK_SYS S5P_PMUREG(0x13C0)
+
+/* OPTION registers */
+#define S5P_ISP_ARM_OPTION S5P_PMUREG(0x2288)
+#define S5P_ARM_L2_0_OPTION S5P_PMUREG(0x2608)
+#define S5P_ARM_L2_1_OPTION S5P_PMUREG(0x2628)
+#define S5P_ONENAND_MEM_OPTION S5P_PMUREG(0x2E08)
+#define S5P_HSI_MEM_OPTION S5P_PMUREG(0x2E28)
+#define S5P_G2D_ACP_MEM_OPTION S5P_PMUREG(0x2E48)
+#define S5P_USBOTG_MEM_OPTION S5P_PMUREG(0x2E68)
+#define S5P_SDMMC_MEM_OPTION S5P_PMUREG(0x2E88)
+#define S5P_CSSYS_MEM_OPTION S5P_PMUREG(0x2EA8)
+#define S5P_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8)
+#define S5P_ROTATOR_MEM_OPTION S5P_PMUREG(0x2F48)
+#define S5P_PAD_RETENTION_GPIO_COREBLK_OPTION S5P_PMUREG(0x31E8)
+
+#define S5P_PS_HOLD_CONTROL S5P_PMUREG(0x330C)
+
+#define S5P_PMU_ISP_CONF S5P_PMUREG(0x3CA0)
+#define S5P_PMU_GPS_ALIVE_CONF S5P_PMUREG(0x3D00)
+#define S5P_PMU_GPS_ALIVE_CONF S5P_PMUREG(0x3D00)
+#define S5P_PMU_MAUDIO_CONF S5P_PMUREG(0x3CC0)
+
+#endif /* __ASM_ARCH_REGS_PMU_4212_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu-5210.h b/arch/arm/mach-exynos/include/mach/regs-pmu-5210.h
new file mode 100644
index 0000000..48301b8
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu-5210.h
@@ -0,0 +1,34 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-pmu-5210.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - 5210 Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU_5210_H
+#define __ASM_ARCH_REGS_PMU_5210_H __FILE__
+
+#define EXYNOS5_OneNANDXL_MEM_SYS_PWR_REG S5P_PMUREG(0x11C0)
+#define EXYNOS5_USBDEV_MEM_SYS_PWR_REG S5P_PMUREG(0x11CC)
+
+#define EXYNOS5_CMU_CLKSTOP_DISP0_SYS_PWR_REG S5P_PMUREG(0x1490)
+#define EXYNOS5_CMU_SYSCLK_DISP0_SYS_PWR_REG S5P_PMUREG(0x14D0)
+#define EXYNOS5_CMU_RESET_DISP0_SYS_PWR_REG S5P_PMUREG(0x1590)
+
+#define EXYNOS5_DISP0_CONFIGURATION S5P_PMUREG(0x4080)
+#define EXYNOS5_DISP0_STATUS S5P_PMUREG(0x4084)
+#define EXYNOS5_DISP0_OPTION S5P_PMUREG(0x4088)
+
+#define EXYNOS5_CMU_CLKSTOP_DISP0_CONFIGURATION S5P_PMUREG(0x4480)
+#define EXYNOS5_CMU_CLKSTOP_DISP0_STATUS S5P_PMUREG(0x4484)
+#define EXYNOS5_CMU_CLKSTOP_DISP0_OPTION S5P_PMUREG(0x4488)
+
+#define EXYNOS5_CMU_SYSCLK_DISP0_STATUS S5P_PMUREG(0x4684)
+#define EXYNOS5_CMU_SYSCLK_DISP0_OPTION S5P_PMUREG(0x4688)
+
+#endif /* __ASM_ARCH_REGS_PMU_5210_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu-5250.h b/arch/arm/mach-exynos/include/mach/regs-pmu-5250.h
new file mode 100644
index 0000000..2e5a187
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu-5250.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-pmu-5250.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - 5250 Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU_5250_H
+#define __ASM_ARCH_REGS_PMU_5250_H __FILE__
+
+#define EXYNOS5_SATA_PHY_CONTROL S5P_PMUREG(0x0724)
+
+#define EXYNOS5_ABBG_INT_CONTROL S5P_PMUREG(0x0780)
+#define EXYNOS5_ABBG_ARM_CONTROL S5P_PMUREG(0x0784)
+
+#define EXYNOS5_USBOTG_MEM_SYS_PWR_REG S5P_PMUREG(0x11C0)
+#define EXYNOS5_USBDRD_MEM_SYS_PWR_REG S5P_PMUREG(0x11CC)
+#define EXYNOS5_SATA_MEM_SYS_PWR_REG S5P_PMUREG(0x11FC)
+
+#define EXYNOS5_PAD_RETENTION_EFNAND_SYS_PWR_REG S5P_PMUREG(0x1208)
+
+#define EXYNOS5_SATA_MEM_CONFIGURATION S5P_PMUREG(0x2FC0)
+#define EXYNOS5_SATA_MEM_STATUS S5P_PMUREG(0x2FC4)
+#define EXYNOS5_SATA_MEM_OPTION S5P_PMUREG(0x2FC8)
+
+#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4)
+#define S5P_MIPI_DPHY_ENABLE (1 << 0)
+#define S5P_MIPI_DPHY_SRESETN (1 << 1)
+#define S5P_MIPI_DPHY_MRESETN (1 << 2)
+
+#endif /* __ASM_ARCH_REGS_PMU_5250_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
new file mode 100644
index 0000000..21a9f05
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -0,0 +1,207 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-pmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU_H
+#define __ASM_ARCH_REGS_PMU_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
+
+#include "regs-pmu-4210.h"
+#include "regs-pmu-4212.h"
+
+#define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200)
+
+#define S5P_CENTRAL_LOWPWR_CFG (1 << 16)
+
+#define S5P_CENTRAL_SEQ_OPTION S5P_PMUREG(0x0208)
+
+#define S5P_USE_STANDBY_WFI0 (1 << 16)
+#define S5P_USE_STANDBY_WFI1 (1 << 17)
+#define S5P_USE_STANDBYWFI_ISP_ARM (1 << 18)
+#define S5P_USE_STANDBY_WFE0 (1 << 24)
+#define S5P_USE_STANDBY_WFE1 (1 << 25)
+#define S5P_USE_STANDBYWFE_ISP_ARM (1 << 26)
+#define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24))
+
+#define S5P_SWRESET S5P_PMUREG(0x0400)
+
+#define S5P_WAKEUP_STAT S5P_PMUREG(0x0600)
+#define S5P_WAKEUP_STAT_SYSTIMER (1 << 14)
+#define S5P_WAKEUP_STAT_AUDIO (1 << 13)
+#define S5P_WAKEUP_STAT_MMC3 (1 << 12)
+#define S5P_WAKEUP_STAT_MMC2 (1 << 11)
+#define S5P_WAKEUP_STAT_RTCTICK (1 << 2)
+#define S5P_WAKEUP_STAT_RTCALARM (1 << 1)
+#define S5P_WAKEUP_STAT_EINT (1 << 0)
+
+#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
+#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#define S5P_WAKEUP_MASK_BIT 0x3FFFFFF
+#else
+#define S5P_WAKEUP_MASK_BIT 0xFFFF
+#endif
+
+#define S5P_HDMI_PHY_CONTROL S5P_PMUREG(0x0700)
+#define S5P_HDMI_PHY_ENABLE (1 << 0)
+
+#define S5P_DAC_CONTROL S5P_PMUREG(0x70C)
+#define S5P_DAC_ENABLE (1)
+#define S5P_DAC_DISABLE (0)
+
+#define S5P_DAC_PHY_CONTROL S5P_PMUREG(0x070C)
+#define S5P_DAC_PHY_ENABLE (1 << 0)
+#define S5P_DAC_DISABLE (0)
+
+#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4)
+#define S5P_MIPI_DPHY_ENABLE (1 << 0)
+#define S5P_MIPI_DPHY_SRESETN (1 << 1)
+#define S5P_MIPI_DPHY_MRESETN (1 << 2)
+
+#define S5P_DPTX_PHY_CONTROL S5P_PMUREG(0x720)
+#define S5P_DPTX_PHY_ENABLE (1 << 0)
+
+#define S5P_INFORM0 S5P_PMUREG(0x0800)
+#define S5P_INFORM1 S5P_PMUREG(0x0804)
+#define S5P_INFORM2 S5P_PMUREG(0x0808)
+#define S5P_INFORM3 S5P_PMUREG(0x080C)
+#define S5P_INFORM4 S5P_PMUREG(0x0810)
+#define S5P_INFORM5 S5P_PMUREG(0x0814)
+#define S5P_INFORM6 S5P_PMUREG(0x0818)
+#define S5P_INFORM7 S5P_PMUREG(0x081C)
+
+#define S5P_PMU_DEBUG S5P_PMUREG(0x0A00)
+#define S5P_PMU_CLKOUT_SEL_SHIFT (8)
+#define S5P_CLKOUT_DISABLE (0x1 << 0)
+
+#define S5P_ARM_CORE0_SYS S5P_PMUREG(0x1000)
+#define S5P_DIS_IRQ_ARM_CORE0_LOCAL_SYS S5P_PMUREG(0x1004)
+#define S5P_DIS_IRQ_ARM_CORE0_CENTRAL_SYS S5P_PMUREG(0x1008)
+#define S5P_ARM_CORE1_SYS S5P_PMUREG(0x1010)
+#define S5P_DIS_IRQ_ARM_CORE1_LOCAL_SYS S5P_PMUREG(0x1014)
+#define S5P_DIS_IRQ_ARM_CORE1_CENTRAL_SYS S5P_PMUREG(0x1018)
+#define S5P_ARM_COMMON_SYS S5P_PMUREG(0x1080)
+#define S5P_ARM_L2_0_SYS S5P_PMUREG(0x10C0)
+#define S5P_ARM_L2_1_SYS S5P_PMUREG(0x10C4)
+#define S5P_CMU_ACLKSTOP_SYS S5P_PMUREG(0x1100)
+#define S5P_CMU_SCLKSTOP_SYS S5P_PMUREG(0x1104)
+#define S5P_CMU_RESET_SYS S5P_PMUREG(0x110C)
+#define S5P_APLL_SYSCLK_SYS S5P_PMUREG(0x1120)
+#define S5P_MPLL_SYSCLK_SYS S5P_PMUREG(0x1124)
+#define S5P_VPLL_SYSCLK_SYS S5P_PMUREG(0x1128)
+#define S5P_EPLL_SYSCLK_SYS S5P_PMUREG(0x112C)
+#define S5P_CMU_CLKSTOP_GPS_ALIVE_SYS S5P_PMUREG(0x1138)
+#define S5P_CMU_RESET_GPSALIVE_SYS S5P_PMUREG(0x113C)
+#define S5P_CMU_CLKSTOP_CAM_SYS S5P_PMUREG(0x1140)
+#define S5P_CMU_CLKSTOP_TV_SYS S5P_PMUREG(0x1144)
+#define S5P_CMU_CLKSTOP_MFC_SYS S5P_PMUREG(0x1148)
+#define S5P_CMU_CLKSTOP_G3D_SYS S5P_PMUREG(0x114C)
+#define S5P_CMU_CLKSTOP_LCD0_SYS S5P_PMUREG(0x1150)
+#define S5P_CMU_CLKSTOP_MAUDIO_SYS S5P_PMUREG(0x1158)
+#define S5P_CMU_CLKSTOP_GPS_SYS S5P_PMUREG(0x115C)
+#define S5P_CMU_RESET_CAM_SYS S5P_PMUREG(0x1160)
+#define S5P_CMU_RESET_TV_SYS S5P_PMUREG(0x1164)
+#define S5P_CMU_RESET_MFC_SYS S5P_PMUREG(0x1168)
+#define S5P_CMU_RESET_G3D_SYS S5P_PMUREG(0x116C)
+#define S5P_CMU_RESET_LCD0_SYS S5P_PMUREG(0x1170)
+#define S5P_CMU_RESET_MAUDIO_SYS S5P_PMUREG(0x1178)
+#define S5P_CMU_RESET_GPS_SYS S5P_PMUREG(0x117C)
+#define S5P_TOP_BUS_SYS S5P_PMUREG(0x1180)
+#define S5P_TOP_RETENTION_SYS S5P_PMUREG(0x1184)
+#define S5P_TOP_PWR_SYS S5P_PMUREG(0x1188)
+#define S5P_LOGIC_RESET_SYS S5P_PMUREG(0x11A0)
+#define S5P_ONENAND_MEM_SYS S5P_PMUREG(0x11C0)
+#define S5P_G2D_ACP_MEM_SYS S5P_PMUREG(0x11C8)
+#define S5P_USBOTG_MEM_SYS S5P_PMUREG(0x11CC)
+#define S5P_SDMMC_MEM_SYS S5P_PMUREG(0x11D0)
+#define S5P_CSSYS_MEM_SYS S5P_PMUREG(0x11D4)
+#define S5P_SECSS_MEM_SYS S5P_PMUREG(0x11D8)
+#define S5P_PAD_RETENTION_DRAM_SYS S5P_PMUREG(0x1200)
+#define S5P_PAD_RETENTION_MAUDIO_SYS S5P_PMUREG(0x1204)
+#define S5P_PAD_RETENTION_GPIO_SYS S5P_PMUREG(0x1220)
+#define S5P_PAD_RETENTION_UART_SYS S5P_PMUREG(0x1224)
+#define S5P_PAD_RETENTION_MMCA_SYS S5P_PMUREG(0x1228)
+#define S5P_PAD_RETENTION_MMCB_SYS S5P_PMUREG(0x122C)
+#define S5P_PAD_RETENTION_EBIA_SYS S5P_PMUREG(0x1230)
+#define S5P_PAD_RETENTION_EBIB_SYS S5P_PMUREG(0x1234)
+#define S5P_PAD_ISOLATION_SYS S5P_PMUREG(0x1240)
+#define S5P_PAD_ALV_SEL_SYS S5P_PMUREG(0x1260)
+#define S5P_XUSBXTI_SYS S5P_PMUREG(0x1280)
+#define S5P_XXTI_SYS S5P_PMUREG(0x1284)
+#define S5P_EXT_REGULATOR_SYS S5P_PMUREG(0x12C0)
+#define S5P_GPIO_MODE_SYS S5P_PMUREG(0x1300)
+#define S5P_GPIO_MODE_MAUDIO_SYS S5P_PMUREG(0x1340)
+#define S5P_CAM_SYS S5P_PMUREG(0x1380)
+#define S5P_TV_SYS S5P_PMUREG(0x1384)
+#define S5P_MFC_SYS S5P_PMUREG(0x1388)
+#define S5P_G3D_SYS S5P_PMUREG(0x138C)
+#define S5P_LCD0_SYS S5P_PMUREG(0x1390)
+#define S5P_LCD1_SYS S5P_PMUREG(0x1394)
+#define S5P_MAUDIO_SYS S5P_PMUREG(0x1398)
+#define S5P_GPS_SYS S5P_PMUREG(0x139C)
+#define S5P_GPS_ALIVE_SYS S5P_PMUREG(0x13A0)
+
+#define S5P_ARM_CORE0_CONFIGURATION S5P_PMUREG(0x2000)
+#define S5P_ARM_CORE0_STATUS S5P_PMUREG(0x2004)
+#define S5P_ARM_CORE0_OPTION S5P_PMUREG(0x2008)
+
+#define S5P_ARM_CORE_OPTION(_nr) (S5P_ARM_CORE0_OPTION + ((_nr) * 0x80))
+#define S5P_ARM_CORE_STATUS(_nr) (S5P_ARM_CORE0_STATUS + ((_nr) * 0x80))
+#define S5P_ARM_CORE_CONFIGURATION(_nr) (S5P_ARM_CORE0_CONFIGURATION + ((_nr) * 0x80))
+
+#define S5P_CORE_OPTION_DIS (1 << 8)
+
+#define S5P_ARM_COMMON_OPTION S5P_PMUREG(0x2408)
+#define S5P_CAM_OPTION S5P_PMUREG(0x3C08)
+#define S5P_TV_OPTION S5P_PMUREG(0x3C28)
+#define S5P_MFC_OPTION S5P_PMUREG(0x3C48)
+#define S5P_G3D_OPTION S5P_PMUREG(0x3C68)
+#define S5P_LCD0_OPTION S5P_PMUREG(0x3C88)
+#define S5P_LCD1_OPTION S5P_PMUREG(0x3CA8)
+#define S5P_MAUDIO_OPTION S5P_PMUREG(0x3CC8)
+#define S5P_GPS_OPTION S5P_PMUREG(0x3CE8)
+#define S5P_GPS_ALIVE_OPTION S5P_PMUREG(0x3D08)
+
+#define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028)
+#define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108)
+#define S5P_PAD_RET_UART_OPTION S5P_PMUREG(0x3128)
+#define S5P_PAD_RET_MMCA_OPTION S5P_PMUREG(0x3148)
+#define S5P_PAD_RET_MMCB_OPTION S5P_PMUREG(0x3168)
+#define S5P_PAD_RET_EBIA_OPTION S5P_PMUREG(0x3188)
+#define S5P_PAD_RET_EBIB_OPTION S5P_PMUREG(0x31A8)
+
+#define S5P_XXTI_CONFIGURATION S5P_PMUREG(0x3420)
+#define S5P_XXTI_STATUS S5P_PMUREG(0x3424)
+
+#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
+#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
+#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
+#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
+#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
+#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
+
+#define S5P_CORE_LOCAL_PWR_EN 0x3
+
+#define S5P_USE_DELAYED_RESET_ASSERTION (1 << 12)
+#define S5P_USE_DELAYED_RESET_OFFSET 12
+
+#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1
+#define S5P_INT_LOCAL_PWR_EN 0x7
+
+#define S5P_CHECK_SLEEP 0x00000BAD
+#define S5P_CHECK_DIDLE 0xBAD00000
+#define S5P_CHECK_LPA 0xABAD0000
+
+#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu5.h b/arch/arm/mach-exynos/include/mach/regs-pmu5.h
new file mode 100644
index 0000000..6bd9481
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu5.h
@@ -0,0 +1,568 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-pmu5.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - Power management unit definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_PMU5_H
+#define __ASM_ARCH_REGS_PMU5_H __FILE__
+
+#include "regs-pmu-5210.h"
+#include "regs-pmu-5250.h"
+
+#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
+
+#define EXYNOS5_OM_STAT S5P_PMUREG(0x0000)
+#define EXYNOS5_GPS_LPI S5P_PMUREG(0x0004)
+#define EXYNOS5_RTC_CLKO_SEL S5P_PMUREG(0x001C)
+#define EXYNOS5_GNSS_RTC_OUT_CTRL S5P_PMUREG(0x0020)
+#define EXYNOS5_C2C_CTRL S5P_PMUREG(0x0024)
+#define EXYNOS5_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200)
+#define EXYNOS5_CENTRAL_LOWPWR_CFG (1 << 16)
+
+#define EXYNOS5_CENTRAL_SEQ_STATUS S5P_PMUREG(0x0204)
+#define EXYNOS5_CENTRAL_SEQ_OPTION S5P_PMUREG(0x0208)
+
+#define EXYNOS5_USE_STANDBYWFE_ISP_ARM (1 << 29)
+#define EXYNOS5_USE_STANDBYWFE_FSYS_ARM (1 << 28)
+#define EXYNOS5_USE_STANDBYWFE_ARM_CORE1 (1 << 25)
+#define EXYNOS5_USE_STANDBYWFE_ARM_CORE0 (1 << 24)
+#define EXYNOS5_USE_STANDBYWFI_ISP_ARM (1 << 21)
+#define EXYNOS5_USE_STANDBYWFI_FSYS_ARM (1 << 20)
+#define EXYNOS5_USE_STANDBYWFI_ARM_CORE1 (1 << 17)
+#define EXYNOS5_USE_STANDBYWFI_ARM_CORE0 (1 << 16)
+#define EXYNOS5_FAST_PWUP (1 << 9)
+#define EXYNOS5_FAST_PWDN (1 << 8)
+
+#define EXYNOS5_SEQ_TRANSITION0 S5P_PMUREG(0x0220)
+#define EXYNOS5_SEQ_TRANSITION1 S5P_PMUREG(0x0224)
+#define EXYNOS5_SEQ_TRANSITION2 S5P_PMUREG(0x0228)
+#define EXYNOS5_SEQ_TRANSITION3 S5P_PMUREG(0x022C)
+#define EXYNOS5_SEQ_TRANSITION4 S5P_PMUREG(0x0230)
+#define EXYNOS5_SEQ_TRANSITION5 S5P_PMUREG(0x0234)
+#define EXYNOS5_SEQ_TRANSITION6 S5P_PMUREG(0x0238)
+#define EXYNOS5_SEQ_TRANSITION7 S5P_PMUREG(0x023C)
+#define EXYNOS5_CENTRAL_SEQ_SYSMEM_CONFIGURATION S5P_PMUREG(0x0240)
+#define EXYNOS5_CENTRAL_SEQ_SYSMEM_STATUS S5P_PMUREG(0x0244)
+#define EXYNOS5_CENTRAL_SEQ_SYSMEM_OPTION S5P_PMUREG(0x0248)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION0 S5P_PMUREG(0x0260)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION1 S5P_PMUREG(0x0264)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION2 S5P_PMUREG(0x0268)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION3 S5P_PMUREG(0x026C)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION4 S5P_PMUREG(0x0270)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION5 S5P_PMUREG(0x0274)
+#define EXYNOS5_SEQ_SYSMEM_TRANSITION6 S5P_PMUREG(0x0278)
+#define EXYNOS5_SEQ__TRANSITION7 S5P_PMUREG(0x027C)
+#define EXYNOS5_SWRESET S5P_PMUREG(0x0400)
+#define EXYNOS5_RST_STAT S5P_PMUREG(0x0404)
+
+#define EXYNOS5_SYS_WDTRESET (1 << 20)
+
+#define EXYNOS5_AUTOMATIC_WDT_RESET_DISABLE S5P_PMUREG(0x0408)
+#define EXYNOS5_MASK_WDT_RESET_REQUEST S5P_PMUREG(0x040C)
+#define EXYNOS5_RESET_SEQUENCER_CONFIGURATION S5P_PMUREG(0x0500)
+#define EXYNOS5_RESET_SEQUENCER_STATUS S5P_PMUREG(0x0504)
+#define EXYNOS5_RESET_SEQUENCER_OPTION S5P_PMUREG(0x0508)
+#define EXYNOS5_WAKEUP_STAT S5P_PMUREG(0x0600)
+#define EXYNOS5_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
+#define EXYNOS5_WAKEUP_MASK S5P_PMUREG(0x0608)
+
+#define EXYNOS5_DEFAULT_WAKEUP_MACK (0xF << 16)
+#define EXYNOS5_MASK_RTC_ALARM (1 << 1)
+#define EXYNOS5_MASK_RTC_TICK (1 << 2)
+#define EXYNOS5_MASK_KEY (1 << 5)
+#define EXYNOS5_MASK_HSI (1 << 8)
+#define EXYNOS5_MASK_MMC0 (1 << 9)
+#define EXYNOS5_MASK_MMC1 (1 << 10)
+#define EXYNOS5_MASK_MMC2 (1 << 11)
+#define EXYNOS5_MASK_MMC3 (1 << 12)
+#define EXYNOS5_MASK_I2S (1 << 13)
+#define EXYNOS5_MASK_TIMER (1 << 14)
+#define EXYNOS5_MASK_CEC (1 << 15)
+#define EXYNOS5_MASK_EXT_GIC0_IRQ (1 << 16)
+#define EXYNOS5_MASK_EXT_GIC0_FIQ (1 << 17)
+#define EXYNOS5_MASK_EXT_GIC1_IRQ (1 << 18)
+#define EXYNOS5_MASK_EXT_GIC1_FIQ (1 << 19)
+#define EXYNOS5_MASK_C2C_RESET_REQ (1 << 20)
+#define EXYNOS5_MASK_GPS (1 << 21)
+
+#define EXYNOS5_DEFAULT_WAKEUP_MASK (EXYNOS5_MASK_EXT_GIC0_IRQ |\
+ EXYNOS5_MASK_EXT_GIC0_FIQ |\
+ EXYNOS5_MASK_EXT_GIC1_IRQ |\
+ EXYNOS5_MASK_EXT_GIC1_FIQ)
+
+#define EXYNOS5_WAKEUP_INTERRUPT S5P_PMUREG(0x060C)
+#define EXYNOS5_WAKEUP_STAT_SYSMEM S5P_PMUREG(0x0620)
+#define EXYNOS5_EINT_WAKEUP_MASK_SYSMEM S5P_PMUREG(0x0624)
+#define EXYNOS5_WAKEUP_MASK_SYSMEM S5P_PMUREG(0x0628)
+#define EXYNOS5_WAKEUP_INTERRUPT_SYSMEM S5P_PMUREG(0x062C)
+#define EXYNOS5_HDMI_PHY_CONTROL S5P_PMUREG(0x0700)
+#define EXYNOS5_USBDEV_PHY_CONTROL S5P_PMUREG(0x0704)
+#define EXYNOS5_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708)
+#define EXYNOS5_MIPI_PHY0_CONTROL S5P_PMUREG(0x0710)
+#define EXYNOS5_MIPI_PHY1_CONTROL S5P_PMUREG(0x0714)
+#define EXYNOS5_ADC_PHY_CONTROL S5P_PMUREG(0x0718)
+#define EXYNOS5_MTCADC_PHY_CONTROL S5P_PMUREG(0x071C)
+#define EXYNOS5_DPTX_PHY_CONTROL S5P_PMUREG(0x0720)
+#define EXYNOS5_SATA_PHY_CONTROL S5P_PMUREG(0x0724)
+
+#define EXYNOS5_ABB_INT S5P_PMUREG(0x0780)
+#define EXYNOS5_ABB_ARM S5P_PMUREG(0x0784)
+#define EXYNOS5_ABB_G3D S5P_PMUREG(0x0788)
+#define EXYNOS5_ABB_MIF S5P_PMUREG(0x078C)
+
+#define EXYNOS5_ABB_MEMBER(_member) EXYNOS5_##_member
+
+#define EXYNOS5_INFORM0 S5P_PMUREG(0x0800)
+#define EXYNOS5_INFORM1 S5P_PMUREG(0x0804)
+#define EXYNOS5_INFORM2 S5P_PMUREG(0x0808)
+#define EXYNOS5_INFORM3 S5P_PMUREG(0x080C)
+#define EXYNOS5_INFORM4 S5P_PMUREG(0x0810)
+#define EXYNOS5_INFORM5 S5P_PMUREG(0x0814)
+#define EXYNOS5_INFORM6 S5P_PMUREG(0x0818)
+#define EXYNOS5_INFORM7 S5P_PMUREG(0x081C)
+#define EXYNOS5_PMU_SPARE0 S5P_PMUREG(0x0900)
+#define EXYNOS5_PMU_SPARE1 S5P_PMUREG(0x0904)
+#define EXYNOS5_PMU_SPARE2 S5P_PMUREG(0x0908)
+#define EXYNOS5_PMU_SPARE3 S5P_PMUREG(0x090C)
+#define EXYNOS5_IROM_DATA_REG0 S5P_PMUREG(0x0980)
+#define EXYNOS5_IROM_DATA_REG1 S5P_PMUREG(0x0984)
+#define EXYNOS5_IROM_DATA_REG2 S5P_PMUREG(0x0988)
+#define EXYNOS5_IROM_DATA_REG3 S5P_PMUREG(0x098C)
+
+#define EXYNOS5_ARM_CORE0_SYS_PWR_REG S5P_PMUREG(0x1000)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1004)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1008)
+#define EXYNOS5_ARM_CORE1_SYS_PWR_REG S5P_PMUREG(0x1010)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1014)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1018)
+#define EXYNOS5_FSYS_ARM_SYS_PWR_REG S5P_PMUREG(0x1040)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1048)
+#define EXYNOS5_ISP_ARM_SYS_PWR_REG S5P_PMUREG(0x1050)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG S5P_PMUREG(0x1054)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG S5P_PMUREG(0x1058)
+#define EXYNOS5_ARM_COMMON_SYS_PWR_REG S5P_PMUREG(0x1080)
+#define EXYNOS5_ARM_L2_SYS_PWR_REG S5P_PMUREG(0x10C0)
+#define EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1100)
+#define EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG S5P_PMUREG(0x1104)
+#define EXYNOS5_CMU_RESET_SYS_PWR_REG S5P_PMUREG(0x110C)
+#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1120)
+#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1124)
+#define EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x112C)
+#define EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG S5P_PMUREG(0x1130)
+#define EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG S5P_PMUREG(0x1134)
+#define EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG S5P_PMUREG(0x1138)
+#define EXYNOS5_APLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1140)
+#define EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1144)
+#define EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1148)
+#define EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x114C)
+#define EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1150)
+#define EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1154)
+#define EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1164)
+#define EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG S5P_PMUREG(0x1170)
+#define EXYNOS5_TOP_BUS_SYS_PWR_REG S5P_PMUREG(0x1180)
+#define EXYNOS5_TOP_RETENTION_SYS_PWR_REG S5P_PMUREG(0x1184)
+#define EXYNOS5_TOP_PWR_SYS_PWR_REG S5P_PMUREG(0x1188)
+#define EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1190)
+#define EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1194)
+#define EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1198)
+#define EXYNOS5_LOGIC_RESET_SYS_PWR_REG S5P_PMUREG(0x11A0)
+#define EXYNOS5_OSCCLK_GATE_SYS_PWR_REG S5P_PMUREG(0x11A4)
+#define EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B0)
+#define EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x11B4)
+#define EXYNOS5_G2D_MEM_SYS_PWR_REG S5P_PMUREG(0x11C8)
+#define EXYNOS5_SDMMC_MEM_SYS_PWR_REG S5P_PMUREG(0x11D0)
+#define EXYNOS5_CSSYS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D4)
+#define EXYNOS5_SECSS_MEM_SYS_PWR_REG S5P_PMUREG(0x11D8)
+#define EXYNOS5_ROTATOR_MEM_SYS_PWR_REG S5P_PMUREG(0x11DC)
+#define EXYNOS5_INTRAM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E0)
+#define EXYNOS5_INTROM_MEM_SYS_PWR_REG S5P_PMUREG(0x11E4)
+#define EXYNOS5_JPEG_MEM_SYS_PWR_REG S5P_PMUREG(0x11E8)
+#define EXYNOS5_HSI_MEM_SYS_PWR_REG S5P_PMUREG(0x11EC)
+#define EXYNOS5_MCUIOP_MEM_SYS_PWR_REG S5P_PMUREG(0x11F4)
+#define EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG S5P_PMUREG(0x1200)
+#define EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG S5P_PMUREG(0x1204)
+#define EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG S5P_PMUREG(0x1220)
+#define EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG S5P_PMUREG(0x1224)
+#define EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG S5P_PMUREG(0x1228)
+#define EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG S5P_PMUREG(0x122C)
+#define EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG S5P_PMUREG(0x1230)
+#define EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG S5P_PMUREG(0x1234)
+#define EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG S5P_PMUREG(0x1238)
+#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x123C)
+#define EXYNOS5_PAD_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1240)
+#define EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1250)
+#define EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG S5P_PMUREG(0x1260)
+#define EXYNOS5_XUSBXTI_SYS_PWR_REG S5P_PMUREG(0x1280)
+#define EXYNOS5_XXTI_SYS_PWR_REG S5P_PMUREG(0x1284)
+#define EXYNOS5_EXT_REGULATOR_SYS_PWR_REG S5P_PMUREG(0x12C0)
+#define EXYNOS5_GPIO_MODE_SYS_PWR_REG S5P_PMUREG(0x1300)
+#define EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG S5P_PMUREG(0x1320)
+#define EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG S5P_PMUREG(0x1340)
+#define EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG S5P_PMUREG(0x1344)
+#define EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG S5P_PMUREG(0x1348)
+#define EXYNOS5_GSCL_SYS_PWR_REG S5P_PMUREG(0x1400)
+#define EXYNOS5_ISP_SYS_PWR_REG S5P_PMUREG(0x1404)
+#define EXYNOS5_MFC_SYS_PWR_REG S5P_PMUREG(0x1408)
+#define EXYNOS5_G3D_SYS_PWR_REG S5P_PMUREG(0x140C)
+#define EXYNOS5_DISP0_SYS_PWR_REG S5P_PMUREG(0x1410)
+#define EXYNOS5_DISP1_SYS_PWR_REG S5P_PMUREG(0x1414)
+#define EXYNOS5_MAU_SYS_PWR_REG S5P_PMUREG(0x1418)
+#define EXYNOS5_GPS_SYS_PWR_REG S5P_PMUREG(0x141C)
+#define EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG S5P_PMUREG(0x1480)
+#define EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG S5P_PMUREG(0x1484)
+#define EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG S5P_PMUREG(0x1488)
+#define EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG S5P_PMUREG(0x148C)
+#define EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG S5P_PMUREG(0x1494)
+#define EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG S5P_PMUREG(0x1498)
+#define EXYNOS5_CMU_CLKSTOP_GPS_SYS_PWR_REG S5P_PMUREG(0x149C)
+#define EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG S5P_PMUREG(0x14C0)
+#define EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG S5P_PMUREG(0x14C4)
+#define EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG S5P_PMUREG(0x14C8)
+#define EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG S5P_PMUREG(0x14CC)
+#define EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG S5P_PMUREG(0x14D4)
+#define EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG S5P_PMUREG(0x14D8)
+#define EXYNOS5_CMU_SYSCLK_GPS_SYS_PWR_REG S5P_PMUREG(0x14DC)
+#define EXYNOS5_CMU_SCLKSTOP_GSCL_SYS_PWR_REG S5P_PMUREG(0x1500)
+#define EXYNOS5_CMU_SCLKSTOP_ISP_SYS_PWR_REG S5P_PMUREG(0x1504)
+#define EXYNOS5_CMU_SCLKSTOP_MFC_SYS_PWR_REG S5P_PMUREG(0x1508)
+#define EXYNOS5_CMU_SCLKSTOP_G3D_SYS_PWR_REG S5P_PMUREG(0x150C)
+#define EXYNOS5_CMU_SCLKSTOP_DISP1_SYS_PWR_REG S5P_PMUREG(0x1514)
+#define EXYNOS5_CMU_SCLKSTOP_MAU_SYS_PWR_REG S5P_PMUREG(0x1518)
+#define EXYNOS5_CMU_SCLKSTOP_GPS_SYS_PWR_REG S5P_PMUREG(0x151C)
+#define EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG S5P_PMUREG(0x1580)
+#define EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG S5P_PMUREG(0x1584)
+#define EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG S5P_PMUREG(0x1588)
+#define EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG S5P_PMUREG(0x158C)
+#define EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG S5P_PMUREG(0x1594)
+#define EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG S5P_PMUREG(0x1598)
+#define EXYNOS5_CMU_RESET_GPS_SYS_PWR_REG S5P_PMUREG(0x159C)
+
+/* Definition for XXX_OPTION */
+#define EXYNOS5_OPTION_USE_STANDBYWFE (1 << 24)
+#define EXYNOS5_OPTION_USE_STANDBYWFI (1 << 16)
+#define EXYNOS5_OPTION_USE_RETENTION (1 << 4)
+#define EXYNOS5_USE_SC_FEEDBACK (1 << 1)
+#define EXYNOS5_USE_SC_COUNTER (1 << 0)
+
+#define EXYNOS5_ARM_CORE0_CONFIGURATION S5P_PMUREG(0x2000)
+#define EXYNOS5_ARM_CORE0_STATUS S5P_PMUREG(0x2004)
+#define EXYNOS5_ARM_CORE0_OPTION S5P_PMUREG(0x2008)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_CONFIGURATION S5P_PMUREG(0x2020)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_STATUS S5P_PMUREG(0x2024)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_OPTION S5P_PMUREG(0x2028)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_CONFIGURATION S5P_PMUREG(0x2040)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_STATUS S5P_PMUREG(0x2044)
+#define EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_OPTION S5P_PMUREG(0x2048)
+#define EXYNOS5_ARM_CORE1_CONFIGURATION S5P_PMUREG(0x2080)
+#define EXYNOS5_ARM_CORE1_STATUS S5P_PMUREG(0x2084)
+#define EXYNOS5_ARM_CORE1_OPTION S5P_PMUREG(0x2088)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_CONFIGURATION S5P_PMUREG(0x20A0)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_STATUS S5P_PMUREG(0x20A4)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_OPTION S5P_PMUREG(0x20A8)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_CONFIGURATION S5P_PMUREG(0x20C0)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_STATUS S5P_PMUREG(0x20C4)
+#define EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_OPTION S5P_PMUREG(0x20C8)
+#define EXYNOS5_FSYS_ARM_CONFIGURATION S5P_PMUREG(0x2200)
+#define EXYNOS5_FSYS_ARM_STATUS S5P_PMUREG(0x2204)
+#define EXYNOS5_FSYS_ARM_OPTION S5P_PMUREG(0x2208)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_LOCAL_CONFIGURATION S5P_PMUREG(0x2220)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_LOCAL_STATUS S5P_PMUREG(0x2224)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_LOCAL_OPTION S5P_PMUREG(0x2228)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_CONFIGURATION S5P_PMUREG(0x2240)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_STATUS S5P_PMUREG(0x2244)
+#define EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_OPTION S5P_PMUREG(0x2248)
+#define EXYNOS5_ISP_ARM_CONFIGURATION S5P_PMUREG(0x2280)
+#define EXYNOS5_ISP_ARM_STATUS S5P_PMUREG(0x2284)
+#define EXYNOS5_ISP_ARM_OPTION S5P_PMUREG(0x2288)
+
+#define EXYNOS5_ISP_ARM_ENABLE (1 << 15)
+
+#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_CONFIGURATION S5P_PMUREG(0x22A0)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_STATUS S5P_PMUREG(0x22A4)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_OPTION S5P_PMUREG(0x22A8)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_CONFIGURATION S5P_PMUREG(0x22C0)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_STATUS S5P_PMUREG(0x22C4)
+#define EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_OPTION S5P_PMUREG(0x22C8)
+#define EXYNOS5_ARM_COMMON_CONFIGURATION S5P_PMUREG(0x2400)
+#define EXYNOS5_ARM_COMMON_STATUS S5P_PMUREG(0x2404)
+#define EXYNOS5_ARM_COMMON_OPTION S5P_PMUREG(0x2408)
+
+#define EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL (1 << 2)
+#define EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN (1 << 7)
+
+#define EXYNOS5_ARM_L2_CONFIGURATION S5P_PMUREG(0x2600)
+#define EXYNOS5_ARM_L2_STATUS S5P_PMUREG(0x2604)
+#define EXYNOS5_ARM_L2_OPTION S5P_PMUREG(0x2608)
+#define EXYNOS5_CMU_ACLKSTOP_CONFIGURATION S5P_PMUREG(0x2800)
+#define EXYNOS5_CMU_ACLKSTOP_STATUS S5P_PMUREG(0x2804)
+#define EXYNOS5_CMU_ACLKSTOP_OPTION S5P_PMUREG(0x2808)
+#define EXYNOS5_CMU_SCLKSTOP_CONFIGURATION S5P_PMUREG(0x2820)
+#define EXYNOS5_CMU_SCLKSTOP_STATUS S5P_PMUREG(0x2824)
+#define EXYNOS5_CMU_SCLKSTOP_OPTION S5P_PMUREG(0x2828)
+#define EXYNOS5_CMU_RESET_CONFIGURATION S5P_PMUREG(0x2860)
+#define EXYNOS5_CMU_RESET_STATUS S5P_PMUREG(0x2864)
+#define EXYNOS5_CMU_RESET_OPTION S5P_PMUREG(0x2868)
+#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_CONFIGURATION S5P_PMUREG(0x2900)
+#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_STATUS S5P_PMUREG(0x2904)
+#define EXYNOS5_CMU_ACLKSTOP_SYSMEM_OPTION S5P_PMUREG(0x2908)
+#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_CONFIGURATION S5P_PMUREG(0x2920)
+#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_STATUS S5P_PMUREG(0x2924)
+#define EXYNOS5_CMU_SCLKSTOP_SYSMEM_OPTION S5P_PMUREG(0x2928)
+#define EXYNOS5_CMU_RESET_SYSMEM_CONFIGURATION S5P_PMUREG(0x2960)
+#define EXYNOS5_CMU_RESET_SYSMEM_STATUS S5P_PMUREG(0x2964)
+#define EXYNOS5_CMU_RESET_SYSMEM_OPTION S5P_PMUREG(0x2968)
+#define EXYNOS5_DRAM_FREQ_DOWN_CONFIGURATION S5P_PMUREG(0x2980)
+#define EXYNOS5_DRAM_FREQ_DOWN_STATUS S5P_PMUREG(0x2984)
+#define EXYNOS5_DRAM_FREQ_DOWN_OPTION S5P_PMUREG(0x2988)
+#define EXYNOS5_DDRPHY_DLLOFF_CONFIGURATION S5P_PMUREG(0x29A0)
+#define EXYNOS5_DDRPHY_DLLOFF_STATUS S5P_PMUREG(0x29A4)
+#define EXYNOS5_DDRPHY_DLLOFF_OPTION S5P_PMUREG(0x29A8)
+#define EXYNOS5_DDRPHY_DLLLOCK_CONFIGURATION S5P_PMUREG(0x29C0)
+#define EXYNOS5_DDRPHY_DLLLOCK_STATUS S5P_PMUREG(0x29C4)
+#define EXYNOS5_DDRPHY_DLLLOCK_OPTION S5P_PMUREG(0x29C8)
+#define EXYNOS5_APLL_SYSCLK_CONFIGURATION S5P_PMUREG(0x2A00)
+#define EXYNOS5_APLL_SYSCLK_STATUS S5P_PMUREG(0x2A04)
+#define EXYNOS5_APLL_SYSCLK_OPTION S5P_PMUREG(0x2A08)
+#define EXYNOS5_MPLL_SYSCLK_STATUS S5P_PMUREG(0x2A24)
+#define EXYNOS5_MPLL_SYSCLK_OPTION S5P_PMUREG(0x2A28)
+#define EXYNOS5_VPLL_SYSCLK_CONFIGURATION S5P_PMUREG(0x2A40)
+#define EXYNOS5_VPLL_SYSCLK_STATUS S5P_PMUREG(0x2A44)
+#define EXYNOS5_VPLL_SYSCLK_OPTION S5P_PMUREG(0x2A48)
+#define EXYNOS5_EPLL_SYSCLK_CONFIGURATION S5P_PMUREG(0x2A60)
+#define EXYNOS5_EPLL_SYSCLK_STATUS S5P_PMUREG(0x2A64)
+#define EXYNOS5_EPLL_SYSCLK_OPTION S5P_PMUREG(0x2A68)
+#define EXYNOS5_BPLL_SYSCLK_CONFIGURATION S5P_PMUREG(0x2A80)
+#define EXYNOS5_BPLL_SYSCLK_STATUS S5P_PMUREG(0x2A84)
+#define EXYNOS5_BPLL_SYSCLK_OPTION S5P_PMUREG(0x2A88)
+#define EXYNOS5_CPLL_SYSCLK_CONFIGURATION S5P_PMUREG(0x2AA0)
+#define EXYNOS5_CPLL_SYSCLK_STATUS S5P_PMUREG(0x2AA4)
+#define EXYNOS5_CPLL_SYSCLK_OPTION S5P_PMUREG(0x2AA8)
+#define EXYNOS5_MPLLUSER_SYSCLK_CONFIGURATION S5P_PMUREG(0x2B20)
+#define EXYNOS5_MPLLUSER_SYSCLK_STATUS S5P_PMUREG(0x2B24)
+#define EXYNOS5_MPLLUSER_SYSCLK_OPTION S5P_PMUREG(0x2B28)
+#define EXYNOS5_BPLLUSER_SYSCLK_CONFIGURATION S5P_PMUREG(0x2B80)
+#define EXYNOS5_BPLLUSER_SYSCLK_STATUS S5P_PMUREG(0x2B84)
+#define EXYNOS5_BPLLUSER_SYSCLK_OPTION S5P_PMUREG(0x2B88)
+#define EXYNOS5_TOP_BUS_CONFIGURATION S5P_PMUREG(0x2C00)
+#define EXYNOS5_TOP_BUS_STATUS S5P_PMUREG(0x2C04)
+#define EXYNOS5_TOP_BUS_OPTION S5P_PMUREG(0x2C08)
+#define EXYNOS5_TOP_RETENTION_CONFIGURATION S5P_PMUREG(0x2C20)
+#define EXYNOS5_TOP_RETENTION_STATUS S5P_PMUREG(0x2C24)
+#define EXYNOS5_TOP_RETENTION_OPTION S5P_PMUREG(0x2C28)
+#define EXYNOS5_TOP_PWR_CONFIGURATION S5P_PMUREG(0x2C40)
+#define EXYNOS5_TOP_PWR_STATUS S5P_PMUREG(0x2C44)
+#define EXYNOS5_TOP_PWR_OPTION S5P_PMUREG(0x2C48)
+#define EXYNOS5_TOP_BUS_SYSMEM_CONFIGURATION S5P_PMUREG(0x2C80)
+#define EXYNOS5_TOP_BUS_SYSMEM_STATUS S5P_PMUREG(0x2C84)
+#define EXYNOS5_TOP_BUS_SYSMEM_OPTION S5P_PMUREG(0x2C88)
+#define EXYNOS5_TOP_RETENTION_SYSMEM_CONFIGURATION S5P_PMUREG(0x2CA0)
+#define EXYNOS5_TOP_RETENTION_SYSMEM_STATUS S5P_PMUREG(0x2CA4)
+#define EXYNOS5_TOP_RETENTION_SYSMEM_OPTION S5P_PMUREG(0x2CA8)
+#define EXYNOS5_TOP_PWR_SYSMEM_CONFIGURATION S5P_PMUREG(0x2CC0)
+#define EXYNOS5_TOP_PWR_SYSMEM_STATUS S5P_PMUREG(0x2CC4)
+#define EXYNOS5_TOP_PWR_SYSMEM_OPTION S5P_PMUREG(0x2CC8)
+#define EXYNOS5_LOGIC_RESET_CONFIGURATION S5P_PMUREG(0x2D00)
+#define EXYNOS5_LOGIC_RESET_STATUS S5P_PMUREG(0x2D04)
+#define EXYNOS5_LOGIC_RESET_OPTION S5P_PMUREG(0x2D08)
+#define EXYNOS5_OSCCLK_GATE_CONFIGURATION S5P_PMUREG(0x2D20)
+#define EXYNOS5_OSCCLK_GATE_STATUS S5P_PMUREG(0x2D24)
+#define EXYNOS5_OSCCLK_GATE_OPTION S5P_PMUREG(0x2D28)
+#define EXYNOS5_LOGIC_RESET_SYSMEM_CONFIGURATION S5P_PMUREG(0x2D80)
+#define EXYNOS5_LOGIC_RESET_SYSMEM_STATUS S5P_PMUREG(0x2D84)
+#define EXYNOS5_LOGIC_RESET_SYSMEM_OPTION S5P_PMUREG(0x2D88)
+#define EXYNOS5_OSCCLK_GATE_SYSMEM_CONFIGURATION S5P_PMUREG(0x2DA0)
+#define EXYNOS5_OSCCLK_GATE_SYSMEM_STATUS S5P_PMUREG(0x2DA4)
+#define EXYNOS5_OSCCLK_GATE_SYSMEM_OPTION S5P_PMUREG(0x2DA8)
+#define EXYNOS5_OneNANDXL_MEM_CONFIGURATION S5P_PMUREG(0x2E00)
+#define EXYNOS5_OneNANDXL_MEM_STATUS S5P_PMUREG(0x2E04)
+#define EXYNOS5_OneNANDXL_MEM_OPTION S5P_PMUREG(0x2E08)
+#define EXYNOS5_G2D_MEM_CONFIGURATION S5P_PMUREG(0x2E40)
+#define EXYNOS5_G2D_MEM_STATUS S5P_PMUREG(0x2E44)
+#define EXYNOS5_G2D_MEM_OPTION S5P_PMUREG(0x2E48)
+#define EXYNOS5_USBDEV_MEM_CONFIGURATION S5P_PMUREG(0x2E60)
+#define EXYNOS5_USBDEV_MEM_STATUS S5P_PMUREG(0x2E64)
+#define EXYNOS5_USBDEV_MEM_OPTION S5P_PMUREG(0x2E68)
+#define EXYNOS5_SDMMC_MEM_CONFIGURATION S5P_PMUREG(0x2E80)
+#define EXYNOS5_SDMMC_MEM_STATUS S5P_PMUREG(0x2E84)
+#define EXYNOS5_SDMMC_MEM_OPTION S5P_PMUREG(0x2E88)
+#define EXYNOS5_CSSYS_MEM_CONFIGURATION S5P_PMUREG(0x2EA0)
+#define EXYNOS5_CSSYS_MEM_STATUS S5P_PMUREG(0x2EA4)
+#define EXYNOS5_CSSYS_MEM_OPTION S5P_PMUREG(0x2EA8)
+#define EXYNOS5_SECSS_MEM_CONFIGURATION S5P_PMUREG(0x2EC0)
+#define EXYNOS5_SECSS_MEM_STATUS S5P_PMUREG(0x2EC4)
+#define EXYNOS5_SECSS_MEM_OPTION S5P_PMUREG(0x2EC8)
+#define EXYNOS5_ROTATOR_MEM_CONFIGURATION S5P_PMUREG(0x2EE0)
+#define EXYNOS5_ROTATOR_MEM_STATUS S5P_PMUREG(0x2EE4)
+#define EXYNOS5_ROTATOR_MEM_OPTION S5P_PMUREG(0x2EE8)
+#define EXYNOS5_INTRAM_MEM_CONFIGURATION S5P_PMUREG(0x2F00)
+#define EXYNOS5_INTRAM_MEM_STATUS S5P_PMUREG(0x2F04)
+#define EXYNOS5_INTRAM_MEM_OPTION S5P_PMUREG(0x2F08)
+#define EXYNOS5_INTROM_MEM_CONFIGURATION S5P_PMUREG(0x2F20)
+#define EXYNOS5_INTROM_MEM_STATUS S5P_PMUREG(0x2F24)
+#define EXYNOS5_INTROM_MEM_OPTION S5P_PMUREG(0x2F28)
+#define EXYNOS5_JPEG_MEM_CONFIGURATION S5P_PMUREG(0x2F40)
+#define EXYNOS5_JPEG_MEM_STATUS S5P_PMUREG(0x2F44)
+#define EXYNOS5_JPEG_MEM_OPTION S5P_PMUREG(0x2F48)
+#define EXYNOS5_HSI_MEM_CONFIGURATION S5P_PMUREG(0x2F60)
+#define EXYNOS5_HSI_MEM_STATUS S5P_PMUREG(0x2F64)
+#define EXYNOS5_HSI_MEM_OPTION S5P_PMUREG(0x2F68)
+#define EXYNOS5_MCUIOP_MEM_CONFIGURATION S5P_PMUREG(0x2FA0)
+#define EXYNOS5_MCUIOP_MEM_STATUS S5P_PMUREG(0x2FA4)
+#define EXYNOS5_MCUIOP_MEM_OPTION S5P_PMUREG(0x2FA8)
+#define EXYNOS5_PAD_RETENTION_DRAM_CONFIGURATION S5P_PMUREG(0x3000)
+#define EXYNOS5_PAD_RETENTION_DRAM_STATUS S5P_PMUREG(0x3004)
+#define EXYNOS5_PAD_RETENTION_DRAM_OPTION S5P_PMUREG(0x3008)
+#define EXYNOS5_PAD_RETENTION_MAU_CONFIGURATION S5P_PMUREG(0x3020)
+#define EXYNOS5_PAD_RETENTION_MAU_STATUS S5P_PMUREG(0x3024)
+#define EXYNOS5_PAD_RETENTION_MAU_OPTION S5P_PMUREG(0x3028)
+#define EXYNOS5_PAD_RETENTION_GPIO_CONFIGURATION S5P_PMUREG(0x3100)
+#define EXYNOS5_PAD_RETENTION_GPIO_STATUS S5P_PMUREG(0x3104)
+#define EXYNOS5_PAD_RETENTION_GPIO_OPTION S5P_PMUREG(0x3108)
+#define EXYNOS5_PAD_RETENTION_UART_CONFIGURATION S5P_PMUREG(0x3120)
+#define EXYNOS5_PAD_RETENTION_UART_STATUS S5P_PMUREG(0x3124)
+#define EXYNOS5_PAD_RETENTION_UART_OPTION S5P_PMUREG(0x3128)
+#define EXYNOS5_PAD_RETENTION_MMCA_CONFIGURATION S5P_PMUREG(0x3140)
+#define EXYNOS5_PAD_RETENTION_MMCA_STATUS S5P_PMUREG(0x3144)
+#define EXYNOS5_PAD_RETENTION_MMCA_OPTION S5P_PMUREG(0x3148)
+#define EXYNOS5_PAD_RETENTION_MMCB_CONFIGURATION S5P_PMUREG(0x3160)
+#define EXYNOS5_PAD_RETENTION_MMCB_STATUS S5P_PMUREG(0x3164)
+#define EXYNOS5_PAD_RETENTION_MMCB_OPTION S5P_PMUREG(0x3168)
+#define EXYNOS5_PAD_RETENTION_EBIA_CONFIGURATION S5P_PMUREG(0x3180)
+#define EXYNOS5_PAD_RETENTION_EBIA_STATUS S5P_PMUREG(0x3184)
+#define EXYNOS5_PAD_RETENTION_EBIA_OPTION S5P_PMUREG(0x3188)
+#define EXYNOS5_PAD_RETENTION_EBIB_CONFIGURATION S5P_PMUREG(0x31A0)
+#define EXYNOS5_PAD_RETENTION_EBIB_STATUS S5P_PMUREG(0x31A4)
+#define EXYNOS5_PAD_RETENTION_EBIB_OPTION S5P_PMUREG(0x31A8)
+#define EXYNOS5_PAD_RETENTION_SPI_CONFIGURATION S5P_PMUREG(0x31C0)
+#define EXYNOS5_PAD_RETENTION_SPI_STATUS S5P_PMUREG(0x31C4)
+#define EXYNOS5_PAD_RETENTION_SPI_OPTION S5P_PMUREG(0x31C8)
+#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_CONFIGURATION S5P_PMUREG(0x31E0)
+#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_STATUS S5P_PMUREG(0x31E4)
+#define EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_OPTION S5P_PMUREG(0x31E8)
+#define EXYNOS5_PAD_ISOLATION_CONFIGURATION S5P_PMUREG(0x3200)
+#define EXYNOS5_PAD_ISOLATION_STATUS S5P_PMUREG(0x3204)
+#define EXYNOS5_PAD_ISOLATION_OPTION S5P_PMUREG(0x3208)
+#define EXYNOS5_PAD_ISOLATION_SYSMEM_CONFIGURATION S5P_PMUREG(0x3280)
+#define EXYNOS5_PAD_ISOLATION_SYSMEM_STATUS S5P_PMUREG(0x3284)
+#define EXYNOS5_PAD_ISOLATION_SYSMEM_OPTION S5P_PMUREG(0x3288)
+#define EXYNOS5_PAD_ALV_SEL_CONFIGURATION S5P_PMUREG(0x3300)
+#define EXYNOS5_PAD_ALV_SEL_STATUS S5P_PMUREG(0x3304)
+#define EXYNOS5_PAD_ALV_SEL_OPTION0 S5P_PMUREG(0x3308)
+#define EXYNOS5_PS_HOLD_CONTROL S5P_PMUREG(0x330C)
+#define EXYNOS5_XUSBXTI_CONFIGURATION S5P_PMUREG(0x3400)
+#define EXYNOS5_XUSBXTI_STATUS S5P_PMUREG(0x3404)
+#define EXYNOS5_XUSBXTI_OPTION S5P_PMUREG(0x3408)
+#define EXYNOS5_XUSBXTI_DURATION3 S5P_PMUREG(0x341C)
+#define EXYNOS5_XXTI_CONFIGURATION S5P_PMUREG(0x3420)
+#define EXYNOS5_XXTI_STATUS S5P_PMUREG(0x3424)
+#define EXYNOS5_XXTI_OPTION S5P_PMUREG(0x3428)
+#define EXYNOS5_XXTI_DURATION3 S5P_PMUREG(0x343C)
+#define EXYNOS5_EXT_REGULATOR_CONFIGURATION S5P_PMUREG(0x3600)
+#define EXYNOS5_EXT_REGULATOR_STATUS S5P_PMUREG(0x3604)
+#define EXYNOS5_EXT_REGULATOR_OPTION S5P_PMUREG(0x3608)
+#define EXYNOS5_EXT_REGULATOR_DURATION3 S5P_PMUREG(0x361C)
+#define EXYNOS5_GPIO_MODE_CONFIGURATION S5P_PMUREG(0x3800)
+#define EXYNOS5_GPIO_MODE_STATUS S5P_PMUREG(0x3804)
+#define EXYNOS5_GPIO_MODE_OPTION S5P_PMUREG(0x3808)
+#define EXYNOS5_GPIO_MODE_SYSMEM_CONFIGURATION S5P_PMUREG(0x3900)
+#define EXYNOS5_GPIO_MODE_SYSMEM_STATUS S5P_PMUREG(0x3904)
+#define EXYNOS5_GPIO_MODE_SYSMEM_OPTION S5P_PMUREG(0x3908)
+#define EXYNOS5_GPIO_MODE_MAU_CONFIGURATION S5P_PMUREG(0x39E0)
+#define EXYNOS5_GPIO_MODE_MAU_STATUS S5P_PMUREG(0x39E4)
+#define EXYNOS5_GPIO_MODE_MAU_OPTION S5P_PMUREG(0x39E8)
+#define EXYNOS5_TOP_ASB_RESET_CONFIGURATION S5P_PMUREG(0x3A00)
+#define EXYNOS5_TOP_ASB_RESET_STATUS S5P_PMUREG(0x3A04)
+#define EXYNOS5_TOP_ASB_RESET_OPTION S5P_PMUREG(0x3A08)
+#define EXYNOS5_TOP_ASB_ISOLATION_CONFIGURATION S5P_PMUREG(0x3A20)
+#define EXYNOS5_TOP_ASB_ISOLATION_STATUS S5P_PMUREG(0x3A24)
+#define EXYNOS5_TOP_ASB_ISOLATION_OPTION S5P_PMUREG(0x3A28)
+#define EXYNOS5_GSCL_CONFIGURATION S5P_PMUREG(0x4000)
+#define EXYNOS5_GSCL_STATUS S5P_PMUREG(0x4004)
+#define EXYNOS5_GSCL_OPTION S5P_PMUREG(0x4008)
+#define EXYNOS5_ISP_CONFIGURATION S5P_PMUREG(0x4020)
+#define EXYNOS5_ISP_STATUS S5P_PMUREG(0x4024)
+#define EXYNOS5_ISP_OPTION S5P_PMUREG(0x4028)
+#define EXYNOS5_MFC_CONFIGURATION S5P_PMUREG(0x4040)
+#define EXYNOS5_MFC_STATUS S5P_PMUREG(0x4044)
+#define EXYNOS5_MFC_OPTION S5P_PMUREG(0x4048)
+#define EXYNOS5_G3D_CONFIGURATION S5P_PMUREG(0x4060)
+#define EXYNOS5_G3D_STATUS S5P_PMUREG(0x4064)
+#define EXYNOS5_G3D_OPTION S5P_PMUREG(0x4068)
+#define EXYNOS5_DISP1_CONFIGURATION S5P_PMUREG(0x40A0)
+#define EXYNOS5_DISP1_STATUS S5P_PMUREG(0x40A4)
+#define EXYNOS5_DISP1_OPTION S5P_PMUREG(0x40A8)
+#define EXYNOS5_MAU_CONFIGURATION S5P_PMUREG(0x40C0)
+#define EXYNOS5_MAU_STATUS S5P_PMUREG(0x40C4)
+#define EXYNOS5_MAU_OPTION S5P_PMUREG(0x40C8)
+#define EXYNOS5_GPS_CONFIGURATION S5P_PMUREG(0x40E0)
+#define EXYNOS5_GPS_STATUS S5P_PMUREG(0x40E4)
+#define EXYNOS5_GPS_OPTION S5P_PMUREG(0x40E8)
+#define EXYNOS5_CMU_CLKSTOP_GSCL_CONFIGURATION S5P_PMUREG(0x4400)
+#define EXYNOS5_CMU_CLKSTOP_GSCL_STATUS S5P_PMUREG(0x4404)
+#define EXYNOS5_CMU_CLKSTOP_GSCL_OPTION S5P_PMUREG(0x4408)
+#define EXYNOS5_CMU_CLKSTOP_ISP_CONFIGURATION S5P_PMUREG(0x4420)
+#define EXYNOS5_CMU_CLKSTOP_ISP_STATUS S5P_PMUREG(0x4424)
+#define EXYNOS5_CMU_CLKSTOP_ISP_OPTION S5P_PMUREG(0x4428)
+#define EXYNOS5_CMU_CLKSTOP_MFC_CONFIGURATION S5P_PMUREG(0x4440)
+#define EXYNOS5_CMU_CLKSTOP_MFC_STATUS S5P_PMUREG(0x4444)
+#define EXYNOS5_CMU_CLKSTOP_MFC_OPTION S5P_PMUREG(0x4448)
+#define EXYNOS5_CMU_CLKSTOP_G3D_CONFIGURATION S5P_PMUREG(0x4460)
+#define EXYNOS5_CMU_CLKSTOP_G3D_STATUS S5P_PMUREG(0x4464)
+#define EXYNOS5_CMU_CLKSTOP_G3D_OPTION S5P_PMUREG(0x4468)
+#define EXYNOS5_CMU_CLKSTOP_DISP1_CONFIGURATION S5P_PMUREG(0x44A0)
+#define EXYNOS5_CMU_CLKSTOP_DISP1_STATUS S5P_PMUREG(0x44A4)
+#define EXYNOS5_CMU_CLKSTOP_DISP1_OPTION S5P_PMUREG(0x44A8)
+#define EXYNOS5_CMU_CLKSTOP_MAU_CONFIGURATION S5P_PMUREG(0x44C0)
+#define EXYNOS5_CMU_CLKSTOP_MAU_STATUS S5P_PMUREG(0x44C4)
+#define EXYNOS5_CMU_CLKSTOP_MAU_OPTION S5P_PMUREG(0x44C8)
+#define EXYNOS5_CMU_CLKSTOP_GPS_CONFIGURATION S5P_PMUREG(0x44E0)
+#define EXYNOS5_CMU_CLKSTOP_GPS_STATUS S5P_PMUREG(0x44E4)
+#define EXYNOS5_CMU_CLKSTOP_GPS_OPTION S5P_PMUREG(0x44E8)
+#define EXYNOS5_CMU_SYSCLK_GSCL_CONFIGURATION S5P_PMUREG(0x4600)
+#define EXYNOS5_CMU_SYSCLK_GSCL_STATUS S5P_PMUREG(0x4604)
+#define EXYNOS5_CMU_SYSCLK_GSCL_OPTION S5P_PMUREG(0x4608)
+#define EXYNOS5_CMU_SYSCLK_ISP_STATUS S5P_PMUREG(0x4624)
+#define EXYNOS5_CMU_SYSCLK_ISP_OPTION S5P_PMUREG(0x4628)
+#define EXYNOS5_CMU_SYSCLK_MFC_STATUS S5P_PMUREG(0x4644)
+#define EXYNOS5_CMU_SYSCLK_MFC_OPTION S5P_PMUREG(0x4648)
+#define EXYNOS5_CMU_SYSCLK_G3D_STATUS S5P_PMUREG(0x4664)
+#define EXYNOS5_CMU_SYSCLK_G3D_OPTION S5P_PMUREG(0x4668)
+#define EXYNOS5_CMU_SYSCLK_DISP1_STATUS S5P_PMUREG(0x46A4)
+#define EXYNOS5_CMU_SYSCLK_DISP1_OPTION S5P_PMUREG(0x46A8)
+#define EXYNOS5_CMU_SYSCLK_MAU_STATUS S5P_PMUREG(0x46C4)
+#define EXYNOS5_CMU_SYSCLK_MAU_OPTION S5P_PMUREG(0x46C8)
+#define EXYNOS5_CMU_SYSCLK_GPS_STATUS S5P_PMUREG(0x46E4)
+#define EXYNOS5_CMU_SYSCLK_GPS_OPTION S5P_PMUREG(0x46E8)
+#define EXYNOS5_CMU_RESET_GSCL_CONFIGURATION S5P_PMUREG(0x4C00)
+#define EXYNOS5_CMU_RESET_GSCL_STATUS S5P_PMUREG(0x4C04)
+#define EXYNOS5_CMU_RESET_GSCL_OPTION S5P_PMUREG(0x4C08)
+#define EXYNOS5_CMU_RESET_ISP_CONFIGURATION S5P_PMUREG(0x4C20)
+#define EXYNOS5_CMU_RESET_ISP_STATUS S5P_PMUREG(0x4C24)
+#define EXYNOS5_CMU_RESET_ISP_OPTION S5P_PMUREG(0x4C28)
+#define EXYNOS5_CMU_RESET_MFC_CONFIGURATION S5P_PMUREG(0x4C40)
+#define EXYNOS5_CMU_RESET_MFC_STATUS S5P_PMUREG(0x4C44)
+#define EXYNOS5_CMU_RESET_MFC_OPTION S5P_PMUREG(0x4C48)
+#define EXYNOS5_CMU_RESET_G3D_CONFIGURATION S5P_PMUREG(0x4C60)
+#define EXYNOS5_CMU_RESET_G3D_STATUS S5P_PMUREG(0x4C64)
+#define EXYNOS5_CMU_RESET_G3D_OPTION S5P_PMUREG(0x4C68)
+#define EXYNOS5_CMU_RESET_DISP0_CONFIGURATION S5P_PMUREG(0x4C80)
+#define EXYNOS5_CMU_RESET_DISP0_STATUS S5P_PMUREG(0x4C84)
+#define EXYNOS5_CMU_RESET_DISP0_OPTION S5P_PMUREG(0x4C88)
+#define EXYNOS5_CMU_RESET_DISP1_CONFIGURATION S5P_PMUREG(0x4CA0)
+#define EXYNOS5_CMU_RESET_DISP1_STATUS S5P_PMUREG(0x4CA4)
+#define EXYNOS5_CMU_RESET_DISP1_OPTION S5P_PMUREG(0x4CA8)
+#define EXYNOS5_CMU_RESET_MAU_CONFIGURATION S5P_PMUREG(0x4CC0)
+#define EXYNOS5_CMU_RESET_MAU_STATUS S5P_PMUREG(0x4CC4)
+#define EXYNOS5_CMU_RESET_MAU_OPTION S5P_PMUREG(0x4CC8)
+#define EXYNOS5_CMU_RESET_GPS_CONFIGURATION S5P_PMUREG(0x4CE0)
+#define EXYNOS5_CMU_RESET_GPS_STATUS S5P_PMUREG(0x4CE4)
+#define EXYNOS5_CMU_RESET_GPS_OPTION S5P_PMUREG(0x4CE8)
+
+#endif /* __ASM_ARCH_REGS_PMU5_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-sdo.h b/arch/arm/mach-exynos/include/mach/regs-sdo.h
new file mode 100644
index 0000000..7e1344c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-sdo.h
@@ -0,0 +1,449 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-sdo.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * SDO register description file for Samsung TVOUT driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_REGS_SDO_H
+#define __ARCH_ARM_REGS_SDO_H
+
+/*
+ * Register part
+ */
+#define S5P_SDO_CLKCON (0x0000)
+#define S5P_SDO_CONFIG (0x0008)
+#define S5P_SDO_SCALE (0x000C)
+#define S5P_SDO_SYNC (0x0010)
+#define S5P_SDO_VBI (0x0014)
+#define S5P_SDO_SCALE_CH0 (0x001C)
+#define S5P_SDO_SCALE_CH1 (0x0020)
+#define S5P_SDO_SCALE_CH2 (0x0024)
+#define S5P_SDO_YCDELAY (0x0034)
+#define S5P_SDO_SCHLOCK (0x0038)
+#define S5P_SDO_DAC (0x003C)
+#define S5P_SDO_FINFO (0x0040)
+#define S5P_SDO_Y0 (0x0044)
+#define S5P_SDO_Y1 (0x0048)
+#define S5P_SDO_Y2 (0x004C)
+#define S5P_SDO_Y3 (0x0050)
+#define S5P_SDO_Y4 (0x0054)
+#define S5P_SDO_Y5 (0x0058)
+#define S5P_SDO_Y6 (0x005C)
+#define S5P_SDO_Y7 (0x0060)
+#define S5P_SDO_Y8 (0x0064)
+#define S5P_SDO_Y9 (0x0068)
+#define S5P_SDO_Y10 (0x006C)
+#define S5P_SDO_Y11 (0x0070)
+#define S5P_SDO_CB0 (0x0080)
+#define S5P_SDO_CB1 (0x0084)
+#define S5P_SDO_CB2 (0x0088)
+#define S5P_SDO_CB3 (0x008C)
+#define S5P_SDO_CB4 (0x0090)
+#define S5P_SDO_CB5 (0x0094)
+#define S5P_SDO_CB6 (0x0098)
+#define S5P_SDO_CB7 (0x009C)
+#define S5P_SDO_CB8 (0x00A0)
+#define S5P_SDO_CB9 (0x00A4)
+#define S5P_SDO_CB10 (0x00A8)
+#define S5P_SDO_CB11 (0x00AC)
+#define S5P_SDO_CR0 (0x00C0)
+#define S5P_SDO_CR1 (0x00C4)
+#define S5P_SDO_CR2 (0x00C8)
+#define S5P_SDO_CR3 (0x00CC)
+#define S5P_SDO_CR4 (0x00D0)
+#define S5P_SDO_CR5 (0x00D4)
+#define S5P_SDO_CR6 (0x00D8)
+#define S5P_SDO_CR7 (0x00DC)
+#define S5P_SDO_CR8 (0x00E0)
+#define S5P_SDO_CR9 (0x00E4)
+#define S5P_SDO_CR10 (0x00E8)
+#define S5P_SDO_CR11 (0x00EC)
+#define S5P_SDO_MV_ON (0x0100)
+#define S5P_SDO_MV_SLINE_FIRST_EVEN (0x0104)
+#define S5P_SDO_MV_SLINE_FIRST_SPACE_EVEN (0x0108)
+#define S5P_SDO_MV_SLINE_FIRST_ODD (0x010C)
+#define S5P_SDO_MV_SLINE_FIRST_SPACE_ODD (0x0110)
+#define S5P_SDO_MV_SLINE_SPACING (0x0114)
+#define S5P_SDO_MV_STRIPES_NUMBER (0x0118)
+#define S5P_SDO_MV_STRIPES_THICKNESS (0x011C)
+#define S5P_SDO_MV_PSP_DURATION (0x0120)
+#define S5P_SDO_MV_PSP_FIRST (0x0124)
+#define S5P_SDO_MV_PSP_SPACING (0x0128)
+#define S5P_SDO_MV_SEL_LINE_PSP_AGC (0x012C)
+#define S5P_SDO_MV_SEL_FORMAT_PSP_AGC (0x0130)
+#define S5P_SDO_MV_PSP_AGC_A_ON (0x0134)
+#define S5P_SDO_MV_PSP_AGC_B_ON (0x0138)
+#define S5P_SDO_MV_BACK_PORCH (0x013C)
+#define S5P_SDO_MV_BURST_ADVANCED_ON (0x0140)
+#define S5P_SDO_MV_BURST_DURATION_ZONE1 (0x0144)
+#define S5P_SDO_MV_BURST_DURATION_ZONE2 (0x0148)
+#define S5P_SDO_MV_BURST_DURATION_ZONE3 (0x014C)
+#define S5P_SDO_MV_BURST_PHASE_ZONE (0x0150)
+#define S5P_SDO_MV_SLICE_PHASE_LINE (0x0154)
+#define S5P_SDO_MV_RGB_PROTECTION_ON (0x0158)
+#define S5P_SDO_MV_480P_PROTECTION_ON (0x015C)
+#define S5P_SDO_CCCON (0x0180)
+#define S5P_SDO_YSCALE (0x0184)
+#define S5P_SDO_CBSCALE (0x0188)
+#define S5P_SDO_CRSCALE (0x018C)
+#define S5P_SDO_CB_CR_OFFSET (0x0190)
+#define S5P_SDO_CVBS_CC_Y1 (0x0198)
+#define S5P_SDO_CVBS_CC_Y2 (0x019C)
+#define S5P_SDO_CVBS_CC_C (0x01A0)
+#define S5P_SDO_CSC_525_PORCH (0x01B0)
+#define S5P_SDO_CSC_625_PORCH (0x01B4)
+#define S5P_SDO_OSFC00_0 (0x0200)
+#define S5P_SDO_OSFC01_0 (0x0204)
+#define S5P_SDO_OSFC02_0 (0x0208)
+#define S5P_SDO_OSFC03_0 (0x020C)
+#define S5P_SDO_OSFC04_0 (0x0210)
+#define S5P_SDO_OSFC05_0 (0x0214)
+#define S5P_SDO_OSFC06_0 (0x0218)
+#define S5P_SDO_OSFC07_0 (0x021C)
+#define S5P_SDO_OSFC08_0 (0x0220)
+#define S5P_SDO_OSFC09_0 (0x0224)
+#define S5P_SDO_OSFC10_0 (0x0228)
+#define S5P_SDO_OSFC11_0 (0x022C)
+#define S5P_SDO_OSFC12_0 (0x0230)
+#define S5P_SDO_OSFC13_0 (0x0234)
+#define S5P_SDO_OSFC14_0 (0x0238)
+#define S5P_SDO_OSFC15_0 (0x023C)
+#define S5P_SDO_OSFC16_0 (0x0240)
+#define S5P_SDO_OSFC17_0 (0x0244)
+#define S5P_SDO_OSFC18_0 (0x0248)
+#define S5P_SDO_OSFC19_0 (0x024C)
+#define S5P_SDO_OSFC20_0 (0x0250)
+#define S5P_SDO_OSFC21_0 (0x0254)
+#define S5P_SDO_OSFC22_0 (0x0258)
+#define S5P_SDO_OSFC23_0 (0x025C)
+#define S5P_SDO_XTALK0 (0x0260)
+#define S5P_SDO_XTALK1 (0x0264)
+#define S5P_SDO_XTALK2 (0x0268)
+#define S5P_SDO_BB_CTRL (0x026C)
+#define S5P_SDO_IRQ (0x0280)
+#define S5P_SDO_IRQMASK (0x0284)
+#define S5P_SDO_OSFC00_1 (0x02C0)
+#define S5P_SDO_OSFC01_1 (0x02C4)
+#define S5P_SDO_OSFC02_1 (0x02C8)
+#define S5P_SDO_OSFC03_1 (0x02CC)
+#define S5P_SDO_OSFC04_1 (0x02D0)
+#define S5P_SDO_OSFC05_1 (0x02D4)
+#define S5P_SDO_OSFC06_1 (0x02D8)
+#define S5P_SDO_OSFC07_1 (0x02DC)
+#define S5P_SDO_OSFC08_1 (0x02E0)
+#define S5P_SDO_OSFC09_1 (0x02E4)
+#define S5P_SDO_OSFC10_1 (0x02E8)
+#define S5P_SDO_OSFC11_1 (0x02EC)
+#define S5P_SDO_OSFC12_1 (0x02E0)
+#define S5P_SDO_OSFC13_1 (0x02F4)
+#define S5P_SDO_OSFC14_1 (0x02F8)
+#define S5P_SDO_OSFC15_1 (0x02FC)
+#define S5P_SDO_OSFC16_1 (0x0300)
+#define S5P_SDO_OSFC17_1 (0x0304)
+#define S5P_SDO_OSFC18_1 (0x0308)
+#define S5P_SDO_OSFC19_1 (0x030C)
+#define S5P_SDO_OSFC20_1 (0x0310)
+#define S5P_SDO_OSFC21_1 (0x0314)
+#define S5P_SDO_OSFC22_1 (0x0318)
+#define S5P_SDO_OSFC23_1 (0x031C)
+#define S5P_SDO_OSFC00_2 (0x0320)
+#define S5P_SDO_OSFC01_2 (0x0324)
+#define S5P_SDO_OSFC02_2 (0x0328)
+#define S5P_SDO_OSFC03_2 (0x032C)
+#define S5P_SDO_OSFC04_2 (0x0330)
+#define S5P_SDO_OSFC05_2 (0x0334)
+#define S5P_SDO_OSFC06_2 (0x0338)
+#define S5P_SDO_OSFC07_2 (0x033C)
+#define S5P_SDO_OSFC08_2 (0x0340)
+#define S5P_SDO_OSFC09_2 (0x0344)
+#define S5P_SDO_OSFC10_2 (0x0348)
+#define S5P_SDO_OSFC11_2 (0x034C)
+#define S5P_SDO_OSFC12_2 (0x0350)
+#define S5P_SDO_OSFC13_2 (0x0354)
+#define S5P_SDO_OSFC14_2 (0x0358)
+#define S5P_SDO_OSFC15_2 (0x035C)
+#define S5P_SDO_OSFC16_2 (0x0360)
+#define S5P_SDO_OSFC17_2 (0x0364)
+#define S5P_SDO_OSFC18_2 (0x0368)
+#define S5P_SDO_OSFC19_2 (0x036C)
+#define S5P_SDO_OSFC20_2 (0x0370)
+#define S5P_SDO_OSFC21_2 (0x0374)
+#define S5P_SDO_OSFC22_2 (0x0378)
+#define S5P_SDO_OSFC23_2 (0x037C)
+#define S5P_SDO_ARMCC (0x03C0)
+#define S5P_SDO_ARMWSS525 (0x03C4)
+#define S5P_SDO_ARMWSS625 (0x03C8)
+#define S5P_SDO_ARMCGMS525 (0x03CC)
+#define S5P_SDO_ARMCGMS625 (0x03D4)
+#define S5P_SDO_VERSION (0x03D8)
+#define S5P_SDO_CC (0x0380)
+#define S5P_SDO_WSS525 (0x0384)
+#define S5P_SDO_WSS625 (0x0388)
+#define S5P_SDO_CGMS525 (0x038C)
+#define S5P_SDO_CGMS625 (0x0394)
+
+/*
+ * Bit definition part
+*/
+/* SDO Clock Control Register (SDO_CLKCON) */
+#define S5P_SDO_TVOUT_SW_RESET (1 << 4)
+#define S5P_SDO_TVOUT_CLOCK_ON (1)
+#define S5P_SDO_TVOUT_CLOCK_OFF (0)
+
+/* SDO Video Standard Configuration Register (SDO_CONFIG) */
+#define S5P_SDO_DAC2_Y_G (0 << 20)
+#define S5P_SDO_DAC2_PB_B (1 << 20)
+#define S5P_SDO_DAC2_PR_R (2 << 20)
+#define S5P_SDO_DAC1_Y_G (0 << 18)
+#define S5P_SDO_DAC1_PB_B (1 << 18)
+#define S5P_SDO_DAC1_PR_R (2 << 18)
+#define S5P_SDO_DAC0_Y_G (0 << 16)
+#define S5P_SDO_DAC0_PB_B (1 << 16)
+#define S5P_SDO_DAC0_PR_R (2 << 16)
+#define S5P_SDO_DAC2_CVBS (0 << 12)
+#define S5P_SDO_DAC2_Y (1 << 12)
+#define S5P_SDO_DAC2_C (2 << 12)
+#define S5P_SDO_DAC1_CVBS (0 << 10)
+#define S5P_SDO_DAC1_Y (1 << 10)
+#define S5P_SDO_DAC1_C (2 << 10)
+#define S5P_SDO_DAC0_CVBS (0 << 8)
+#define S5P_SDO_DAC0_Y (1 << 8)
+#define S5P_SDO_DAC0_C (2 << 8)
+#define S5P_SDO_COMPOSITE (0 << 6)
+#define S5P_SDO_COMPONENT (1 << 6)
+#define S5P_SDO_RGB (0 << 5)
+#define S5P_SDO_YPBPR (1 << 5)
+#define S5P_SDO_INTERLACED (0 << 4)
+#define S5P_SDO_PROGRESSIVE (1 << 4)
+#define S5P_SDO_NTSC_M (0)
+#define S5P_SDO_PAL_M (1)
+#define S5P_SDO_PAL_BGHID (2)
+#define S5P_SDO_PAL_N (3)
+#define S5P_SDO_PAL_NC (4)
+#define S5P_SDO_NTSC_443 (8)
+#define S5P_SDO_PAL_60 (9)
+
+/* SDO Video Scale Configuration Register (SDO_SCALE) */
+#define S5P_SDO_COMPONENT_LEVEL_SEL_0IRE (0 << 3)
+#define S5P_SDO_COMPONENT_LEVEL_SEL_75IRE (1 << 3)
+#define S5P_SDO_COMPONENT_VTOS_RATIO_10_4 (0 << 2)
+#define S5P_SDO_COMPONENT_VTOS_RATIO_7_3 (1 << 2)
+#define S5P_SDO_COMPOSITE_LEVEL_SEL_0IRE (0 << 1)
+#define S5P_SDO_COMPOSITE_LEVEL_SEL_75IRE (1 << 1)
+#define S5P_SDO_COMPOSITE_VTOS_RATIO_10_4 (0)
+#define S5P_SDO_COMPOSITE_VTOS_RATIO_7_3 (1)
+
+/* SDO Video sync Register */
+#define S5P_SDO_COMPONENT_SYNC_ABSENT (0)
+#define S5P_SDO_COMPONENT_SYNC_YG (1)
+#define S5P_SDO_COMPONENT_SYNC_ALL (3)
+
+/* SDO VBI Configuration Register (SDO_VBI) */
+#define S5P_SDO_CVBS_NO_WSS (0 << 14)
+#define S5P_SDO_CVBS_WSS_INS (1 << 14)
+#define S5P_SDO_CVBS_NO_CLOSED_CAPTION (0 << 12)
+#define S5P_SDO_CVBS_21H_CLOSED_CAPTION (1 << 12)
+#define S5P_SDO_CVBS_21H_284H_CLOSED_CAPTION (2 << 12)
+#define S5P_SDO_CVBS_USE_OTHERS (3 << 12)
+
+/* SDO Channel #0 Scale Control Register (SDO_SCALE_CH0) */
+#define S5P_SDO_SCALE_CONV_OFFSET(x) (((x) & 0x3FF) << 16)
+#define S5P_SDO_SCALE_CONV_GAIN(x) ((x) & 0xFFF)
+
+/* SDO Video Delay Control Register (SDO_YCDELAY) */
+#define S5P_SDO_DELAY_YTOC(x) (((x) & 0xF) << 16)
+#define S5P_SDO_ACTIVE_START_OFFSET(x) (((x) & 0xFF) << 8)
+#define S5P_SDO_ACTIVE_END_OFFSET(x) ((x) & 0xFF)
+
+/* SDO SCH Phase Control Register (SDO_SCHLOCK) */
+#define S5P_SDO_COLOR_SC_PHASE_ADJ (1)
+#define S5P_SDO_COLOR_SC_PHASE_NOADJ (0)
+
+/* SDO DAC Configuration Register (SDO_DAC) */
+#define S5P_SDO_POWER_ON_DAC (1 << 0)
+#define S5P_SDO_POWER_DOWN_DAC (0 << 0)
+
+/* SDO Status Register (SDO_FINFO) */
+#define S5P_SDO_FIELD_MOD_1001(x) (((x) & (0x3ff << 16)) >> 16)
+#define S5P_SDO_FIELD_ID_BOTTOM(x) ((x) & (1 << 1))
+#define S5P_SDO_FIELD_ID_BOTTOM_PI_INCATION(x) (1)
+
+#define S5P_SDO_MV_AGC_103_ON (1)
+
+/* SDO Color Compensation On/Off Control (SDO_CCCON) */
+#define S5P_SDO_COMPENSATION_BHS_ADJ_ON (0 << 4)
+#define S5P_SDO_COMPENSATION_BHS_ADJ_OFF (1 << 4)
+#define S5P_SDO_COMPENSATION_CVBS_COMP_ON (0)
+#define S5P_SDO_COMPENSATION_CVBS_COMP_OFF (1)
+
+/* SDO Brightness Control for Y (SDO_YSCALE) */
+#define S5P_SDO_BRIGHTNESS_GAIN(x) (((x) & 0xFF) << 16)
+#define S5P_SDO_BRIGHTNESS_OFFSET(x) ((x) & 0xFF)
+
+/* SDO Hue/Saturation Control for CB (SDO_CBSCALE) */
+#define S5P_SDO_HS_CB_GAIN0(x) (((x) & 0x1FF) << 16)
+#define S5P_SDO_HS_CB_GAIN1(x) ((x) & 0x1FF)
+
+/* SDO Hue/Saturation Control for CR (SDO_CRSCALE) */
+#define S5P_SDO_HS_CR_GAIN0(x) (((x) & 0x1FF) << 16)
+#define S5P_SDO_HS_CR_GAIN1(x) ((x) & 0x1FF)
+
+/* SDO Hue/Saturation Control for CB/CR (SDO_CB_CR_OFFSET) */
+#define S5P_SDO_HS_CR_OFFSET(x) (((x) & 0x3FF) << 16)
+#define S5P_SDO_HS_CB_OFFSET(x) ((x) & 0x3FF)
+
+#define S5P_SDO_MAX_RGB_CUBE(x) (((x) & 0xFF) << 8)
+#define S5P_SDO_MIN_RGB_CUBE(x) ((x) & 0xFF)
+
+/* Color Compensation Control Register for CVBS Output (SDO_CVBS_CC_Y1) */
+#define S5P_SDO_Y_LOWER_MID_CVBS_CORN(x) (((x) & 0x3FF) << 16)
+#define S5P_SDO_Y_BOTTOM_CVBS_CORN(x) ((x) & 0x3FF)
+
+/* Color Compensation Control Register for CVBS Output (SDO_CVBS_CC_Y2) */
+#define S5P_SDO_Y_TOP_CVBS_CORN(x) (((x) & 0x3FF) << 16)
+#define S5P_SDO_Y_UPPER_MID_CVBS_CORN(x) ((x) & 0x3FF)
+
+/* Color Compensation Control Register for CVBS Output (SDO_CVBS_CC_C) */
+#define S5P_SDO_RADIUS_CVBS_CORN(x) ((x) & 0x1FF)
+
+/*
+ * SDO 525 Line Component Front/Back Porch Position
+ * Control Register (SDO_CSC_525_PORCH)
+ */
+#define S5P_SDO_COMPONENT_525_BP(x) (((x) & 0x3FF) << 16)
+#define S5P_SDO_COMPONENT_525_FP(x) ((x) & 0x3FF)
+
+/*
+ * SDO 625 Line Component Front/Back Porch Position
+ * Control Resigter(SDO_CSC_625_PORCH
+ */
+#define S5P_SDO_COMPONENT_625_BP(x) (((x) & 0x3FF) << 16)
+#define S5P_SDO_COMPONENT_625_FP(x) ((x) & 0x3FF)
+
+/* SDO Oversampling #0 Filter Coefficient (SDO_OSFC00_0) */
+#define S5P_SDO_OSF_COEF_ODD(x) (((x) & 0xFFF) << 16)
+#define S5P_SDO_OSF_COEF_EVEN(x) ((x) & 0xFFF)
+
+/* SDO Channel Crosstalk Cancellation Coefficient for Ch. 0 (SDO_XTALK0) */
+#define S5P_SDO_XTALK_COEF02(x) (((x) & 0xFF) << 16)
+#define S5P_SDO_XTALK_COEF01(x) ((x) & 0xFF)
+
+/* SDO Black Burst Control Register (SDO_BB_CTRL) */
+#define S5P_SDO_REF_BB_LEVEL_NTSC (0x11A << 8)
+#define S5P_SDO_REF_BB_LEVEL_PAL (0xFB << 8)
+#define S5P_SDO_SEL_BB_CJAN_CVBS0_BB1_BB2 (0 << 4)
+#define S5P_SDO_SEL_BB_CJAN_BB0_CVBS1_BB2 (1 << 4)
+#define S5P_SDO_SEL_BB_CJAN_BB0_BB1_CVBS2 (2 << 4)
+#define S5P_SDO_BB_MODE_ENABLE (1)
+#define S5P_SDO_BB_MODE_DISABLE (0)
+
+/* SDO Interrupt Request Register (SDO_IRQ) */
+#define S5P_SDO_VSYNC_IRQ_PEND (1)
+#define S5P_SDO_VSYNC_NO_IRQ (0)
+
+/* SDO Interrupt Request Masking Register (SDO_IRQMASK) */
+#define S5P_SDO_VSYNC_IRQ_ENABLE (0)
+#define S5P_SDO_VSYNC_IRQ_DISABLE (1)
+
+/* SDO Closed Caption Data Registers (SDO_ARMCC) */
+#define S5P_SDO_DISPLAY_CC_CAPTION(x) (((x) & 0xFF) << 16)
+#define S5P_SDO_NON_DISPLAY_CC_CAPTION(x) ((x) & 0xFF)
+
+/* SDO WSS 525 Data Registers (SDO_ARMWSS525) */
+#define S5P_SDO_CRC_WSS525(x) (((x) & 0x3F) << 14)
+#define S5P_SDO_WORD2_WSS525_COPY_PERMIT (0 << 6)
+#define S5P_SDO_WORD2_WSS525_ONECOPY_PERMIT (1 << 6)
+#define S5P_SDO_WORD2_WSS525_NOCOPY_PERMIT (3 << 6)
+#define S5P_SDO_WORD2_WSS525_MV_PSP_OFF (0 << 8)
+#define S5P_SDO_WORD2_WSS525_MV_PSP_ON_2LINE_BURST (1 << 8)
+#define S5P_SDO_WORD2_WSS525_MV_PSP_ON_BURST_OFF (2 << 8)
+#define S5P_SDO_WORD2_WSS525_MV_PSP_ON_4LINE_BURST (3 << 8)
+#define S5P_SDO_WORD2_WSS525_ANALOG_OFF (0 << 10)
+#define S5P_SDO_WORD2_WSS525_ANALOG_ON (1 << 10)
+#define S5P_SDO_WORD1_WSS525_COPY_INFO (0 << 2)
+#define S5P_SDO_WORD1_WSS525_DEFAULT (0xF << 2)
+#define S5P_SDO_WORD0_WSS525_4_3_NORMAL (0)
+#define S5P_SDO_WORD0_WSS525_16_9_ANAMORPIC (1)
+#define S5P_SDO_WORD0_WSS525_4_3_LETTERBOX (2)
+
+/* SDO WSS 625 Data Registers (SDO_ARMWSS625) */
+#define S5P_SDO_WSS625_SURROUND_SOUND_DISABLE (0 << 11)
+#define S5P_SDO_WSS625_SURROUND_SOUND_ENABLE (1 << 11)
+#define S5P_SDO_WSS625_NO_COPYRIGHT (0 << 12)
+#define S5P_SDO_WSS625_COPYRIGHT (1 << 12)
+#define S5P_SDO_WSS625_COPY_NOT_RESTRICTED (0 << 13)
+#define S5P_SDO_WSS625_COPY_RESTRICTED (1 << 13)
+#define S5P_SDO_WSS625_TELETEXT_NO_SUBTITLES (0 << 8)
+#define S5P_SDO_WSS625_TELETEXT_SUBTITLES (1 << 8)
+#define S5P_SDO_WSS625_NO_OPEN_SUBTITLES (0 << 9)
+#define S5P_SDO_WSS625_INACT_OPEN_SUBTITLES (1 << 9)
+#define S5P_SDO_WSS625_OUTACT_OPEN_SUBTITLES (2 << 9)
+#define S5P_SDO_WSS625_CAMERA (0 << 4)
+#define S5P_SDO_WSS625_FILM (1 << 4)
+#define S5P_SDO_WSS625_NORMAL_PAL (0 << 5)
+#define S5P_SDO_WSS625_MOTION_ADAPTIVE_COLORPLUS (1 << 5)
+#define S5P_SDO_WSS625_HELPER_NO_SIG (0 << 6)
+#define S5P_SDO_WSS625_HELPER_SIG (1 << 6)
+#define S5P_SDO_WSS625_4_3_FULL_576 (0x8)
+#define S5P_SDO_WSS625_14_9_LETTERBOX_CENTER_504 (0x1)
+#define S5P_SDO_WSS625_14_9_LETTERBOX_TOP_504 (0x2)
+#define S5P_SDO_WSS625_16_9_LETTERBOX_CENTER_430 (0xb)
+#define S5P_SDO_WSS625_16_9_LETTERBOX_TOP_430 (0x4)
+#define S5P_SDO_WSS625_16_9_LETTERBOX_CENTER (0xd)
+#define S5P_SDO_WSS625_14_9_FULL_CENTER_576 (0xe)
+#define S5P_SDO_WSS625_16_9_ANAMORPIC_576 (0x7)
+
+/* SDO CGMS-A 525 Data Registers (SDO_ARMCGMS525) */
+#define S5P_SDO_CRC_CGMS525(x) (((x) & 0x3F) << 14)
+#define S5P_SDO_WORD2_CGMS525_COPY_PERMIT (0 << 6)
+#define S5P_SDO_WORD2_CGMS525_ONECOPY_PERMIT (1 << 6)
+#define S5P_SDO_WORD2_CGMS525_NOCOPY_PERMIT (3 << 6)
+#define S5P_SDO_WORD2_CGMS525_MV_PSP_OFF (0 << 8)
+#define S5P_SDO_WORD2_CGMS525_MV_PSP_ON_2LINE_BURST (1 << 8)
+#define S5P_SDO_WORD2_CGMS525_MV_PSP_ON_BURST_OFF (2 << 8)
+#define S5P_SDO_WORD2_CGMS525_MV_PSP_ON_4LINE_BURST (3 << 8)
+#define S5P_SDO_WORD2_CGMS525_ANALOG_OFF (0 << 10)
+#define S5P_SDO_WORD2_CGMS525_ANALOG_ON (1 << 10)
+#define S5P_SDO_WORD1_CGMS525_COPY_INFO (0 << 2)
+#define S5P_SDO_WORD1_CGMS525_DEFAULT (0xF << 2)
+#define S5P_SDO_WORD0_CGMS525_4_3_NORMAL (0)
+#define S5P_SDO_WORD0_CGMS525_16_9_ANAMORPIC (1)
+#define S5P_SDO_WORD0_CGMS525_4_3_LETTERBOX (2)
+
+/* SDO CGMS-A 625 Data Registers (SDO_ARMCGMS625) */
+#define S5P_SDO_CGMS625_SURROUND_SOUND_DISABLE (0 << 11)
+#define S5P_SDO_CGMS625_SURROUND_SOUND_ENABLE (1 << 11)
+#define S5P_SDO_CGMS625_NO_COPYRIGHT (0 << 12)
+#define S5P_SDO_CGMS625_COPYRIGHT (1 << 12)
+#define S5P_SDO_CGMS625_COPY_NOT_RESTRICTED (0 << 13)
+#define S5P_SDO_CGMS625_COPY_RESTRICTED (1 << 13)
+#define S5P_SDO_CGMS625_TELETEXT_NO_SUBTITLES (0 << 8)
+#define S5P_SDO_CGMS625_TELETEXT_SUBTITLES (1 << 8)
+#define S5P_SDO_CGMS625_NO_OPEN_SUBTITLES (0 << 9)
+#define S5P_SDO_CGMS625_INACT_OPEN_SUBTITLES (1 << 9)
+#define S5P_SDO_CGMS625_OUTACT_OPEN_SUBTITLES (2 << 9)
+#define S5P_SDO_CGMS625_CAMERA (0 << 4)
+#define S5P_SDO_CGMS625_FILM (1 << 4)
+#define S5P_SDO_CGMS625_NORMAL_PAL (0 << 5)
+#define S5P_SDO_CGMS625_MOTION_ADAPTIVE_COLORPLUS (1 << 5)
+#define S5P_SDO_CGMS625_HELPER_NO_SIG (0 << 6)
+#define S5P_SDO_CGMS625_HELPER_SIG (1 << 6)
+#define S5P_SDO_CGMS625_4_3_FULL_576 (0x8)
+#define S5P_SDO_CGMS625_14_9_LETTERBOX_CENTER_504 (0x1)
+#define S5P_SDO_CGMS625_14_9_LETTERBOX_TOP_504 (0x2)
+#define S5P_SDO_CGMS625_16_9_LETTERBOX_CENTER_430 (0xb)
+#define S5P_SDO_CGMS625_16_9_LETTERBOX_TOP_430 (0x4)
+#define S5P_SDO_CGMS625_16_9_LETTERBOX_CENTER (0xd)
+#define S5P_SDO_CGMS625_14_9_FULL_CENTER_576 (0xe)
+#define S5P_SDO_CGMS625_16_9_ANAMORPIC_576 (0x7)
+
+/* SDO Version Register (SDO_VERSION) */
+#define S5P_SDO_VERSION_NUMBER_MASK (0xFFFFFFFF)
+
+#endif /* __ARCH_ARM_REGS_SDO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
index 68ff6ad..a0626fa 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
+/* linux/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -24,5 +24,10 @@
#define S5P_AW_FAULT_ADDR 0x028
#define S5P_AR_FAULT_ADDR 0x02C
#define S5P_DEFAULT_SLAVE_ADDR 0x030
+#define S5P_MMU_VERSION 0x034
+#define S5P_PB0_SADDR 0x04C
+#define S5P_PB0_EADDR 0x050
+#define S5P_PB1_SADDR 0x054
+#define S5P_PB1_EADDR 0x058
#endif /* __ASM_ARCH_REGS_SYSMMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-tmu.h b/arch/arm/mach-exynos/include/mach/regs-tmu.h
new file mode 100644
index 0000000..8bfa3f5
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-tmu.h
@@ -0,0 +1,164 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-tmu.h
+
+* Copyright (c) 2010 Samsung Electronics Co., Ltd.
+* http://www.samsung.com/
+*
+* EXYNOS4 - Thermal Management support
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_TMU_H
+#define __ASM_ARCH_REGS_TMU_H __FILE__
+
+enum tmu_state_t {
+ TMU_STATUS_NORMAL = 0,
+ TMU_STATUS_THROTTLED,
+ TMU_STATUS_WARNING,
+ TMU_STATUS_TRIPPED,
+ TMU_STATUS_INIT,
+ TMU_STATUS_TC,
+};
+
+#define FREQ_IN_PLL 24000000 /* 24MHZ in Hz */
+#define AUTO_REFRESH_PERIOD_TQ0 1950
+#define AUTO_REFRESH_PERIOD_NORMAL 3900
+
+/* TMU Common registers */
+#define EXYNOS4_TMU_TRIMINFO (0x0000)
+#define TMU_TRIMINFO_MASK (0xFF)
+
+#define EXYNOS4_TMU_CONTROL (0x0020)
+#define TMUCORE_ENABLE (1 << 0)
+
+#define EXYNOS4_TMU_STATUS (0x0028)
+#define TMU_IDLE (1 << 0)
+#define TMU_BUSY (0 << 0)
+
+#define EXYNOS4_TMU_SAMPLING_INTERNAL (0x002C)
+#define EXYNOS4_TMU_COUNTER_VALUE0 (0x0030)
+#define EXYNOS4_TMU_COUNTER_VALUE1 (0x0034)
+
+#define EXYNOS4_TMU_CURRENT_TEMP (0x0040)
+/* TMU has temperature code within a temperature range of 25C to 125C */
+#define TEMP_MIN_CELCIUS 25
+#define TEMP_MAX_CELCIUS 125
+#define TMU_DC_VALUE 25
+
+#define EXYNOS4_TMU_INTEN (0x0070)
+#define EXYNOS4_TMU_INTSTAT (0x0074)
+#define EXYNOS4_TMU_INTCLEAR (0x0078)
+
+/*
+ * The below registers and definition is used
+ * in only EXYNOS4210
+ *
+*/
+/* Below 3line is used to exynos4210 evt0 without right e-fusing */
+#define EFUSE_MIN_VALUE 60
+#define EFUSE_AVG_VALUE 80
+#define EFUSE_MAX_VALUE 100
+
+/* To get rightly current temperature, EXYNOS4_TMU_CONTROL setting value */
+#define VREF_SLOPE 0x07000F02
+
+#define EXYNOS4210_TMU_THRESHOLD_TEMP (0x0044)
+#define EXYNOS4210_TMU_TRIG_LEVEL0 (0x0050)
+#define EXYNOS4210_TMU_TRIG_LEVEL1 (0x0054)
+#define EXYNOS4210_TMU_TRIG_LEVEL2 (0x0058)
+#define EXYNOS4210_TMU_TRIG_LEVEL3 (0x005C)
+#define TRIGGER_LEV_MAX (0xFF)
+
+#define EXYNOS4210_TMU_PAST_TMEP0 (0x0060)
+#define EXYNOS4210_TMU_PAST_TMEP1 (0x0064)
+#define EXYNOS4210_TMU_PAST_TMEP2 (0x0068)
+#define EXYNOS4210_TMU_PAST_TMEP3 (0x006C)
+
+/* bit definition at EXYNOS4_TMU_INTEN reg of exynos4210 */
+#define INTEN0 (1 << 0)
+#define INTEN1 (1 << 4)
+#define INTEN2 (1 << 8)
+#define INTEN3 (1 << 12)
+
+/* bit definition at EXYNOS4_TMU_INTSTAT reg of exynos4210 */
+#define TMU_INTSTAT0 (1 << 0)
+#define TMU_INTSTAT1 (1 << 4)
+#define TMU_INTSTAT2 (1 << 8)
+#define TMU_INTSTAT3 (1 << 12)
+
+
+/* bit definition at EXYNOS4_TMU_INTCLEAR regof exynos4210 */
+#define INTCLEAR0 (1 << 0)
+#define INTCLEAR1 (1 << 4)
+#define INTCLEAR2 (1 << 8)
+#define INTCLEAR3 (1 << 12)
+
+#ifdef CONFIG_CPU_EXYNOS4210
+#define INTCLEARALL (INTCLEAR0 | INTCLEAR1 | INTCLEAR2 | INTCLEAR3)
+#else
+#define INTCLEARALL (INTCLEAR_RISE0 | INTCLEAR_RISE1 | INTCLEAR_RISE2 \
+ | INTCLEAR_FALL0 | INTCLEAR_FALL1 | INTCLEAR_FALL2)
+#endif
+
+/*
+ * The below registers and definition is added or changed
+ * in EXYNOS4x12
+ *
+*/
+#define EXYNOS4x12_TMU_TRIMINFO_CONROL (0x0014)
+#define TMU_RELOAD (1 << 0)
+#define TMU_ACTIME (1 << 0)
+
+/* Newly added bit definition at EXYNOS4_TMU_CONTROL register, */
+#define THERM_TRIP_ENABLE (1 << 12)
+#define THERM_TRIP_MODE_000 (0 << 13)
+#define THERM_TRIP_MODE_100 (4 << 13)
+#define THERM_TRIP_MODE_101 (5 << 13)
+#define THERM_TRIP_MODE_110 (6 << 13)
+#define THERM_TRIP_MODE_111 (7 << 13)
+
+#define EXYNOS4x12_TMU_TRESHOLD_TEMP_RISE (0x0050)
+#define THRES_LEVEL_RISE0_SHIFT (1 << 0)
+#define THRES_LEVEL_RISE1_SHIFT (1 << 8)
+#define THRES_LEVEL_RISE2_SHIFT (1 << 16)
+#define THRES_LEVEL_RISE3_SHIFT (1 << 24)
+
+#define EXYNOS4x12_TMU_TRESHOLD_TEMP_FALL (0x0054)
+#define THRES_LEVEL_FALL0_SHIFT (1 << 0)
+#define THRES_LEVEL_FALL1_SHIFT (1 << 8)
+#define THRES_LEVEL_FALL2_SHIFT (1 << 16)
+
+#define EXYNOS4x12_TMU_PAST_TMEP3_0 (0x0060)
+#define EXYNOS4x12_TMU_PAST_TMEP7_4 (0x0064)
+#define EXYNOS4x12_TMU_PAST_TMEP11_8 (0x0068)
+#define EXYNOS4x12_TMU_PAST_TMEP15_12 (0x006C)
+
+/* Newly changed bit definition at EXYNOS4_TMU_INTEN register, */
+#define INTEN_RISE0 (1 << 0)
+#define INTEN_RISE1 (1 << 4)
+#define INTEN_RISE2 (1 << 8)
+#define INTEN_FALL0 (1 << 16)
+#define INTEN_FALL1 (1 << 20)
+#define INTEN_FALL2 (1 << 24)
+
+/* Newly changed bit definition at EXYNOS4_TMU_INSTAT */
+#define INTSTAT_RISE0 (1 << 0)
+#define INTSTAT_RISE1 (1 << 4)
+#define INTSTAT_RISE2 (1 << 8)
+#define INTSTAT_FALL0 (1 << 16)
+#define INTSTAT_FALL1 (1 << 20)
+#define INTSTAT_FALL2 (1 << 24)
+
+/* Newly changed bit definition at EXYNOS4_TMU_CLEAR */
+#define INTCLEAR_RISE0 (1 << 0)
+#define INTCLEAR_RISE1 (1 << 4)
+#define INTCLEAR_RISE2 (1 << 8)
+#define INTCLEAR_FALL0 (1 << 12)
+#define INTCLEAR_FALL1 (1 << 16)
+#define INTCLEAR_FALL2 (1 << 20)
+
+#define EXYNOS4x12_TMU_EMUL_CON (0x0080)
+
+#endif /* ___ASM_ARCH_REGS_TMU_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-tsi.h b/arch/arm/mach-exynos/include/mach/regs-tsi.h
new file mode 100644
index 0000000..d7d03ca
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-tsi.h
@@ -0,0 +1,163 @@
+/* arch/arm/plat-s3c/include/plat/regs-tsi.h
+ *
+ * Copyright (c) 2004 Samsung
+ *
+ * This program is free software; yosu can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S5PC110 TSI registers
+*/
+#ifndef __ASM_ARCH_REGS_TSI_H
+#define __ASM_ARCH_REGS_TSI_H "regs-tsi.h"
+
+#define S3C_TSIREG(x) (x)
+
+#define S3C_TS_CLKCON S3C_TSIREG(0x00)
+#define S3C_TS_CON S3C_TSIREG(0x04)
+#define S3C_TS_SYNC S3C_TSIREG(0x08)
+#define S3C_TS_CNT S3C_TSIREG(0x0C)
+#define S3C_TS_BASE S3C_TSIREG(0x10)
+#define S3C_TS_SIZE S3C_TSIREG(0x14)
+#define S3C_TS_CADDR S3C_TSIREG(0x18)
+#define S3C_TS_INTMASK S3C_TSIREG(0x1C)
+#define S3C_TS_INT S3C_TSIREG(0x20)
+#define S3C_TS_PID0 S3C_TSIREG(0x24)
+#define S3C_TS_PID1 S3C_TSIREG(0x28)
+#define S3C_TS_PID2 S3C_TSIREG(0x2C)
+#define S3C_TS_PID3 S3C_TSIREG(0x30)
+#define S3C_TS_PID4 S3C_TSIREG(0x34)
+#define S3C_TS_PID5 S3C_TSIREG(0x38)
+#define S3C_TS_PID6 S3C_TSIREG(0x3C)
+#define S3C_TS_PID7 S3C_TSIREG(0x40)
+#define S3C_TS_PID8 S3C_TSIREG(0x44)
+#define S3C_TS_PID9 S3C_TSIREG(0x48)
+#define S3C_TS_PID10 S3C_TSIREG(0x4C)
+#define S3C_TS_PID11 S3C_TSIREG(0x50)
+#define S3C_TS_PID12 S3C_TSIREG(0x54)
+#define S3C_TS_PID13 S3C_TSIREG(0x58)
+#define S3C_TS_PID14 S3C_TSIREG(0x5C)
+#define S3C_TS_PID15 S3C_TSIREG(0x60)
+#define S3C_TS_PID16 S3C_TSIREG(0x64)
+#define S3C_TS_PID17 S3C_TSIREG(0x68)
+#define S3C_TS_PID18 S3C_TSIREG(0x6C)
+#define S3C_TS_PID19 S3C_TSIREG(0x70)
+#define S3C_TS_PID20 S3C_TSIREG(0x74)
+#define S3C_TS_PID21 S3C_TSIREG(0x78)
+#define S3C_TS_PID22 S3C_TSIREG(0x7C)
+#define S3C_TS_PID23 S3C_TSIREG(0x80)
+#define S3C_TS_PID24 S3C_TSIREG(0x84)
+#define S3C_TS_PID25 S3C_TSIREG(0x88)
+#define S3C_TS_PID26 S3C_TSIREG(0x8C)
+#define S3C_TS_PID27 S3C_TSIREG(0x90)
+#define S3C_TS_PID28 S3C_TSIREG(0x94)
+#define S3C_TS_PID29 S3C_TSIREG(0x98)
+#define S3C_TS_PID30 S3C_TSIREG(0x9C)
+#define S3C_TS_PID31 S3C_TSIREG(0xA0)
+#define S3C_TS_BYTE_SWAP S3C_TSIREG(0xBC)
+
+#define TS_TIMEOUT_CNT_MAX (0x00FFFFFF)
+#define TS_NUM_PKT (4)
+#define TS_PKT_SIZE 47
+#define TS_PKT_BUF_SIZE (TS_PKT_SIZE*TS_NUM_PKT)
+#define TSI_CLK_START 1
+#define TSI_CLK_STOP 0
+
+
+
+
+/*bit definitions*/
+/*CLKCON*/
+
+#define S3C_TSI_ON (0x1<<0)
+#define S3C_TSI_ON_MASK (0x1<<0)
+#define S3C_TSI_BLK_READY (0x1<<1)
+
+/*TS_CON*/
+#define S3C_TSI_SWRESET (0x1 << 31)
+#define S3C_TSI_SWRESET_MASK (0x1 << 31)
+#define S3C_TSI_CLKFILTER_ON (0x1 << 30)
+#define S3C_TSI_CLKFILTER_MASK (0x1 << 30)
+#define S3C_TSI_CLKFILTER_SHIFT 30
+#define S3C_TSI_BURST_LEN_0 (0x0 << 28)
+#define S3C_TSI_BURST_LEN_4 (0x1 << 28)
+#define S3C_TSI_BURST_LEN_8 (0x2 << 28)
+#define S3C_TSI_BURST_LEN_MASK (0x3 << 28)
+#define S3C_TSI_BURST_LEN_SHIFT (28)
+
+#define S3C_TSI_OUT_BUF_FULL_INT_ENA (0x1 << 27)
+#define S3C_TSI_OUT_BUF_FULL_INT_MASK (0x1 << 27)
+#define S3C_TSI_INT_FIFO_FULL_INT_ENA (0x1 << 26)
+#define S3C_TSI_INT_FIFO_FULL_INT_ENA_MASK (0x1 << 26)
+
+#define S3C_TSI_SYNC_MISMATCH_INT_SKIP (0x2 << 24)
+#define S3C_TSI_SYNC_MISMATCH_INT_STOP (0x3 << 24)
+#define S3C_TSI_SYNC_MISMATCH_INT_MASK (0x3 << 24)
+
+#define S3C_TSI_PSUF_INT_SKIP (0x2 << 22)
+#define S3C_TSI_PSUF_INT_STOP (0x3 << 22)
+#define S3C_TSI_PSUF_INT_MASK (0x3 << 22)
+
+#define S3C_TSI_PSOF_INT_SKIP (0x2 << 20)
+#define S3C_TSI_PSOF_INT_STOP (0x3 << 20)
+#define S3C_TSI_PSOF_INT_MASK (0x3 << 20)
+
+#define S3C_TSI_TS_CLK_TIME_OUT_INT (0x1 << 19)
+#define S3C_TSI_TS_CLK_TIME_OUT_INT_MASK (0x1 << 19)
+
+#define S3C_TSI_TS_ERROR_SKIP_SIZE_INT (4<<16)
+#define S3C_TSI_TS_ERROR_STOP_SIZE_INT (5<<16)
+#define S3C_TSI_TS_ERROR_SKIP_PKT_INT (6<<16)
+#define S3C_TSI_TS_ERROR_STOP_PKT_INT (7<<16)
+#define S3C_TSI_TS_ERROR_MASK (7<<16)
+#define S3C_TSI_PAD_PATTERN_SHIFT (8)
+#define S3C_TSI_PID_FILTER_ENA (1 << 7)
+#define S3C_TSI_PID_FILTER_MASK (1 << 7)
+#define S3C_TSI_PID_FILTER_SHIFT (7)
+#define S3C_TSI_ERROR_ACTIVE_LOW (1<<6)
+#define S3C_TSI_ERROR_ACTIVE_HIGH (0<<6)
+#define S3C_TSI_ERROR_ACTIVE_MASK (1<<6)
+
+#define S3C_TSI_DATA_BYTE_ORDER_M2L (0 << 5)
+#define S3C_TSI_DATA_BYTE_ORDER_L2M (1 << 5)
+#define S3C_TSI_DATA_BYTE_ORDER_MASK (1 << 5)
+#define S3C_TSI_DATA_BYTE_ORDER_SHIFT (5)
+#define S3C_TSI_TS_VALID_ACTIVE_HIGH (0<<4)
+#define S3C_TSI_TS_VALID_ACTIVE_LOW (1<<4)
+#define S3C_TSI_TS_VALID_ACTIVE_MASK (1<<4)
+
+#define S3C_TSI_SYNC_ACTIVE_HIGH (0 << 3)
+#define S3C_TSI_SYNC_ACTIVE_LOW (1 << 3)
+#define S3C_TSI_SYNC_ACTIVE_MASK (1 << 3)
+
+#define S3C_TSI_CLK_INVERT_HIGH (0 << 2)
+#define S3C_TSI_CLK_INVERT_LOW (1 << 2)
+#define S3C_TSI_CLK_INVERT_MASK (1 << 2)
+
+/*TS_SYNC*/
+#define S3C_TSI_SYNC_DET_MODE_TS_SYNC8 (0<<0)
+#define S3C_TSI_SYNC_DET_MODE_TS_SYNC1 (1<<0)
+#define S3C_TSI_SYNC_DET_MODE_TS_SYNC_BYTE (2<<0)
+#define S3C_TSI_SYNC_DET_MODE_TS_SYNC_MASK (3<<0)
+
+
+/* TS_INT_MASK */
+#define S3C_TSI_DMA_COMPLETE_ENA (1 << 7)
+#define S3C_TSI_OUTPUT_BUF_FULL_ENA (1 << 6)
+#define S3C_TSI_INT_FIFO_FULL_ENA (1 << 5)
+#define S3C_TSI_SYNC_MISMATCH_ENA (1 << 4)
+#define S3C_TSI_PKT_SIZE_UNDERFLOW_ENA (1 << 3)
+#define S3C_TSI_PKT_SIZE_OVERFLOW_ENA (1 << 2)
+#define S3C_TSI_TS_CLK_ENA (1 << 1)
+#define S3C_TSI_TS_ERROR_ENA (1 << 0)
+
+/* TS_INT_FLAG */
+#define S3C_TSI_DMA_COMPLETE (1<<7)
+#define S3C_TSI_OUT_BUF_FULL (1<<6)
+#define S3C_TSI_INT_FIFO_FULL (1<<5)
+#define S3C_TSI_SYNC_MISMATCH (1<<4)
+#define S3C_TSI_PKT_UNDERFLOW (1<<3)
+#define S3C_TSI_PKT_OVERFLOW (1<<2)
+#define S3C_TSI_PKT_CLK (1<<1)
+#define S3C_TSI_ERROR (1<<0)
+#endif /* __ASM_ARCH_REGS_TSI_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-usb-host.h b/arch/arm/mach-exynos/include/mach/regs-usb-host.h
new file mode 100644
index 0000000..95132e6
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-usb-host.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Yulgon Kim <Yulgon.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_ARCH_MACH_REGS_USB_HOST_H
+#define __ASM_ARCH_MACH_REGS_USB_HOST_H
+
+#define INSNREG00(base) (base + 0x90)
+#define ENA_DMA_INCR (0xF << 22)
+#define ENA_INCR16 (1 << 25)
+#define ENA_INCR8 (1 << 24)
+#define ENA_INCR4 (1 << 23)
+#define ENA_INCRX_ALIGN (1 << 22)
+#define APP_START_CLK (1 << 21)
+#define OHCI_SUSP_LGCY (1 << 20)
+#define MICROFRAME_BASE_VALUE_MASK (0x1FFF << 1)
+#define MICROFRAME_BASE_VALUE_SHIFT (1)
+#define ENA_MICROFRAME_LENGTH_VALUE (1 << 0)
+
+#define INSNREG01(base, offset) (base + 0x94)
+#define PACKET_BUFFER_THRESHOLDS_OUT_MASK (0xFFFF << 16)
+#define PACKET_BUFFER_THRESHOLDS_OUT_SHIFT (16)
+#define PACKET_BUFFER_THRESHOLDS_IN_MASK (0xFFFF << 0)
+#define PACKET_BUFFER_THRESHOLDS_IN_SHIFT (0)
+
+#define INSNREG02(base, offset) (base + 0x98)
+#define PACKET_BUFFER_DEPTH_MASK (0xFFFFFFFF << 0)
+
+#define INSNREG03(base, offset) (base + 0x9C)
+#define TX_TURNAROUD_DELAY_ADD_MASK (0x7 << 10)
+#define TX_TURNAROUD_DELAY_ADD_SHIFT (10)
+#define PERIODIC_FRAME_LIST_FETCH (1 << 9)
+#define TIME_AVAILABLE_OFFSET_MASK (0xFF << 1)
+#define TIME_AVAILABLE_OFFSET_SHIFT (1)
+#define BREAK_MEMORY_TRANSFER (1 << 0)
+
+#define INSNREG04(base, offset) (base + 0xA0)
+
+#define INSNREG05(base, offset) (base + 0xA4)
+
+#define INSNREG06(base, offset) (base + 0xA8)
+#define AHB_ERROR_CAPTURED (1 << 31)
+#define HBURST_VALUE_OF_CONTROL_MASK (0x7 << 9)
+#define HBURST_VALUE_OF_CONTROL_SHIFT (9)
+#define NUMBER_OF_BEATS_EXPECTED_MASK (0x1F << 4)
+#define NUMBER_OF_BEATS_EXPECTED_SHIFT (4)
+#define NUMBER_OF_SUCCESSFULLY_MASK (0xF << 0)
+#define NUMBER_OF_SUCCESSFULLY_SHIFT (0)
+
+#define INSNREG07(base, offset) (base + 0xAC)
+#define AHB_MASTER_ERROR_ADDRESS_MASK (0xFFFFFFFF << 0)
+#define AHB_MASTER_ERROR_ADDRESS_SHIFT (0)
+
+#endif /* __ASM_ARCH_MACH_REGS_USB_HOST_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-usb-phy-4210.h b/arch/arm/mach-exynos/include/mach/regs-usb-phy-4210.h
new file mode 100644
index 0000000..eccf619
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-usb-phy-4210.h
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-usb-phy-4210.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - 4210 USB PHY definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_USB_PHY_4210_H
+#define __ASM_ARCH_REGS_USB_PHY_4210_H __FILE__
+
+/* EXYNOS4210 HSIC PHYPWR */
+#define EXYNOS4210_HSIC1_NORMAL_MASK (0x3 << 11)
+#define EXYNOS4210_HSIC1_SLEEP (1 << 12)
+#define EXYNOS4210_HSIC1_FORCE_SUSPEND (1 << 11)
+#define EXYNOS4210_HSIC0_NORMAL_MASK (0x3 << 9)
+#define EXYNOS4210_HSIC0_SLEEP (1 << 10)
+#define EXYNOS4210_HSIC0_FORCE_SUSPEND (1 << 9)
+
+/* EXYNOS4210 PHYCLK */
+#define EXYNOS4210_PHY0_ID_PULLUP (1 << 2)
+#define EXYNOS4210_CLKSEL_MASK (0x3 << 0)
+#define EXYNOS4210_CLKSEL_48M (0x0 << 0)
+#define EXYNOS4210_CLKSEL_12M (0x2 << 0)
+#define EXYNOS4210_CLKSEL_24M (0x3 << 0)
+
+/* EXYNOS4210 PHYCLK */
+#define EXYNOS4210_HOST_LINK_PORT_SWRST_MASK (0xf << 6)
+#define EXYNOS4210_HOST_LINK_PORT2_SWRST (1 << 9)
+#define EXYNOS4210_HOST_LINK_PORT1_SWRST (1 << 8)
+#define EXYNOS4210_HOST_LINK_PORT0_SWRST (1 << 7)
+#define EXYNOS4210_HOST_LINK_ALL_SWRST (1 << 6)
+#define EXYNOS4210_PHY1_SWRST_MASK (0x7 << 3)
+#define EXYNOS4210_PHY1_HSIC_SWRST (1 << 5)
+#define EXYNOS4210_PHY1_STD_SWRST (1 << 4)
+#define EXYNOS4210_PHY1_ALL_SWRST (1 << 3)
+
+#endif /* __ASM_ARCH_REGS_USB_PHY_4210_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-usb-phy-4212.h b/arch/arm/mach-exynos/include/mach/regs-usb-phy-4212.h
new file mode 100644
index 0000000..e56eb16
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-usb-phy-4212.h
@@ -0,0 +1,49 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-usb-phy-4212.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - 4212 USB PHY definition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_USB_PHY_4212_H
+#define __ASM_ARCH_REGS_USB_PHY_4212_H __FILE__
+
+/* EXYNOS4212 HSIC PHYPWR */
+#define EXYNOS4212_HSIC1_NORMAL_MASK (0x7 << 12)
+#define EXYNOS4212_HSIC1_SLEEP (1 << 14)
+#define EXYNOS4212_HSIC1_ANALOG_POWERDOWN (1 << 13)
+#define EXYNOS4212_HSIC1_FORCE_SUSPEND (1 << 12)
+#define EXYNOS4212_HSIC0_NORMAL_MASK (0x7 << 9)
+#define EXYNOS4212_HSIC0_SLEEP (1 << 11)
+#define EXYNOS4212_HSIC0_ANALOG_POWERDOWN (1 << 10)
+#define EXYNOS4212_HSIC0_FORCE_SUSPEND (1 << 9)
+
+/* EXYNOS4212 PHYCLK */
+#define EXYNOS4212_PHY0_ID_PULLUP (1 << 3)
+#define EXYNOS4212_CLKSEL_MASK (0x7 << 0)
+#define EXYNOS4212_CLKSEL_SHIFT (0)
+#define EXYNOS4212_CLKSEL_9600K (0x0 << 0)
+#define EXYNOS4212_CLKSEL_10M (0x1 << 0)
+#define EXYNOS4212_CLKSEL_12M (0x2 << 0)
+#define EXYNOS4212_CLKSEL_19200K (0x3 << 0)
+#define EXYNOS4212_CLKSEL_20M (0x4 << 0)
+#define EXYNOS4212_CLKSEL_24M (0x5 << 0)
+
+/* EXYNOS4212 PHYCLK */
+#define EXYNOS4212_HOST_LINK_PORT_SWRST_MASK (0xf << 7)
+#define EXYNOS4212_HOST_LINK_PORT2_SWRST (1 << 10)
+#define EXYNOS4212_HOST_LINK_PORT1_SWRST (1 << 9)
+#define EXYNOS4212_HOST_LINK_PORT0_SWRST (1 << 8)
+#define EXYNOS4212_HOST_LINK_ALL_SWRST (1 << 7)
+#define EXYNOS4212_PHY1_SWRST_MASK (0xf << 3)
+#define EXYNOS4212_PHY1_HSIC1_SWRST (1 << 6)
+#define EXYNOS4212_PHY1_HSIC0_SWRST (1 << 5)
+#define EXYNOS4212_PHY1_SWRST (1 << 4)
+#define EXYNOS4212_HOST_PHY_SWRST (1 << 3)
+
+#endif /* __ASM_ARCH_REGS_USB_PHY_4212_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos/include/mach/regs-usb-phy.h
new file mode 100644
index 0000000..39a475f
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-usb-phy.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Yulgon Kim <yulgon.kim@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_PHY_H
+#define __ASM_ARCH_REGS_USB_PHY_H
+
+#define EXYNOS4_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
+
+#include "regs-usb-phy-4210.h"
+#include "regs-usb-phy-4212.h"
+
+/* For Exynos4 */
+#define EXYNOS4_PHYPWR EXYNOS4_HSOTG_PHYREG(0x00)
+
+#define PHY1_STD_SLEEP (1 << 8)
+#define PHY1_STD_ANALOG_POWERDOWN (1 << 7)
+#define PHY1_STD_FORCE_SUSPEND (1 << 6)
+#define PHY1_STD_NORMAL_MASK (0x7 << 6)
+
+#define PHY0_SLEEP (1 << 5)
+#define PHY0_OTG_DISABLE (1 << 4)
+#define PHY0_ANALOG_POWERDOWN (1 << 3)
+#define PHY0_FORCE_SUSPEND (1 << 0)
+#define PHY0_NORMAL_MASK (0x29 << 0)
+#define PHY0_PHYTUNE EXYNOS4_HSOTG_PHYREG(0x24)
+#define PHY1_PHYTUNE EXYNOS4_HSOTG_PHYREG(0x20)
+
+#define EXYNOS4_PHYCLK EXYNOS4_HSOTG_PHYREG(0x04)
+#define PHY1_COMMON_ON_N (1 << 7)
+#define PHY0_COMMON_ON_N (1 << 4)
+
+#define CLKSEL_SHIFT (0)
+
+#define EXYNOS4_RSTCON EXYNOS4_HSOTG_PHYREG(0x08)
+
+#define PHY0_SWRST_MASK (0x7 << 0)
+#define PHY0_PHYLINK_SWRST (1 << 2)
+#define PHY0_HLINK_SWRST (1 << 1)
+#define PHY0_SWRST (1 << 0)
+
+#define EXYNOS4_PHY1CON EXYNOS4_HSOTG_PHYREG(0x34)
+#define FPENABLEN (1 << 0)
+
+/* For Exynos5 */
+#define EXYNOS5_PHY_HOST_CTRL0 EXYNOS4_HSOTG_PHYREG(0x00)
+#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31)
+#define HOST_CTRL0_REFCLKSEL(val) (val << 19)
+#define EXYNOS5_CLKSEL_50M (0x7)
+#define EXYNOS5_CLKSEL_24M (0x5)
+#define EXYNOS5_CLKSEL_20M (0x4)
+#define EXYNOS5_CLKSEL_19200K (0x3)
+#define EXYNOS5_CLKSEL_12M (0x2)
+#define EXYNOS5_CLKSEL_10M (0x1)
+#define EXYNOS5_CLKSEL_9600K (0x0)
+#define HOST_CTRL0_CLKSEL_SHIFT (16)
+#define HOST_CTRL0_FSEL_MASK (0x7 << 16)
+
+#define HOST_CTRL0_COMMONON_N (0x1 << 9)
+#define HOST_CTRL0_SIDDQ (0x1 << 6)
+#define HOST_CTRL0_FORCESLEEP (0x1 << 5)
+#define HOST_CTRL0_FORCESUSPEND (0x1 << 4)
+#define HOST_CTRL0_WORDINTERFACE (0x1 << 3)
+#define HOST_CTRL0_UTMISWRST (0x1 << 2)
+#define HOST_CTRL0_LINKSWRST (0x1 << 1)
+#define HOST_CTRL0_PHYSWRST (0x1 << 0)
+
+#define EXYNOS5_PHY_HOST_TUNE0 EXYNOS4_HSOTG_PHYREG(0x04)
+#define EXYNOS5_PHY_HOST_TEST0 EXYNOS4_HSOTG_PHYREG(0x08)
+
+#define EXYNOS5_PHY_HSIC_CTRL1 EXYNOS4_HSOTG_PHYREG(0x10)
+#define EXYNOS5_PHY_HSIC_CTRL2 EXYNOS4_HSOTG_PHYREG(0x20)
+#define HSIC_CTRL_REFCLKSEL(val) ((val&0x3) << 23)
+#define HSIC_CTRL_REFCLKDIV(val) ((val&0x7f) << 16)
+#define HSIC_CTRL_SIDDQ (0x1 << 6)
+#define HSIC_CTRL_FORCESLEEP (0x1 << 5)
+#define HSIC_CTRL_FORCESUSPEND (0x1 << 4)
+#define HSIC_CTRL_WORDINTERFACE (0x1 << 3)
+#define HSIC_CTRL_UTMISWRST (0x1 << 2)
+#define HSIC_CTRL_PHYSWRST (0x1 << 0)
+
+#define EXYNOS5_PHY_HOST_EHCICTRL EXYNOS4_HSOTG_PHYREG(0x30)
+#define EHCICTRL_ENAINCRXALIGN (0x1 << 29)
+#define EHCICTRL_ENAINCR4 (0x1 << 28)
+#define EHCICTRL_ENAINCR8 (0x1 << 27)
+#define EHCICTRL_ENAINCR16 (0x1 << 26)
+
+#define EXYNOS5_PHY_HOST_OHCICTRL EXYNOS4_HSOTG_PHYREG(0x34)
+#define OHCICTRL_SUSPLGCY (0x1 << 3)
+#define OHCICTRL_APPSTARTCLK (0x1 << 2)
+#define OHCICTRL_CNTSEL (0x1 << 1)
+#define OHCICTRL_CLKCKTRST (0x1 << 0)
+
+#define EXYNOS5_PHY_OTG_SYS EXYNOS4_HSOTG_PHYREG(0x38)
+#define OTG_SYS_PHYLINK_SW_RESET (0x1 << 14)
+#define OTG_SYS_LINK_SW_RST_UOTG (0x1 << 13)
+#define OTG_SYS_PHY0_SW_RST (0x1 << 12)
+#define OTG_SYS_REF_CLK_SEL(val) ((val&0x3) << 9)
+#define OTG_SYS_REF_CLK_SEL_MASK (0x3 << 9)
+#define OTG_SYS_IP_PULLUP_UOTG (0x1 << 8)
+#define OTG_SYS_COMMON_ON (0x1 << 7)
+#define OTG_SYS_CLKSEL_SHIFT (4)
+#define OTG_SYS_CTRL0_FSEL_MASK (0x7 << 4)
+#define OTG_SYS_FORCE_SLEEP (0x1 <<3)
+#define OTG_SYS_OTGDISABLE (0x1 <<2)
+#define OTG_SYS_SIDDQ_UOTG (0x1 <<1)
+#define OTG_SYS_FORCE_SUSPEND (0x1 <<0)
+
+extern int exynos_check_usb_op(void);
+
+#endif /* __ASM_ARCH_REGS_USB_PHY_H */
diff --git a/arch/arm/mach-exynos/include/mach/regs-vp.h b/arch/arm/mach-exynos/include/mach/regs-vp.h
new file mode 100644
index 0000000..68a2b0d
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/regs-vp.h
@@ -0,0 +1,293 @@
+/* linux/arch/arm/mach-exynos/include/mach/regs-vp.h
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * Video processor register header file for Samsung TVOUT driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_REGS_VP_H
+#define __ARCH_ARM_REGS_VP_H
+
+/*
+ * Register part
+ */
+#define S5P_VP_ENABLE (0x0000)
+#define S5P_VP_SRESET (0x0004)
+#define S5P_VP_SHADOW_UPDATE (0x0008)
+#define S5P_VP_FIELD_ID (0x000C)
+#define S5P_VP_MODE (0x0010)
+#define S5P_VP_IMG_SIZE_Y (0x0014)
+#define S5P_VP_IMG_SIZE_C (0x0018)
+#define S5P_VP_PER_RATE_CTRL (0x001C)
+#define S5P_VP_TOP_Y_PTR (0x0028)
+#define S5P_VP_BOT_Y_PTR (0x002C)
+#define S5P_VP_TOP_C_PTR (0x0030)
+#define S5P_VP_BOT_C_PTR (0x0034)
+#define S5P_VP_ENDIAN_MODE (0x03CC)
+#define S5P_VP_SRC_H_POSITION (0x0044)
+#define S5P_VP_SRC_V_POSITION (0x0048)
+#define S5P_VP_SRC_WIDTH (0x004C)
+#define S5P_VP_SRC_HEIGHT (0x0050)
+#define S5P_VP_DST_H_POSITION (0x0054)
+#define S5P_VP_DST_V_POSITION (0x0058)
+#define S5P_VP_DST_WIDTH (0x005C)
+#define S5P_VP_DST_HEIGHT (0x0060)
+#define S5P_VP_H_RATIO (0x0064)
+#define S5P_VP_V_RATIO (0x0068)
+#define S5P_VP_POLY8_Y0_LL (0x006C)
+#define S5P_VP_POLY8_Y0_LH (0x0070)
+#define S5P_VP_POLY8_Y0_HL (0x0074)
+#define S5P_VP_POLY8_Y0_HH (0x0078)
+#define S5P_VP_POLY8_Y1_LL (0x007C)
+#define S5P_VP_POLY8_Y1_LH (0x0080)
+#define S5P_VP_POLY8_Y1_HL (0x0084)
+#define S5P_VP_POLY8_Y1_HH (0x0088)
+#define S5P_VP_POLY8_Y2_LL (0x008C)
+#define S5P_VP_POLY8_Y2_LH (0x0090)
+#define S5P_VP_POLY8_Y2_HL (0x0094)
+#define S5P_VP_POLY8_Y2_HH (0x0098)
+#define S5P_VP_POLY8_Y3_LL (0x009C)
+#define S5P_VP_POLY8_Y3_LH (0x00A0)
+#define S5P_VP_POLY8_Y3_HL (0x00A4)
+#define S5P_VP_POLY8_Y3_HH (0x00A8)
+#define S5P_VP_POLY4_Y0_LL (0x00EC)
+#define S5P_VP_POLY4_Y0_LH (0x00F0)
+#define S5P_VP_POLY4_Y0_HL (0x00F4)
+#define S5P_VP_POLY4_Y0_HH (0x00F8)
+#define S5P_VP_POLY4_Y1_LL (0x00FC)
+#define S5P_VP_POLY4_Y1_LH (0x0100)
+#define S5P_VP_POLY4_Y1_HL (0x0104)
+#define S5P_VP_POLY4_Y1_HH (0x0108)
+#define S5P_VP_POLY4_Y2_LL (0x010C)
+#define S5P_VP_POLY4_Y2_LH (0x0110)
+#define S5P_VP_POLY4_Y2_HL (0x0114)
+#define S5P_VP_POLY4_Y2_HH (0x0118)
+#define S5P_VP_POLY4_Y3_LL (0x011C)
+#define S5P_VP_POLY4_Y3_LH (0x0120)
+#define S5P_VP_POLY4_Y3_HL (0x0124)
+#define S5P_VP_POLY4_Y3_HH (0x0128)
+#define S5P_VP_POLY4_C0_LL (0x012C)
+#define S5P_VP_POLY4_C0_LH (0x0130)
+#define S5P_VP_POLY4_C0_HL (0x0134)
+#define S5P_VP_POLY4_C0_HH (0x0138)
+#define S5P_VP_POLY4_C1_LL (0x013C)
+#define S5P_VP_POLY4_C1_LH (0x0140)
+#define S5P_VP_POLY4_C1_HL (0x0144)
+#define S5P_VP_POLY4_C1_HH (0x0148)
+#define S5P_VP_FIELD_ID_S (0x016C)
+#define S5P_VP_MODE_S (0x0170)
+#define S5P_VP_IMG_SIZE_Y_S (0x0174)
+#define S5P_VP_IMG_SIZE_C_S (0x0178)
+#define S5P_VP_TOP_Y_PTR_S (0x0190)
+#define S5P_VP_BOT_Y_PTR_S (0x0194)
+#define S5P_VP_TOP_C_PTR_S (0x0198)
+#define S5P_VP_BOT_C_PTR_S (0x019C)
+#define S5P_VP_SRC_H_POSITION_S (0x01AC)
+#define S5P_VP_SRC_V_POSITION_S (0x01B0)
+#define S5P_VP_SRC_WIDTH_S (0x01B4)
+#define S5P_VP_SRC_HEIGHT_S (0x01B8)
+#define S5P_VP_DST_H_POSITION_S (0x01BC)
+#define S5P_VP_DST_V_POSITION_S (0x01C0)
+#define S5P_VP_DST_WIDTH_S (0x01C4)
+#define S5P_VP_DST_HEIGHT_S (0x01C8)
+#define S5P_VP_H_RATIO_S (0x01CC)
+#define S5P_VP_V_RATIO_S (0x01D0)
+#define S5P_PP_CSC_Y2Y_COEF (0x01D4)
+#define S5P_PP_CSC_CB2Y_COEF (0x01D8)
+#define S5P_PP_CSC_CR2Y_COEF (0x01DC)
+#define S5P_PP_CSC_Y2CB_COEF (0x01E0)
+#define S5P_PP_CSC_CB2CB_COEF (0x01E4)
+#define S5P_PP_CSC_CR2CB_COEF (0x01E8)
+#define S5P_PP_CSC_Y2CR_COEF (0x01EC)
+#define S5P_PP_CSC_CB2CR_COEF (0x01F0)
+#define S5P_PP_CSC_CR2CR_COEF (0x01F4)
+#define S5P_PP_BYPASS (0x0200)
+#define S5P_PP_SATURATION (0x020C)
+#define S5P_PP_SHARPNESS (0x0210)
+#define S5P_PP_LINE_EQ0 (0x0218)
+#define S5P_PP_LINE_EQ1 (0x021C)
+#define S5P_PP_LINE_EQ2 (0x0220)
+#define S5P_PP_LINE_EQ3 (0x0224)
+#define S5P_PP_LINE_EQ4 (0x0228)
+#define S5P_PP_LINE_EQ5 (0x022C)
+#define S5P_PP_LINE_EQ6 (0x0230)
+#define S5P_PP_LINE_EQ7 (0x0234)
+#define S5P_PP_BRIGHT_OFFSET (0x0238)
+#define S5P_PP_CSC_EN (0x023C)
+#define S5P_PP_BYPASS_S (0x0258)
+#define S5P_PP_SATURATION_S (0x025C)
+#define S5P_PP_SHARPNESS_S (0x0260)
+#define S5P_PP_LINE_EQ0_S (0x0268)
+#define S5P_PP_LINE_EQ1_S (0x026C)
+#define S5P_PP_LINE_EQ2_S (0x0270)
+#define S5P_PP_LINE_EQ3_S (0x0274)
+#define S5P_PP_LINE_EQ4_S (0x0278)
+#define S5P_PP_LINE_EQ5_S (0x027C)
+#define S5P_PP_LINE_EQ6_S (0x0280)
+#define S5P_PP_LINE_EQ7_S (0x0284)
+#define S5P_PP_BRIGHT_OFFSET_S (0x0288)
+#define S5P_PP_CSC_EN_S (0x028C)
+#define S5P_PP_CSC_Y2Y_COEF_S (0x0290)
+#define S5P_PP_CSC_CB2Y_COEF_S (0x0294)
+#define S5P_PP_CSC_CR2Y_COEF_S (0x0298)
+#define S5P_PP_CSC_Y2CB_COEF_S (0x029C)
+#define S5P_PP_CSC_CB2CB_COEF_S (0x02A0)
+#define S5P_PP_CSC_CR2CB_COEF_S (0x02A4)
+#define S5P_PP_CSC_Y2CR_COEF_S (0x02A8)
+#define S5P_PP_CSC_CB2CR_COEF_S (0x02AC)
+#define S5P_PP_CSC_CR2CR_COEF_S (0x02B0)
+#define S5P_VP_ENDIAN_MODE_S (0x03EC)
+#define S5P_VP_VERSION_INFO (0x03FC)
+
+/*
+ * Bit definition part
+ */
+ /* VP_ENABLE */
+#define S5P_VP_ENABLE_ON_S (1 << 2)
+#define S5P_VP_ENABLE_OPERATING (1 << 1)
+#define S5P_VP_ENABLE_IDLE_MODE (0 << 1)
+#define S5P_VP_ENABLE_ON (1 << 0)
+#define S5P_VP_ENABLE_OFF (0 << 0)
+
+/* VP_SRESET */
+#define S5P_VP_SRESET_LAST_COMPLETE (0 << 0)
+#define S5P_VP_SRESET_PROCESSING (1 << 0)
+
+/* VP_SHADOW_UPDATE */
+#define S5P_VP_SHADOW_UPDATE_DISABLE (0 << 0)
+#define S5P_VP_SHADOW_UPDATE_ENABLE (1 << 0)
+
+/* VP_FIELD_ID */
+#define S5P_VP_FIELD_ID_TOP (0 << 0)
+#define S5P_VP_FIELD_ID_BOTTOM (1 << 0)
+
+/* VP_MODE */
+#define S5P_VP_MODE_IMG_TYPE_YUV420_NV12 (0 << 6)
+#define S5P_VP_MODE_IMG_TYPE_YUV420_NV21 (1 << 6)
+#define S5P_VP_MODE_LINE_SKIP_OFF (0 << 5)
+#define S5P_VP_MODE_LINE_SKIP_ON (1 << 5)
+#define S5P_VP_MODE_MEM_MODE_LINEAR (0 << 4)
+#define S5P_VP_MODE_MEM_MODE_2D_TILE (1 << 4)
+#define S5P_VP_MODE_CROMA_EXP_C_TOP_PTR (0 << 3)
+#define S5P_VP_MODE_CROMA_EXP_C_TOPBOTTOM_PTR (1 << 3)
+#define S5P_VP_MODE_FIELD_ID_MAN_TOGGLING (0 << 2)
+#define S5P_VP_MODE_FIELD_ID_AUTO_TOGGLING (1 << 2)
+#define S5P_VP_MODE_2D_IPC_DISABLE (0 << 1)
+#define S5P_VP_MODE_2D_IPC_ENABLE (1 << 1)
+
+/* VP_IMG_SIZE_Y */
+/* VP_IMG_SIZE_C */
+#define S5P_VP_IMG_HSIZE(x) (((x) & 0x3FFF) << 16)
+#define S5P_VP_IMG_VSIZE(x) (((x) & 0x3FFF) << 0)
+#define S5P_VP_IMG_SIZE_ILLEGAL(x) ((x) & 0x7)
+
+/* VP_PER_RATE_CTRL */ /* Not support in S5PV210 */
+#define S5P_VP_PEL_RATE_CTRL(x) (((x) & 0x3) << 0)
+
+/* VP_TOP_Y_PTR */
+/* VP_BOT_Y_PTR */
+/* VP_TOP_C_PTR */
+/* VP_BOT_C_PTR */
+#define S5P_VP_PTR_ILLEGAL(x) ((x) & 0x7)
+
+/* VP_ENDIAN_MODE */
+#define S5P_VP_ENDIAN_MODE_BIG (0 << 0)
+#define S5P_VP_ENDIAN_MODE_LITTLE (1 << 0)
+
+/* VP_SRC_H_POSITION */
+#define S5P_VP_SRC_H_POSITION_VAL(x) (((x) & 0x7FF) << 4)
+#define S5P_VP_SRC_X_FRACT_STEP(x) ((x) & 0xF)
+
+/* VP_SRC_V_POSITION */
+#define S5P_VP_SRC_V_POSITION_VAL(x) ((x) & 0x7FF)
+
+/* VP_SRC_WIDTH */
+/* VP_SRC_HEIGHT */
+#define S5P_VP_SRC_WIDTH_VAL(x) ((x) & 0x7FF)
+#define S5P_VP_SRC_HEIGHT_VAL(x) ((x) & 0x7FF)
+
+/* VP_DST_H_POSITION */
+/* VP_DST_V_POSITION */
+#define S5P_VP_DST_H_POSITION_VAL(x) ((x) & 0x7FF)
+#define S5P_VP_DST_V_POSITION_VAL(x) ((x) & 0x7FF)
+
+/* VP_DST_WIDTH */
+/* VP_DST_HEIGHT */
+#define S5P_VP_DST_WIDTH_VAL(x) ((x) & 0x7FF)
+#define S5P_VP_DST_HEIGHT_VAL(x) ((x) & 0x7FF)
+
+/* VP_H_RATIO */
+/* VP_V_RATIO */
+#define S5P_VP_H_RATIO_VAL(x) ((x) & 0x7FFFF)
+#define S5P_VP_V_RATIO_VAL(x) ((x) & 0x7FFFF)
+
+/* PP_CSC_Y2Y_COEF */
+#define S5P_PP_Y2Y_COEF_601_TO_709 (0x400)
+#define S5P_PP_Y2Y_COEF_709_TO_601 (0x400)
+
+/* PP_CSC_CB2Y_COEF */
+#define S5P_PP_CB2Y_COEF_601_TO_709 (0x879)
+#define S5P_PP_CB2Y_COEF_709_TO_601 (0x068)
+
+/* PP_CSC_CR2Y_COEF */
+#define S5P_PP_CR2Y_COEF_601_TO_709 (0x8D9)
+#define S5P_PP_CR2Y_COEF_709_TO_601 (0x0C9)
+
+/* PP_CSC_Y2CB_COEF */
+#define S5P_PP_Y2CB_COEF_601_TO_709 (0x0)
+#define S5P_PP_Y2CB_COEF_709_TO_601 (0x0)
+
+/* PP_CSC_CB2CB_COEF */
+#define S5P_PP_CB2CB_COEF_601_TO_709 (0x413)
+#define S5P_PP_CB2CB_COEF_709_TO_601 (0x3F6)
+
+/* PP_CSC_CR2CB_COEF */
+#define S5P_PP_CR2CB_COEF_601_TO_709 (0x875)
+#define S5P_PP_CR2CB_COEF_709_TO_601 (0x871)
+
+/* PP_CSC_Y2CR_COEF */
+#define S5P_PP_Y2CR_COEF_601_TO_709 (0x0)
+#define S5P_PP_Y2CR_COEF_709_TO_601 (0x0)
+
+/* PP_CSC_CB2CR_COEF */
+#define S5P_PP_CB2CR_COEF_601_TO_709 (0x04D)
+#define S5P_PP_CB2CR_COEF_709_TO_601 (0x84A)
+
+/* PP_CSC_CR2CR_COEF */
+#define S5P_PP_CR2CR_COEF_601_TO_709 (0x41A)
+#define S5P_PP_CR2CR_COEF_709_TO_601 (0xBEF)
+
+#define S5P_PP_CSC_COEF(x) ((x) & 0xFFF)
+
+/* PP_BYPASS */
+#define S5P_VP_BY_PASS_ENABLE (0)
+#define S5P_VP_BY_PASS_DISABLE (1)
+
+/* PP_SATURATION */
+#define S5P_VP_SATURATION(x) ((x) & 0xFF)
+
+/* PP_SHARPNESS */
+#define S5P_VP_TH_HNOISE(x) (((x) & 0xF) << 8)
+#define S5P_VP_SHARPNESS(x) ((x) & 0x3)
+
+/* PP_LINE_EQ0 ~ 7 */
+#define S5P_VP_LINE_INTC(x) (((x) & 0xFFFF) << 8)
+#define S5P_VP_LINE_SLOPE(x) ((x) & 0xFF)
+#define S5P_VP_LINE_INTC_CLEAR(x) ((x) & ~(0xFFFF << 8))
+#define S5P_VP_LINE_SLOPE_CLEAR(x) ((x) & ~0xFF)
+
+/* PP_BRIGHT_OFFSET */
+#define S5P_VP_BRIGHT_OFFSET(x) ((x) & 0x1FF)
+
+/* PP_CSC_EN */
+#define S5P_VP_SUB_Y_OFFSET_ENABLE (1 << 1)
+#define S5P_VP_SUB_Y_OFFSET_DISABLE (0 << 1)
+#define S5P_VP_CSC_ENABLE (1)
+#define S5P_VP_CSC_DISABLE (0)
+
+#endif /* __ARCH_ARM_REGS_VP_H */
diff --git a/arch/arm/mach-exynos/include/mach/restart.h b/arch/arm/mach-exynos/include/mach/restart.h
new file mode 100644
index 0000000..84df9bc
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/restart.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ASM_ARCH_MSM_RESTART_H_
+#define _ASM_ARCH_MSM_RESTART_H_
+
+#define RESTART_NORMAL 0x0
+#define RESTART_DLOAD 0x1
+
+#ifdef CONFIG_MSM_NATIVE_RESTART
+void msm_set_restart_mode(int mode);
+#else
+#define msm_set_restart_mode(mode)
+#endif
+
+extern int pmic_reset_irq;
+
+#endif
+
diff --git a/arch/arm/mach-exynos/include/mach/sec_debug.h b/arch/arm/mach-exynos/include/mach/sec_debug.h
new file mode 100644
index 0000000..53ca0cb
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/sec_debug.h
@@ -0,0 +1,196 @@
+#ifndef SEC_DEBUG_H
+#define SEC_DEBUG_H
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+
+#ifdef CONFIG_SEC_DEBUG
+
+union sec_debug_level_t {
+ struct {
+ u16 kernel_fault;
+ u16 user_fault;
+ } en;
+ u32 uint_val;
+};
+
+extern union sec_debug_level_t sec_debug_level;
+
+extern int sec_debug_init(void);
+
+extern int sec_debug_magic_init(void);
+
+extern void sec_debug_check_crash_key(unsigned int code, int value);
+
+extern void sec_getlog_supply_fbinfo(void *p_fb, u32 res_x, u32 res_y, u32 bpp,
+ u32 frames);
+extern void sec_getlog_supply_loggerinfo(void *p_main, void *p_radio,
+ void *p_events, void *p_system);
+extern void sec_getlog_supply_kloginfo(void *klog_buf);
+
+extern void sec_gaf_supply_rqinfo(unsigned short curr_offset,
+ unsigned short rq_offset);
+#else
+static inline int sec_debug_init(void)
+{
+ return 0;
+}
+
+static inline int sec_debug_magic_init(void)
+{
+ return 0;
+}
+
+static inline void sec_debug_check_crash_key(unsigned int code, int value)
+{
+}
+
+static inline void sec_getlog_supply_fbinfo(void *p_fb, u32 res_x, u32 res_y,
+ u32 bpp, u32 frames)
+{
+}
+
+static inline void sec_getlog_supply_meminfo(u32 size0, u32 addr0, u32 size1,
+ u32 addr1)
+{
+}
+
+static inline void sec_getlog_supply_loggerinfo(void *p_main,
+ void *p_radio, void *p_events,
+ void *p_system)
+{
+}
+
+static inline void sec_getlog_supply_kloginfo(void *klog_buf)
+{
+}
+
+static inline void sec_gaf_supply_rqinfo(unsigned short curr_offset,
+ unsigned short rq_offset)
+{
+}
+
+#endif
+
+struct worker;
+struct work_struct;
+
+#ifdef CONFIG_SEC_DEBUG_SCHED_LOG
+extern void __sec_debug_task_log(int cpu, struct task_struct *task);
+extern void __sec_debug_irq_log(unsigned int irq, void *fn, int en);
+extern void __sec_debug_work_log(struct worker *worker,
+ struct work_struct *work, work_func_t f);
+
+static inline void sec_debug_task_log(int cpu, struct task_struct *task)
+{
+ if (unlikely(sec_debug_level.en.kernel_fault))
+ __sec_debug_task_log(cpu, task);
+}
+
+static inline void sec_debug_irq_log(unsigned int irq, void *fn, int en)
+{
+ if (unlikely(sec_debug_level.en.kernel_fault))
+ __sec_debug_irq_log(irq, fn, en);
+}
+
+static inline void sec_debug_work_log(struct worker *worker,
+ struct work_struct *work, work_func_t f)
+{
+ if (unlikely(sec_debug_level.en.kernel_fault))
+ __sec_debug_work_log(worker, work, f);
+}
+
+#ifdef CONFIG_SEC_DEBUG_SOFTIRQ_LOG
+static inline void sec_debug_softirq_log(unsigned int irq, void *fn, int en)
+{
+ if (unlikely(sec_debug_level.en.kernel_fault))
+ __sec_debug_irq_log(irq, fn, en);
+}
+#else
+static inline void sec_debug_softirq_log(unsigned int irq, void *fn, int en)
+{
+}
+#endif
+#else
+static inline void sec_debug_task_log(int cpu, struct task_struct *task)
+{
+}
+
+static inline void sec_debug_irq_log(unsigned int irq, void *fn, int en)
+{
+}
+
+static inline void sec_debug_work_log(struct worker *worker,
+ struct work_struct *work, work_func_t f)
+{
+}
+
+static inline void sec_debug_softirq_log(unsigned int irq, void *fn, int en)
+{
+}
+#endif
+
+#ifdef CONFIG_SEC_DEBUG_IRQ_EXIT_LOG
+extern void sec_debug_irq_last_exit_log(void);
+#else
+static inline void sec_debug_irq_last_exit_log(void)
+{
+}
+#endif
+
+#ifdef CONFIG_SEC_DEBUG_SEMAPHORE_LOG
+extern void debug_semaphore_init(void);
+extern void debug_semaphore_down_log(struct semaphore *sem);
+extern void debug_semaphore_up_log(struct semaphore *sem);
+extern void debug_rwsemaphore_init(void);
+extern void debug_rwsemaphore_down_log(struct rw_semaphore *sem, int dir);
+extern void debug_rwsemaphore_up_log(struct rw_semaphore *sem);
+#define debug_rwsemaphore_down_read_log(x) \
+ debug_rwsemaphore_down_log(x,READ_SEM)
+#define debug_rwsemaphore_down_write_log(x) \
+ debug_rwsemaphore_down_log(x,WRITE_SEM)
+#else
+static inline void debug_semaphore_init(void)
+{
+}
+
+static inline void debug_semaphore_down_log(struct semaphore *sem)
+{
+}
+
+static inline void debug_semaphore_up_log(struct semaphore *sem)
+{
+}
+
+static inline void debug_rwsemaphore_init(void)
+{
+}
+
+static inline void debug_rwsemaphore_down_read_log(struct rw_semaphore *sem)
+{
+}
+
+static inline void debug_rwsemaphore_down_write_log(struct rw_semaphore *sem)
+{
+}
+
+static inline void debug_rwsemaphore_up_log(struct rw_semaphore *sem)
+{
+}
+#endif
+
+enum sec_debug_aux_log_idx {
+ SEC_DEBUG_AUXLOG_CPU_BUS_CLOCK_CHANGE,
+ SEC_DEBUG_AUXLOG_LOGBUF_LOCK_CHANGE,
+ SEC_DEBUG_AUXLOG_ITEM_MAX,
+};
+
+#ifdef CONFIG_SEC_DEBUG_AUXILIARY_LOG
+extern void sec_debug_aux_log(int idx, char *fmt, ...);
+#else
+#define sec_debug_aux_log(idx, ...) do { } while (0)
+#endif
+
+extern void read_lcd_register(void);
+
+#endif /* SEC_DEBUG_H */
diff --git a/arch/arm/mach-exynos/include/mach/sec_modem.h b/arch/arm/mach-exynos/include/mach/sec_modem.h
new file mode 100644
index 0000000..097726b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/sec_modem.h
@@ -0,0 +1,18 @@
+#ifndef _SEC_MODEM_H_
+#define _SEC_MODEM_H_
+
+enum hsic_lpa_states {
+ STATE_HSIC_LPA_ENTER,
+ STATE_HSIC_LPA_WAKE,
+ STATE_HSIC_LPA_PHY_INIT,
+};
+
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+void set_host_states(struct platform_device *pdev, int type);
+void set_hsic_lpa_states(int states);
+int get_cp_active_state(void);
+#else
+#define set_hsic_lpa_states(states) do {} while (0);
+#endif
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/sec_thermistor.h b/arch/arm/mach-exynos/include/mach/sec_thermistor.h
new file mode 100644
index 0000000..0df32ed
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/sec_thermistor.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_SEC_THERMISTOR_H
+#define __MACH_SEC_THERMISTOR_H __FILE__
+
+
+/**
+ * struct sec_therm_adc_table - adc to temperature table for sec thermistor
+ * driver
+ * @adc: adc value
+ * @temperature: temperature(C) * 10
+ */
+struct sec_therm_adc_table {
+ int adc;
+ int temperature;
+};
+
+/**
+ * struct sec_bat_plaform_data - init data for sec batter driver
+ * @adc_channel: adc channel that connected to thermistor
+ * @adc_table: array of adc to temperature data
+ * @adc_arr_size: size of adc_table
+ * @polling_interval: interval for polling thermistor (msecs)
+ */
+struct sec_therm_platform_data {
+ unsigned int adc_channel;
+ unsigned int adc_arr_size;
+ struct sec_therm_adc_table *adc_table;
+ unsigned int polling_interval;
+ int (*get_siop_level)(int);
+};
+
+#endif /* __MACH_SEC_THERMISTOR_H */
diff --git a/arch/arm/mach-exynos/include/mach/secmem.h b/arch/arm/mach-exynos/include/mach/secmem.h
new file mode 100644
index 0000000..2b21366
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/secmem.h
@@ -0,0 +1,70 @@
+/* linux/arch/arm/mach-exynos/include/mach/secmem.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - Secure memory support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SECMEM_H
+#define __ASM_ARCH_SECMEM_H __FILE__
+
+#include <linux/miscdevice.h>
+#if defined(CONFIG_ION)
+#include <linux/ion.h>
+#endif
+
+struct secchunk_info {
+ int index;
+ phys_addr_t base;
+ size_t size;
+};
+
+extern struct miscdevice secmem;
+#if defined(CONFIG_ION)
+struct secfd_info {
+ int fd;
+ ion_phys_addr_t phys;
+};
+#endif
+
+
+struct secmem_crypto_driver_ftn {
+ int (*lock) (void);
+ int (*release) (void);
+};
+
+struct secmem_region {
+ char *virt_addr;
+ unsigned long phys_addr;
+ unsigned long len;
+};
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) || \
+ defined(CONFIG_CPU_EXYNOS5250)
+void secmem_crypto_register(struct secmem_crypto_driver_ftn *ftn);
+void secmem_crypto_deregister(void);
+#else
+#define secmem_crypto_register(ftn)
+#define secmem_crypto_deregister()
+#endif
+
+#define SECMEM_IOC_CHUNKINFO _IOWR('S', 1, struct secchunk_info)
+#define SECMEM_IOC_SET_DRM_ONOFF _IOWR('S', 2, int)
+#define SECMEM_IOC_GET_DRM_ONOFF _IOWR('S', 3, int)
+#define SECMEM_IOC_GET_CRYPTO_LOCK _IOR('S', 4, int)
+#define SECMEM_IOC_RELEASE_CRYPTO_LOCK _IOR('S', 5, int)
+#define SECMEM_IOC_GET_ADDR _IOWR('S', 6, int)
+#define SECMEM_IOC_RELEASE_ADDR _IOWR('S', 7, int)
+#if defined(CONFIG_CPU_EXYNOS5250)
+#define SECMEM_IOC_GET_FD_PHYS_ADDR _IOWR('S', 8, int)
+#endif
+
+#define SECMEM_IOC_MFC_MAGIC_KEY _IOWR('S', 9, int)
+
+
+#endif /* __ASM_ARCH_SECMEM_H */
diff --git a/arch/arm/mach-exynos/include/mach/smc.h b/arch/arm/mach-exynos/include/mach/smc.h
new file mode 100644
index 0000000..dd0eb36c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/smc.h
@@ -0,0 +1,50 @@
+/* linux/arch/arm/mach-exynos/include/mach/smc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - SMC Call
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SMC_H
+#define __ASM_ARCH_SMC_H __FILE__
+
+#define SMC_CMD_INIT (-1)
+#define SMC_CMD_INFO (-2)
+/* For Power Management */
+#define SMC_CMD_SLEEP (-3)
+#define SMC_CMD_CPU1BOOT (-4)
+#define SMC_CMD_CPU0AFTR (-5)
+/* For CP15 Access */
+#define SMC_CMD_C15RESUME (-11)
+/* For L2 Cache Access */
+#define SMC_CMD_L2X0CTRL (-21)
+#define SMC_CMD_L2X0SETUP1 (-22)
+#define SMC_CMD_L2X0SETUP2 (-23)
+#define SMC_CMD_L2X0INVALL (-24)
+#define SMC_CMD_L2X0DEBUG (-25)
+
+/* For Accessing CP15/SFR (General) */
+#define SMC_CMD_REG (-101)
+
+/* MACRO for SMC_CMD_REG */
+#define SMC_REG_CLASS_CP15 (0x0 << 30)
+#define SMC_REG_CLASS_SFR_W (0x1 << 30)
+#define SMC_REG_CLASS_SFR_R (0x3 << 30)
+#define SMC_REG_CLASS_MASK (0x3 << 30)
+#define SMC_REG_ID_CP15(CRn, Op1, CRm, Op2) \
+ (SMC_REG_CLASS_CP15 | \
+ ((CRn) << 10) | ((Op1) << 7) | ((CRm) << 3) | (Op2))
+#define SMC_REG_ID_SFR_W(ADDR) (SMC_REG_CLASS_SFR_W | ((ADDR) >> 2))
+#define SMC_REG_ID_SFR_R(ADDR) (SMC_REG_CLASS_SFR_R | ((ADDR) >> 2))
+
+#ifndef __ASSEMBLY__
+extern u32 exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3);
+extern u32 exynos_smc_readsfr(u32 addr, u32 *val);
+#endif
+
+#endif /* __ASM_ARCH_SMC_H */
diff --git a/arch/arm/mach-exynos/include/mach/spi-clocks.h b/arch/arm/mach-exynos/include/mach/spi-clocks.h
new file mode 100644
index 0000000..d544241
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/spi-clocks.h
@@ -0,0 +1,17 @@
+/* linux/arch/arm/mach-exynos/include/mach/spi-clocks.h
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __EXYNOS_PLAT_SPI_CLKS_H
+#define __EXYNOS_PLAT_SPI_CLKS_H __FILE__
+
+/* Must source from SCLK_SPI */
+#define EXYNOS_SPI_SRCCLK_SCLK 0
+
+#endif /* __EXYNOS4_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-exynos/include/mach/subsystem_notif.h b/arch/arm/mach-exynos/include/mach/subsystem_notif.h
new file mode 100644
index 0000000..37d4eec
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/subsystem_notif.h
@@ -0,0 +1,80 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Subsystem restart notifier API header
+ *
+ */
+
+#ifndef _SUBSYS_NOTIFIER_H
+#define _SUBSYS_NOTIFIER_H
+
+#include <linux/notifier.h>
+
+enum subsys_notif_type {
+ SUBSYS_BEFORE_SHUTDOWN,
+ SUBSYS_AFTER_SHUTDOWN,
+ SUBSYS_BEFORE_POWERUP,
+ SUBSYS_AFTER_POWERUP,
+ SUBSYS_NOTIF_TYPE_COUNT
+};
+
+#if defined(CONFIG_MSM_SUBSYSTEM_RESTART)
+/* Use the subsys_notif_register_notifier API to register for notifications for
+ * a particular subsystem. This API will return a handle that can be used to
+ * un-reg for notifications using the subsys_notif_unregister_notifier API by
+ * passing in that handle as an argument.
+ *
+ * On receiving a notification, the second (unsigned long) argument of the
+ * notifier callback will contain the notification type, and the third (void *)
+ * argument will contain the handle that was returned by
+ * subsys_notif_register_notifier.
+ */
+void *subsys_notif_register_notifier(
+ const char *subsys_name, struct notifier_block *nb);
+int subsys_notif_unregister_notifier(void *subsys_handle,
+ struct notifier_block *nb);
+
+/* Use the subsys_notif_init_subsys API to initialize the notifier chains form
+ * a particular subsystem. This API will return a handle that can be used to
+ * queue notifications using the subsys_notif_queue_notification API by passing
+ * in that handle as an argument.
+ */
+void *subsys_notif_add_subsys(const char *);
+int subsys_notif_queue_notification(void *subsys_handle,
+ enum subsys_notif_type notif_type);
+#else
+
+static inline void *subsys_notif_register_notifier(
+ const char *subsys_name, struct notifier_block *nb)
+{
+ return NULL;
+}
+
+static inline int subsys_notif_unregister_notifier(void *subsys_handle,
+ struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline void *subsys_notif_add_subsys(const char *subsys_name)
+{
+ return NULL;
+}
+
+static inline int subsys_notif_queue_notification(void *subsys_handle,
+ enum subsys_notif_type notif_type)
+{
+ return 0;
+}
+#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/subsystem_restart.h b/arch/arm/mach-exynos/include/mach/subsystem_restart.h
new file mode 100644
index 0000000..f7becef
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/subsystem_restart.h
@@ -0,0 +1,72 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __SUBSYS_RESTART_H
+#define __SUBSYS_RESTART_H
+
+#include <linux/spinlock.h>
+
+#define SUBSYS_NAME_MAX_LENGTH 40
+
+enum {
+ RESET_SOC = 1,
+ RESET_SUBSYS_COUPLED,
+ RESET_SUBSYS_INDEPENDENT,
+ RESET_SUBSYS_MIXED = 25,
+ RESET_LEVEL_MAX
+};
+
+struct subsys_data {
+ const char *name;
+ int (*shutdown) (const struct subsys_data *);
+ int (*powerup) (const struct subsys_data *);
+ void (*crash_shutdown) (const struct subsys_data *);
+ int (*ramdump) (int, const struct subsys_data *);
+
+ /* Internal use only */
+ struct list_head list;
+ void *notif_handle;
+
+ struct mutex shutdown_lock;
+ struct mutex powerup_lock;
+
+ void *restart_order;
+ struct subsys_data *single_restart_list[1];
+};
+
+#if defined(CONFIG_MSM_SUBSYSTEM_RESTART)
+
+int get_restart_level(void);
+int subsystem_restart(const char *subsys_name);
+int ssr_register_subsystem(struct subsys_data *subsys);
+
+#else
+
+static inline int get_restart_level(void)
+{
+ return 0;
+}
+
+static inline int subsystem_restart(const char *subsystem_name)
+{
+ return 0;
+}
+
+static inline int ssr_register_subsystem(struct subsys_data *subsys)
+{
+ return 0;
+}
+
+#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h
new file mode 100644
index 0000000..ccdb975
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/sysmmu.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - System MMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _ARM_MACH_EXYNOS_SYSMMU_H_
+#define _ARM_MACH_EXYNOS_SYSMMU_H_
+
+struct sysmmu_platform_data {
+ char *dbgname;
+ /* comma(,) separated list of clock names for clock gating */
+ char *clockname;
+};
+
+#define SYSMMU_DEVNAME_BASE "exynos-sysmmu"
+
+#define SYSMMU_CLOCK_NAME "sysmmu"
+#define SYSMMU_CLOCK_NAME2 "sysmmu_mc"
+
+#ifdef CONFIG_EXYNOS_DEV_SYSMMU
+#include <linux/device.h>
+struct platform_device;
+
+#define SYSMMU_PLATDEV(ipname) exynos_device_sysmmu_##ipname
+
+extern struct platform_device SYSMMU_PLATDEV(mfc_lr);
+extern struct platform_device SYSMMU_PLATDEV(tv);
+extern struct platform_device SYSMMU_PLATDEV(jpeg);
+extern struct platform_device SYSMMU_PLATDEV(rot);
+extern struct platform_device SYSMMU_PLATDEV(fimc0);
+extern struct platform_device SYSMMU_PLATDEV(fimc1);
+extern struct platform_device SYSMMU_PLATDEV(fimc2);
+extern struct platform_device SYSMMU_PLATDEV(fimc3);
+extern struct platform_device SYSMMU_PLATDEV(gsc0);
+extern struct platform_device SYSMMU_PLATDEV(gsc1);
+extern struct platform_device SYSMMU_PLATDEV(gsc2);
+extern struct platform_device SYSMMU_PLATDEV(gsc3);
+extern struct platform_device SYSMMU_PLATDEV(isp);
+extern struct platform_device SYSMMU_PLATDEV(fimd0);
+extern struct platform_device SYSMMU_PLATDEV(fimd1);
+extern struct platform_device SYSMMU_PLATDEV(camif0);
+extern struct platform_device SYSMMU_PLATDEV(camif1);
+extern struct platform_device SYSMMU_PLATDEV(camif2);
+extern struct platform_device SYSMMU_PLATDEV(2d);
+
+#ifdef CONFIG_IOMMU_API
+static inline void platform_set_sysmmu(
+ struct device *sysmmu, struct device *dev)
+{
+ dev->archdata.iommu = sysmmu;
+}
+#else
+#define platform_set_sysmmu(dev, sysmmu) do { } while (0)
+#endif
+
+#else /* !CONFIG_EXYNOS_DEV_SYSMMU */
+#define platform_set_sysmmu(dev, sysmmu) do { } while (0)
+#endif
+
+#define SYSMMU_CLOCK_DEVNAME(ipname, id) (SYSMMU_DEVNAME_BASE "." #id)
+
+#endif /* _ARM_MACH_EXYNOS_SYSMMU_H_ */
diff --git a/arch/arm/mach-exynos4/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h
index 5e3220c..51d9bca 100644
--- a/arch/arm/mach-exynos4/include/mach/system.h
+++ b/arch/arm/mach-exynos/include/mach/system.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/system.h
+/* linux/arch/arm/mach-exynos/include/mach/system.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/tdmb_pdata.h b/arch/arm/mach-exynos/include/mach/tdmb_pdata.h
new file mode 100644
index 0000000..ce8a986
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/tdmb_pdata.h
@@ -0,0 +1,31 @@
+/*
+*
+* arch/arm/mach-s5pv310/include/mach/tdmb_pdata.h
+*
+* tdmb driver
+*
+* Copyright (C) (2011, Samsung Electronics)
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation version 2.
+*
+* This program is distributed "as is" WITHOUT ANY WARRANTY of any
+* kind, whether express or implied; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef _TDMB_PDATA_H_
+#define _TDMB_PDATA_H_
+
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+struct tdmb_platform_data {
+ void (*gpio_on) (void);
+ void (*gpio_off)(void);
+ int irq;
+};
+#endif
+#endif
diff --git a/arch/arm/mach-exynos4/include/mach/timex.h b/arch/arm/mach-exynos/include/mach/timex.h
index 6d13875..cb5ada2 100644
--- a/arch/arm/mach-exynos4/include/mach/timex.h
+++ b/arch/arm/mach-exynos/include/mach/timex.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/timex.h
+/* linux/arch/arm/mach-exynos/include/mach/timex.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos4/include/mach/uncompress.h b/arch/arm/mach-exynos/include/mach/uncompress.h
index 21d97bc..0180490 100644
--- a/arch/arm/mach-exynos4/include/mach/uncompress.h
+++ b/arch/arm/mach-exynos/include/mach/uncompress.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
+/* linux/arch/arm/mach-exynos/include/mach/uncompress.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/include/mach/usb_bridge.h b/arch/arm/mach-exynos/include/mach/usb_bridge.h
new file mode 100644
index 0000000..1a1c23b
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/usb_bridge.h
@@ -0,0 +1,156 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#ifndef __LINUX_USB_BRIDGE_H__
+#define __LINUX_USB_BRIDGE_H__
+
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+/* bridge device 0: DUN
+ * bridge device 1 : Tethered RMNET
+ */
+#define MAX_BRIDGE_DEVICES 2
+
+struct bridge_ops {
+ int (*send_pkt)(void *, void *, size_t actual);
+ void (*send_cbits)(void *, unsigned int);
+
+ /* flow control */
+ void (*unthrottle_tx)(void *);
+};
+
+#define TX_THROTTLED BIT(0)
+#define RX_THROTTLED BIT(1)
+
+struct bridge {
+ /* context of the gadget port using bridge driver */
+ void *ctx;
+
+ /* bridge device array index mapped to the gadget port array index.
+ * data bridge[ch_id] <-- bridge --> gadget port[ch_id]
+ */
+ unsigned int ch_id;
+
+ /* flow control bits */
+ unsigned long flags;
+
+ /* data/ctrl bridge callbacks */
+ struct bridge_ops ops;
+};
+
+/**
+ * timestamp_info: stores timestamp info for skb life cycle during data
+ * transfer for tethered rmnet/DUN.
+ * @created: stores timestamp at the time of creation of SKB.
+ * @rx_queued: stores timestamp when SKB queued to HW to receive
+ * data.
+ * @rx_done: stores timestamp when skb queued to h/w is completed.
+ * @rx_done_sent: stores timestamp when SKB is sent from gadget rmnet/DUN
+ * driver to bridge rmnet/DUN driver or vice versa.
+ * @tx_queued: stores timestamp when SKB is queued to send data.
+ *
+ * note that size of this struct shouldnt exceed 48bytes that's the max skb->cb
+ * holds.
+ */
+struct timestamp_info {
+ struct data_bridge *dev;
+
+ unsigned int created;
+ unsigned int rx_queued;
+ unsigned int rx_done;
+ unsigned int rx_done_sent;
+ unsigned int tx_queued;
+};
+
+/* Maximum timestamp message length */
+#define DBG_DATA_MSG 128UL
+
+/* Maximum timestamp messages */
+#define DBG_DATA_MAX 32UL
+
+/* timestamp buffer descriptor */
+struct timestamp_buf {
+ char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
+ unsigned idx; /* index */
+ rwlock_t lck; /* lock */
+};
+
+#if defined(CONFIG_USB_QCOM_MDM_BRIDGE) || \
+ defined(CONFIG_USB_QCOM_MDM_BRIDGE_MODULE)
+
+/* Bridge APIs called by gadget driver */
+int ctrl_bridge_open(struct bridge *);
+void ctrl_bridge_close(unsigned int);
+int ctrl_bridge_write(unsigned int, char *, size_t);
+int ctrl_bridge_set_cbits(unsigned int, unsigned int);
+unsigned int ctrl_bridge_get_cbits_tohost(unsigned int);
+int data_bridge_open(struct bridge *brdg);
+void data_bridge_close(unsigned int);
+int data_bridge_write(unsigned int , struct sk_buff *);
+int data_bridge_unthrottle_rx(unsigned int);
+
+/* defined in control bridge */
+int ctrl_bridge_probe(struct usb_interface *, struct usb_host_endpoint *, int);
+void ctrl_bridge_disconnect(unsigned int);
+int ctrl_bridge_resume(unsigned int);
+int ctrl_bridge_suspend(unsigned int);
+
+#else
+
+static inline int __maybe_unused ctrl_bridge_open(struct bridge *brdg)
+{
+ return -ENODEV;
+}
+
+static inline void __maybe_unused ctrl_bridge_close(unsigned int id) { }
+
+static inline int __maybe_unused ctrl_bridge_write(unsigned int id,
+ char *data, size_t size)
+{
+ return -ENODEV;
+}
+
+static inline int __maybe_unused ctrl_bridge_set_cbits(unsigned int id,
+ unsigned int cbits)
+{
+ return -ENODEV;
+}
+
+static inline unsigned int __maybe_unused
+ctrl_bridge_get_cbits_tohost(unsigned int id)
+{
+ return -ENODEV;
+}
+
+static inline int __maybe_unused data_bridge_open(struct bridge *brdg)
+{
+ return -ENODEV;
+}
+
+static inline void __maybe_unused data_bridge_close(unsigned int id) { }
+
+static inline int __maybe_unused data_bridge_write(unsigned int id,
+ struct sk_buff *skb)
+{
+ return -ENODEV;
+}
+
+static inline int __maybe_unused data_bridge_unthrottle_rx(unsigned int id)
+{
+ return -ENODEV;
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/usb_switch.h b/arch/arm/mach-exynos/include/mach/usb_switch.h
new file mode 100644
index 0000000..de054b6
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/usb_switch.h
@@ -0,0 +1,28 @@
+#ifndef __USB_SWITCH_H__
+#define __USB_SWITCH_H__
+
+extern struct class *sec_class;
+
+enum usb_path_t {
+ USB_PATH_NONE = 0,
+ USB_PATH_ADCCHECK = (1 << 28),
+ USB_PATH_TA = (1 << 24),
+ USB_PATH_CP = (1 << 20),
+#if defined(CONFIG_MACH_P4NOTE)
+ USB_PATH_AP = (1 << 16),
+#else
+ USB_PATH_OTG = (1 << 16),
+ USB_PATH_HOST = (1 << 12)
+#endif
+};
+
+extern int usb_switch_lock(void);
+extern int usb_switch_trylock(void);
+extern void usb_switch_unlock(void);
+
+extern void usb_switch_set_path(enum usb_path_t path);
+extern void usb_switch_clr_path(enum usb_path_t path);
+
+extern void set_usb_connection_state(bool connected);
+
+#endif
diff --git a/arch/arm/mach-exynos/include/mach/usbdiag.h b/arch/arm/mach-exynos/include/mach/usbdiag.h
new file mode 100644
index 0000000..d1e3605
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/usbdiag.h
@@ -0,0 +1,58 @@
+/* include/asm-arm/arch-msm/usbdiag.h
+ *
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * All source code in this file is licensed under the following license except
+ * where indicated.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can find it at http://www.fsf.org
+ */
+
+#ifndef _DRIVERS_USB_DIAG_H_
+#define _DRIVERS_USB_DIAG_H_
+
+#define DIAG_LEGACY "diag"
+#define DIAG_MDM "diag_mdm"
+
+#define USB_DIAG_CONNECT 0
+#define USB_DIAG_DISCONNECT 1
+#define USB_DIAG_WRITE_DONE 2
+#define USB_DIAG_READ_DONE 3
+
+struct diag_request {
+ char *buf;
+ int length;
+ int actual;
+ int status;
+ void *context;
+};
+
+struct usb_diag_ch {
+ const char *name;
+ struct list_head list;
+ void (*notify)(void *priv, unsigned event, struct diag_request *d_req);
+ void *priv;
+ void *priv_usb;
+};
+
+struct usb_diag_ch *usb_diag_open(const char *name, void *priv,
+ void (*notify)(void *, unsigned, struct diag_request *));
+void usb_diag_close(struct usb_diag_ch *ch);
+int usb_diag_alloc_req(struct usb_diag_ch *ch, int n_write, int n_read);
+void usb_diag_free_req(struct usb_diag_ch *ch);
+int usb_diag_read(struct usb_diag_ch *ch, struct diag_request *d_req);
+int usb_diag_write(struct usb_diag_ch *ch, struct diag_request *d_req);
+
+int diag_read_from_cb(unsigned char * , int);
+
+#endif /* _DRIVERS_USB_DIAG_H_ */
diff --git a/arch/arm/mach-exynos/include/mach/videonode-exynos4.h b/arch/arm/mach-exynos/include/mach/videonode-exynos4.h
new file mode 100644
index 0000000..48af509
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/videonode-exynos4.h
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-exynos/include/mach/videonode-exynos4.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Video node definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_VIDEONODE_EXYNOS4_H
+#define __MACH_VIDEONODE_EXYNOS4_H __FILE__
+
+#define S5P_VIDEONODE_MFC_DEC 6
+#define S5P_VIDEONODE_MFC_ENC 7
+
+#define EXYNOS_VIDEONODE_ROTATOR 21
+
+#endif /* __MACH_VIDEONODE_EXYNOS4_H */
diff --git a/arch/arm/mach-exynos/include/mach/videonode-exynos5.h b/arch/arm/mach-exynos/include/mach/videonode-exynos5.h
new file mode 100644
index 0000000..fc8065c
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/videonode-exynos5.h
@@ -0,0 +1,32 @@
+/* linux/arch/arm/mach-exynos/include/mach/videonode-exynos5.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - Video node definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_VIDEONODE_EXYNOS5_H
+#define __MACH_VIDEONODE_EXYNOS5_H __FILE__
+
+#define S5P_VIDEONODE_MFC_DEC 6
+#define S5P_VIDEONODE_MFC_ENC 7
+
+#define EXYNOS_VIDEONODE_ROTATOR 21
+
+#define EXYNOS_VIDEONODE_GSC_M2M(x) (23 + (x) * 3)
+#define EXYNOS_VIDEONODE_GSC_OUT(x) (24 + (x) * 3)
+#define EXYNOS_VIDEONODE_GSC_CAP(x) (25 + (x) * 3)
+
+#define EXYNOS_VIDEONODE_FLITE(x) (36 + x)
+/* Exynos4x12 supports video, graphic0~1 layer
+ * Exynos5250 supports graphic0~3 layer */
+#define EXYNOS_VIDEONODE_MXR_GRP(x) (16 + x)
+#define EXYNOS_VIDEONODE_MXR_VIDEO 20
+#define EXYNOS_VIDEONODE_FIMC_IS (40)
+
+#endif /* __MACH_VIDEONODE_EXYNOS5_H */
diff --git a/arch/arm/mach-exynos/include/mach/videonode.h b/arch/arm/mach-exynos/include/mach/videonode.h
new file mode 100644
index 0000000..b0502d4
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/videonode.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-exynos/include/mach/videonode.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - Video node definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_VIDEONODE_H
+#define __MACH_VIDEONODE_H __FILE__
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#include "videonode-exynos4.h"
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#include "videonode-exynos5.h"
+#else
+#error "ARCH_EXYNOS* is not defined"
+#endif
+
+#endif /* __MACH_VIDEONODE */
diff --git a/arch/arm/mach-exynos4/include/mach/vmalloc.h b/arch/arm/mach-exynos/include/mach/vmalloc.h
index 284330e..30b2e38 100644
--- a/arch/arm/mach-exynos4/include/mach/vmalloc.h
+++ b/arch/arm/mach-exynos/include/mach/vmalloc.h
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/include/mach/vmalloc.h
+/* linux/arch/arm/mach-exynos/include/mach/vmalloc.h
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -17,6 +17,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__
-#define VMALLOC_END 0xF6000000UL
+#define VMALLOC_END (unsigned long)CONFIG_S3C_ADDR_BASE
#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos/init.c
index a8a83e3..e24d848 100644
--- a/arch/arm/mach-exynos4/init.c
+++ b/arch/arm/mach-exynos/init.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/init.c
+/* linux/arch/arm/mach-exynos/init.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -14,7 +14,7 @@
#include <plat/devs.h>
#include <plat/regs-serial.h>
-static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
+static struct s3c24xx_uart_clksrc exynos_serial_clocks[] = {
[0] = {
.name = "uclk1",
.divisor = 1,
@@ -24,7 +24,7 @@ static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
};
/* uart registration process */
-void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+void __init exynos_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
struct s3c2410_uartcfg *tcfg = cfg;
u32 ucnt;
@@ -32,8 +32,8 @@ void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
if (!tcfg->clocks) {
tcfg->has_fracval = 1;
- tcfg->clocks = exynos4_serial_clocks;
- tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
+ tcfg->clocks = exynos_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(exynos_serial_clocks);
}
tcfg->flags |= NO_NEED_CHECK_CLKSRC;
}
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos/irq-combiner.c
index 5a2758a..f2855de 100644
--- a/arch/arm/mach-exynos4/irq-combiner.c
+++ b/arch/arm/mach-exynos/irq-combiner.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/irq-combiner.c
+/* linux/arch/arm/mach-exynos/irq-combiner.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -13,8 +13,11 @@
*/
#include <linux/io.h>
+#include <linux/interrupt.h>
#include <asm/mach/irq.h>
+#include <plat/cpu.h>
+#include <mach/map.h>
#define COMBINER_ENABLE_SET 0x0
#define COMBINER_ENABLE_CLEAR 0x4
@@ -26,6 +29,7 @@ struct combiner_chip_data {
unsigned int irq_offset;
unsigned int irq_mask;
void __iomem *base;
+ unsigned int parent_irq;
};
static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
@@ -66,8 +70,10 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
spin_unlock(&irq_controller_lock);
status &= chip_data->irq_mask;
- if (status == 0)
+ if (status == 0) {
+ do_bad_IRQ(irq, desc);
goto out;
+ }
combiner_irq = __ffs(status);
@@ -81,10 +87,29 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
+#ifdef CONFIG_SMP
+static int combiner_set_affinity(struct irq_data *d,
+ const struct cpumask *mask_val,
+ bool force)
+{
+ struct combiner_chip_data *cd = irq_data_get_irq_chip_data(d);
+ struct irq_chip *chip = irq_get_chip(cd->parent_irq);
+ struct irq_data *pd = irq_get_irq_data(cd->parent_irq);
+
+ if (chip && chip->irq_set_affinity)
+ return chip->irq_set_affinity(pd, mask_val, force);
+ else
+ return -EINVAL;
+}
+#endif
+
static struct irq_chip combiner_chip = {
- .name = "COMBINER",
- .irq_mask = combiner_mask_irq,
- .irq_unmask = combiner_unmask_irq,
+ .name = "COMBINER",
+ .irq_mask = combiner_mask_irq,
+ .irq_unmask = combiner_unmask_irq,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = combiner_set_affinity,
+#endif
};
void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
@@ -94,6 +119,8 @@ void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
BUG();
irq_set_chained_handler(irq, combiner_handle_cascade_irq);
+
+ combiner_data[combiner_nr].parent_irq = irq;
}
void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
@@ -113,6 +140,9 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
__raw_writel(combiner_data[combiner_nr].irq_mask,
base + COMBINER_ENABLE_CLEAR);
+ if (soc_is_exynos4210())
+ __raw_writel(0x01010101, S5P_VA_COMBINER_BASE + 0x40);
+
/* Setup the Linux IRQ subsystem */
for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos/irq-eint.c
index 9d87d2a..1241dfc 100644
--- a/arch/arm/mach-exynos4/irq-eint.c
+++ b/arch/arm/mach-exynos/irq-eint.c
@@ -1,9 +1,9 @@
-/* linux/arch/arm/mach-exynos4/irq-eint.c
+/* linux/arch/arm/mach-exynos/irq-eint.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
- * EXYNOS4 - IRQ EINT support
+ * EXYNOS - IRQ EINT support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,6 +17,8 @@
#include <linux/sysdev.h>
#include <linux/gpio.h>
+#include <asm/mach/irq.h>
+
#include <plat/pm.h>
#include <plat/cpu.h>
#include <plat/gpio-cfg.h>
@@ -27,28 +29,14 @@ static DEFINE_SPINLOCK(eint_lock);
static unsigned int eint0_15_data[16];
-static unsigned int exynos4_get_irq_nr(unsigned int number)
-{
- u32 ret = 0;
-
- switch (number) {
- case 0 ... 3:
- ret = (number + IRQ_EINT0);
- break;
- case 4 ... 7:
- ret = (number + (IRQ_EINT4 - 4));
- break;
- case 8 ... 15:
- ret = (number + (IRQ_EINT8 - 8));
- break;
- default:
- printk(KERN_ERR "number available : %d\n", number);
- }
-
- return ret;
-}
+static unsigned int eint0_15_src_int[16] = {
+ IRQ_EINT0, IRQ_EINT1, IRQ_EINT2, IRQ_EINT3,
+ IRQ_EINT4, IRQ_EINT5, IRQ_EINT6, IRQ_EINT7,
+ IRQ_EINT8, IRQ_EINT9, IRQ_EINT10, IRQ_EINT11,
+ IRQ_EINT12, IRQ_EINT13, IRQ_EINT14, IRQ_EINT15,
+};
-static inline void exynos4_irq_eint_mask(struct irq_data *data)
+static inline void exynos_irq_eint_mask(struct irq_data *data)
{
u32 mask;
@@ -59,7 +47,7 @@ static inline void exynos4_irq_eint_mask(struct irq_data *data)
spin_unlock(&eint_lock);
}
-static void exynos4_irq_eint_unmask(struct irq_data *data)
+static void exynos_irq_eint_unmask(struct irq_data *data)
{
u32 mask;
@@ -70,24 +58,25 @@ static void exynos4_irq_eint_unmask(struct irq_data *data)
spin_unlock(&eint_lock);
}
-static inline void exynos4_irq_eint_ack(struct irq_data *data)
+static inline void exynos_irq_eint_ack(struct irq_data *data)
{
__raw_writel(eint_irq_to_bit(data->irq),
S5P_EINT_PEND(EINT_REG_NR(data->irq)));
}
-static void exynos4_irq_eint_maskack(struct irq_data *data)
+static void exynos_irq_eint_maskack(struct irq_data *data)
{
- exynos4_irq_eint_mask(data);
- exynos4_irq_eint_ack(data);
+ exynos_irq_eint_mask(data);
+ exynos_irq_eint_ack(data);
}
-static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
+static int exynos_irq_eint_set_type(struct irq_data *data, unsigned int type)
{
int offs = EINT_OFFSET(data->irq);
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
+ struct irq_desc *desc = irq_to_desc(data->irq);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -142,22 +131,28 @@ static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type)
printk(KERN_ERR "No such irq number %d", offs);
}
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ desc->handle_irq = handle_edge_irq;
+ else
+ desc->handle_irq = handle_level_irq;
+
return 0;
}
-static struct irq_chip exynos4_irq_eint = {
- .name = "exynos4-eint",
- .irq_mask = exynos4_irq_eint_mask,
- .irq_unmask = exynos4_irq_eint_unmask,
- .irq_mask_ack = exynos4_irq_eint_maskack,
- .irq_ack = exynos4_irq_eint_ack,
- .irq_set_type = exynos4_irq_eint_set_type,
+static struct irq_chip exynos_irq_eint = {
+ .name = "exynos-eint",
+ .irq_mask = exynos_irq_eint_mask,
+ .irq_unmask = exynos_irq_eint_unmask,
+ .irq_mask_ack = exynos_irq_eint_maskack,
+ .irq_disable = exynos_irq_eint_maskack,
+ .irq_ack = exynos_irq_eint_ack,
+ .irq_set_type = exynos_irq_eint_set_type,
#ifdef CONFIG_PM
.irq_set_wake = s3c_irqext_wake,
#endif
};
-/* exynos4_irq_demux_eint
+/* exynos_irq_demux_eint
*
* This function demuxes the IRQ from from EINTs 16 to 31.
* It is designed to be inlined into the specific handler
@@ -165,12 +160,13 @@ static struct irq_chip exynos4_irq_eint = {
*
* Each EINT pend/mask registers handle eight of them.
*/
-static inline void exynos4_irq_demux_eint(unsigned int start)
+static inline u32 exynos_irq_demux_eint(unsigned int start)
{
unsigned int irq;
u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+ u32 action = 0;
status &= ~mask;
status &= 0xff;
@@ -179,52 +175,58 @@ static inline void exynos4_irq_demux_eint(unsigned int start)
irq = fls(status) - 1;
generic_handle_irq(irq + start);
status &= ~(1 << irq);
+ ++action;
}
+
+ return action;
}
-static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
- exynos4_irq_demux_eint(IRQ_EINT(16));
- exynos4_irq_demux_eint(IRQ_EINT(24));
+ struct irq_chip *chip = irq_get_chip(irq);
+ u32 a16_23, a24_31;
+
+ chained_irq_enter(chip, desc);
+ a16_23 = exynos_irq_demux_eint(IRQ_EINT(16));
+ a24_31 = exynos_irq_demux_eint(IRQ_EINT(24));
+ chained_irq_exit(chip, desc);
+
+ if (!a16_23 && !a24_31)
+ do_bad_IRQ(irq, desc);
}
-static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
+static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
{
u32 *irq_data = irq_get_handler_data(irq);
struct irq_chip *chip = irq_get_chip(irq);
- chip->irq_mask(&desc->irq_data);
-
- if (chip->irq_ack)
- chip->irq_ack(&desc->irq_data);
-
+ chained_irq_enter(chip, desc);
generic_handle_irq(*irq_data);
-
- chip->irq_unmask(&desc->irq_data);
+ chained_irq_exit(chip, desc);
}
-int __init exynos4_init_irq_eint(void)
+int __init exynos_init_irq_eint(void)
{
int irq;
for (irq = 0 ; irq <= 31 ; irq++) {
- irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint,
+ irq_set_chip_and_handler(IRQ_EINT(irq), &exynos_irq_eint,
handle_level_irq);
set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
}
- irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
+ irq_set_chained_handler(IRQ_EINT16_31, exynos_irq_demux_eint16_31);
for (irq = 0 ; irq <= 15 ; irq++) {
eint0_15_data[irq] = IRQ_EINT(irq);
- irq_set_handler_data(exynos4_get_irq_nr(irq),
+ irq_set_handler_data(eint0_15_src_int[irq],
&eint0_15_data[irq]);
- irq_set_chained_handler(exynos4_get_irq_nr(irq),
- exynos4_irq_eint0_15);
+ irq_set_chained_handler(eint0_15_src_int[irq],
+ exynos_irq_eint0_15);
}
return 0;
}
-arch_initcall(exynos4_init_irq_eint);
+arch_initcall(exynos_init_irq_eint);
diff --git a/arch/arm/mach-exynos/irq-sgi.c b/arch/arm/mach-exynos/irq-sgi.c
new file mode 100644
index 0000000..ca5973c
--- /dev/null
+++ b/arch/arm/mach-exynos/irq-sgi.c
@@ -0,0 +1,76 @@
+/* linux/arch/arm/mach-exynos/irq-sgi.c
+ *
+ * Copyright (c) 2011 Gisecke & Devrient
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * Based on linux/arch/arm/plat-s5p/irq-eint.c
+ *
+ * EXYNOS - Software Generated Interrupts Dummy chip support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/regs-irq.h>
+
+static inline void exynos_irq_sgi_mask(struct irq_data *d)
+{
+ /* Do nothing, because SGIs are always enabled. */
+}
+
+static void exynos_irq_sgi_unmask(struct irq_data *d)
+{
+ /* Do nothing, because SGIs are always enabled. */
+}
+
+static inline void exynos_irq_sgi_eoi(struct irq_data *d)
+{
+ unsigned int irq = (d->irq - S5P_IRQ_OFFSET);
+
+ writel(irq, S5P_VA_GIC_CPU + GIC_CPU_EOI);
+}
+
+static int exynos_irq_sgi_set_type(struct irq_data *d, unsigned int type)
+{
+ return 0;
+}
+
+static struct irq_chip exynos_irq_sgi = {
+ .name = "exynos_sgi",
+ .irq_mask = exynos_irq_sgi_mask,
+ .irq_unmask = exynos_irq_sgi_unmask,
+ .irq_eoi = exynos_irq_sgi_eoi,
+ .irq_set_type = exynos_irq_sgi_set_type,
+};
+
+/*
+ * exynos_init_irq_sgi
+ *
+ * Setup the SGI IRQ to a dummy GIC. The interrupts use the same id
+ * as provided by get_irqnr_and_base, no demuxing is necesarry but
+ * we are handling the last 8 SGIs as normal interrupts in
+ * get_irqnr_and_base.
+ *
+ * NOTE: SGIs are bound to the CPU for which they have been generated
+ * so use with care.
+ */
+int __init exynos_init_irq_sgi(void)
+{
+ int irq;
+
+ for (irq = 8; irq <= 15; irq++) {
+ irq_set_chip_and_handler(IRQ_SGI(irq), &exynos_irq_sgi, handle_fasteoi_irq);
+ set_irq_flags(IRQ_SGI(irq), IRQF_VALID);
+ }
+
+ return 0;
+}
+
+arch_initcall(exynos_init_irq_sgi);
diff --git a/arch/arm/mach-exynos4/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index b482c62..f6b0ba7 100644
--- a/arch/arm/mach-exynos4/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/mach-armlex4210.c
+/* linux/arch/arm/mach-exynos/mach-armlex4210.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -155,7 +155,6 @@ static struct platform_device *armlex4210_devices[] __initdata = {
&s3c_device_hsmmc3,
&s3c_device_rtc,
&s3c_device_wdt,
- &exynos4_device_sysmmu,
&samsung_asoc_dma,
&armlex4210_smsc911x,
&exynos4_device_ahci,
diff --git a/arch/arm/mach-exynos/mach-midas.c b/arch/arm/mach-exynos/mach-midas.c
new file mode 100644
index 0000000..5603258
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-midas.c
@@ -0,0 +1,2802 @@
+/* linux/arch/arm/mach-exynos/mach-smdk4212.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio_event.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/pwm_backlight.h>
+#include <linux/input.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#ifdef CONFIG_LEDS_AAT1290A
+#include <linux/leds-aat1290a.h>
+#endif
+#ifdef CONFIG_MFD_MAX77693
+#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-private.h>
+#include <linux/leds-max77693.h>
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17047_FUELGAUGE
+#include <linux/battery/max17047_fuelgauge.h>
+#endif
+#if defined(CONFIG_BATTERY_SAMSUNG) || defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
+#include <linux/power_supply.h>
+#include <linux/battery/samsung_battery.h>
+#endif
+#if defined(CONFIG_CHARGER_MAX8922_U1) || defined(CONFIG_CHARGER_MAX8922_S2PLUS)
+#include <linux/power/max8922_charger_u1.h>
+#endif
+#ifdef CONFIG_STMPE811_ADC
+#include <linux/stmpe811-adc.h>
+#endif
+#include <linux/v4l2-mediabus.h>
+#include <linux/memblock.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/keypad.h>
+#include <plat/devs.h>
+#include <plat/fb-s5p.h>
+#include <plat/fb-core.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/backlight.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#include <plat/s3c64xx-spi.h>
+#include <plat/tvout.h>
+#include <plat/csis.h>
+#include <plat/media.h>
+#include <plat/adc.h>
+#include <media/exynos_fimc_is.h>
+#include <mach/exynos-ion.h>
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#include <mach/tdmb_pdata.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/spi-clocks.h>
+
+#include <mach/dev.h>
+#include <mach/ppmu.h>
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+#include <plat/s5p-tmu.h>
+#include <mach/regs-tmu.h>
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+#include <mach/c2c.h>
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+
+#include <plat/fb-s5p.h>
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct s3cfb_extdsp_lcd {
+ int width;
+ int height;
+ int bpp;
+};
+#endif
+#include <mach/dev-sysmmu.h>
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#include <plat/jpeg.h>
+#endif
+
+#include <plat/fimg2d.h>
+#include <plat/s5p-sysmmu.h>
+
+#include <mach/sec_debug.h>
+
+#include <mach/gpio-midas.h>
+#ifdef CONFIG_MACH_GC1
+#include <mach/gc1-power.h>
+#else
+#include <mach/midas-power.h>
+#endif
+#ifdef CONFIG_SEC_THERMISTOR
+#include <mach/sec_thermistor.h>
+#endif
+#include <mach/midas-thermistor.h>
+#include <mach/midas-tsp.h>
+#include <mach/regs-clock.h>
+
+#include <mach/midas-lcd.h>
+#include <mach/midas-sound.h>
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI)
+#include <linux/phone_svn/ipc_spi.h>
+#include <linux/irq.h>
+#endif
+
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+#include <linux/i2c/touchkey_i2c.h>
+#endif
+
+#include "board-mobile.h"
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK4212_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK4212_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK4212_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+#define SMDK4212_UFCON_GPS (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG8 | \
+ S5PV210_UFCON_RXTRIG32)
+
+static struct s3c2410_uartcfg smdk4212_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_GPS,
+ .set_runstate = set_gps_uart_op,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_DEFAULT,
+ },
+};
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(5),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+ {
+ .modalias = "s5c73m3_spi",
+ .platform_data = NULL,
+ .max_speed_hz = 50000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi1_csi[0],
+ }
+};
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI) \
+ || defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+static struct s3c64xx_spi_csinfo spi2_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPC1(2),
+ .set_level = gpio_set_value,
+ },
+};
+
+static struct spi_board_info spi2_board_info[] __initdata = {
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {
+ .modalias = "tdmbspi",
+ .platform_data = NULL,
+ .max_speed_hz = 5000000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi2_csi[0],
+ },
+#else
+ {
+ .modalias = "ipc_spi",
+ .platform_data = NULL,
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 12*1000*1000,
+ .mode = SPI_MODE_1,
+ .controller_data = &spi2_csi[0],
+ }
+#endif
+};
+#endif
+#endif
+
+static struct i2c_board_info i2c_devs8_emul[];
+
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+static void touchkey_init_hw(void)
+{
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1VZW)\
+|| defined(CONFIG_MACH_C1)
+#if defined(CONFIG_MACH_M0_CHNOPEN) || defined(CONFIG_MACH_M0_HKTW)\
+|| defined(CONFIG_TARGET_LOCALE_KOR)
+/* do nothing */
+#elif defined(CONFIG_MACH_C1)
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+ if (system_rev < 8)
+ return ;
+#elif defined(CONFIG_MACH_C1_KOR_LGT)
+ if (system_rev < 5)
+ return ;
+#else
+ if (system_rev < 7)
+ return ;
+#endif
+#else
+ /*rev 1.0*/
+ if (system_rev < 11)
+ return ;
+#endif
+#endif
+#if defined(CONFIG_MACH_S2PLUS)\
+|| defined(CONFIG_TARGET_LOCALE_KOR)\
+|| defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1VZW)\
+|| defined(CONFIG_MACH_C1)
+ gpio_request(GPIO_3_TOUCH_EN, "gpio_3_touch_en");
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ gpio_request(GPIO_3_TOUCH_LDO_EN, "gpio_3_touch_ldo_en");
+#endif
+#endif
+ gpio_request(GPIO_3_TOUCH_INT, "3_TOUCH_INT");
+ s3c_gpio_setpull(GPIO_3_TOUCH_INT, S3C_GPIO_PULL_NONE);
+ s5p_register_gpio_interrupt(GPIO_3_TOUCH_INT);
+ gpio_direction_input(GPIO_3_TOUCH_INT);
+
+ i2c_devs8_emul[0].irq = gpio_to_irq(GPIO_3_TOUCH_INT);
+ irq_set_irq_type(gpio_to_irq(GPIO_3_TOUCH_INT), IRQF_TRIGGER_FALLING);
+ s3c_gpio_cfgpin(GPIO_3_TOUCH_INT, S3C_GPIO_SFN(0xf));
+
+ s3c_gpio_setpull(GPIO_3_TOUCH_SCL, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_3_TOUCH_SDA, S3C_GPIO_PULL_DOWN);
+
+}
+
+static int touchkey_suspend(void)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, TK_REGULATOR_NAME);
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ #if defined(CONFIG_MACH_C1_KOR_LGT)
+ gpio_request(GPIO_3_TOUCH_LDO_EN, "gpio_3_touch_ldo_en");
+ gpio_direction_output(GPIO_3_TOUCH_LDO_EN, 0);
+ #endif
+
+ s3c_gpio_setpull(GPIO_3_TOUCH_SCL, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_3_TOUCH_SDA, S3C_GPIO_PULL_DOWN);
+
+ regulator_put(regulator);
+
+ return 1;
+}
+
+static int touchkey_resume(void)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, TK_REGULATOR_NAME);
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ #if defined(CONFIG_MACH_C1_KOR_LGT)
+ gpio_request(GPIO_3_TOUCH_LDO_EN, "gpio_3_touch_ldo_en");
+ gpio_direction_output(GPIO_3_TOUCH_LDO_EN, 1);
+ #endif
+ regulator_put(regulator);
+
+ s3c_gpio_setpull(GPIO_3_TOUCH_SCL, S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(GPIO_3_TOUCH_SDA, S3C_GPIO_PULL_NONE);
+
+ return 1;
+}
+
+static int touchkey_power_on(bool on)
+{
+ int ret;
+
+ if (on) {
+ gpio_direction_output(GPIO_3_TOUCH_INT, 1);
+ irq_set_irq_type(gpio_to_irq(GPIO_3_TOUCH_INT), IRQF_TRIGGER_FALLING);
+ s3c_gpio_cfgpin(GPIO_3_TOUCH_INT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_3_TOUCH_INT, S3C_GPIO_PULL_NONE);
+ } else
+ gpio_direction_input(GPIO_3_TOUCH_INT);
+
+ if (on)
+ ret = touchkey_resume();
+ else
+ ret = touchkey_suspend();
+
+ return ret;
+}
+
+static int touchkey_led_power_on(bool on)
+{
+#if defined(LED_LDO_WITH_EN_PIN)
+ if (on)
+ gpio_direction_output(GPIO_3_TOUCH_EN, 1);
+ else
+ gpio_direction_output(GPIO_3_TOUCH_EN, 0);
+#else
+ struct regulator *regulator;
+
+ if (on) {
+ regulator = regulator_get(NULL, "touch_led");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "touch_led");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+#endif
+ return 1;
+}
+
+static struct touchkey_platform_data touchkey_pdata = {
+ .gpio_sda = GPIO_3_TOUCH_SDA,
+ .gpio_scl = GPIO_3_TOUCH_SCL,
+ .gpio_int = GPIO_3_TOUCH_INT,
+ .init_platform_hw = touchkey_init_hw,
+ .suspend = touchkey_suspend,
+ .resume = touchkey_resume,
+ .power_on = touchkey_power_on,
+ .led_power_on = touchkey_led_power_on,
+};
+#endif /*CONFIG_KEYBOARD_CYPRESS_TOUCH*/
+
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+static void tdmb_set_config_poweron(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_SFN(GPIO_TDMB_INT_AF));
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_SPI_CLK, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(GPIO_TDMB_SPI_MISO, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(GPIO_TDMB_SPI_MOSI, S3C_GPIO_SFN(5));
+ s3c_gpio_setpull(GPIO_TDMB_SPI_CLK, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_TDMB_SPI_MISO, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_TDMB_SPI_MOSI, S3C_GPIO_PULL_DOWN);
+}
+static void tdmb_set_config_poweroff(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_INT, GPIO_LEVEL_LOW);
+}
+
+static void tdmb_gpio_on(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_on\n");
+
+ tdmb_set_config_poweron();
+
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+ usleep_range(1000, 1000);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_HIGH);
+}
+
+static void tdmb_gpio_off(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_off\n");
+
+ tdmb_set_config_poweroff();
+
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+}
+
+static struct tdmb_platform_data tdmb_pdata = {
+ .gpio_on = tdmb_gpio_on,
+ .gpio_off = tdmb_gpio_off,
+};
+
+static struct platform_device tdmb_device = {
+ .name = "tdmb",
+ .id = -1,
+ .dev = {
+ .platform_data = &tdmb_pdata,
+ },
+};
+
+static int __init tdmb_dev_init(void)
+{
+ tdmb_set_config_poweroff();
+ s5p_register_gpio_interrupt(GPIO_TDMB_INT);
+ tdmb_pdata.irq = GPIO_TDMB_IRQ;
+ platform_device_register(&tdmb_device);
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI)
+static void ipc_spi_cfg_gpio(void);
+
+static struct ipc_spi_platform_data ipc_spi_data = {
+ .gpio_ipc_mrdy = GPIO_IPC_MRDY,
+ .gpio_ipc_srdy = GPIO_IPC_SRDY,
+ .gpio_ipc_sub_mrdy = GPIO_IPC_SUB_MRDY,
+ .gpio_ipc_sub_srdy = GPIO_IPC_SUB_SRDY,
+
+ .cfg_gpio = ipc_spi_cfg_gpio,
+};
+
+static struct resource ipc_spi_res[] = {
+ [0] = {
+ .start = IRQ_IPC_SRDY,
+ .end = IRQ_IPC_SRDY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ipc_spi_device = {
+ .name = "onedram",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ipc_spi_res),
+ .resource = ipc_spi_res,
+ .dev = {
+ .platform_data = &ipc_spi_data,
+ },
+};
+
+static void ipc_spi_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_ipc_mrdy = ipc_spi_data.gpio_ipc_mrdy;
+ unsigned gpio_ipc_srdy = ipc_spi_data.gpio_ipc_srdy;
+ unsigned gpio_ipc_sub_mrdy = ipc_spi_data.gpio_ipc_sub_mrdy;
+ unsigned gpio_ipc_sub_srdy = ipc_spi_data.gpio_ipc_sub_srdy;
+
+ err = gpio_request(gpio_ipc_mrdy, "IPC_MRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_MRDY", err);
+ } else {
+ gpio_direction_output(gpio_ipc_mrdy, 0);
+ }
+
+ err = gpio_request(gpio_ipc_srdy, "IPC_SRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SRDY", err);
+ } else {
+ gpio_direction_input(gpio_ipc_srdy);
+ s3c_gpio_cfgpin(gpio_ipc_srdy, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_srdy, S3C_GPIO_PULL_DOWN);
+ }
+
+ err = gpio_request(gpio_ipc_sub_mrdy, "IPC_SUB_MRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SUB_MRDY", err);
+ } else {
+ gpio_direction_output(gpio_ipc_sub_mrdy, 0);
+ }
+
+ err = gpio_request(gpio_ipc_sub_srdy, "IPC_SUB_SRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SUB_SRDY", err);
+ } else {
+ gpio_direction_input(gpio_ipc_sub_srdy);
+ s3c_gpio_cfgpin(gpio_ipc_sub_srdy, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_sub_srdy, S3C_GPIO_PULL_DOWN);
+ }
+
+ irq_set_irq_type(gpio_to_irq(GPIO_IPC_SRDY), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(GPIO_IPC_SUB_SRDY), IRQ_TYPE_EDGE_RISING);
+}
+#endif
+
+#ifdef CONFIG_LEDS_AAT1290A
+static int aat1290a_initGpio(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_CAM_SW_EN, "CAM_SW_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request CAM_SW_EN\n");
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_CAM_SW_EN, 1);
+
+ return 0;
+}
+
+static void aat1290a_switch(int enable)
+{
+ gpio_set_value(GPIO_CAM_SW_EN, enable);
+}
+
+static int aat1290a_setGpio(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_TORCH_EN, "TORCH_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request TORCH_EN\n");
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_TORCH_EN, 0);
+ err = gpio_request(GPIO_TORCH_SET, "TORCH_SET");
+ if (err) {
+ printk(KERN_ERR "failed to request TORCH_SET\n");
+ gpio_free(GPIO_TORCH_EN);
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_TORCH_SET, 0);
+
+ return 0;
+}
+
+static int aat1290a_freeGpio(void)
+{
+ gpio_free(GPIO_TORCH_EN);
+ gpio_free(GPIO_TORCH_SET);
+
+ return 0;
+}
+
+static void aat1290a_torch_en(int onoff)
+{
+ gpio_set_value(GPIO_TORCH_EN, onoff);
+}
+
+static void aat1290a_torch_set(int onoff)
+{
+ gpio_set_value(GPIO_TORCH_SET, onoff);
+}
+
+static struct aat1290a_led_platform_data aat1290a_led_data = {
+ .brightness = TORCH_BRIGHTNESS_50,
+ .status = STATUS_UNAVAILABLE,
+ .switch_sel = aat1290a_switch,
+ .initGpio = aat1290a_initGpio,
+ .setGpio = aat1290a_setGpio,
+ .freeGpio = aat1290a_freeGpio,
+ .torch_en = aat1290a_torch_en,
+ .torch_set = aat1290a_torch_set,
+};
+
+static struct platform_device s3c_device_aat1290a_led = {
+ .name = "aat1290a-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &aat1290a_led_data,
+ },
+};
+#endif
+
+static DEFINE_MUTEX(notify_lock);
+
+#define DEFINE_MMC_CARD_NOTIFIER(num) \
+static void (*hsmmc##num##_notify_func)(struct platform_device *, int state); \
+static int ext_cd_init_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func); \
+ hsmmc##num##_notify_func = notify_func; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+} \
+static int ext_cd_cleanup_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func != notify_func); \
+ hsmmc##num##_notify_func = NULL; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+}
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ DEFINE_MMC_CARD_NOTIFIER(3)
+#endif
+
+/*
+ * call this when you need sd stack to recognize insertion or removal of card
+ * that can't be told by SDHCI regs
+ */
+void mmc_force_presence_change(struct platform_device *pdev)
+{
+ void (*notify_func)(struct platform_device *, int state) = NULL;
+ mutex_lock(&notify_lock);
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ if (pdev == &s3c_device_hsmmc3)
+ notify_func = hsmmc3_notify_func;
+#endif
+
+ if (notify_func)
+ notify_func(pdev, 1);
+ else
+ pr_warn("%s: called for device with no notifier\n", __func__);
+ mutex_unlock(&notify_lock);
+}
+EXPORT_SYMBOL_GPL(mmc_force_presence_change);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdk4212_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdk4212_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdk4212_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = EXYNOS4_GPX3(4),
+ .ext_cd_gpio_invert = true,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .vmmc_name = "vtf_2.8v"
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdk4212_hsmmc3_pdata __initdata = {
+/* new code for brm4334 */
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+ .ext_cd_init = ext_cd_init_hsmmc3,
+ .ext_cd_cleanup = ext_cd_cleanup_hsmmc3,
+};
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+ .fifo_depth = 0x80,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50 | MMC_CAP_CMD23,
+ .host_caps2 = MMC_CAP2_PACKED_CMD,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_CMD23,
+#endif
+ .int_power_gpio = GPIO_eMMC_EN,
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdk4212_ehci_pdata;
+
+static void __init smdk4212_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk4212_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdk4212_ohci_pdata;
+
+static void __init smdk4212_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk4212_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdk4212_usbgadget_pdata;
+
+#include <linux/usb/android_composite.h>
+static void __init smdk4212_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdk4212_usbgadget_pdata;
+ struct android_usb_platform_data *android_pdata =
+ s3c_device_android_usb.dev.platform_data;
+ if (android_pdata) {
+#if defined(CONFIG_MACH_M0_CTC)
+ /*FOR CTC PC-MODEM START*/
+ unsigned int newluns = 3;
+ /*FOR CTC PC-MODEM END*/
+#else
+ unsigned int newluns = 2;
+#endif
+ printk(KERN_DEBUG "usb: %s: default luns=%d, new luns=%d\n",
+ __func__, android_pdata->nluns, newluns);
+ android_pdata->nluns = newluns;
+ } else {
+ printk(KERN_DEBUG "usb: %s android_pdata is not available\n",
+ __func__);
+ }
+
+ s5p_usbgadget_set_platdata(pdata);
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ pdata = s3c_device_usbgadget.dev.platform_data;
+ if (pdata) {
+ /* Squelch Threshold Tune [13:11] (111 : -20%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x7 << 11);
+ printk(KERN_DEBUG "usb: %s tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+ }
+#endif
+
+}
+#endif
+
+#ifdef CONFIG_MFD_MAX77693
+#ifdef CONFIG_VIBETONZ
+static struct max77693_haptic_platform_data max77693_haptic_pdata = {
+ .max_timeout = 10000,
+ .duty = 37050,
+ .period = 38054,
+ .reg2 = MOTOR_LRA | EXT_PWM | DIVIDER_128,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 0,
+ .regulator_name = "vmotor",
+};
+#endif
+
+#ifdef CONFIG_LEDS_MAX77693
+static struct max77693_led_platform_data max77693_led_pdata = {
+ .num_leds = 4,
+
+ .leds[0].name = "leds-sec1",
+ .leds[0].id = MAX77693_FLASH_LED_1,
+ .leds[0].timer = MAX77693_FLASH_TIME_500MS,
+ .leds[0].timer_mode = MAX77693_TIMER_MODE_MAX_TIMER,
+ .leds[0].cntrl_mode = MAX77693_LED_CTRL_BY_FLASHSTB,
+ .leds[0].brightness = 0x1F,
+
+ .leds[1].name = "leds-sec2",
+ .leds[1].id = MAX77693_FLASH_LED_2,
+ .leds[1].timer = MAX77693_FLASH_TIME_500MS,
+ .leds[1].timer_mode = MAX77693_TIMER_MODE_MAX_TIMER,
+ .leds[1].cntrl_mode = MAX77693_LED_CTRL_BY_FLASHSTB,
+ .leds[1].brightness = 0x1F,
+
+ .leds[2].name = "torch-sec1",
+ .leds[2].id = MAX77693_TORCH_LED_1,
+ .leds[2].cntrl_mode = MAX77693_LED_CTRL_BY_FLASHSTB,
+ .leds[2].brightness = 0x0F,
+
+ .leds[3].name = "torch-sec2",
+ .leds[3].id = MAX77693_TORCH_LED_2,
+ .leds[3].cntrl_mode = MAX77693_LED_CTRL_BY_I2C,
+ .leds[3].brightness = 0x0F,
+};
+
+#endif
+
+#ifdef CONFIG_BATTERY_MAX77693_CHARGER
+static struct max77693_charger_platform_data max77693_charger_pdata = {
+#ifdef CONFIG_BATTERY_WPC_CHARGER
+ .wpc_irq_gpio = GPIO_WPC_INT,
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1) || \
+ defined(CONFIG_MACH_C1VZW)
+ .vbus_irq_gpio = GPIO_V_BUS_INT,
+#endif
+ .wc_pwr_det = false,
+#endif
+};
+#endif
+
+extern struct max77693_muic_data max77693_muic;
+extern struct max77693_regulator_data max77693_regulators;
+
+static bool is_muic_default_uart_path_cp(void)
+{
+#if defined(CONFIG_MACH_M0_CTC)
+ return false;
+#endif
+#ifdef CONFIG_MACH_M0
+ if (system_rev == 5)
+ return true;
+#endif
+#ifdef CONFIG_MACH_C1
+ if (system_rev == 4)
+ return true;
+#endif
+#ifdef CONFIG_MACH_S2PLUS
+ if (system_rev >= 2)
+ return true;
+#endif
+ return false;
+}
+
+struct max77693_platform_data exynos4_max77693_info = {
+ .irq_base = IRQ_BOARD_IFIC_START,
+ .irq_gpio = GPIO_IF_PMIC_IRQ,
+ .wakeup = 1,
+ .muic = &max77693_muic,
+ .is_default_uart_path_cp = is_muic_default_uart_path_cp,
+ .regulators = &max77693_regulators,
+ .num_regulators = MAX77693_REG_MAX,
+#ifdef CONFIG_VIBETONZ
+ .haptic_data = &max77693_haptic_pdata,
+#endif
+#ifdef CONFIG_LEDS_MAX77693
+ .led_data = &max77693_led_pdata,
+#endif
+#ifdef CONFIG_BATTERY_MAX77693_CHARGER
+ .charger_data = &max77693_charger_pdata,
+#endif
+};
+#endif
+
+#if defined(CONFIG_CHARGER_MAX8922_U1) || defined(CONFIG_CHARGER_MAX8922_S2PLUS)
+static int max8922_cfg_gpio(void)
+{
+ printk(KERN_INFO "[Battery] %s called.\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_CHG_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_CHG_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CHG_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_CHG_ING_N, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CHG_ING_N, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TA_nCONNECTED, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCONNECTED, S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static struct max8922_platform_data max8922_pdata = {
+ .cfg_gpio = max8922_cfg_gpio,
+ .gpio_chg_en = GPIO_CHG_EN,
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+ .gpio_ta_nconnected = GPIO_TA_nCONNECTED,
+};
+
+static struct platform_device max8922_device_charger = {
+ .name = "max8922-charger",
+ .id = -1,
+ .dev.platform_data = &max8922_pdata,
+};
+#endif /* CONFIG_CHARGER_MAX8922_U1 || CONFIG_CHARGER_MAX8922_S2PLUS */
+
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+};
+
+#ifdef CONFIG_S3C_DEV_I2C4
+#ifdef CONFIG_MFD_MAX77693
+static struct i2c_board_info i2c_devs4_max77693[] __initdata = {
+ {
+ I2C_BOARD_INFO("max77693", (0xCC >> 1)),
+ .platform_data = &exynos4_max77693_info,
+ }
+};
+#endif
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C5
+#ifdef CONFIG_MACH_GC1
+static struct i2c_board_info i2c_devs5[] __initdata = {
+ /* HDMI */
+ {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+ },
+};
+#else
+static struct i2c_board_info i2c_devs5[] __initdata = {
+#ifdef CONFIG_REGULATOR_MAX8997
+ {
+ I2C_BOARD_INFO("max8997", (0xcc >> 1)),
+ .platform_data = &exynos4_max8997_info,
+ },
+#endif
+
+#if defined(CONFIG_REGULATOR_MAX77686)
+ /* max77686 on i2c5 other than M1 board */
+ {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ },
+#elif defined(CONFIG_REGULATOR_S5M8767)
+ /* s5m on i2c5 other than M1 board */
+ {
+ I2C_BOARD_INFO("s5m87xx", (0x12 >> 1)),
+ .platform_data = &exynos4_s5m8767_info,
+ },
+#endif
+};
+#endif /* CONFIG_MACH_GC1 */
+#ifdef CONFIG_MACH_GC1
+static void hdmi_ext_ic_control_gc1(bool ic_on)
+{
+ if (ic_on)
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+ else
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+}
+
+static void s3c_i2c5_cfg_gpio_gc1(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(EXYNOS4_GPB(2), S5P_GPIO_DRVSTR_LV4);
+ s5p_gpio_set_drvstr(EXYNOS4_GPB(3), S5P_GPIO_DRVSTR_LV4);
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT); /* HDMI_EN */
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+}
+#endif
+struct s3c2410_platform_i2c default_i2c5_data __initdata = {
+ .bus_num = 5,
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+#ifdef CONFIG_MACH_GC1
+ .cfg_gpio = s3c_i2c5_cfg_gpio_gc1,
+#endif
+};
+
+#endif
+
+#ifdef CONFIG_MACH_GC1
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ },
+};
+static struct i2c_board_info i2c_devs7_s5m[] __initdata = {
+ {
+ I2C_BOARD_INFO("s5m87xx", 0xCC >> 1),
+ .platform_data = &exynos4_s5m8767_info,
+ },
+};
+#else
+static struct i2c_board_info i2c_devs7[] __initdata = {
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3)
+#if defined(CONFIG_REGULATOR_MAX77686) /* max77686 on i2c7 with M1 board */
+ {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ },
+#endif
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+ {
+ I2C_BOARD_INFO("s5m87xx", 0xCC >> 1),
+ .platform_data = &exynos4_s5m8767_info,
+ .irq = IRQ_EINT(7),
+ },
+#endif
+#endif
+};
+#endif /* CONFIG_MACH_GC1 */
+
+/* Bluetooth */
+#ifdef CONFIG_BT_BCM4334
+static struct platform_device bcm4334_bluetooth_device = {
+ .name = "bcm4334_bluetooth",
+ .id = -1,
+};
+#endif
+
+#if !defined(CONFIG_MACH_M0_GRANDECTC)
+static struct i2c_gpio_platform_data gpio_i2c_data8 = {
+ .sda_pin = GPIO_3_TOUCH_SDA,
+ .scl_pin = GPIO_3_TOUCH_SCL,
+};
+
+struct platform_device s3c_device_i2c8 = {
+ .name = "i2c-gpio",
+ .id = 8,
+ .dev.platform_data = &gpio_i2c_data8,
+};
+#endif
+
+/* I2C8 */
+static struct i2c_board_info i2c_devs8_emul[] = {
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+ {
+ I2C_BOARD_INFO("sec_touchkey", 0x20),
+ .platform_data = &touchkey_pdata,
+ },
+#endif
+};
+
+/* I2C9 */
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+};
+
+/* I2C10 */
+static struct i2c_board_info i2c_devs10_emul[] __initdata = {
+};
+
+/* I2C11 */
+static struct i2c_board_info i2c_devs11_emul[] __initdata = {
+};
+
+/* I2C12 */
+#if defined(CONFIG_PN65N_NFC) && !defined(CONFIG_MACH_C1) \
+ && !defined(CONFIG_MACH_C1VZW) && !defined(CONFIG_MACH_M3)
+static struct i2c_board_info i2c_devs12_emul[] __initdata = {
+};
+#endif
+
+#if defined(CONFIG_MACH_S2PLUS)
+static struct i2c_gpio_platform_data gpio_i2c_data13 = {
+ .sda_pin = GPIO_VT_CAM_SDA_18V,
+ .scl_pin = GPIO_VT_CAM_SCL_18V,
+};
+
+struct platform_device s3c_device_i2c13 = {
+ .name = "i2c-gpio",
+ .id = 13,
+ .dev.platform_data = &gpio_i2c_data13,
+};
+
+/* I2C13 */
+static struct i2c_board_info i2c_devs13_emul[] __initdata = {
+};
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17047_FUELGAUGE
+static struct i2c_gpio_platform_data gpio_i2c_data14 = {
+ .sda_pin = GPIO_FUEL_SDA,
+ .scl_pin = GPIO_FUEL_SCL,
+};
+
+struct platform_device s3c_device_i2c14 = {
+ .name = "i2c-gpio",
+ .id = 14,
+ .dev.platform_data = &gpio_i2c_data14,
+};
+
+static struct max17047_platform_data max17047_pdata = {
+ .irq_gpio = GPIO_FUEL_ALERT,
+};
+
+/* I2C14 */
+static struct i2c_board_info i2c_devs14_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17047-fuelgauge", 0x36),
+ .platform_data = &max17047_pdata,
+ },
+};
+#endif
+
+#if !defined(CONFIG_MACH_M0_GRANDECTC)
+/* I2C15 */
+static struct i2c_gpio_platform_data gpio_i2c_data15 = {
+ .sda_pin = GPIO_MHL_SDA_1_8V,
+ .scl_pin = GPIO_MHL_SCL_1_8V,
+ .udelay = 3,
+ .timeout = 0,
+};
+
+struct platform_device s3c_device_i2c15 = {
+ .name = "i2c-gpio",
+ .id = 15,
+ .dev = {
+ .platform_data = &gpio_i2c_data15,
+ }
+};
+
+static struct i2c_board_info i2c_devs15_emul[] __initdata = {
+};
+
+/* I2C16 */
+static struct i2c_gpio_platform_data gpio_i2c_data16 = {
+ .sda_pin = GPIO_MHL_DSDA_2_8V,
+ .scl_pin = GPIO_MHL_DSCL_2_8V,
+};
+
+struct platform_device s3c_device_i2c16 = {
+ .name = "i2c-gpio",
+ .id = 16,
+ .dev.platform_data = &gpio_i2c_data16,
+};
+
+static struct i2c_board_info i2c_devs16_emul[] __initdata = {
+};
+#endif
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3) || \
+ defined(CONFIG_MACH_GC1)
+static struct i2c_gpio_platform_data gpio_i2c_data17 = {
+ .sda_pin = GPIO_IF_PMIC_SDA,
+ .scl_pin = GPIO_IF_PMIC_SCL,
+};
+
+struct platform_device s3c_device_i2c17 = {
+ .name = "i2c-gpio",
+ .id = 17,
+ .dev.platform_data = &gpio_i2c_data17,
+};
+
+/* I2C17 */
+static struct i2c_board_info i2c_devs17_emul[] __initdata = {
+#ifdef CONFIG_MFD_MAX77693
+ {
+ I2C_BOARD_INFO("max77693", (0xCC >> 1)),
+ .platform_data = &exynos4_max77693_info,
+ }
+#endif
+};
+#endif
+
+#if 0
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3)
+static struct i2c_gpio_platform_data i2c18_platdata = {
+ .sda_pin = GPIO_8M_CAM_SDA_18V,
+ .scl_pin = GPIO_8M_CAM_SCL_18V,
+ .udelay = 2, /* 250 kHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c18 = {
+ .name = "i2c-gpio",
+ .id = 18,
+ .dev.platform_data = &i2c18_platdata,
+};
+
+/* I2C18 */
+/* No explicit i2c client array here. The channel number 18 is passed
+ to camera driver from midas-camera.c instead. */
+#endif
+#endif
+
+#if defined(CONFIG_STMPE811_ADC) || defined(CONFIG_FM_SI4709_MODULE) \
+ || defined(CONFIG_FM_SI4705_MODULE)
+static struct i2c_gpio_platform_data gpio_i2c_data19 = {
+ .sda_pin = GPIO_ADC_SDA,
+ .scl_pin = GPIO_ADC_SCL,
+};
+
+struct platform_device s3c_device_i2c19 = {
+ .name = "i2c-gpio",
+ .id = 19,
+ .dev.platform_data = &gpio_i2c_data19,
+};
+
+
+/* I2C19 */
+static struct i2c_board_info i2c_devs19_emul[] __initdata = {
+#if defined(CONFIG_STMPE811_ADC)
+ {
+ I2C_BOARD_INFO("stmpe811-adc", (0x82 >> 1)),
+ .platform_data = &stmpe811_pdata,
+ },
+#endif
+#ifdef CONFIG_FM_SI4705_MODULE
+ {
+ I2C_BOARD_INFO("Si4709", (0x22 >> 1)),
+ },
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+ {
+ I2C_BOARD_INFO("Si4709", (0x20 >> 1)),
+ },
+#endif
+
+};
+#endif
+
+/* I2C21 */
+#ifdef CONFIG_LEDS_AN30259A
+static struct i2c_gpio_platform_data gpio_i2c_data21 = {
+ .scl_pin = GPIO_S_LED_I2C_SCL,
+ .sda_pin = GPIO_S_LED_I2C_SDA,
+};
+
+struct platform_device s3c_device_i2c21 = {
+ .name = "i2c-gpio",
+ .id = 21,
+ .dev.platform_data = &gpio_i2c_data21,
+};
+#endif
+
+/* I2C21 */
+#ifdef CONFIG_LEDS_AN30259A
+static struct i2c_board_info i2c_devs21_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("an30259a", 0x30),
+ },
+};
+#endif
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE
+static struct resource ram_console_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device ram_console_device = {
+ .name = "ram_console",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ram_console_resource),
+ .resource = ram_console_resource,
+};
+
+static int __init setup_ram_console_mem(char *str)
+{
+ unsigned size = memparse(str, &str);
+
+ if (size && (*str == '@')) {
+ unsigned long long base = 0;
+
+ base = simple_strtoul(++str, &str, 0);
+ if (reserve_bootmem(base, size, BOOTMEM_EXCLUSIVE)) {
+ pr_err("%s: failed reserving size %d "
+ "at base 0x%llx\n", __func__, size, base);
+ return -1;
+ }
+
+ ram_console_resource[0].start = base;
+ ram_console_resource[0].end = base + size - 1;
+ pr_err("%s: %x at %llx\n", __func__, size, base);
+ }
+ return 0;
+}
+
+__setup("ram_console=", setup_ram_console_mem);
+#endif
+
+#if defined(CONFIG_BATTERY_SAMSUNG) || defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
+static struct samsung_battery_platform_data samsung_battery_pdata = {
+ .charger_name = "max77693-charger",
+ .fuelgauge_name = "max17047-fuelgauge",
+#if defined(CONFIG_CHARGER_MAX8922_U1) || defined(CONFIG_CHARGER_MAX8922_S2PLUS)
+ .sub_charger_name = "max8922-charger",
+#if defined(CONFIG_CHARGER_MAX8922_S2PLUS)
+ .use_sub_charger = true,
+#endif
+#endif
+#if defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
+ .voltage_max = 4200000,
+#else
+ .voltage_max = 4350000,
+#endif
+ .voltage_min = 3400000,
+
+ .in_curr_limit = 1000,
+#if defined(CONFIG_MACH_GC1)
+ .chg_curr_ta = 700,
+#else
+ .chg_curr_ta = 1000,
+#endif
+ .chg_curr_usb = 475,
+ .chg_curr_cdp = 1000,
+ .chg_curr_wpc = 475,
+ .chg_curr_dock = 1000,
+ .chg_curr_etc = 475,
+
+ .chng_interval = 30,
+ .chng_susp_interval = 60,
+ .norm_interval = 120,
+ .norm_susp_interval = 7200,
+ .emer_lv1_interval = 30,
+ .emer_lv2_interval = 10,
+
+#if defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
+ .recharge_voltage = 4150000,
+#else
+ .recharge_voltage = 4300000, /* it will be cacaluated in probe */
+#endif
+
+#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)
+ .abstimer_charge_duration = 8 * 60 * 60,
+ .abstimer_recharge_duration = 2 * 60 * 60,
+#else
+ .abstimer_charge_duration = 6 * 60 * 60,
+ .abstimer_recharge_duration = 1.5 * 60 * 60,
+#endif
+
+ .cb_det_src = CABLE_DET_CHARGER,
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+ .overheat_stop_temp = 640,
+ .overheat_recovery_temp = 429,
+ .freeze_stop_temp = -70,
+ .freeze_recovery_temp = 8,
+#elif defined(CONFIG_MACH_C1_KOR_LGT)
+ .overheat_stop_temp = 630,
+ .overheat_recovery_temp = 430,
+ .freeze_stop_temp = -50,
+ .freeze_recovery_temp = 0,
+#elif defined(CONFIG_MACH_M0_KOR_SKT) || defined(CONFIG_MACH_M0_KOR_KT)
+ .overheat_stop_temp = 710,
+ .overheat_recovery_temp = 430,
+ .freeze_stop_temp = -40,
+ .freeze_recovery_temp = 30,
+#else
+ .overheat_stop_temp = 600,
+ .overheat_recovery_temp = 430,
+ .freeze_stop_temp = -50,
+ .freeze_recovery_temp = 0,
+#endif /* KOR model */
+#elif defined(CONFIG_MACH_M0_CTC)
+ .overheat_stop_temp = 640,
+ .overheat_recovery_temp = 400,
+ .freeze_stop_temp = -50,
+ .freeze_recovery_temp = 30,
+#else
+ .overheat_stop_temp = 600,
+ .overheat_recovery_temp = 400,
+ .freeze_stop_temp = -50,
+ .freeze_recovery_temp = 0,
+#endif
+
+ .temper_src = TEMPER_AP_ADC,
+ .temper_ch = 2,
+#ifdef CONFIG_S3C_ADC
+ /* s3c adc driver does not convert raw adc data.
+ * so, register convert function.
+ */
+ .covert_adc = convert_adc,
+#endif
+
+ .suspend_chging = true,
+
+ .led_indicator = false,
+
+ .battery_standever = false,
+};
+
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-battery",
+ .id = -1,
+ .dev.platform_data = &samsung_battery_pdata,
+};
+#endif
+
+#define GPIO_KEYS(_code, _gpio, _active_low, _iswake, _hook) \
+ { \
+ .code = _code, \
+ .gpio = _gpio, \
+ .active_low = _active_low, \
+ .type = EV_KEY, \
+ .wakeup = _iswake, \
+ .debounce_interval = 10, \
+ .isr_hook = _hook, \
+ .value = 1 \
+ }
+
+struct gpio_keys_button midas_buttons[] = {
+#if defined(CONFIG_MACH_GC1)
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_RECORD, GPIO_RECORD_KEY,
+ 1, 1, sec_debug_check_crash_key),
+#if 0
+ GPIO_KEYS(KEY_HOMEPAGE, GPIO_OK_KEY_ANDROID,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_MENU, GPIO_MENU_KEY,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_BACK, GPIO_BACK_KEY,
+ 1, 1, sec_debug_check_crash_key),
+#endif
+ GPIO_KEYS(KEY_PLAY, GPIO_PLAY_KEY,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_CAMERA_FOCUS, GPIO_S1_KEY,
+ 1, 1, sec_debug_check_crash_key),
+ /*KEY_CAMERA_SHUTTER*/
+ GPIO_KEYS(0x220, GPIO_S2_KEY,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_CAMERA_ZOOMIN, GPIO_TELE_KEY,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_CAMERA_ZOOMOUT, GPIO_WIDE_KEY,
+ 1, 1, sec_debug_check_crash_key),
+#else
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+#endif
+};
+
+struct gpio_keys_button m0_buttons[] = {
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP_00,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN_00,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+#if defined(CONFIG_MACH_S2PLUS)
+ GPIO_KEYS(KEY_HOME, GPIO_OK_KEY,
+ 1, 1, sec_debug_check_crash_key),
+#endif
+};
+
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_C1_USA_ATT)
+struct gpio_keys_button m0_rev11_buttons[] = {
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP_00,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN_00,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_HOMEPAGE, GPIO_OK_KEY_ANDROID,
+ 1, 1, sec_debug_check_crash_key),
+};
+#endif
+
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+struct gpio_keys_button c1_rev04_buttons[] = {
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP_00,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN_00,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_HOMEPAGE, GPIO_OK_KEY_ANDROID,
+ 1, 1, sec_debug_check_crash_key),
+};
+#endif
+
+struct gpio_keys_platform_data midas_gpiokeys_platform_data = {
+ midas_buttons,
+ ARRAY_SIZE(midas_buttons),
+};
+
+static struct platform_device midas_keypad = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &midas_gpiokeys_platform_data,
+ },
+};
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 0x41,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 199 * 1000000, /* 160 Mhz */
+};
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+struct exynos_c2c_platdata smdk4212_c2c_pdata = {
+ .setup_gpio = NULL,
+ .shdmem_addr = C2C_SHAREDMEM_BASE,
+ .shdmem_size = C2C_MEMSIZE_64,
+ .ap_sscm_addr = NULL,
+ .cp_sscm_addr = NULL,
+ .rx_width = C2C_BUSWIDTH_16,
+ .tx_width = C2C_BUSWIDTH_16,
+ .clk_opp100 = 400,
+ .clk_opp50 = 266,
+ .clk_opp25 = 0,
+ .default_opp_mode = C2C_OPP50,
+ .get_c2c_state = NULL,
+};
+#endif
+/* BUSFREQ to control memory/bus */
+static struct device_domain busfreq;
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+
+static struct i2c_gpio_platform_data i2c9_platdata = {
+#if defined(CONFIG_SENSORS_CM3663)
+ .sda_pin = GPIO_PS_ALS_SDA_18V,
+ .scl_pin = GPIO_PS_ALS_SCL_18V,
+#elif defined(CONFIG_SENSORS_BH1721)
+ .sda_pin = GPIO_PS_ALS_SDA_28V,
+ .scl_pin = GPIO_PS_ALS_SCL_28V,
+#elif defined(CONFIG_SENSORS_CM36651)
+ .sda_pin = GPIO_RGB_SDA_1_8V,
+ .scl_pin = GPIO_RGB_SCL_1_8V,
+#endif
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c9 = {
+ .name = "i2c-gpio",
+ .id = 9,
+ .dev.platform_data = &i2c9_platdata,
+};
+
+#ifdef CONFIG_SENSORS_AK8975C
+static struct i2c_gpio_platform_data i2c10_platdata = {
+ .sda_pin = GPIO_MSENSOR_SDA_18V,
+ .scl_pin = GPIO_MSENSOR_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c10 = {
+ .name = "i2c-gpio",
+ .id = 10,
+ .dev.platform_data = &i2c10_platdata,
+};
+#endif
+
+#ifdef CONFIG_SENSORS_LPS331
+static struct i2c_gpio_platform_data i2c11_platdata = {
+ .sda_pin = GPIO_BSENSE_SDA_18V,
+ .scl_pin = GPIO_BENSE_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c11 = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &i2c11_platdata,
+};
+#endif
+
+#if defined(CONFIG_PN65N_NFC) && !defined(CONFIG_MACH_C1) \
+ && !defined(CONFIG_MACH_C1VZW) && !defined(CONFIG_MACH_M3)
+static struct i2c_gpio_platform_data i2c12_platdata = {
+ .sda_pin = GPIO_NFC_SDA_18V,
+ .scl_pin = GPIO_NFC_SCL_18V,
+ .udelay = 2, /* 250 kHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c12 = {
+ .name = "i2c-gpio",
+ .id = 12,
+ .dev.platform_data = &i2c12_platdata,
+};
+#endif
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+static void otg_accessory_power(int enable)
+{
+ u8 on = (u8)!!enable;
+
+ /* max77693 otg power control */
+ otg_control(enable);
+
+ gpio_request(GPIO_OTG_EN, "USB_OTG_EN");
+ gpio_direction_output(GPIO_OTG_EN, on);
+ gpio_free(GPIO_OTG_EN);
+ pr_info("%s: otg accessory power = %d\n", __func__, on);
+}
+
+static void otg_accessory_powered_booster(int enable)
+{
+ u8 on = (u8)!!enable;
+
+ /* max77693 powered otg power control */
+ powered_otg_control(enable);
+ pr_info("%s: otg accessory power = %d\n", __func__, on);
+}
+
+static struct host_notifier_platform_data host_notifier_pdata = {
+ .ndev.name = "usb_otg",
+ .booster = otg_accessory_power,
+ .powered_booster = otg_accessory_powered_booster,
+ .thread_enable = 0,
+};
+
+struct platform_device host_notifier_device = {
+ .name = "host_notifier",
+ .dev.platform_data = &host_notifier_pdata,
+};
+#endif
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+static struct platform_device watchdog_reset_device = {
+ .name = "watchdog-reset",
+ .id = -1,
+};
+#endif
+
+static struct platform_device *midas_devices[] __initdata = {
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ &watchdog_reset_device,
+#endif
+#ifdef CONFIG_ANDROID_RAM_CONSOLE
+ &ram_console_device,
+#endif
+ /* Samsung Power Domain */
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &exynos4_device_pd[PD_ISP],
+#endif
+ &exynos4_device_pd[PD_GPS_ALIVE],
+ /* legacy fimd */
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ &s3c_device_spi_gpio,
+#endif
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+ &mdnie_device,
+#endif
+
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &s3c_device_timer[2],
+ &s3c_device_timer[3],
+#endif
+
+#ifdef CONFIG_SND_SOC_WM8994
+ &vbatt_device,
+#endif
+
+ &s3c_device_wdt,
+ &s3c_device_rtc,
+
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_i2c3,
+#ifdef CONFIG_S3C_DEV_I2C4
+ &s3c_device_i2c4,
+#endif
+ /* &s3c_device_i2c5, */
+
+#ifdef CONFIG_AUDIENCE_ES305
+ &s3c_device_i2c6,
+#endif
+ &s3c_device_i2c7,
+#if !defined(CONFIG_MACH_M0_GRANDECTC)
+ &s3c_device_i2c8,
+#endif
+ &s3c_device_i2c9,
+#ifdef CONFIG_SENSORS_AK8975C
+ &s3c_device_i2c10,
+#endif
+#ifdef CONFIG_SENSORS_LPS331
+ &s3c_device_i2c11,
+#endif
+ /* &s3c_device_i2c12, */
+#if defined(CONFIG_MACH_S2PLUS)
+ &s3c_device_i2c13,
+#endif
+#ifdef CONFIG_BATTERY_MAX17047_FUELGAUGE
+ &s3c_device_i2c14, /* max17047-fuelgauge */
+#endif
+
+#ifdef CONFIG_SAMSUNG_MHL
+ &s3c_device_i2c15,
+ &s3c_device_i2c16,
+#endif
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3) || \
+ defined(CONFIG_MACH_GC1)
+ &s3c_device_i2c17,
+#if 0
+ &s3c_device_i2c18,
+#endif
+#endif
+#ifdef CONFIG_LEDS_AN30259A
+ &s3c_device_i2c21,
+#endif
+
+#if defined CONFIG_USB_EHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ehci,
+#endif
+#if defined CONFIG_USB_OHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &exynos4_device_fimc_is,
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ &ld9040_spi_gpio,
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+#ifdef CONFIG_FB_S5P_EXTDSP
+ &s3c_device_extdsp,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+/* CONFIG_VIDEO_SAMSUNG_S5P_FIMC is the feature for mainline */
+#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+ &s5p_device_fimc0,
+ &s5p_device_fimc1,
+ &s5p_device_fimc2,
+ &s5p_device_fimc3,
+#endif
+#if defined(CONFIG_VIDEO_FIMC_MIPI)
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(g2d_acp),
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(jpeg),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+ &SYSMMU_PLATDEV(tv),
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &SYSMMU_PLATDEV(is_isp),
+ &SYSMMU_PLATDEV(is_drc),
+ &SYSMMU_PLATDEV(is_fd),
+ &SYSMMU_PLATDEV(is_cpu),
+#endif
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ &exynos_device_flite0,
+ &exynos_device_flite1,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ &s5p_device_jpeg,
+#endif
+ &samsung_asoc_dma,
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+ &samsung_asoc_idma,
+#endif
+#if defined(CONFIG_CHARGER_MAX8922_U1) || defined(CONFIG_CHARGER_MAX8922_S2PLUS)
+ &max8922_device_charger,
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ &exynos_device_c2c,
+#endif
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+ &exynos_device_spi1,
+#endif
+#if defined(CONFIG_PHONE_IPC_SPI)
+ &exynos_device_spi2,
+ &ipc_spi_device,
+#elif defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ &exynos_device_spi2,
+#endif
+#endif
+
+#ifdef CONFIG_BT_BCM4334
+ &bcm4334_bluetooth_device,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+ &exynos4_busfreq,
+#ifdef CONFIG_USB_HOST_NOTIFY
+ &host_notifier_device,
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+};
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct s5p_platform_tmu midas_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 78,
+ .start_1st_throttle = 80,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110, /* temp to do tripping */
+ .start_emergency = 120, /* To protect chip,forcely kernel panic */
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ .stop_tc = 13,
+ .start_tc = 10,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000, /* 800MHz in KHz order */
+ .limit_2nd_throttle = 200000, /* 200MHz in KHz order */
+ },
+ .temp_compensate = {
+ .arm_volt = 925000, /* vdd_arm in uV for temperature compensation */
+ .bus_volt = 900000, /* vdd_bus in uV for temperature compensation */
+ .g3d_volt = 900000, /* vdd_g3d in uV for temperature compensation */
+ },
+};
+#endif
+
+#if defined CONFIG_USB_OHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ohci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ohci);
+}
+late_initcall(s5p_ohci_device_initcall);
+#endif
+#if defined CONFIG_USB_EHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ehci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ehci);
+}
+late_initcall(s5p_ehci_device_initcall);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+#if defined(CONFIG_MACH_GC1) && defined(CONFIG_HDMI_CONTROLLED_BY_EXT_IC)
+ .ext_ic_control = hdmi_ext_ic_control_gc1,
+#endif
+
+};
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#if defined(CONFIG_CMA)
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ {
+ .name = "fimc_is",
+ .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ {
+ .alignment = 1 << 20,
+ },
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0)
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE)
+ {
+ .name = "ion",
+ .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ {
+ .name = "b2",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "b1",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "fw",
+ .size = 1 << 20,
+ { .alignment = 128 << 10 },
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .start = 0x65c00000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0x64000000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL
+ {
+ .name = "mfc-normal",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL * SZ_1K,
+ .start = 0x64000000,
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ static struct cma_region regions_secure[] = {
+#ifdef CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE
+ {
+ .name = "ion",
+ .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE
+ {
+ .name = "mfc-secure",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE * SZ_1K,
+ },
+#endif
+ {
+ .name = "sectbl",
+ .size = SZ_1M,
+ },
+ {
+ .size = 0
+ },
+ };
+#else /* !CONFIG_EXYNOS_CONTENT_PATH_PROTECTION */
+ struct cma_region *regions_secure = NULL;
+#endif
+
+ static const char map[] __initconst =
+#ifdef CONFIG_EXYNOS_C2C
+ "samsung-c2c=c2c_shdmem;"
+#endif
+ "s3cfb.0=fimd;exynos4-fb.0=fimd;"
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;s3c-fimc.3=fimc3;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc.3=fimc3;"
+#ifdef CONFIG_ION_EXYNOS
+ "ion-exynos=ion;"
+#endif
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc/A=mfc0,mfc-secure;"
+ "s3c-mfc/B=mfc1,mfc-normal;"
+ "s3c-mfc/AB=mfc;"
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ "s5p-mfc/f=fw;"
+ "s5p-mfc/a=b1;"
+ "s5p-mfc/b=b2;"
+#endif
+ "samsung-rp=srp;"
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ "exynos4-fimc-is=fimc_is;"
+#endif
+ "s5p-fimg2d=fimg2d;"
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ "s5p-smem/sectbl=sectbl;"
+#endif
+ "s5p-smem/mfc=mfc-secure;"
+ "s5p-smem/fimc=ion;"
+ "s5p-smem/mfc-shm=mfc-normal;"
+ "s5p-smem/fimd=fimd;";
+
+ s5p_cma_region_reserve(regions, regions_secure, 0, map);
+}
+#else
+static inline void exynos4_reserve_mem(void)
+{
+}
+#endif
+
+#ifdef CONFIG_BACKLIGHT_PWM
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk4212_bl_gpio_info = {
+ .no = EXYNOS4_GPD0(1),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk4212_bl_data = {
+ .pwm_id = 1,
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ .pwm_period_ns = 1000,
+#endif
+};
+#endif
+
+static void __init midas_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdk4212_uartcfgs, ARRAY_SIZE(smdk4212_uartcfgs));
+
+#if defined(CONFIG_S5P_MEM_CMA)
+ exynos4_reserve_mem();
+#endif
+
+ /* as soon as INFORM6 is visible, sec_debug is ready to run */
+ sec_debug_init();
+}
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+#endif
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(g2d_acp).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_MFC5X
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ ASSIGN_SYSMMU_POWERDOMAIN(is_isp, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_drc, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_fd, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_cpu, &exynos4_device_pd[PD_ISP].dev);
+
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_isp).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_drc).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_fd).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_cpu).dev,
+ &exynos4_device_fimc_is.dev);
+#endif
+}
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct platform_device s3c_device_extdsp = {
+ .name = "s3cfb_extdsp",
+ .id = 0,
+};
+
+static struct s3cfb_extdsp_lcd dummy_buffer = {
+ .width = 1920,
+ .height = 1080,
+ .bpp = 16,
+};
+
+static struct s3c_platform_fb default_extdsp_data __initdata = {
+ .hw_ver = 0x70,
+ .nr_wins = 1,
+ .default_win = 0,
+ .swap = FB_SWAP_WORD | FB_SWAP_HWORD,
+ .lcd = &dummy_buffer
+};
+
+void __init s3cfb_extdsp_set_platdata(struct s3c_platform_fb *pd)
+{
+ struct s3c_platform_fb *npd;
+ int i;
+
+ if (!pd)
+ pd = &default_extdsp_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ for (i = 0; i < npd->nr_wins; i++)
+ npd->nr_buffers[i] = 1;
+ s3c_device_extdsp.dev.platform_data = npd;
+ }
+}
+#endif
+
+static inline int need_i2c5(void)
+{
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3)
+ return system_rev != 3;
+#elif defined(CONFIG_MACH_JENGA)
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+static void __init midas_machine_init(void)
+{
+ struct clk *ppmu_clk = NULL;
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+ unsigned int gpio;
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi1_dev = &exynos_device_spi1.dev;
+#endif
+#if defined(CONFIG_PHONE_IPC_SPI) \
+ || defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ struct device *spi2_dev = &exynos_device_spi2.dev;
+#endif
+#endif
+
+ /*
+ * prevent 4x12 ISP power off problem
+ * ISP_SYS Register has to be 0 before ISP block power off.
+ */
+ __raw_writel(0x0, S5P_CMU_RESET_ISP_SYS);
+
+ /* initialise the gpios */
+ midas_config_gpio_table();
+ exynos4_sleep_gpio_table_set = midas_config_sleep_gpio_table;
+
+ midas_power_init();
+
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ s3c_i2c3_set_platdata(NULL);
+ midas_tsp_init();
+#ifndef CONFIG_TOUCHSCREEN_MELFAS_GC
+#if !defined(CONFIG_MACH_M0_GRANDECTC)
+ midas_tsp_set_lcdtype(lcdtype);
+#endif
+#endif
+
+#ifdef CONFIG_LEDS_AAT1290A
+ platform_device_register(&s3c_device_aat1290a_led);
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C4
+#ifdef CONFIG_MACH_MIDAS_02_BD
+ s3c_i2c4_set_platdata(NULL);
+ i2c_register_board_info(4, i2c_devs4_max77693,
+ ARRAY_SIZE(i2c_devs4_max77693));
+#else
+ s3c_i2c4_set_platdata(NULL);
+ if (!(system_rev != 3 && system_rev >= 0)) {
+ i2c_register_board_info(4, i2c_devs4_max77693,
+ ARRAY_SIZE(i2c_devs4_max77693));
+ }
+#endif
+#endif
+ midas_sound_init();
+
+#ifdef CONFIG_S3C_DEV_I2C5
+ if (need_i2c5()) {
+ s3c_i2c5_set_platdata(&default_i2c5_data);
+ i2c_register_board_info(5, i2c_devs5,
+ ARRAY_SIZE(i2c_devs5));
+ }
+#endif
+
+#ifdef CONFIG_MACH_GC1
+ s3c_i2c7_set_platdata(NULL);
+ if (system_rev < 1) {
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+ } else {
+ i2c_register_board_info(7, i2c_devs7_s5m,
+ ARRAY_SIZE(i2c_devs7_s5m));
+ }
+#else
+ s3c_i2c7_set_platdata(NULL);
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+#endif
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+ touchkey_init_hw();
+#endif
+ i2c_register_board_info(8, i2c_devs8_emul, ARRAY_SIZE(i2c_devs8_emul));
+
+#ifndef CONFIG_LEDS_AAT1290A
+ gpio_request(GPIO_3_TOUCH_INT, "3_TOUCH_INT");
+ s5p_register_gpio_interrupt(GPIO_3_TOUCH_INT);
+#endif
+
+ i2c_register_board_info(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+
+ i2c_register_board_info(10, i2c_devs10_emul,
+ ARRAY_SIZE(i2c_devs10_emul));
+
+ i2c_register_board_info(11, i2c_devs11_emul,
+ ARRAY_SIZE(i2c_devs11_emul));
+
+#if defined(CONFIG_PN65N_NFC) && !defined(CONFIG_MACH_C1) \
+ && !defined(CONFIG_MACH_C1VZW) && !defined(CONFIG_MACH_M3)
+ i2c_register_board_info(12, i2c_devs12_emul,
+ ARRAY_SIZE(i2c_devs12_emul));
+#endif
+
+#if defined(CONFIG_MACH_S2PLUS)
+ i2c_register_board_info(13, i2c_devs13_emul,
+ ARRAY_SIZE(i2c_devs13_emul));
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17047_FUELGAUGE
+ /* max17047 fuel gauge */
+ i2c_register_board_info(14, i2c_devs14_emul,
+ ARRAY_SIZE(i2c_devs14_emul));
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ printk(KERN_INFO "%s() register sii9234 driver\n", __func__);
+
+ i2c_register_board_info(15, i2c_devs15_emul,
+ ARRAY_SIZE(i2c_devs15_emul));
+ i2c_register_board_info(16, i2c_devs16_emul,
+ ARRAY_SIZE(i2c_devs16_emul));
+#endif
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3) || \
+ defined(CONFIG_MACH_GC1)
+ i2c_register_board_info(17, i2c_devs17_emul,
+ ARRAY_SIZE(i2c_devs17_emul));
+#endif
+#if defined(CONFIG_STMPE811_ADC) || defined(CONFIG_FM_SI4709_MODULE) \
+ || defined(CONFIG_FM_SI4705_MODULE)
+ i2c_register_board_info(19, i2c_devs19_emul,
+ ARRAY_SIZE(i2c_devs19_emul));
+#endif
+
+#ifdef CONFIG_LEDS_AN30259A
+ i2c_register_board_info(21, i2c_devs21_emul,
+ ARRAY_SIZE(i2c_devs21_emul));
+#endif
+
+#if defined(GPIO_OLED_DET)
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s5p_register_gpio_interrupt(GPIO_OLED_DET);
+ gpio_free(GPIO_OLED_DET);
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&lms501kf03_data);
+#endif
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+ mipi_fb_init();
+#elif defined(CONFIG_FB_S5P_LD9040)
+ ld9040_fb_init();
+#elif defined(CONFIG_BACKLIGHT_PWM)
+ samsung_bl_set(&smdk4212_bl_gpio_info, &smdk4212_bl_data);
+#endif
+ s3cfb_set_platdata(&fb_platform_data);
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdk4212_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdk4212_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdk4212_usbgadget_init();
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ exynos4_fimc_is_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ exynos4_device_fimc_is.dev.parent = &exynos4_device_pd[PD_ISP].dev;
+#endif
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdk4212_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdk4212_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdk4212_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdk4212_hsmmc3_pdata);
+#endif
+
+ midas_camera_init();
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+ s3cfb_extdsp_set_platdata(&default_extdsp_data);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+ exynos4_device_pd[PD_TV].dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ exynos4_jpeg_setup_clock(&s5p_device_jpeg.dev, 160000000);
+#endif
+#endif
+
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ);
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ exynos_c2c_set_platdata(&smdk4212_c2c_pdata);
+#endif
+
+ brcm_wlan_init();
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(&midas_tmu_data);
+#endif
+
+ exynos_sysmmu_init();
+
+ platform_add_devices(midas_devices, ARRAY_SIZE(midas_devices));
+
+#ifdef CONFIG_S3C_ADC
+#if defined(CONFIG_MACH_S2PLUS)
+ platform_device_register(&s3c_device_adc);
+#else
+ if (system_rev != 3)
+ platform_device_register(&s3c_device_adc);
+#endif
+#endif
+#if defined(CONFIG_STMPE811_ADC) || defined(CONFIG_FM_SI4709_MODULE) \
+ || defined(CONFIG_FM_SI4705_MODULE)
+ platform_device_register(&s3c_device_i2c19);
+#endif
+#if defined(CONFIG_BATTERY_SAMSUNG) || defined(CONFIG_BATTERY_SAMSUNG_S2PLUS)
+ platform_device_register(&samsung_device_battery);
+#endif
+#ifdef CONFIG_SEC_THERMISTOR
+ platform_device_register(&sec_device_thermistor);
+#endif
+#if defined(CONFIG_MACH_M0_CTC)
+ midas_gpiokeys_platform_data.buttons = m0_buttons;
+ midas_gpiokeys_platform_data.nbuttons = ARRAY_SIZE(m0_buttons);
+#elif defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3)
+ if (system_rev != 3 && system_rev >= 1) {
+ midas_gpiokeys_platform_data.buttons = m0_buttons;
+ midas_gpiokeys_platform_data.nbuttons = ARRAY_SIZE(m0_buttons);
+ }
+#endif
+ /* Above logic is too complex. Let's override whatever the
+ result is... */
+
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1VZW)
+#if defined(CONFIG_MACH_M0_CHNOPEN) || defined(CONFIG_MACH_M0_HKTW)
+ {
+#else
+ if (system_rev >= 11) {
+#endif
+ s3c_gpio_setpull(GPIO_OK_KEY_ANDROID, S3C_GPIO_PULL_NONE);
+ midas_gpiokeys_platform_data.buttons = m0_rev11_buttons;
+ midas_gpiokeys_platform_data.nbuttons =
+ ARRAY_SIZE(m0_rev11_buttons);
+ }
+#elif defined(CONFIG_TARGET_LOCALE_KOR)
+ s3c_gpio_setpull(GPIO_OK_KEY_ANDROID, S3C_GPIO_PULL_NONE);
+ midas_gpiokeys_platform_data.buttons = c1_rev04_buttons;
+ midas_gpiokeys_platform_data.nbuttons =
+ ARRAY_SIZE(c1_rev04_buttons);
+
+#elif defined(CONFIG_MACH_C1_USA_ATT)
+ if (system_rev >= 7) {
+ s3c_gpio_setpull(GPIO_OK_KEY_ANDROID, S3C_GPIO_PULL_UP);
+ midas_gpiokeys_platform_data.buttons = m0_rev11_buttons;
+ midas_gpiokeys_platform_data.nbuttons =
+ ARRAY_SIZE(m0_rev11_buttons);
+ }
+#endif
+
+ platform_device_register(&midas_keypad);
+#ifdef CONFIG_MACH_GC1
+ gpio_direction_output(GPIO_TOP_PCB_PWREN, 1);
+#endif
+
+#if defined(CONFIG_S3C_DEV_I2C5)
+ if (need_i2c5())
+ platform_device_register(&s3c_device_i2c5);
+#endif
+
+#if defined(CONFIG_PN65N_NFC) && !defined(CONFIG_MACH_C1) \
+ && !defined(CONFIG_MACH_C1VZW) && !defined(CONFIG_MACH_M3)
+ platform_device_register(&s3c_device_i2c12);
+#endif
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+ sclk = clk_get(spi1_dev, "dout_spi1");
+ if (IS_ERR(sclk))
+ dev_err(spi1_dev, "failed to get sclk for SPI-1\n");
+ prnt = clk_get(spi1_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi1_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 88 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(5), "SPI_CS1")) {
+ gpio_direction_output(EXYNOS4_GPB(5), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(5), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(5), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi1_csi));
+ }
+
+ for (gpio = EXYNOS4_GPB(4); gpio < EXYNOS4_GPB(8); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info));
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI) \
+ || defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ sclk = NULL;
+ prnt = NULL;
+
+ sclk = clk_get(spi2_dev, "dout_spi2");
+ if (IS_ERR(sclk))
+ dev_err(spi2_dev, "failed to get sclk for SPI-2\n");
+ prnt = clk_get(spi2_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi2_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPC1(2), "SPI_CS2")) {
+ gpio_direction_output(EXYNOS4_GPC1(2), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(2), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPC1(2), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi2_csi));
+ }
+ for (gpio = EXYNOS4_GPC1(1); gpio < EXYNOS4_GPC1(5); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ tdmb_dev_init();
+#endif
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+
+ /* PPMUs using for cpufreq get clk from clk_list */
+ ppmu_clk = clk_get(NULL, "ppmudmc0");
+ if (IS_ERR(ppmu_clk))
+ printk(KERN_ERR "failed to get ppmu_dmc0\n");
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_clk = clk_get(NULL, "ppmudmc1");
+ if (IS_ERR(ppmu_clk))
+ printk(KERN_ERR "failed to get ppmu_dmc1\n");
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_clk = clk_get(NULL, "ppmucpu");
+ if (IS_ERR(ppmu_clk))
+ printk(KERN_ERR "failed to get ppmu_cpu\n");
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_init(&exynos_ppmu[PPMU_DMC0], &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DMC1], &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos4_busfreq.dev);
+#endif
+
+
+ /* 400 kHz for initialization of MMC Card */
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS3) & 0xfffffff0)
+ | 0x9, EXYNOS4_CLKDIV_FSYS3);
+#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS2) & 0x00f0fff0)
+ | 0x10008, EXYNOS4_CLKDIV_FSYS2);
+#else
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS2) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS2);
+#endif
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS1) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS1);
+}
+
+#ifdef CONFIG_EXYNOS_C2C
+static void __init exynos_c2c_reserve(void)
+{
+ static struct cma_region region = {
+ .name = "c2c_shdmem",
+ .size = 64 * SZ_1M,
+ { .alignment = 64 * SZ_1M },
+ .start = C2C_SHAREDMEM_BASE
+ };
+
+ BUG_ON(cma_early_region_register(&region));
+ BUG_ON(cma_early_region_reserve(&region));
+
+ pr_info("%s %10s %8x %8x\n", __func__,
+ region.name, region.start, region.size);
+}
+#endif
+
+static void __init exynos_init_reserve(void)
+{
+ sec_debug_magic_init();
+}
+
+MACHINE_START(SMDK4412, "SMDK4x12")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = midas_map_io,
+ .init_machine = midas_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+ .init_early = &exynos_init_reserve,
+MACHINE_END
+
+MACHINE_START(SMDK4212, "SMDK4x12")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = midas_map_io,
+ .init_machine = midas_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+ .init_early = &exynos_init_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 642702b..efa5921 100644
--- a/arch/arm/mach-exynos4/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/mach-nuri.c
+ * linux/arch/arm/mach-exynos/mach-nuri.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
*
diff --git a/arch/arm/mach-exynos/mach-p10.c b/arch/arm/mach-exynos/mach-p10.c
new file mode 100644
index 0000000..5ee8289
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-p10.c
@@ -0,0 +1,3091 @@
+/* linux/arch/arm/mach-exynos/mach-p10.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mmc/host.h>
+#include <linux/memblock.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <video/platform_lcd.h>
+#include <video/s5p-dp.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <media/exynos_gscaler.h>
+#include <media/exynos_flite.h>
+#include <media/exynos_fimc_is.h>
+#include <plat/gpio-cfg.h>
+#include <plat/adc.h>
+#include <plat/regs-serial.h>
+#include <plat/exynos5.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/hwmon.h>
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+
+#include <plat/fb.h>
+#include <plat/fb-s5p.h>
+#include <plat/fb-core.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+#include <plat/ehci.h>
+#include <plat/s5p-mfc.h>
+#include <plat/dp.h>
+#include <plat/backlight.h>
+#include <plat/usbgadget.h>
+#include <plat/fimg2d.h>
+#include <plat/tv-core.h>
+#include <plat/s3c64xx-spi.h>
+
+#include <plat/mipi_csis.h>
+#include <mach/map.h>
+#include <mach/exynos-ion.h>
+#include <mach/sysmmu.h>
+#include <mach/spi-clocks.h>
+#include <mach/ppmu.h>
+#include <mach/dev.h>
+#include <mach/pmu.h>
+#include <mach/regs-pmu.h>
+#include <mach/dwmci.h>
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#include <plat/jpeg.h>
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+#include <mach/c2c.h>
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+#include <plat/tvout.h>
+#endif
+
+#ifdef CONFIG_MFD_MAX77686
+#include <linux/mfd/max77686.h>
+#endif
+
+#ifdef CONFIG_SENSORS_BH1721FVC
+#include <linux/bh1721fvc.h>
+#endif
+
+#include <mach/gpio-p10.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu5.h>
+#include <mach/midas-sound.h>
+
+#if defined(CONFIG_SEC_DEBUG)
+#include <mach/sec_debug.h>
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU6050
+#include <linux/mpu_411.h>
+#endif
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+#include <plat/s5p-tmu.h>
+#include <mach/regs-tmu.h>
+#endif
+#include <plat/media.h>
+
+#ifdef CONFIG_BATTERY_SAMSUNG_P1X
+#include <mach/p10-battery.h>
+#endif
+
+#ifdef CONFIG_STMPE811_ADC
+#include <linux/stmpe811-adc.h>
+struct stmpe811_platform_data stmpe811_pdata;
+#endif
+
+#include <mach/p10-input.h>
+#ifdef CONFIG_LEDS_SPFCW043
+#include <linux/leds-spfcw043.h>
+#endif
+
+#include "p10-wlan.h"
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct s3cfb_extdsp_lcd {
+ int width;
+ int height;
+ int bpp;
+};
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU6050
+ struct mpu_platform_data mpu6050_data = {
+ .int_config = 0x10,
+ .orientation = {0, 1, 0,
+ 1, 0, 0,
+ 0, 0, -1},
+ .enable_irq_handler = NULL,
+ };
+
+static struct ext_slave_platform_data mpu_ak8975_data = {
+ .bus = EXT_SLAVE_BUS_PRIMARY,
+ .adapt_num = 11,
+ .orientation = {1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1},
+ .address = 0x0C,
+ .irq = IRQ_EINT(18),
+ };
+
+static struct i2c_gpio_platform_data gpio_i2c_data11 = {
+ .sda_pin = GPIO_MSENSE_SDA,
+ .scl_pin = GPIO_MSENSE_SCL,
+};
+
+struct platform_device s3c_device_i2c11 = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &gpio_i2c_data11,
+};
+
+static struct i2c_board_info i2c_devs11[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8975_mod", 0x0C),
+ .irq = IRQ_EINT(18),
+ .platform_data = &mpu_ak8975_data,
+ },
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("mpu6050",0x68),
+ .irq = IRQ_EINT(12),
+ .platform_data = &mpu6050_data,
+ },
+/*
+ {
+ I2C_BOARD_INFO("ak8975_mod",0x0C),
+ .irq = IRQ_EINT(18),
+ .platform_data = &mpu_ak8975_data,
+ },
+*/
+};
+
+void magnetic_init()
+{
+ pr_info("%s : AK8963C Init", __func__);
+ s3c_gpio_cfgpin(GPIO_MSENSE_RST, S3C_GPIO_SFN(S3C_GPIO_OUTPUT));
+ s3c_gpio_setpull(GPIO_MSENSE_RST, S3C_GPIO_PULL_UP);
+ gpio_set_value(GPIO_MSENSE_RST, 0);
+ usleep_range(20, 20);
+ gpio_set_value(GPIO_MSENSE_RST, 1);
+}
+
+#else
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("dummy", (0x10)),
+ }
+};
+#endif /* CONFIG_MPU_SENSORS_MPU6050 */
+
+
+#define REG_INFORM4 (S5P_INFORM4)
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK5250_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK5250_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK5250_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+#ifdef CONFIG_30PIN_CONN
+#include <linux/30pin_con.h>
+#endif
+
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+#include <linux/isa1200_vibrator.h>
+#endif
+
+static struct s3c2410_uartcfg smdk5250_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+};
+
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+struct platform_device exynos_device_md0 = {
+ .name = "exynos-mdev",
+ .id = 0,
+};
+
+struct platform_device exynos_device_md1 = {
+ .name = "exynos-mdev",
+ .id = 1,
+};
+struct platform_device exynos_device_md2 = {
+ .name = "exynos-mdev",
+ .id = 2,
+};
+#endif
+
+#if defined(CONFIG_DP_40HZ_P10)
+#define FPS 40
+#elif defined(CONFIG_DP_60HZ_P10)
+#define FPS 60
+#endif
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_MACH_P10_DP_01)
+
+static struct s3c_fb_pd_win p10_fb_win0 = {
+ .win_mode = {
+ .refresh = FPS,
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win p10_fb_win1 = {
+ .win_mode = {
+ .refresh = FPS,
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+
+};
+
+static struct s3c_fb_pd_win p10_fb_win2 = {
+ .win_mode = {
+ .refresh = FPS,
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+
+};
+
+static struct s3c_fb_pd_win p10_fb_win3 = {
+ .win_mode = {
+ .refresh = FPS,
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+
+};
+
+static struct s3c_fb_pd_win p10_fb_win4 = {
+ .win_mode = {
+ .refresh = FPS,
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 37,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+
+};
+
+#elif defined(CONFIG_MACH_P10_DP_00)
+
+static struct s3c_fb_pd_win p10_fb_win0 = {
+ .win_mode = {
+ .refresh = 20,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 20,
+ .lower_margin = 3,
+ .hsync_len = 16,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win p10_fb_win1 = {
+ .win_mode = {
+ .refresh = 20,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 20,
+ .lower_margin = 3,
+ .hsync_len = 16,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+
+};
+
+static struct s3c_fb_pd_win p10_fb_win2 = {
+ .win_mode = {
+ .refresh = 20,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 20,
+ .lower_margin = 3,
+ .hsync_len = 16,
+ .vsync_len = 6,
+ .xres = 2560,
+ .yres = 1600,
+
+ },
+ .virtual_x = 2560,
+ .virtual_y = 1640 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+
+};
+#endif
+static void exynos_fimd_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+ unsigned int uRead = 0;
+
+#if defined(CONFIG_S5P_DP)
+ /* Set Hotplug detect for DP */
+ s3c_gpio_cfgpin(GPIO_DP_HPD, S3C_GPIO_SFN(3));
+#endif
+ /*
+ * Set DISP1BLK_CFG register for Display path selection
+ *
+ * FIMD of DISP1_BLK Bypass selection : DISP1BLK_CFG[15]
+ * ---------------------
+ * 0 | MIE/MDNIE
+ * 1 | FIMD : selected
+ */
+ reg = __raw_readl(S3C_VA_SYS + 0x0214);
+ reg &= ~(1 << 15); /* To save other reset values */
+ reg |= (1 << 15);
+ __raw_writel(reg, S3C_VA_SYS + 0x0214);
+#if defined(CONFIG_S5P_DP)
+#if defined(CONFIG_MACH_P10_DP_01)
+ // MPLL => FIMD Bus clock
+ uRead = __raw_readl(EXYNOS5_CLKSRC_TOP0);
+ uRead = (uRead & ~(0x3<<14)) | (0x0<<14);
+ __raw_writel(uRead, EXYNOS5_CLKSRC_TOP0);
+
+ uRead = __raw_readl(EXYNOS5_CLKDIV_TOP0);
+ uRead = (uRead & ~(0x7<<28)) | (0x2<<28);
+ __raw_writel(uRead,EXYNOS5_CLKDIV_TOP0);
+
+ /* Reference clcok selection for DPTX_PHY: pad_osc_clk_24M */
+ reg = __raw_readl(S3C_VA_SYS + 0x04d4);
+ reg = (reg & ~(0x1 << 0)) | (0x0 << 0);
+ __raw_writel(reg, S3C_VA_SYS + 0x04d4);
+
+ /* DPTX_PHY: XXTI */
+ reg = __raw_readl(S3C_VA_SYS + 0x04d8);
+ reg = (reg & ~(0x1 << 3)) | (0x0 << 3);
+ __raw_writel(reg, S3C_VA_SYS + 0x04d8);
+#elif defined(CONFIG_MACH_P10_DP_00)
+
+ reg = __raw_readl(S3C_VA_SYS + 0x04d4);
+ reg |= (1 << 0);
+ __raw_writel(reg, S3C_VA_SYS + 0x04d4);
+
+ /* DPTX_PHY: XXTI */
+ reg = __raw_readl(S3C_VA_SYS + 0x04d8);
+ reg &= ~(1 << 3);
+ __raw_writel(reg, S3C_VA_SYS + 0x04d8);
+#endif
+#endif
+}
+
+static struct s3c_fb_platdata p10_lcd1_pdata __initdata = {
+ .win[0] = &p10_fb_win0,
+ .win[1] = &p10_fb_win1,
+ .win[2] = &p10_fb_win2,
+ .win[3] = &p10_fb_win3,
+ .win[4] = &p10_fb_win4,
+ .default_win = 2,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = 0,
+ .setup_gpio = exynos_fimd_gpio_setup_24bpp,
+};
+#endif
+
+#if defined CONFIG_VIDEO_EXYNOS5_FIMC_IS
+static struct exynos5_platform_fimc_is exynos5_fimc_is_data;
+
+#if defined CONFIG_VIDEO_S5K4E5
+static struct exynos5_fimc_is_sensor_info s5k4e5= {
+ .sensor_name = "S5K4E5",
+ .sensor_id = SENSOR_NAME_S5K4E5,
+#if defined CONFIG_S5K4E5_POSITION_FRONT
+ .sensor_position = SENSOR_POSITION_FRONT,
+#elif defined CONFIG_S5K4E5_POSITION_REAR
+ .sensor_position = SENSOR_POSITION_REAR,
+#endif
+#if defined CONFIG_S5K4E5_CSI_C
+ .csi_id = CSI_ID_A,
+ .flite_id = FLITE_ID_A,
+ .i2c_channel = SENSOR_CONTROL_I2C0,
+#elif defined CONFIG_S5K4E5_CSI_D
+ .csi_id = CSI_ID_B,
+ .flite_id = FLITE_ID_B,
+ .i2c_channel = SENSOR_CONTROL_I2C1,
+#endif
+
+ .max_width = 2560,
+ .max_height = 1920,
+ .max_frame_rate = 30,
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+};
+#endif
+
+#if defined CONFIG_VIDEO_S5K6A3
+static struct exynos5_fimc_is_sensor_info s5k6a3= {
+ .sensor_name = "S5K6A3",
+ .sensor_id = SENSOR_NAME_S5K6A3,
+#if defined CONFIG_S5K6A3_POSITION_FRONT
+ .sensor_position = SENSOR_POSITION_FRONT,
+#elif defined CONFIG_S5K6A3_POSITION_REAR
+ .sensor_position = SENSOR_POSITION_REAR,
+#endif
+#if defined CONFIG_S5K6A3_CSI_C
+ .csi_id = CSI_ID_A,
+ .flite_id = FLITE_ID_A,
+ .i2c_channel = SENSOR_CONTROL_I2C0,
+#elif defined CONFIG_S5K6A3_CSI_D
+ .csi_id = CSI_ID_B,
+ .flite_id = FLITE_ID_B,
+ .i2c_channel = SENSOR_CONTROL_I2C1,
+#endif
+
+ .max_width = 1280,
+ .max_height = 720,
+ .max_frame_rate = 30,
+
+ .mipi_lanes = 1,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+};
+#endif
+#endif
+
+#ifdef CONFIG_S5P_DP
+static void dp_lcd_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+
+ /* LCD_PWM_IN_2.8V, AH21, XPWMOUT_0 => LCD_B_PWM */
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_request_one(GPIO_LCD_PWM_IN_18V, GPIOF_OUT_INIT_LOW, "GPB2");
+#endif
+
+#ifdef CONFIG_MACH_P10_00_BD
+ /* LCD_APS_EN_2.8V, R6, XCI1RGB_2 => GPG0_2 */
+ gpio_request_one(GPIO_LCD_APS_EN_18V, GPIOF_OUT_INIT_LOW, "GPG0");
+#endif
+ /* LCD_EN , XMMC2CDN => GPC2_2 */
+ gpio_request_one(GPIO_LCD_EN, GPIOF_OUT_INIT_LOW, "GPC2");
+
+ /* LCD_EN , XMMC2CDN => GPC2_2 */
+ gpio_set_value(GPIO_LCD_EN, 1);
+
+#ifdef CONFIG_MACH_P10_00_BD
+ /* LCD_APS_EN_2.8V, R6, XCI1RGB_2 => GPG0_2 */
+ gpio_set_value(GPIO_LCD_APS_EN_18V, 1);
+#endif
+
+ udelay(1000);
+
+ /* LCD_PWM_IN_2.8V, AH21, XPWMOUT_0=> LCD_B_PWM */
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_set_value(GPIO_LCD_PWM_IN_18V, 1);
+#endif
+ } else {
+ /* LCD_PWM_IN_2.8V, AH21, XPWMOUT_0=> LCD_B_PWM */
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_set_value(GPIO_LCD_PWM_IN_18V, 0);
+#endif
+
+#ifdef CONFIG_MACH_P10_00_BD
+ /* LCD_APS_EN_2.8V, R6, XCI1RGB_2 => GPG0_2 */
+ gpio_set_value(GPIO_LCD_APS_EN_18V, 0);
+#endif
+
+ /* LCD_EN , XMMC2CDN => GPC2_2 */
+ gpio_set_value(GPIO_LCD_EN, 0);
+
+#ifdef CONFIG_MACH_P10_00_BD
+ /* LCD_APS_EN_2.8V, R6, XCI1RGB_2 => GPG0_2 */
+ gpio_free(GPIO_LCD_APS_EN_18V);
+#endif
+
+ /* LCD_EN , XMMC2CDN => GPC2_2 */
+ gpio_free(GPIO_LCD_EN);
+
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_free(GPIO_LCD_PWM_IN_18V);
+#endif
+ }
+}
+
+static struct plat_lcd_data p10_dp_lcd_data = {
+ .set_power = dp_lcd_set_power,
+};
+
+static struct platform_device p10_dp_lcd = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd1.dev,
+ .dev.platform_data = &p10_dp_lcd_data,
+};
+
+static struct video_info p10_dp_config = {
+ .name = "for p10 TEST",
+#if defined(CONFIG_MACH_P10_DP_01)
+ .h_sync_polarity = 0,
+ .v_sync_polarity = 0,
+ .interlaced = 0,
+
+ .color_space = COLOR_RGB,
+ .dynamic_range = VESA,
+ .ycbcr_coeff = COLOR_YCBCR601,
+ .color_depth = COLOR_8,
+
+ .link_rate = LINK_RATE_2_70GBPS,
+ .lane_count = LANE_COUNT4,
+
+#elif defined(CONFIG_MACH_P10_DP_00)
+
+ .h_sync_polarity = 0,
+ .v_sync_polarity = 0,
+ .interlaced = 0,
+
+ .color_space = COLOR_RGB,
+ .dynamic_range = VESA,
+ .ycbcr_coeff = COLOR_YCBCR601,
+ .color_depth = COLOR_8,
+
+ .link_rate = LINK_RATE_1_62GBPS,
+ .lane_count = LANE_COUNT4,
+#endif
+};
+
+static void s5p_dp_backlight_on(void)
+{
+ /* LED_BACKLIGHT_RESET: XCI1RGB_5 => GPG0_5 */
+ gpio_request_one(GPIO_LED_BACKLIGHT_RESET, GPIOF_OUT_INIT_LOW, "GPG0");
+
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, 1);
+}
+
+static void s5p_dp_backlight_off(void)
+{
+ /* LED_BACKLIGHT_RESET: XCI1RGB_5 => GPG0_5 */
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, 0);
+
+ gpio_free(GPIO_LED_BACKLIGHT_RESET);
+
+}
+
+static struct s5p_dp_platdata p10_dp_data __initdata = {
+ .video_info = &p10_dp_config,
+ .phy_init = s5p_dp_phy_init,
+ .phy_exit = s5p_dp_phy_exit,
+ .backlight_on = s5p_dp_backlight_on,
+ .backlight_off = s5p_dp_backlight_off,
+};
+#endif
+
+/* LCD Backlight data */
+#ifdef CONFIG_BACKLIGHT_PWM
+static struct samsung_bl_gpio_info p10_bl_gpio_info = {
+ .no = GPIO_LCD_PWM_IN_18V,
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data p10_bl_data = {
+ .pwm_id = 0,
+ .pwm_period_ns = 10000,
+};
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+static struct s5p_mfc_platdata smdk5250_mfc_pd = {
+ .clock_rate = 333000000,
+};
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+struct exynos_c2c_platdata smdk5250_c2c_pdata = {
+ .setup_gpio = NULL,
+ .shdmem_addr = C2C_SHAREDMEM_BASE,
+ .shdmem_size = C2C_MEMSIZE_64,
+ .ap_sscm_addr = NULL,
+ .cp_sscm_addr = NULL,
+ .rx_width = C2C_BUSWIDTH_16,
+ .tx_width = C2C_BUSWIDTH_16,
+ .clk_opp100 = 400,
+ .clk_opp50 = 200,
+ .clk_opp25 = 100,
+ .default_opp_mode = C2C_OPP25,
+ .get_c2c_state = NULL,
+ .c2c_sysreg = S3C_VA_SYS + 0x0360,
+};
+#endif
+
+static int exynos5_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ int mode = 0;
+
+ if ((code == SYS_RESTART) && _cmd)
+ if (!strcmp((char *)_cmd, "recovery"))
+ mode = 0xf;
+
+ __raw_writel(mode, REG_INFORM4);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos5_reboot_notifier = {
+ .notifier_call = exynos5_notifier_call,
+};
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+static void exynos_dwmci_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC0(0); gpio < EXYNOS5_GPC0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_8:
+ for (gpio = EXYNOS5_GPC1(3); gpio <= EXYNOS5_GPC1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC0(3); gpio <= EXYNOS5_GPC0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos_dwmci_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 66 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci_cfg_gpio,
+};
+#endif
+
+static void exynos_dwmci0_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC0(0); gpio < EXYNOS5_GPC0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_8:
+ for (gpio = EXYNOS5_GPC1(0); gpio <= EXYNOS5_GPC1(3); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC0(3); gpio <= EXYNOS5_GPC0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos5_dwmci0_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 100 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci0_cfg_gpio,
+};
+
+static void exynos_dwmci1_cfg_gpio(int width)
+{
+ unsigned int gpio;
+ for (gpio = EXYNOS5_GPC2(0); gpio < EXYNOS5_GPC2(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC2(3); gpio <= EXYNOS5_GPC2(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC2(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+ default:
+ break;
+ }
+}
+
+static void (*wlan_notify_func)(struct platform_device *dev, int state);
+static DEFINE_MUTEX(wlan_mutex_lock);
+
+static int ext_cd_init_wlan(void (*notify_func)(struct platform_device *dev, int state))
+{
+ mutex_lock(&wlan_mutex_lock);
+ WARN_ON(wlan_notify_func);
+
+ wlan_notify_func = notify_func;
+
+ if (wlan_notify_func) {
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ wlan_notify_func(&exynos_device_dwmci1, 1);
+ else
+ wlan_notify_func(&s3c_device_hsmmc3, 1);
+ }
+
+ mutex_unlock(&wlan_mutex_lock);
+
+ return 0;
+}
+
+static int ext_cd_cleanup_wlan(void (*notify_func)(struct platform_device *dev, int state))
+{
+ mutex_lock(&wlan_mutex_lock);
+ WARN_ON(wlan_notify_func);
+
+ if (wlan_notify_func) {
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ wlan_notify_func(&exynos_device_dwmci1, 0);
+ else
+ wlan_notify_func(&s3c_device_hsmmc3, 0);
+ }
+
+ wlan_notify_func = NULL;
+
+ mutex_unlock(&wlan_mutex_lock);
+
+ return 0;
+}
+
+static struct dw_mci_board exynos5_dwmci1_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 50 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci1_cfg_gpio,
+ .ext_cd_init = ext_cd_init_wlan,
+ .ext_cd_cleanup = ext_cd_cleanup_wlan,
+ .cd_type = DW_MCI_CD_EXTERNAL,
+};
+
+void mmc_force_presence_change(struct platform_device *pdev)
+{
+ void (*notify_func)(struct platform_device *, int state) = NULL;
+ mutex_lock(&wlan_mutex_lock);
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ if (pdev == &exynos_device_dwmci1)
+ notify_func = wlan_notify_func;
+ } else {
+ if (pdev == &s3c_device_hsmmc3)
+ notify_func = wlan_notify_func;
+ }
+
+ if (notify_func)
+ notify_func(pdev, 1);
+ else
+ pr_warn("%s: called for device with no notifier\n", __func__);
+ mutex_unlock(&wlan_mutex_lock);
+}
+EXPORT_SYMBOL_GPL(mmc_force_presence_change);
+
+static int smdk5250_dwmci_get_ro(u32 slot_id)
+{
+ /* smdk5250 rev1.0 did not support SD/MMC card write pritect. */
+ return 0;
+}
+
+static void exynos_dwmci2_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC3(0); gpio <= EXYNOS5_GPC3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS5_GPC3(3); gpio <= EXYNOS5_GPC3(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS5_GPC3(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos5_dwmci2_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 22 * 1000 * 1000,
+ .caps = MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci2_cfg_gpio,
+ .get_ro = smdk5250_dwmci_get_ro,
+};
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 0x42,
+ .gate_clkname = "fimg2d",
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdk5250_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdk5250_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdk5250_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .ext_cd_gpio = GPIO_T_FLASH_DETECT,
+ .ext_cd_gpio_invert = true,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+struct class *camera_class;
+EXPORT_SYMBOL(camera_class);
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdk5250_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+ /* ext_cd_xxx should be used in only .cd_type = S3C_SDHCI_CD_EXTERNAL */
+ .ext_cd_init = ext_cd_init_wlan,
+ .ext_cd_cleanup = ext_cd_cleanup_wlan,
+};
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+ [0] = {
+ .line = GPIO_5M_SPI_CS,
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi1_csi[0],
+ }
+};
+#endif
+
+#ifdef CONFIG_LEDS_SPFCW043
+static int spfcw043_setGpio(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_CAM_FLASH_EN, "TORCH_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request TORCH_EN\n");
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_CAM_FLASH_EN, 1);
+ err = gpio_request(GPIO_CAM_FLASH_SET, "TORCH_SET");
+ if (err) {
+ printk(KERN_ERR "failed to request TORCH_SET\n");
+ gpio_free(GPIO_CAM_FLASH_EN);
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_CAM_FLASH_SET, 1);
+ gpio_set_value(GPIO_CAM_FLASH_EN, 0);
+ gpio_set_value(GPIO_CAM_FLASH_SET, 0);
+
+ return 0;
+}
+
+static int spfcw043_freeGpio(void)
+{
+ gpio_free(GPIO_CAM_FLASH_EN);
+ gpio_free(GPIO_CAM_FLASH_SET);
+
+ return 0;
+}
+
+static void spfcw043_torch_en(int onoff)
+{
+ gpio_set_value(GPIO_CAM_FLASH_EN, onoff);
+}
+
+static void spfcw043_torch_set(int onoff)
+{
+ gpio_set_value(GPIO_CAM_FLASH_SET, onoff);
+}
+
+static struct spfcw043_led_platform_data spfcw043_led_data = {
+ .brightness = TORCH_BRIGHTNESS_50,
+ .status = STATUS_UNAVAILABLE,
+ .setGpio = spfcw043_setGpio,
+ .freeGpio = spfcw043_freeGpio,
+ .torch_en = spfcw043_torch_en,
+ .torch_set = spfcw043_torch_set,
+};
+
+static struct platform_device s3c_device_spfcw043_led = {
+ .name = "spfcw043-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &spfcw043_led_data,
+ },
+};
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+#if defined(CONFIG_ITU_A)
+static int smdk5250_cam0_reset(int dummy)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS5_GPX1(2), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPX1(2), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPX1(2), 0);
+ gpio_direction_output(EXYNOS5_GPX1(2), 1);
+ gpio_free(EXYNOS5_GPX1(2));
+
+ return 0;
+}
+#endif
+#if defined(CONFIG_ITU_B)
+static int smdk5250_cam1_reset(int dummy)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS5_GPX1(0), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPX1(0), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPX1(0), 0);
+ gpio_direction_output(EXYNOS5_GPX1(0), 1);
+ gpio_free(EXYNOS5_GPX1(0));
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4BA
+static struct s5k4ba_mbus_platform_data s5k4ba_mbus_plat = {
+ .id = 0,
+ .fmt = {
+ .width = 1600,
+ .height = 1200,
+ /* .code = V4L2_MBUS_FMT_UYVY8_2X8, */
+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
+ },
+ .clk_rate = 24000000UL,
+#ifdef CONFIG_ITU_A
+ .set_power = smdk5250_cam0_reset,
+#endif
+#ifdef CONFIG_ITU_B
+ .set_power = smdk5250_cam1_reset,
+#endif
+};
+
+static struct i2c_board_info s5k4ba_info = {
+ I2C_BOARD_INFO("S5K4BA", 0x2d),
+ .platform_data = &s5k4ba_mbus_plat,
+};
+#endif
+
+/* 1 MIPI Cameras */
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct m5mols_platform_data m5mols_platdata = {
+#ifdef CONFIG_CSI_C
+ .gpio_rst = EXYNOS5_GPX1(2), /* ISP_RESET */
+#endif
+#ifdef CONFIG_CSI_D
+ .gpio_rst = EXYNOS5_GPX1(0), /* ISP_RESET */
+#endif
+ .enable_rst = true, /* positive reset */
+ .irq = IRQ_EINT(22),
+};
+
+static struct i2c_board_info m5mols_board_info = {
+ I2C_BOARD_INFO("M5MOLS", 0x1F),
+ .platform_data = &m5mols_platdata,
+};
+#endif
+#endif /* CONFIG_VIDEO_EXYNOS_FIMC_LITE */
+
+#ifdef CONFIG_VIDEO_EXYNOS_MIPI_CSIS
+static struct regulator_consumer_supply mipi_csi_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.0"),
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.1"),
+};
+
+static struct regulator_init_data mipi_csi_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mipi_csi_fixed_voltage_supplies),
+ .consumer_supplies = mipi_csi_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config mipi_csi_fixed_voltage_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &mipi_csi_fixed_voltage_init_data,
+};
+
+static struct platform_device mipi_csi_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &mipi_csi_fixed_voltage_config,
+ },
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct regulator_consumer_supply m5mols_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("core", NULL),
+ REGULATOR_SUPPLY("dig_18", NULL),
+ REGULATOR_SUPPLY("d_sensor", NULL),
+ REGULATOR_SUPPLY("dig_28", NULL),
+ REGULATOR_SUPPLY("a_sensor", NULL),
+ REGULATOR_SUPPLY("dig_12", NULL),
+};
+
+static struct regulator_init_data m5mols_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(m5mols_fixed_voltage_supplies),
+ .consumer_supplies = m5mols_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config m5mols_fixed_voltage_config = {
+ .supply_name = "CAM_SENSOR",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &m5mols_fixed_voltage_init_data,
+};
+
+static struct platform_device m5mols_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &m5mols_fixed_voltage_config,
+ },
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_MAX77686)
+/* max77686 */
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL)
+};
+#else
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo4_supply[] = {
+ REGULATOR_SUPPLY("vcc_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_mipi_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("touch_vdd_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.9v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb02_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vhsic_1.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("vhsic_1.8v", NULL),
+};
+
+#if defined(CONFIG_MACH_P10_LUNGO_01_BD) || \
+ defined(CONFIG_MACH_P10_LUNGO_WIFI_01_BD)
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_core_1.8v", NULL),
+};
+#endif
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("cam_io_from_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo20_supply[] = {
+ REGULATOR_SUPPLY("vmem_vdd_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+#if defined(CONFIG_MACH_P10_LUNGO_01_BD) || \
+ defined(CONFIG_MACH_P10_LUNGO_WIFI_01_BD)
+static struct regulator_consumer_supply ldo22_supply[] = {
+ REGULATOR_SUPPLY("vcc_mmc_2.8v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo22_supply[] = {
+ REGULATOR_SUPPLY("cam_core_1.8v", NULL),
+};
+#endif
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("touch_avdd", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("vadc_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("irda_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply max77686_buck1 =
+ REGULATOR_SUPPLY("vdd_mif", NULL);
+static struct regulator_consumer_supply max77686_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3 =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max77686_buck4 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max77686_buck9 =
+ REGULATOR_SUPPLY("cam_isp_core", NULL);
+
+static struct regulator_consumer_supply max77686_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm43241_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask,\
+ _disabled) \
+static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1,
+ 0, 0);
+REGULATOR_INIT(ldo4, "VCC_2.8V_AP", 2800000, 2800000, 1,
+ 0, 0);
+REGULATOR_INIT(ldo5, "CAM_ISP_MIPI_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo9, "TOUCH_VDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo11, "VABB1_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo14, "VABB02_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo15, "VHSIC_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo16, "VHSIC_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_P10_LUNGO_01_BD) || \
+ defined(CONFIG_MACH_P10_LUNGO_WIFI_01_BD)
+REGULATOR_INIT(ldo17, "CAM_CORE_1.8v", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo18, "CAM_IO_FROM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo20, "VMEM_VDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_P10_LUNGO_01_BD) || \
+ defined(CONFIG_MACH_P10_LUNGO_WIFI_01_BD)
+REGULATOR_INIT(ldo22, "VCC_MMC_2.8v", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo22, "CAM_CORE_1.8v", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo23, "TSP_AVDD_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo25, "VADC_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "IRDA_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 900000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1500000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 900000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 700000,
+ .max_uV = 1300000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck4,
+};
+
+static struct regulator_init_data max77686_buck9_data = {
+ .constraints = {
+ .name = "cam_isp_core",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck9,
+};
+
+static struct regulator_init_data max77686_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_enp32khz),
+ .consumer_supplies = max77686_enp32khz,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_BUCK9, &max77686_buck9_data,},
+ {MAX77686_LDO3, &ldo3_init_data,},
+ {MAX77686_LDO4, &ldo4_init_data,},
+ {MAX77686_LDO5, &ldo5_init_data,},
+ {MAX77686_LDO8, &ldo8_init_data,},
+ {MAX77686_LDO9, &ldo9_init_data,},
+ {MAX77686_LDO10, &ldo10_init_data,},
+ {MAX77686_LDO11, &ldo11_init_data,},
+ {MAX77686_LDO12, &ldo12_init_data,},
+ {MAX77686_LDO14, &ldo14_init_data,},
+ {MAX77686_LDO15, &ldo15_init_data,},
+ {MAX77686_LDO16, &ldo16_init_data,},
+#if defined(CONFIG_MACH_P10_LUNGO_01_BD) || \
+ defined(CONFIG_MACH_P10_LUNGO_WIFI_01_BD)
+ {MAX77686_LDO17, &ldo17_init_data,},
+#endif
+ {MAX77686_LDO18, &ldo18_init_data,},
+ {MAX77686_LDO19, &ldo19_init_data,},
+ {MAX77686_LDO20, &ldo20_init_data,},
+ {MAX77686_LDO21, &ldo21_init_data,},
+ {MAX77686_LDO22, &ldo22_init_data,},
+ {MAX77686_LDO23, &ldo23_init_data,},
+ {MAX77686_LDO24, &ldo24_init_data,},
+ {MAX77686_LDO25, &ldo25_init_data,},
+ {MAX77686_LDO26, &ldo26_init_data,},
+ {MAX77686_P32KH, &max77686_enp32khz_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO3] = {MAX77686_LDO3, MAX77686_OPMODE_NORMAL},
+ [MAX77686_LDO8] = {MAX77686_LDO8, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO10] = {MAX77686_LDO10, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO12] = {MAX77686_LDO12, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO15] = {MAX77686_LDO15, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO16] = {MAX77686_LDO16, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+static struct max77686_platform_data exynos4_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+ .has_full_constraints = 1,
+
+ .buck234_gpio_dvs = {
+ GPIO_PMIC_DVS1,
+ GPIO_PMIC_DVS2,
+ GPIO_PMIC_DVS3,
+ },
+ .buck234_gpio_selb = {
+ GPIO_BUCK2_SEL,
+ GPIO_BUCK3_SEL,
+ GPIO_BUCK4_SEL,
+ },
+
+ /*for future work after DVS Table */
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1100000, /* 1.1V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1100000, /* 1.1V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+};
+#endif /* CONFIG_REGULATOR_MAX77686 */
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+ {
+ I2C_BOARD_INFO("exynos_hdcp", (0x74 >> 1)),
+ }
+#endif
+};
+
+#ifdef CONFIG_S3C_DEV_HWMON
+static struct s3c_hwmon_pdata smdk5250_hwmon_pdata __initdata = {
+ /* Reference voltage (1.2V) */
+ .in[0] = &(struct s3c_hwmon_chcfg) {
+ .name = "smdk:reference-voltage",
+ .mult = 3300,
+ .div = 4096,
+ },
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_MAX77686)
+static struct i2c_board_info i2c_devs5[] __initdata = {
+ {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ }
+};
+#endif
+
+#ifdef CONFIG_SENSORS_BH1721FVC
+
+static struct i2c_gpio_platform_data gpio_i2c_data12 = {
+ .sda_pin = GPIO_PS_ALS_SDA,
+ .scl_pin = GPIO_PS_ALS_SCL,
+};
+
+struct platform_device s3c_device_i2c12 = {
+ .name = "i2c-gpio",
+ .id = 12,
+ .dev.platform_data = &gpio_i2c_data12,
+};
+
+static int light_sensor_init(void)
+{
+ int err;
+
+ printk(KERN_INFO"==============================\n");
+ printk(KERN_INFO"== BH1721 Light Sensor Init ==\n");
+ printk(KERN_INFO"==============================\n");
+ printk("%d %d\n", GPIO_PS_ALS_SDA, GPIO_PS_ALS_SCL);
+ err = gpio_request(GPIO_PS_VOUT, "LIGHT_SENSOR_RESET");
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to request the light "
+ " sensor gpio (%d)\n", err);
+ return err;
+ }
+
+ s3c_gpio_cfgpin(GPIO_PS_VOUT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_PS_VOUT, S3C_GPIO_PULL_NONE);
+
+ err = gpio_direction_output(GPIO_PS_VOUT, 0);
+ udelay(2);
+ err = gpio_direction_output(GPIO_PS_VOUT, 1);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(reset)"
+ " high (%d)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int bh1721fvc_light_sensor_reset(void)
+{
+ int err;
+
+ printk(KERN_INFO" bh1721fvc_light_sensor_reset\n");
+ err = gpio_direction_output(GPIO_PS_VOUT, 0);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(reset)"
+ " low (%d)\n", err);
+ return err;
+ }
+
+ udelay(2);
+
+ err = gpio_direction_output(GPIO_PS_VOUT, 1);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(reset)"
+ " high (%d)\n", err);
+ return err;
+ }
+ return 0;
+}
+
+static int bh1721fvc_light_sensor_output(int value)
+{
+ int err;
+ int gpio_vout = GPIO_PS_VOUT;
+
+ err = gpio_direction_output(GPIO_PS_VOUT, value);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(dvi)"
+ " low (%d)\n", err);
+ return err;
+ }
+ return 0;
+}
+
+static struct bh1721fvc_platform_data bh1721fvc_pdata = {
+ .reset = bh1721fvc_light_sensor_reset,
+ /* .output = bh1721fvc_light_sensor_output, */
+};
+
+static struct i2c_board_info i2c_bh1721_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("bh1721fvc", 0x23),
+ .platform_data = &bh1721fvc_pdata,
+ },
+};
+#endif
+
+#ifdef CONFIG_SENSORS_SHT21
+
+static struct i2c_gpio_platform_data gpio_i2c_data13 = {
+ .sda_pin = GPIO_HUM_SDA,
+ .scl_pin = GPIO_HUM_SCL,
+};
+
+struct platform_device s3c_device_i2c13 = {
+ .name = "i2c-gpio",
+ .id = 13,
+ .dev.platform_data = &gpio_i2c_data13,
+};
+
+static struct i2c_board_info i2c_devs13[] __initdata = {
+ {
+ I2C_BOARD_INFO("sht21", 0x40),
+ },
+};
+
+#endif
+
+#if defined(CONFIG_SAMSUNG_MHL)
+static struct i2c_board_info i2c_devs15_emul[] __initdata = {
+};
+
+/* i2c-gpio emulation platform_data */
+static struct i2c_gpio_platform_data i2c15_platdata = {
+ .sda_pin = GPIO_MHL_SDA_18V,
+ .scl_pin = GPIO_MHL_SCL_18V,
+ .udelay = 2, /* 250 kHz*/
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c15 = {
+ .name = "i2c-gpio",
+ .id = 15,
+ .dev.platform_data = &i2c15_platdata,
+};
+
+#endif
+
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+
+static int isa1200_vdd_en(bool en)
+{
+ return gpio_direction_output(GPIO_MOTOR_EN, en);
+}
+
+static struct i2c_gpio_platform_data gpio_i2c_data17 = {
+ .sda_pin = GPIO_MOTOR_SDA_18V,
+ .scl_pin = GPIO_MOTOR_SCL_18V,
+};
+
+struct platform_device s3c_device_i2c17 = {
+ .name = "i2c-gpio",
+ .id = 17,
+ .dev.platform_data = &gpio_i2c_data17,
+};
+
+static struct isa1200_vibrator_platform_data isa1200_vibrator_pdata = {
+ .gpio_en = isa1200_vdd_en,
+ .max_timeout = 10000,
+ .ctrl0 = CTL0_DIVIDER128 | CTL0_PWM_INPUT,
+ .ctrl1 = CTL1_DEFAULT,
+ .ctrl2 = 0,
+ .ctrl4 = 0,
+ .pll = 0,
+ .duty = 0,
+ .period = 0,
+ .get_clk = NULL,
+ .pwm_id = 1,
+ .pwm_duty = 37000,
+ .pwm_period = 38675,/*38109*/
+};
+static struct i2c_board_info i2c_devs17[] = {
+ {
+ I2C_BOARD_INFO("isa1200_vibrator", 0x48),
+ .platform_data = &isa1200_vibrator_pdata,
+ },
+};
+
+static void isa1200_init(void)
+{
+ int gpio, ret;
+
+ gpio = GPIO_MOTOR_EN;
+ gpio_request(gpio, "MOTOR_EN");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+}
+#endif /* CONFIG_MOTOR_DRV_ISA1200 */
+
+#ifdef CONFIG_30PIN_CONN
+
+static void __init acc_con_gpio_init(void)
+{
+ s3c_gpio_cfgpin(GPIO_DOCK_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_DOCK_INT, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_ACCESSORY_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_ACCESSORY_INT, S3C_GPIO_PULL_NONE);
+}
+
+static int acc_dock_con_state(void)
+{
+ /* From ACCESSROY_INT like desktop dock */
+
+ return gpio_get_value(GPIO_ACCESSORY_INT);
+}
+
+static int acc_accessory_con_state(void)
+{
+
+ /* From ACCESSORY_ID pin */
+ return gpio_get_value(GPIO_DOCK_INT);
+}
+
+struct acc_con_platform_data acc_con_pdata = {
+ /*
+ .otg_en =
+ .acc_power =
+ .usb_ldo_en =
+ */
+ .get_dock_state = acc_dock_con_state,
+ .get_acc_state = acc_accessory_con_state,
+ .accessory_irq_gpio = GPIO_ACCESSORY_INT,
+ .dock_irq_gpio = GPIO_DOCK_INT,
+ .mhl_irq_gpio = GPIO_MHL_INT,
+ .hdmi_hpd_gpio = GPIO_HDMI_HPD,
+};
+struct platform_device sec_device_connector = {
+ .name = "acc_con",
+ .id = -1,
+ .dev.platform_data = &acc_con_pdata,
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdk5250_ehci_pdata;
+
+static void __init smdk5250_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk5250_ehci_pdata;
+
+#ifndef CONFIG_USB_EXYNOS_SWITCH
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ if (gpio_request_one(EXYNOS5_GPX2(6), GPIOF_OUT_INIT_HIGH,
+ "HOST_VBUS_CONTROL"))
+ printk(KERN_ERR "failed to request gpio_host_vbus\n");
+ else {
+ s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPX2(6));
+ }
+ }
+#endif
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdk5250_ohci_pdata;
+
+static void __init smdk5250_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk5250_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS5250)
+static void set_usb3_en(int enable)
+{
+ int err;
+ /* XMMC2CDN(USB3.0_EN) for P10 H/W */
+ err = gpio_request(EXYNOS5_GPC2(2), "USB3_EN");
+ if (err)
+ printk(KERN_ERR "usb: failed to request XMMC2CDN GPIO ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPC2(2), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPC2(2), enable);
+ gpio_free(EXYNOS5_GPC2(2));
+ printk(KERN_INFO "usb: set usb3_en gpio (%d)\n", enable);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_S3C_OTGD
+static struct s5p_usbgadget_platdata smdk5250_usbgadget_pdata;
+
+static void __init smdk5250_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdk5250_usbgadget_pdata;
+
+ s5p_usbgadget_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+static struct exynos_usb3_drd_pdata smdk5250_ss_udc_pdata;
+
+static void __init smdk5250_ss_udc_init(void)
+{
+ struct exynos_usb3_drd_pdata *pdata = &smdk5250_ss_udc_pdata;
+
+ exynos_ss_udc_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_XHCI_EXYNOS
+static struct exynos_usb3_drd_pdata smdk5250_xhci_pdata;
+
+static void __init smdk5250_xhci_init(void)
+{
+ struct exynos_usb3_drd_pdata *pdata = &smdk5250_xhci_pdata;
+
+ exynos_xhci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_STMPE811_ADC)
+static struct i2c_gpio_platform_data gpio_i2c_data19 = {
+ .sda_pin = GPIO_ADC_SDA_18V,
+ .scl_pin = GPIO_ADC_SCL_18V,
+};
+
+struct platform_device s3c_device_i2c19 = {
+ .name = "i2c-gpio",
+ .id = 19,
+ .dev.platform_data = &gpio_i2c_data19,
+};
+
+
+/* I2C19 */
+static struct i2c_board_info i2c_devs19_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("stmpe811-adc", (0x82 >> 1)),
+ .platform_data = &stmpe811_pdata,
+ },
+};
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+
+static struct platform_device exynos5_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+#endif
+
+/* Bluetooth */
+#ifdef CONFIG_BT_BCM43241
+static struct platform_device bcm43241_bluetooth_device = {
+ .name = "bcm43241_bluetooth",
+ .id = -1,
+};
+#endif
+
+static struct platform_device *p10_devices[] __initdata = {
+ /* Samsung Power Domain */
+#ifdef CONFIG_EXYNOS_DEV_PD
+ &exynos5_device_pd[PD_MFC],
+ &exynos5_device_pd[PD_G3D],
+ &exynos5_device_pd[PD_ISP],
+ &exynos5_device_pd[PD_GSCL],
+ &exynos5_device_pd[PD_DISP1],
+#endif
+
+#ifdef CONFIG_S5P_DP
+ &s5p_device_dp,
+#endif
+
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd1,
+#endif
+
+#ifdef CONFIG_S5P_DP
+ &p10_dp_lcd,
+#endif
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+ &s3c_device_extdsp,
+#endif
+
+ &s3c_device_wdt,
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ &s5p_device_mfc,
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ &s5p_device_jpeg,
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ &exynos_device_dwmci,
+#endif
+ &exynos_device_dwmci0,
+ &exynos_device_dwmci1,
+ &exynos_device_dwmci2,
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+ &exynos_device_md0,
+ &exynos_device_md1,
+ &exynos_device_md2,
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ &exynos5_device_fimc_is,
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+ &exynos5_device_gsc0,
+ &exynos5_device_gsc1,
+ &exynos5_device_gsc2,
+ &exynos5_device_gsc3,
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ &exynos_device_flite0,
+ &exynos_device_flite1,
+ &exynos_device_flite2,
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_MIPI_CSIS
+ &s5p_device_mipi_csis0,
+ &s5p_device_mipi_csis1,
+ &mipi_csi_fixed_voltage,
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+ &m5mols_fixed_voltage,
+#endif
+
+ &s3c_device_rtc,
+
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[1],
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI
+ &s5p_device_hdmi,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_HDMIPHY
+ &s5p_device_i2c_hdmiphy,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_MIXER
+ &s5p_device_mixer,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+ &s5p_device_cec,
+#endif
+#endif
+ &s3c_device_i2c0,
+#ifdef CONFIG_MPU_SENSORS_MPU6050
+ &s3c_device_i2c1,
+#endif
+ &s3c_device_i2c3,
+ &s3c_device_i2c4,
+ &s3c_device_i2c5,
+ &s3c_device_i2c7,
+
+#ifdef CONFIG_USB_EHCI_S5P
+ &s5p_device_ehci,
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+ &s5p_device_ohci,
+#endif
+
+#ifdef CONFIG_USB_S3C_OTGD
+ &s3c_device_usbgadget,
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+ &exynos_device_ss_udc,
+#endif
+
+#ifdef CONFIG_USB_XHCI_EXYNOS
+ &exynos_device_xhci,
+#endif
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+ &s3c_device_i2c17,
+#endif
+#if defined(CONFIG_STMPE811_ADC)
+ &s3c_device_i2c19,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+
+ &samsung_asoc_dma,
+ &samsung_asoc_idma,
+
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+ &exynos_device_c2c,
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ &exynos_device_spi1,
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ &exynos5_busfreq,
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU6050
+ &s3c_device_i2c11,
+#endif
+#ifdef CONFIG_SENSORS_BH1721FVC
+ &s3c_device_i2c12,
+#endif
+
+#ifdef CONFIG_SENSORS_SHT21
+ &s3c_device_i2c13,
+#endif
+
+#if defined(CONFIG_SAMSUNG_MHL)
+ &s3c_device_i2c15, /* MHL */
+#endif
+
+#ifdef CONFIG_30PIN_CONN
+ &sec_device_connector,
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ &exynos_device_rotator,
+#endif
+#ifdef CONFIG_BT_BCM43241
+ &bcm43241_bluetooth_device,
+#endif
+};
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct s5p_platform_tmu exynos_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 78,
+ .start_1st_throttle = 80,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110, /* temp to do tripping */
+ .start_emergency = 120, /* To protect chip,forcely kernel panic */
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000, /* 800MHz in KHz order */
+ .limit_2nd_throttle = 200000, /* 200MHz in KHz order */
+ },
+};
+
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#if defined(CONFIG_CMA)
+static void __init exynos_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+ {
+ .name = "ion",
+ .size = 256 * SZ_1M,
+ .start = 0
+ },
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC0
+ {
+ .name = "gsc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC1
+ {
+ .name = "gsc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC1 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC2
+ {
+ .name = "gsc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC2 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC3
+ {
+ .name = "gsc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC3 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE0
+ {
+ .name = "flite0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE1
+ {
+ .name = "flite1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE1 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ {
+ .name = "fw",
+ .size = 2 << 20,
+ { .alignment = 128 << 10 },
+ .start = 0x44000000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV
+ {
+ .name = "tv",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_ROT
+ {
+ .name = "rot",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_ROT * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ {
+ .name = "fimc_is",
+ .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+ static const char map[] __initconst =
+#ifdef CONFIG_EXYNOS_C2C
+ "samsung-c2c=c2c_shdmem;"
+#endif
+ "s3cfb.0=fimd;"
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ "samsung-rp=srp;"
+#endif
+ "exynos-gsc.0=gsc0;exynos-gsc.1=gsc1;exynos-gsc.2=gsc2;exynos-gsc.3=gsc3;"
+ "exynos-fimc-lite.0=flite0;exynos-fimc-lite.1=flite1;"
+ "ion-exynos=ion,gsc0,gsc1,gsc2,gsc3,flite0,flite1,fimd,fw,rot;"
+ "exynos-rot=rot;"
+ "s5p-mfc-v6/f=fw;"
+ "s5p-mixer=tv;"
+ "exynos5-fimc-is=fimc_is;";
+
+ s5p_cma_region_reserve(regions, NULL, 0, map);
+}
+#else /* !CONFIG_CMA */
+static inline void exynos_reserve_mem(void)
+{
+}
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+static void __init smdk5250_camera_gpio_cfg(void)
+{
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, CLK_OUT */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPH0(0), 4, S3C_GPIO_SFN(2));
+ /* CAM A port(b0010) : DATA[0-7] */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPH1(0), 8, S3C_GPIO_SFN(2));
+ /* CAM B port(b0010) : PCLK, BAY_RGB[0-6] */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPG0(0), 8, S3C_GPIO_SFN(2));
+ /* CAM B port(b0010) : BAY_Vsync, BAY_RGB[7-13] */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPG1(0), 8, S3C_GPIO_SFN(2));
+ /* CAM B port(b0010) : BAY_Hsync, BAY_MCLK */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPG2(0), 2, S3C_GPIO_SFN(2));
+ /* This is externel interrupt for m5mo */
+#ifdef CONFIG_VIDEO_M5MOLS
+ s3c_gpio_cfgpin(EXYNOS5_GPX2(6), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
+#endif
+}
+#endif
+
+#if defined(CONFIG_VIDEO_EXYNOS_GSCALER) && defined(CONFIG_VIDEO_EXYNOS_FIMC_LITE)
+#if defined(CONFIG_VIDEO_S5K4BA)
+static struct exynos_isp_info s5k4ba = {
+ .board_info = &s5k4ba_info,
+ .cam_srclk_name = "xxti",
+ .clk_frequency = 24000000UL,
+ .bus_type = CAM_TYPE_ITU,
+#ifdef CONFIG_ITU_A
+ .cam_clk_name = "sclk_cam0",
+ .i2c_bus_num = 4,
+ .cam_port = CAM_PORT_A, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_ITU_B
+ .cam_clk_name = "sclk_cam1",
+ .i2c_bus_num = 5,
+ .cam_port = CAM_PORT_B, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = CAM_CLK_INV_VSYNC,
+};
+/* This is for platdata of fimc-lite */
+static struct s3c_platform_camera flite_s5k4ba = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+#if defined(CONFIG_VIDEO_M5MOLS)
+static struct exynos_isp_info m5mols = {
+ .board_info = &m5mols_board_info,
+ .cam_srclk_name = "xxti",
+ .clk_frequency = 24000000UL,
+ .bus_type = CAM_TYPE_MIPI,
+#ifdef CONFIG_CSI_C
+ .cam_clk_name = "sclk_cam0",
+ .i2c_bus_num = 4,
+ .cam_port = CAM_PORT_A, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_CSI_D
+ .cam_clk_name = "sclk_cam1",
+ .i2c_bus_num = 5,
+ .cam_port = CAM_PORT_B, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = CAM_CLK_INV_PCLK | CAM_CLK_INV_VSYNC,
+ .csi_data_align = 32,
+};
+/* This is for platdata of fimc-lite */
+static struct s3c_platform_camera flite_m5mo = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+
+static void __set_gsc_camera_config(struct exynos_platform_gscaler *data,
+ u32 active_index, u32 preview,
+ u32 camcording, u32 max_cam)
+{
+ data->active_cam_index = active_index;
+ data->cam_preview = preview;
+ data->cam_camcording = camcording;
+ data->num_clients = max_cam;
+}
+
+static void __set_flite_camera_config(struct exynos_platform_flite *data,
+ u32 active_index, u32 max_cam)
+{
+ data->active_cam_index = active_index;
+ data->num_clients = max_cam;
+}
+
+static void __init smdk5250_set_camera_platdata(void)
+{
+ int gsc_cam_index = 0;
+ int flite0_cam_index = 0;
+ int flite1_cam_index = 0;
+#if defined(CONFIG_VIDEO_M5MOLS)
+ exynos_gsc0_default_data.isp_info[gsc_cam_index++] = &m5mols;
+#if defined(CONFIG_CSI_C)
+ exynos_flite0_default_data.cam[flite0_cam_index] = &flite_m5mo;
+ exynos_flite0_default_data.isp_info[flite0_cam_index] = &m5mols;
+ flite0_cam_index++;
+#endif
+#if defined(CONFIG_CSI_D)
+ exynos_flite1_default_data.cam[flite1_cam_index] = &flite_m5mo;
+ exynos_flite1_default_data.isp_info[flite1_cam_index] = &m5mols;
+ flite1_cam_index++;
+#endif
+#endif
+ /* flite platdata register */
+ __set_flite_camera_config(&exynos_flite0_default_data, 0, flite0_cam_index);
+ __set_flite_camera_config(&exynos_flite1_default_data, 0, flite1_cam_index);
+
+ /* gscaler platdata register */
+ /* GSC-0 */
+ __set_gsc_camera_config(&exynos_gsc0_default_data, 0, 1, 0, gsc_cam_index);
+
+ /* GSC-1 */
+ /* GSC-2 */
+ /* GSC-3 */
+}
+#endif /* CONFIG_VIDEO_EXYNOS_GSCALER */
+
+static void __init p10_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdk5250_uartcfgs, ARRAY_SIZE(smdk5250_uartcfgs));
+ exynos_reserve_mem();
+
+#if defined(CONFIG_SEC_DEBUG)
+ /* as soon as INFORM6 is visible, sec_debug is ready to run */
+ sec_debug_init();
+#endif
+}
+
+#ifdef CONFIG_EXYNOS_DEV_SYSMMU
+static void __init exynos_sysmmu_init(void)
+{
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ platform_set_sysmmu(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_lr).dev, &s5p_device_mfc.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+ platform_set_sysmmu(&SYSMMU_PLATDEV(tv).dev, &s5p_device_mixer.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc0).dev,
+ &exynos5_device_gsc0.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc1).dev,
+ &exynos5_device_gsc1.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc2).dev,
+ &exynos5_device_gsc2.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc3).dev,
+ &exynos5_device_gsc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ platform_set_sysmmu(&SYSMMU_PLATDEV(camif0).dev,
+ &exynos_device_flite0.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(camif1).dev,
+ &exynos_device_flite1.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ platform_set_sysmmu(&SYSMMU_PLATDEV(rot).dev,
+ &exynos_device_rotator.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ platform_set_sysmmu(&SYSMMU_PLATDEV(2d).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ platform_set_sysmmu(&SYSMMU_PLATDEV(isp).dev,
+ &exynos5_device_fimc_is.dev);
+#endif
+}
+#else /* !CONFIG_EXYNOS_DEV_SYSMMU */
+static inline void exynos_sysmmu_init(void)
+{
+}
+#endif
+
+static void p10_power_off(void)
+{
+ printk(KERN_EMERG "%s: set PS_HOLD low\n", __func__);
+
+ writel(readl(EXYNOS5_PS_HOLD_CONTROL) & 0xFFFFFEFF, EXYNOS5_PS_HOLD_CONTROL);
+ printk(KERN_EMERG "%s: Should not reach here\n", __func__);
+}
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct platform_device s3c_device_extdsp = {
+ .name = "s3cfb_extdsp",
+ .id = 0,
+};
+
+static struct s3cfb_extdsp_lcd dummy_buffer = {
+ .width = 1920,
+ .height = 1080,
+ .bpp = 16,
+};
+
+static struct s3c_platform_fb default_extdsp_data __initdata = {
+ .hw_ver = 0x70,
+ .nr_wins = 1,
+ .default_win = 0,
+ .swap = FB_SWAP_WORD | FB_SWAP_HWORD,
+ .lcd = &dummy_buffer
+};
+
+void __init s3cfb_extdsp_set_platdata(struct s3c_platform_fb *pd)
+{
+ struct s3c_platform_fb *npd;
+ int i;
+
+ if (!pd)
+ pd = &default_extdsp_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ for (i = 0; i < npd->nr_wins; i++)
+ npd->nr_buffers[i] = 1;
+ s3c_device_extdsp.dev.platform_data = npd;
+ }
+}
+#endif
+
+static void camera_init(void)
+{
+ camera_class = class_create(THIS_MODULE, "camera");
+
+ if (IS_ERR(camera_class))
+ pr_err("Failed to create class(camera)!\n");
+}
+
+static void __init p10_machine_init(void)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi1_dev = &exynos_device_spi1.dev;
+#endif
+ pm_power_off = p10_power_off;
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ exynos_dwmci_set_platdata(&exynos5_dwmci0_pdata, 0);
+ dev_set_name(&exynos_device_dwmci0.dev, "s3c-sdhci.0");
+ clk_add_alias("dwmci", "dw_mmc.0", "hsmmc",
+ &exynos_device_dwmci0.dev);
+ clk_add_alias("sclk_dwmci", "dw_mmc.0", "sclk_mmc",
+ &exynos_device_dwmci0.dev);
+
+ exynos_dwmci_set_platdata(&exynos5_dwmci1_pdata, 1);
+ dev_set_name(&exynos_device_dwmci1.dev, "s3c-sdhci.1");
+ clk_add_alias("dwmci", "dw_mmc.1", "hsmmc",
+ &exynos_device_dwmci1.dev);
+ clk_add_alias("sclk_dwmci", "dw_mmc.1", "sclk_mmc",
+ &exynos_device_dwmci1.dev);
+
+ exynos_dwmci_set_platdata(&exynos5_dwmci2_pdata, 2);
+ dev_set_name(&exynos_device_dwmci2.dev, "s3c-sdhci.2");
+ clk_add_alias("dwmci", "dw_mmc.2", "hsmmc",
+ &exynos_device_dwmci2.dev);
+ clk_add_alias("sclk_dwmci", "dw_mmc.2", "sclk_mmc",
+ &exynos_device_dwmci2.dev);
+ } else {
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ exynos_dwmci_set_platdata(&exynos_dwmci_pdata, 0);
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdk5250_hsmmc0_pdata);
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdk5250_hsmmc1_pdata);
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdk5250_hsmmc2_pdata);
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdk5250_hsmmc3_pdata);
+#endif
+ }
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#ifdef CONFIG_LEDS_SPFCW043
+ platform_device_register(&s3c_device_spfcw043_led);
+#endif
+
+#ifdef CONFIG_FB_S3C
+ dev_set_name(&s5p_device_fimd1.dev, "s3cfb.1");
+ clk_add_alias("lcd", "exynos5-fb.1", "lcd", &s5p_device_fimd1.dev);
+ clk_add_alias("sclk_fimd", "exynos5-fb.1", "sclk_fimd",
+ &s5p_device_fimd1.dev);
+ s5p_fb_setname(1, "exynos5-fb");
+
+ s5p_fimd1_set_platdata(&p10_lcd1_pdata);
+#endif
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+ s3cfb_extdsp_set_platdata(&default_extdsp_data);
+#endif
+
+#ifdef CONFIG_BACKLIGHT_PWM
+ samsung_bl_set(&p10_bl_gpio_info, &p10_bl_data);
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+ smdk5250_ehci_init();
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+ smdk5250_ohci_init();
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS5250)
+ set_usb3_en(1);
+#endif
+
+#ifdef CONFIG_USB_S3C_OTGD
+ smdk5250_usbgadget_init();
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+ smdk5250_ss_udc_init();
+#endif
+
+#ifdef CONFIG_USB_XHCI_EXYNOS
+ smdk5250_xhci_init();
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ s5p_device_mfc.dev.parent = &exynos5_device_pd[PD_MFC].dev;
+#endif
+ s5p_mfc_set_platdata(&smdk5250_mfc_pd);
+
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc-v6", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc-v6");
+#endif
+
+#ifdef CONFIG_FB_S3C
+ s5p_device_fimd1.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+#endif
+
+#ifdef CONFIG_S5P_DP
+ s5p_dp_set_platdata(&p10_dp_data);
+#endif
+
+#ifdef CONFIG_S3C_ADC
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ platform_device_register(&s3c_device_adc);
+#ifdef CONFIG_S3C_DEV_HWMON
+ platform_device_register(&s3c_device_hwmon);
+#endif
+ }
+#endif
+
+#ifdef CONFIG_S3C_DEV_HWMON
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ s3c_hwmon_set_platdata(&smdk5250_hwmon_pdata);
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#endif
+
+ exynos_sysmmu_init();
+
+ p10_config_gpio_table();
+
+ exynos5_sleep_gpio_table_set = p10_config_sleep_gpio_table;
+
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+#ifdef CONFIG_MPU_SENSORS_MPU6050
+ pr_info("MPU6050 I2C-1 Init\n");
+ //magnetic_init();
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+#endif
+
+ p10_tsp_init();
+ p10_key_init();
+
+ s3c_i2c5_set_platdata(NULL);
+ i2c_register_board_info(5, i2c_devs5, ARRAY_SIZE(i2c_devs5));
+
+ midas_sound_init();
+
+#ifdef CONFIG_MPU_SENSORS_MPU6050
+ magnetic_init();
+ i2c_register_board_info(11, i2c_devs11, ARRAY_SIZE(i2c_devs11));
+#endif
+
+#ifdef CONFIG_SENSORS_BH1721FVC
+ light_sensor_init();
+ i2c_register_board_info(12, i2c_bh1721_emul, ARRAY_SIZE(i2c_bh1721_emul));
+#endif
+
+#ifdef CONFIG_SENSORS_SHT21
+ i2c_register_board_info(13, i2c_devs13, ARRAY_SIZE(i2c_devs13));
+#endif
+
+#if defined(CONFIG_SAMSUNG_MHL)
+ i2c_register_board_info(15, i2c_devs15_emul,
+ ARRAY_SIZE(i2c_devs15_emul));
+#endif
+
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+ isa1200_init();
+ i2c_register_board_info(17, i2c_devs17,
+ ARRAY_SIZE(i2c_devs17));
+#endif
+
+#if defined(CONFIG_STMPE811_ADC)
+ i2c_register_board_info(19, i2c_devs19_emul,
+ ARRAY_SIZE(i2c_devs19_emul));
+#endif
+#if defined(CONFIG_BATTERY_SAMSUNG_P1X)
+ p10_battery_init();
+#endif
+
+ platform_device_register(&vbatt_device);
+
+ platform_add_devices(p10_devices, ARRAY_SIZE(p10_devices));
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_MACH_P10_DP_01)
+#if defined(CONFIG_DP_40HZ_P10)
+ exynos4_fimd_setup_clock(&s5p_device_fimd1.dev, "sclk_fimd", "sclk_vpll",
+ 180 * MHZ);
+#elif defined(CONFIG_DP_60HZ_P10)
+ exynos4_fimd_setup_clock(&s5p_device_fimd1.dev, "sclk_fimd", "sclk_vpll",
+ 270 * MHZ);
+#endif
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_MIPI_CSIS
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ s5p_device_mipi_csis0.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ s5p_device_mipi_csis1.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+ s3c_set_platdata(&s5p_mipi_csis0_default_data,
+ sizeof(s5p_mipi_csis0_default_data), &s5p_device_mipi_csis0);
+ s3c_set_platdata(&s5p_mipi_csis1_default_data,
+ sizeof(s5p_mipi_csis1_default_data), &s5p_device_mipi_csis1);
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ exynos_device_flite0.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos_device_flite1.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos_device_flite2.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+ smdk5250_camera_gpio_cfg();
+ smdk5250_set_camera_platdata();
+ s3c_set_platdata(&exynos_flite0_default_data,
+ sizeof(exynos_flite0_default_data), &exynos_device_flite0);
+ s3c_set_platdata(&exynos_flite1_default_data,
+ sizeof(exynos_flite1_default_data), &exynos_device_flite1);
+ s3c_set_platdata(&exynos_flite2_default_data,
+ sizeof(exynos_flite2_default_data), &exynos_device_flite2);
+
+/* In EVT0, for using camclk, gscaler clock should be enabled */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ dev_set_name(&exynos_device_flite0.dev, "exynos-gsc.0");
+ clk_add_alias("gscl", "exynos-fimc-lite.0", "gscl",
+ &exynos_device_flite0.dev);
+ dev_set_name(&exynos_device_flite0.dev, "exynos-fimc-lite.0");
+
+ dev_set_name(&exynos_device_flite1.dev, "exynos-gsc.0");
+ clk_add_alias("gscl", "exynos-fimc-lite.1", "gscl",
+ &exynos_device_flite1.dev);
+ dev_set_name(&exynos_device_flite1.dev, "exynos-fimc-lite.1");
+ }
+#endif
+
+#if defined CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ dev_set_name(&exynos5_device_fimc_is.dev, "s5p-mipi-csis.0");
+ clk_add_alias("gscl_wrap0", "exynos5-fimc-is", "gscl_wrap0", &exynos5_device_fimc_is.dev);
+ clk_add_alias("sclk_gscl_wrap0", "exynos5-fimc-is", "sclk_gscl_wrap0", &exynos5_device_fimc_is.dev);
+ dev_set_name(&exynos5_device_fimc_is.dev, "s5p-mipi-csis.1");
+ clk_add_alias("gscl_wrap1", "exynos5-fimc-is", "gscl_wrap1", &exynos5_device_fimc_is.dev);
+ clk_add_alias("sclk_gscl_wrap1", "exynos5-fimc-is", "sclk_gscl_wrap1", &exynos5_device_fimc_is.dev);
+ dev_set_name(&exynos5_device_fimc_is.dev, "exynos-gsc.0");
+ clk_add_alias("gscl", "exynos5-fimc-is", "gscl", &exynos5_device_fimc_is.dev);
+ dev_set_name(&exynos5_device_fimc_is.dev, "exynos5-fimc-is");
+
+#if defined CONFIG_VIDEO_S5K6A3
+ exynos5_fimc_is_data.sensor_info[s5k6a3.sensor_position] = &s5k6a3;
+ printk("add s5k6a3 sensor info(pos : %d)\n", s5k6a3.sensor_position);
+#endif
+#if defined CONFIG_VIDEO_S5K4E5
+ exynos5_fimc_is_data.sensor_info[s5k4e5.sensor_position] = &s5k4e5;
+ printk("add s5k4e5 sensor info(pos : %d)\n", s5k4e5.sensor_position);
+#endif
+
+ exynos5_fimc_is_set_platdata(&exynos5_fimc_is_data);
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ exynos5_device_pd[PD_ISP].dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_fimc_is.dev.parent = &exynos5_device_pd[PD_ISP].dev;
+#endif
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(&exynos_tmu_data);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ exynos5_device_gsc0.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_gsc1.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_gsc2.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_gsc3.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ exynos5_gsc_set_pdev_name(0, "exynos5250-gsc");
+ exynos5_gsc_set_pdev_name(1, "exynos5250-gsc");
+ exynos5_gsc_set_pdev_name(2, "exynos5250-gsc");
+ exynos5_gsc_set_pdev_name(3, "exynos5250-gsc");
+ }
+
+ s3c_set_platdata(&exynos_gsc0_default_data, sizeof(exynos_gsc0_default_data),
+ &exynos5_device_gsc0);
+ s3c_set_platdata(&exynos_gsc1_default_data, sizeof(exynos_gsc1_default_data),
+ &exynos5_device_gsc1);
+ s3c_set_platdata(&exynos_gsc2_default_data, sizeof(exynos_gsc2_default_data),
+ &exynos5_device_gsc2);
+ s3c_set_platdata(&exynos_gsc3_default_data, sizeof(exynos_gsc3_default_data),
+ &exynos5_device_gsc3);
+ /* Gscaler can use MPLL(266MHz) or VPLL(300MHz).
+ In case of P10, Gscaler should use MPLL(266MHz) because FIMD uses VPLL(86MHz).
+ So mout_aclk_300_gscl_mid selects mout_mpll_user and then
+ mout_aclk_300_gscl_mid is set to 267MHz
+ even though the clock name(dout_aclk_300_gscl) implies and requires around 300MHz
+ */
+ exynos5_gsc_set_parent_clock("mout_aclk_300_gscl_mid", "mout_mpll_user");
+ exynos5_gsc_set_parent_clock("mout_aclk_300_gscl", "mout_aclk_300_gscl_mid");
+ exynos5_gsc_set_parent_clock("aclk_300_gscl", "dout_aclk_300_gscl");
+ exynos5_gsc_set_clock_rate("dout_aclk_300_gscl", 267000000);
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+ exynos_c2c_set_platdata(&smdk5250_c2c_pdata);
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ exynos5_jpeg_setup_clock(&s5p_device_jpeg.dev, 150000000);
+#endif
+
+#if defined(CONFIG_VIDEO_EXYNOS_TV) && defined(CONFIG_VIDEO_EXYNOS_HDMI)
+ dev_set_name(&s5p_device_hdmi.dev, "exynos5-hdmi");
+ clk_add_alias("hdmi", "s5p-hdmi", "hdmi", &s5p_device_hdmi.dev);
+ clk_add_alias("hdmiphy", "s5p-hdmi", "hdmiphy", &s5p_device_hdmi.dev);
+
+ s5p_tv_setup();
+
+/* setup dependencies between TV devices */
+ /* This will be added after power domain for exynos5 is developed */
+ s5p_device_hdmi.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+ s5p_device_mixer.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+
+ s5p_i2c_hdmiphy_set_platdata(NULL);
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#endif
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ sclk = clk_get(spi1_dev, "sclk_spi1");
+ if (IS_ERR(sclk))
+ dev_err(spi1_dev, "failed to get sclk for SPI-1\n");
+ prnt = clk_get(spi1_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi1_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(GPIO_5M_SPI_CS, "SPI_CS1")) {
+ gpio_direction_output(GPIO_5M_SPI_CS, 1);
+ s3c_gpio_cfgpin(GPIO_5M_SPI_CS, S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(GPIO_5M_SPI_CS, S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi1_csi));
+ }
+
+ spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info));
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_C], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_R1], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_L], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_RIGHT0_BUS], &exynos5_busfreq.dev);
+#endif
+#ifdef CONFIG_30PIN_CONN
+ acc_con_gpio_init();
+#endif
+
+ /* for BRCM Wi-Fi */
+ brcm_wlan_init();
+
+ /* for camera*/
+ camera_init();
+
+ register_reboot_notifier(&exynos5_reboot_notifier);
+}
+
+#ifdef CONFIG_EXYNOS_C2C
+static void __init exynos_c2c_reserve(void)
+{
+ static struct cma_region regions[] = {
+ {
+ .name = "c2c_shdmem",
+ .size = 64 * SZ_1M,
+ { .alignment = 64 * SZ_1M },
+ .start = C2C_SHAREDMEM_BASE
+ }, {
+ .size = 0,
+ }
+ };
+
+ s5p_cma_region_reserve(regions, NULL, 0, map);
+}
+#endif
+
+#if defined(CONFIG_SEC_DEBUG)
+static void __init exynos_init_reserve(void)
+{
+ sec_debug_magic_init();
+}
+#endif
+
+MACHINE_START(SMDK5250, "SMDK5250")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos5_init_irq,
+ .map_io = p10_map_io,
+ .init_machine = p10_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+#if defined(CONFIG_SEC_DEBUG)
+ .init_early = &exynos_init_reserve,
+#endif
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-p4notepq.c b/arch/arm/mach-exynos/mach-p4notepq.c
new file mode 100644
index 0000000..fc349c1
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-p4notepq.c
@@ -0,0 +1,2561 @@
+/* linux/arch/arm/mach-exynos/mach-smdk4212.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/pwm_backlight.h>
+#include <linux/input.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#ifdef CONFIG_LEDS_AAT1290A
+#include <linux/leds-aat1290a.h>
+#endif
+
+#ifdef CONFIG_MFD_MAX77693
+#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-private.h>
+#include <linux/leds-max77693.h>
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_PX
+#include <linux/power/max17042_fuelgauge_px.h>
+#endif
+#ifdef CONFIG_SMB347_CHARGER
+#include <linux/power/smb347_charger.h>
+#endif
+#ifdef CONFIG_BATTERY_SEC_PX
+#include <linux/power/sec_battery_px.h>
+#endif
+#include <linux/power_supply.h>
+#ifdef CONFIG_STMPE811_ADC
+#include <linux/stmpe811-adc.h>
+#endif
+#include <linux/v4l2-mediabus.h>
+#include <linux/memblock.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/keypad.h>
+#include <plat/devs.h>
+#include <plat/fb-s5p.h>
+#include <plat/fb-core.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/backlight.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#include <plat/s3c64xx-spi.h>
+#include <plat/tvout.h>
+#include <plat/csis.h>
+#include <plat/media.h>
+#include <plat/adc.h>
+#include <media/exynos_fimc_is.h>
+#include <mach/exynos-ion.h>
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#include <mach/tdmb_pdata.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/spi-clocks.h>
+
+#include <mach/dev.h>
+#include <mach/ppmu.h>
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+#include <plat/s5p-tmu.h>
+#include <mach/regs-tmu.h>
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+#include <mach/c2c.h>
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+
+#include <plat/fb-s5p.h>
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct s3cfb_extdsp_lcd {
+ int width;
+ int height;
+ int bpp;
+};
+#endif
+#include <mach/dev-sysmmu.h>
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#include <plat/jpeg.h>
+#endif
+
+#include <plat/fimg2d.h>
+#include <plat/s5p-sysmmu.h>
+
+#include <mach/sec_debug.h>
+
+#include <mach/p4-input.h>
+
+#include <mach/midas-power.h>
+#ifdef CONFIG_SEC_THERMISTOR
+#include <mach/sec_thermistor.h>
+#endif
+#include <mach/midas-thermistor.h>
+#include <mach/midas-tsp.h>
+#include <mach/regs-clock.h>
+
+#include <mach/midas-lcd.h>
+#include <mach/midas-sound.h>
+#if defined(CONFIG_SEC_DEV_JACK)
+#include <mach/p4note-jack.h>
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#include <linux/pm_runtime.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+#include <mach/usb_switch.h>
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI)
+#include <linux/phone_svn/ipc_spi.h>
+#include <linux/irq.h>
+#endif
+
+#ifdef CONFIG_30PIN_CONN
+#include <linux/30pin_con.h>
+#endif
+
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+#include <linux/isa1200_vibrator.h>
+#endif
+
+#include "board-mobile.h"
+
+extern int s6c1372_panel_gpio_init(void);
+
+/* cable state */
+bool is_cable_attached;
+bool is_usb_lpm_enter;
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK4212_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK4212_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK4212_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+#define SMDK4212_UFCON_GPS (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG8 | \
+ S5PV210_UFCON_RXTRIG32)
+
+static struct s3c2410_uartcfg smdk4212_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_GPS,
+ .set_runstate = set_gps_uart_op,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK4212_UCON_DEFAULT,
+ .ulcon = SMDK4212_ULCON_DEFAULT,
+ .ufcon = SMDK4212_UFCON_DEFAULT,
+ },
+};
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(5),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+ {
+ .modalias = "s5c73m3_spi",
+ .platform_data = NULL,
+ .max_speed_hz = 50000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi1_csi[0],
+ }
+};
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI) \
+ || defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+static struct s3c64xx_spi_csinfo spi2_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPC1(2),
+ .set_level = gpio_set_value,
+ },
+};
+
+static struct spi_board_info spi2_board_info[] __initdata = {
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {
+ .modalias = "tdmbspi",
+ .platform_data = NULL,
+ .max_speed_hz = 5000000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi2_csi[0],
+ },
+#else
+ {
+ .modalias = "ipc_spi",
+ .platform_data = NULL,
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 12*1000*1000,
+ .mode = SPI_MODE_1,
+ .controller_data = &spi2_csi[0],
+ }
+#endif
+};
+#endif
+#endif
+
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+static void tdmb_set_config_poweron(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_SFN(GPIO_TDMB_INT_AF));
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+}
+static void tdmb_set_config_poweroff(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_INT, GPIO_LEVEL_LOW);
+}
+
+static void tdmb_gpio_on(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_on\n");
+
+ tdmb_set_config_poweron();
+
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+ usleep_range(1000, 1000);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_HIGH);
+}
+
+static void tdmb_gpio_off(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_off\n");
+
+ tdmb_set_config_poweroff();
+
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+}
+
+static struct tdmb_platform_data tdmb_pdata = {
+ .gpio_on = tdmb_gpio_on,
+ .gpio_off = tdmb_gpio_off,
+};
+
+static struct platform_device tdmb_device = {
+ .name = "tdmb",
+ .id = -1,
+ .dev = {
+ .platform_data = &tdmb_pdata,
+ },
+};
+
+static int __init tdmb_dev_init(void)
+{
+ tdmb_set_config_poweroff();
+ s5p_register_gpio_interrupt(GPIO_TDMB_INT);
+ tdmb_pdata.irq = GPIO_TDMB_IRQ;
+ platform_device_register(&tdmb_device);
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI)
+static void ipc_spi_cfg_gpio(void);
+
+static struct ipc_spi_platform_data ipc_spi_data = {
+ .gpio_ipc_mrdy = GPIO_IPC_MRDY,
+ .gpio_ipc_srdy = GPIO_IPC_SRDY,
+ .gpio_ipc_sub_mrdy = GPIO_IPC_SUB_MRDY,
+ .gpio_ipc_sub_srdy = GPIO_IPC_SUB_SRDY,
+
+ .cfg_gpio = ipc_spi_cfg_gpio,
+};
+
+static struct resource ipc_spi_res[] = {
+ [0] = {
+ .start = IRQ_IPC_SRDY,
+ .end = IRQ_IPC_SRDY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ipc_spi_device = {
+ .name = "onedram",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ipc_spi_res),
+ .resource = ipc_spi_res,
+ .dev = {
+ .platform_data = &ipc_spi_data,
+ },
+};
+
+static void ipc_spi_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_ipc_mrdy = ipc_spi_data.gpio_ipc_mrdy;
+ unsigned gpio_ipc_srdy = ipc_spi_data.gpio_ipc_srdy;
+ unsigned gpio_ipc_sub_mrdy = ipc_spi_data.gpio_ipc_sub_mrdy;
+ unsigned gpio_ipc_sub_srdy = ipc_spi_data.gpio_ipc_sub_srdy;
+
+ err = gpio_request(gpio_ipc_mrdy, "IPC_MRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_MRDY", err);
+ } else {
+ gpio_direction_output(gpio_ipc_mrdy, 0);
+ s3c_gpio_setpull(gpio_ipc_mrdy, S3C_GPIO_PULL_DOWN);
+ }
+
+ err = gpio_request(gpio_ipc_srdy, "IPC_SRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SRDY", err);
+ } else {
+ gpio_direction_input(gpio_ipc_srdy);
+ s3c_gpio_cfgpin(gpio_ipc_srdy, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_srdy, S3C_GPIO_PULL_NONE);
+ }
+
+ err = gpio_request(gpio_ipc_sub_mrdy, "IPC_SUB_MRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SUB_MRDY", err);
+ } else {
+ gpio_direction_output(gpio_ipc_sub_mrdy, 0);
+ s3c_gpio_setpull(gpio_ipc_sub_mrdy, S3C_GPIO_PULL_DOWN);
+ }
+
+ err = gpio_request(gpio_ipc_sub_srdy, "IPC_SUB_SRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SUB_SRDY", err);
+ } else {
+ gpio_direction_input(gpio_ipc_sub_srdy);
+ s3c_gpio_cfgpin(gpio_ipc_sub_srdy, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_sub_srdy, S3C_GPIO_PULL_NONE);
+ }
+
+ irq_set_irq_type(gpio_to_irq(GPIO_IPC_SRDY), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(GPIO_IPC_SUB_SRDY), IRQ_TYPE_EDGE_RISING);
+}
+#endif
+
+#ifdef CONFIG_LEDS_AAT1290A
+static int aat1290a_initGpio(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_CAM_SW_EN, "CAM_SW_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request CAM_SW_EN\n");
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_CAM_SW_EN, 1);
+ gpio_set_value(GPIO_CAM_SW_EN, 1);
+
+ return 0;
+}
+
+static void aat1290a_switch(int enable)
+{
+ gpio_set_value(GPIO_CAM_SW_EN, enable);
+}
+
+static int aat1290a_setGpio(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_TORCH_EN, "TORCH_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request TORCH_EN\n");
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_TORCH_EN, 1);
+ err = gpio_request(GPIO_TORCH_SET, "TORCH_SET");
+ if (err) {
+ printk(KERN_ERR "failed to request TORCH_SET\n");
+ gpio_free(GPIO_TORCH_EN);
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_TORCH_SET, 1);
+ gpio_set_value(GPIO_TORCH_EN, 0);
+ gpio_set_value(GPIO_TORCH_SET, 0);
+
+ return 0;
+}
+
+static int aat1290a_freeGpio(void)
+{
+ gpio_free(GPIO_TORCH_EN);
+ gpio_free(GPIO_TORCH_SET);
+
+ return 0;
+}
+
+static void aat1290a_torch_en(int onoff)
+{
+ gpio_set_value(GPIO_TORCH_EN, onoff);
+}
+
+static void aat1290a_torch_set(int onoff)
+{
+ gpio_set_value(GPIO_TORCH_SET, onoff);
+}
+
+static struct aat1290a_led_platform_data aat1290a_led_data = {
+ .brightness = TORCH_BRIGHTNESS_50,
+ .status = STATUS_UNAVAILABLE,
+ .switch_sel = aat1290a_switch,
+ .initGpio = aat1290a_initGpio,
+ .setGpio = aat1290a_setGpio,
+ .freeGpio = aat1290a_freeGpio,
+ .torch_en = aat1290a_torch_en,
+ .torch_set = aat1290a_torch_set,
+};
+
+static struct platform_device s3c_device_aat1290a_led = {
+ .name = "aat1290a-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &aat1290a_led_data,
+ },
+};
+#endif
+
+static DEFINE_MUTEX(notify_lock);
+
+#define DEFINE_MMC_CARD_NOTIFIER(num) \
+static void (*hsmmc##num##_notify_func)(struct platform_device *, int state); \
+static int ext_cd_init_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func); \
+ hsmmc##num##_notify_func = notify_func; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+} \
+static int ext_cd_cleanup_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func != notify_func); \
+ hsmmc##num##_notify_func = NULL; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+}
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ DEFINE_MMC_CARD_NOTIFIER(3)
+#endif
+
+/*
+ * call this when you need sd stack to recognize insertion or removal of card
+ * that can't be told by SDHCI regs
+ */
+void mmc_force_presence_change(struct platform_device *pdev)
+{
+ void (*notify_func)(struct platform_device *, int state) = NULL;
+ mutex_lock(&notify_lock);
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ if (pdev == &s3c_device_hsmmc3)
+ notify_func = hsmmc3_notify_func;
+#endif
+
+ if (notify_func)
+ notify_func(pdev, 1);
+ else
+ pr_warn("%s: called for device with no notifier\n", __func__);
+ mutex_unlock(&notify_lock);
+}
+EXPORT_SYMBOL_GPL(mmc_force_presence_change);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdk4212_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdk4212_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdk4212_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = EXYNOS4_GPX3(4),
+ .ext_cd_gpio_invert = true,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .vmmc_name = "vtf_2.8v"
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdk4212_hsmmc3_pdata __initdata = {
+/* new code for brm4334 */
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+ .ext_cd_init = ext_cd_init_hsmmc3,
+ .ext_cd_cleanup = ext_cd_cleanup_hsmmc3,
+};
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+ .fifo_depth = 0x80,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50 | MMC_CAP_CMD23,
+ .host_caps2 = MMC_CAP2_PACKED_CMD,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_CMD23,
+#endif
+ .int_power_gpio = GPIO_eMMC_EN,
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdk4212_ehci_pdata;
+
+static void __init smdk4212_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk4212_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdk4212_ohci_pdata;
+
+static void __init smdk4212_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk4212_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdk4212_usbgadget_pdata;
+
+#include <linux/usb/android_composite.h>
+static void __init smdk4212_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdk4212_usbgadget_pdata;
+ struct android_usb_platform_data *android_pdata =
+ s3c_device_android_usb.dev.platform_data;
+ if (android_pdata) {
+ unsigned int newluns = 2;
+ printk(KERN_DEBUG "usb: %s: default luns=%d, new luns=%d\n",
+ __func__, android_pdata->nluns, newluns);
+ android_pdata->nluns = newluns;
+ } else {
+ printk(KERN_DEBUG "usb: %s android_pdata is not available\n",
+ __func__);
+ }
+
+ s5p_usbgadget_set_platdata(pdata);
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ pdata = s3c_device_usbgadget.dev.platform_data;
+ if (pdata) {
+ /* Squelch Threshold Tune [13:11] (111 : -20%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x7 << 11);
+ printk(KERN_DEBUG "usb: %s tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+ }
+#endif
+
+}
+#endif
+
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+};
+
+#ifdef CONFIG_S3C_DEV_I2C5
+static struct i2c_board_info i2c_devs5[] __initdata = {
+#ifdef CONFIG_REGULATOR_MAX8997
+ {
+ I2C_BOARD_INFO("max8997", (0xcc >> 1)),
+ .platform_data = &exynos4_max8997_info,
+ },
+#endif
+#if defined(CONFIG_REGULATOR_MAX77686)
+ /* max77686 on i2c5 other than M1 board */
+ {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ },
+#endif
+};
+#endif
+
+static struct i2c_board_info i2c_devs7[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX77686) /* max77686 on i2c7 with M1 board */
+ {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ },
+#endif
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+ {
+ I2C_BOARD_INFO("s5m87xx", 0xCC >> 1),
+ .platform_data = &exynos4_s5m8767_info,
+ .irq = IRQ_EINT(7),
+ },
+#endif
+};
+
+/* Bluetooth */
+#ifdef CONFIG_BT_BCM4334
+static struct platform_device bcm4334_bluetooth_device = {
+ .name = "bcm4334_bluetooth",
+ .id = -1,
+};
+#endif
+
+/* I2C9 */
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+};
+
+/* I2C10 */
+static struct i2c_board_info i2c_devs10_emul[] __initdata = {
+};
+
+/* I2C11 */
+static struct i2c_board_info i2c_devs11_emul[] __initdata = {
+};
+
+#ifdef CONFIG_SMB347_CHARGER
+struct smb_charger_callbacks *smb_callbacks;
+
+static void smb_charger_register_callbacks(struct smb_charger_callbacks *ptr)
+{
+ smb_callbacks = ptr;
+}
+
+static void smb_charger_unregister_callbacks(void)
+{
+ smb_callbacks = NULL;
+}
+
+static struct smb_charger_data smb_charger_pdata = {
+ .register_callbacks = smb_charger_register_callbacks,
+ .unregister_callbacks = smb_charger_unregister_callbacks,
+ .enable = GPIO_TA_EN,
+ .stat = GPIO_TA_nCHG,
+ .ta_nconnected = GPIO_TA_nCONNECTED,
+};
+
+/* I2C13 */
+static struct i2c_board_info i2c_devs13_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("smb347-charger", 0x0C >> 1),
+ .platform_data = &smb_charger_pdata,
+ },
+};
+
+static void __init smb_gpio_init(void)
+{
+ s3c_gpio_cfgpin(GPIO_TA_nCHG, S3C_GPIO_SFN(0xf));
+ /* external pull up */
+ s3c_gpio_setpull(GPIO_TA_nCHG, S3C_GPIO_PULL_NONE);
+ i2c_devs13_emul[0].irq = gpio_to_irq(GPIO_TA_nCHG);
+}
+
+static struct i2c_gpio_platform_data gpio_i2c_data13 = {
+ .sda_pin = GPIO_CHG_SDA,
+ .scl_pin = GPIO_CHG_SCL,
+};
+
+struct platform_device s3c_device_i2c13 = {
+ .name = "i2c-gpio",
+ .id = 13,
+ .dev.platform_data = &gpio_i2c_data13,
+};
+
+static void sec_bat_set_charging_state(int enable, int cable_status)
+{
+ if (smb_callbacks && smb_callbacks->set_charging_state)
+ smb_callbacks->set_charging_state(enable, cable_status);
+}
+
+static int sec_bat_get_charging_state(void)
+{
+ if (smb_callbacks && smb_callbacks->get_charging_state)
+ return smb_callbacks->get_charging_state();
+ else
+ return 0;
+}
+
+static void sec_bat_set_charging_current(int set_current)
+{
+ if (smb_callbacks && smb_callbacks->set_charging_current)
+ smb_callbacks->set_charging_current(set_current);
+}
+
+static int sec_bat_get_charging_current(void)
+{
+ if (smb_callbacks && smb_callbacks->get_charging_current)
+ return smb_callbacks->get_charging_current();
+ else
+ return 0;
+}
+
+static int sec_bat_get_charger_is_full(void)
+{
+ if (smb_callbacks && smb_callbacks->get_charger_is_full)
+ return smb_callbacks->get_charger_is_full();
+ else
+ return 0;
+}
+#endif
+
+static int check_bootmode(void)
+{
+ int inform2;
+
+ inform2 = __raw_readl(S5P_INFORM2);
+ if (inform2 == 0x1)
+ return 1;
+ else
+ return 0;
+}
+
+static int check_jig_on(void)
+{
+ /* check GPIO_IF_CON_SENSE pin */
+ if (system_rev >= 1)
+ return !gpio_get_value(GPIO_IF_CON_SENSE);
+ else
+ return 0;
+}
+
+/* I2C14 */
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_PX
+static struct i2c_gpio_platform_data gpio_i2c_data14 = {
+ .sda_pin = GPIO_FUEL_SDA,
+ .scl_pin = GPIO_FUEL_SCL,
+};
+
+struct platform_device s3c_device_i2c14 = {
+ .name = "i2c-gpio",
+ .id = 14,
+ .dev.platform_data = &gpio_i2c_data14,
+};
+
+static struct max17042_platform_data max17042_pdata = {
+ .sdi_capacity = 0x3730,
+ .sdi_vfcapacity = 0x4996,
+ .atl_capacity = 0x3022,
+ .atl_vfcapacity = 0x4024,
+ .sdi_low_bat_comp_start_vol = 3600,
+ .atl_low_bat_comp_start_vol = 3450,
+ .fuel_alert_line = GPIO_FUEL_ALERT,
+ .check_jig_status = check_jig_on
+};
+
+static struct i2c_board_info i2c_devs14_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("fuelgauge", 0x36),
+ .platform_data = &max17042_pdata,
+ },
+};
+#endif
+
+/* I2C15 */
+static struct i2c_gpio_platform_data gpio_i2c_data15 = {
+ .sda_pin = GPIO_MHL_SDA_1_8V,
+ .scl_pin = GPIO_MHL_SCL_1_8V,
+ .udelay = 3,
+ .timeout = 0,
+};
+
+struct platform_device s3c_device_i2c15 = {
+ .name = "i2c-gpio",
+ .id = 15,
+ .dev = {
+ .platform_data = &gpio_i2c_data15,
+ }
+};
+
+static struct i2c_board_info i2c_devs15_emul[] __initdata = {
+};
+
+/* I2C16 */
+static struct i2c_gpio_platform_data gpio_i2c_data16 = {
+ .sda_pin = GPIO_MHL_DSDA_2_8V,
+ .scl_pin = GPIO_MHL_DSCL_2_8V,
+};
+
+struct platform_device s3c_device_i2c16 = {
+ .name = "i2c-gpio",
+ .id = 16,
+ .dev.platform_data = &gpio_i2c_data16,
+};
+
+static struct i2c_board_info i2c_devs16_emul[] __initdata = {
+};
+
+#if 0
+static struct i2c_gpio_platform_data i2c18_platdata = {
+ .sda_pin = GPIO_8M_CAM_SDA_18V,
+ .scl_pin = GPIO_8M_CAM_SCL_18V,
+ .udelay = 2, /* 250 kHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c18 = {
+ .name = "i2c-gpio",
+ .id = 18,
+ .dev.platform_data = &i2c18_platdata,
+};
+
+/* I2C18 */
+/* No explicit i2c client array here. The channel number 18 is passed
+ to camera driver from midas-camera.c instead. */
+#endif
+
+#if defined(CONFIG_STMPE811_ADC) || defined(CONFIG_FM_SI4709_MODULE) \
+ || defined(CONFIG_FM_SI4705_MODULE)
+static struct i2c_gpio_platform_data gpio_i2c_data19 = {
+ .sda_pin = GPIO_ADC_SDA,
+ .scl_pin = GPIO_ADC_SCL,
+};
+
+struct platform_device s3c_device_i2c19 = {
+ .name = "i2c-gpio",
+ .id = 19,
+ .dev.platform_data = &gpio_i2c_data19,
+};
+
+
+/* I2C19 */
+static struct i2c_board_info i2c_devs19_emul[] __initdata = {
+#if defined(CONFIG_STMPE811_ADC)
+ {
+ I2C_BOARD_INFO("stmpe811-adc", (0x82 >> 1)),
+ .platform_data = &stmpe811_pdata,
+ },
+#endif
+#ifdef CONFIG_FM_SI4705_MODULE
+ {
+ I2C_BOARD_INFO("Si4709", (0x22 >> 1)),
+ },
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+ {
+ I2C_BOARD_INFO("Si4709", (0x20 >> 1)),
+ },
+#endif
+
+};
+#endif
+
+/* I2C21 */
+#ifdef CONFIG_LEDS_AN30259A
+static struct i2c_gpio_platform_data gpio_i2c_data21 = {
+ .scl_pin = GPIO_S_LED_I2C_SCL,
+ .sda_pin = GPIO_S_LED_I2C_SDA,
+};
+
+struct platform_device s3c_device_i2c21 = {
+ .name = "i2c-gpio",
+ .id = 21,
+ .dev.platform_data = &gpio_i2c_data21,
+};
+#endif
+
+/* I2C21 */
+static struct i2c_board_info i2c_devs21_emul[] __initdata = {
+#ifdef CONFIG_LEDS_AN30259A
+ {
+ I2C_BOARD_INFO("an30259a", 0x30),
+ },
+#endif
+};
+
+#ifdef CONFIG_I2C_GPIO
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+static void isa1200_init(void)
+{
+ int gpio;
+ gpio = GPIO_MOTOR_EN;
+ gpio_request(gpio, "MOTOR_EN");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+}
+static int isa1200_vdd_en(bool en)
+{
+ return gpio_direction_output(GPIO_MOTOR_EN, en);
+}
+
+static struct i2c_gpio_platform_data gpio_i2c_data17 = {
+ .sda_pin = GPIO_MOTOR_SDA,
+ .scl_pin = GPIO_MOTOR_SCL,
+};
+
+struct platform_device s3c_device_i2c17 = {
+ .name = "i2c-gpio",
+ .id = 17,
+ .dev.platform_data = &gpio_i2c_data17,
+};
+
+static struct isa1200_vibrator_platform_data isa1200_vibrator_pdata = {
+ .gpio_en = isa1200_vdd_en,
+ .max_timeout = 10000,
+ .ctrl0 = CTL0_DIVIDER128 | CTL0_PWM_INPUT,
+ .ctrl1 = CTL1_DEFAULT,
+ .ctrl2 = 0,
+ .ctrl4 = 0,
+ . pll = 0x23,
+ .duty = 0x71,
+ .period = 0x74,
+ .get_clk = NULL,
+ .pwm_id = 0,
+ .pwm_duty = 37000,
+ .pwm_period = 38675,
+};
+static struct i2c_board_info i2c_devs17_emul[] = {
+ {
+ I2C_BOARD_INFO("isa1200_vibrator", 0x48),
+ .platform_data = &isa1200_vibrator_pdata,
+ },
+};
+#endif /* CONFIG_MOTOR_DRV_ISA1200 */
+#endif
+
+#ifdef CONFIG_ANDROID_RAM_CONSOLE
+static struct resource ram_console_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device ram_console_device = {
+ .name = "ram_console",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ram_console_resource),
+ .resource = ram_console_resource,
+};
+
+static int __init setup_ram_console_mem(char *str)
+{
+ unsigned size = memparse(str, &str);
+
+ if (size && (*str == '@')) {
+ unsigned long long base = 0;
+
+ base = simple_strtoul(++str, &str, 0);
+ if (reserve_bootmem(base, size, BOOTMEM_EXCLUSIVE)) {
+ pr_err("%s: failed reserving size %d "
+ "at base 0x%llx\n", __func__, size, base);
+ return -1;
+ }
+
+ ram_console_resource[0].start = base;
+ ram_console_resource[0].end = base + size - 1;
+ pr_err("%s: %x at %llx\n", __func__, size, base);
+ }
+ return 0;
+}
+
+__setup("ram_console=", setup_ram_console_mem);
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_PX
+void sec_bat_gpio_init(void)
+{
+
+ s3c_gpio_cfgpin(GPIO_TA_nCONNECTED, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCONNECTED, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TA_nCHG, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCHG, S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(GPIO_TA_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TA_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TA_EN, 0);
+
+ gpio_request(GPIO_TA_nCHG, "TA_nCHG");
+ s5p_register_gpio_interrupt(GPIO_TA_nCHG);
+
+ pr_info("BAT : Battery GPIO initialized.\n");
+}
+
+static void sec_charger_cb(int set_cable_type)
+{
+ struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget);
+ bool cable_state_to_tsp;
+ bool cable_state_to_usb;
+
+ switch (set_cable_type) {
+ case CHARGER_USB:
+ cable_state_to_tsp = true;
+ cable_state_to_usb = true;
+ is_cable_attached = true;
+ is_usb_lpm_enter = false;
+ break;
+ case CHARGER_AC:
+ case CHARGER_DOCK:
+ case CHARGER_MISC:
+ cable_state_to_tsp = true;
+ cable_state_to_usb = false;
+ is_cable_attached = true;
+ is_usb_lpm_enter = true;
+ break;
+ case CHARGER_BATTERY:
+ case CHARGER_DISCHARGE:
+ default:
+ cable_state_to_tsp = false;
+ cable_state_to_usb = false;
+ is_cable_attached = false;
+ is_usb_lpm_enter = true;
+ break;
+ }
+ pr_info("%s:cable_type=%d,tsp(%d),usb(%d),attached(%d),usblpm(%d)\n",
+ __func__, set_cable_type, cable_state_to_tsp,
+ cable_state_to_usb, is_cable_attached, is_usb_lpm_enter);
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301)
+ synaptics_ts_charger_infom(is_cable_attached);
+#endif
+
+/* Send charger state to px-switch. px-switch needs cable type what USB or not */
+ set_usb_connection_state(!is_usb_lpm_enter);
+
+/* Send charger state to USB. USB needs cable type what USB data or not */
+ if (gadget) {
+ if (cable_state_to_usb)
+ usb_gadget_vbus_connect(gadget);
+ else
+ usb_gadget_vbus_disconnect(gadget);
+ }
+
+ pr_info("%s\n", __func__);
+}
+
+static struct sec_battery_platform_data sec_battery_platform = {
+ .charger = {
+ .enable_line = GPIO_TA_EN,
+ .connect_line = GPIO_TA_nCONNECTED,
+ .fullcharge_line = GPIO_TA_nCHG,
+ .accessory_line = GPIO_ACCESSORY_INT,
+ },
+#if defined(CONFIG_SMB347_CHARGER)
+ .set_charging_state = sec_bat_set_charging_state,
+ .get_charging_state = sec_bat_get_charging_state,
+ .set_charging_current = sec_bat_set_charging_current,
+ .get_charging_current = sec_bat_get_charging_current,
+ .get_charger_is_full = sec_bat_get_charger_is_full,
+#endif
+ .init_charger_gpio = sec_bat_gpio_init,
+ .inform_charger_connection = sec_charger_cb,
+
+#if defined(CONFIG_TARGET_LOCALE_USA)
+ .temp_high_threshold = 50000, /* 50c */
+ .temp_high_recovery = 42000, /* 42c */
+ .temp_low_recovery = 0, /* 0c */
+ .temp_low_threshold = -5000, /* -5c */
+#else
+ .temp_high_threshold = 50000, /* 50c */
+ .temp_high_recovery = 42000, /* 42c */
+ .temp_low_recovery = 0, /* 0c */
+ .temp_low_threshold = -5000, /* -5c */
+#endif
+ .recharge_voltage = 4150, /*4.15V */
+
+ .charge_duration = 10*60*60, /* 10 hour */
+ .recharge_duration = 1.5*60*60, /* 1.5 hour */
+ .check_lp_charging_boot = check_bootmode,
+ .check_jig_status = check_jig_on
+};
+
+static struct platform_device sec_battery_device = {
+ .name = "sec-battery",
+ .id = -1,
+ .dev = {
+ .platform_data = &sec_battery_platform,
+ },
+};
+#endif /* CONFIG_BATTERY_SEC_PX */
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+static void px_usb_otg_power(int active);
+#define HOST_NOTIFIER_BOOSTER px_usb_otg_power
+#define HOST_NOTIFIER_GPIO GPIO_ACCESSORY_OUT_5V
+#define RETRY_CNT_LIMIT 100
+
+struct host_notifier_platform_data host_notifier_pdata = {
+ .ndev.name = "usb_otg",
+ .gpio = HOST_NOTIFIER_GPIO,
+ .booster = HOST_NOTIFIER_BOOSTER,
+ .irq_enable = 1,
+};
+
+struct platform_device host_notifier_device = {
+ .name = "host_notifier",
+ .dev.platform_data = &host_notifier_pdata,
+};
+
+static void __init acc_chk_gpio_init(void)
+{
+ gpio_request(GPIO_ACCESSORY_EN, "GPIO_USB_OTG_EN");
+ s3c_gpio_cfgpin(GPIO_ACCESSORY_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_ACCESSORY_EN, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_ACCESSORY_EN, false);
+
+ gpio_request(GPIO_ACCESSORY_OUT_5V, "gpio_acc_5v");
+ s3c_gpio_cfgpin(GPIO_ACCESSORY_OUT_5V, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ACCESSORY_OUT_5V, S3C_GPIO_PULL_NONE);
+ gpio_direction_input(GPIO_ACCESSORY_OUT_5V);
+}
+#endif
+
+#ifdef CONFIG_30PIN_CONN
+static void smdk_accessory_gpio_init(void)
+{
+ gpio_request(GPIO_ACCESSORY_INT, "accessory");
+ s3c_gpio_cfgpin(GPIO_ACCESSORY_INT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ACCESSORY_INT, S3C_GPIO_PULL_NONE);
+ gpio_direction_input(GPIO_ACCESSORY_INT);
+
+ gpio_request(GPIO_DOCK_INT, "dock");
+ s3c_gpio_cfgpin(GPIO_DOCK_INT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_DOCK_INT, S3C_GPIO_PULL_NONE);
+ gpio_direction_input(GPIO_DOCK_INT);
+}
+
+void smdk_accessory_power(u8 token, bool active)
+{
+ int gpio_acc_en = 0;
+ int try_cnt = 0;
+ int gpio_acc_5v = 0;
+ static bool enable;
+ static u8 acc_en_token;
+
+ /*
+ token info
+ 0 : power off,
+ 1 : Keyboard dock
+ 2 : USB
+ */
+ gpio_acc_en = GPIO_ACCESSORY_EN;
+ gpio_acc_5v = GPIO_ACCESSORY_OUT_5V;
+
+ gpio_request(gpio_acc_en, "GPIO_ACCESSORY_EN");
+ s3c_gpio_cfgpin(gpio_acc_en, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio_acc_en, S3C_GPIO_PULL_NONE);
+
+ if (active) {
+ if (acc_en_token) {
+ pr_info("Board : Keyboard dock is connected.\n");
+ gpio_direction_output(gpio_acc_en, 0);
+ msleep(100);
+ }
+
+ acc_en_token |= (1 << token);
+ enable = true;
+ gpio_direction_output(gpio_acc_en, 1);
+
+ if (0 != gpio_acc_5v) {
+ /* prevent the overcurrent */
+ while (!gpio_get_value(gpio_acc_5v)) {
+ gpio_direction_output(gpio_acc_en, 0);
+ msleep(20);
+ gpio_direction_output(gpio_acc_en, 1);
+ if (try_cnt > 10) {
+ pr_err("[acc] failed to enable the accessory_en");
+ break;
+ } else
+ try_cnt++;
+ }
+
+ } else
+ pr_info("[ACC] gpio_acc_5v is not set\n");
+
+ } else {
+ if (0 == token) {
+ gpio_direction_output(gpio_acc_en, 0);
+ enable = false;
+ } else {
+ acc_en_token &= ~(1 << token);
+ if (0 == acc_en_token) {
+ gpio_direction_output(gpio_acc_en, 0);
+ enable = false;
+ }
+ }
+ }
+ gpio_free(gpio_acc_en);
+ pr_info("Board : %s (%d,%d) %s\n", __func__,
+ token, active, enable ? "on" : "off");
+}
+
+static int smdk_get_acc_state(void)
+{
+ return gpio_get_value(GPIO_DOCK_INT);
+}
+
+static int smdk_get_dock_state(void)
+{
+ return gpio_get_value(GPIO_ACCESSORY_INT);
+}
+
+#ifdef CONFIG_SEC_KEYBOARD_DOCK
+static struct sec_keyboard_callbacks *keyboard_callbacks;
+static int check_sec_keyboard_dock(bool attached)
+{
+ if (keyboard_callbacks && keyboard_callbacks->check_keyboard_dock)
+ return keyboard_callbacks->
+ check_keyboard_dock(keyboard_callbacks, attached);
+ return 0;
+}
+
+static void check_uart_path(bool en)
+{
+ int gpio_uart_sel;
+#ifdef CONFIG_MACH_P8LTE
+ int gpio_uart_sel2;
+
+ gpio_uart_sel = GPIO_UART_SEL1;
+ gpio_uart_sel2 = GPIO_UART_SEL2;
+ if (en)
+ gpio_direction_output(gpio_uart_sel2, 1);
+ else
+ gpio_direction_output(gpio_uart_sel2, 0);
+ printk(KERN_DEBUG "[Keyboard] uart_sel2 : %d\n",
+ gpio_get_value(gpio_uart_sel2));
+#else
+ gpio_uart_sel = GPIO_UART_SEL;
+#endif
+
+ if (en)
+ gpio_direction_output(gpio_uart_sel, 1);
+ else
+ gpio_direction_output(gpio_uart_sel, 0);
+
+ printk(KERN_DEBUG "[Keyboard] uart_sel : %d\n",
+ gpio_get_value(gpio_uart_sel));
+}
+
+static void sec_keyboard_register_cb(struct sec_keyboard_callbacks *cb)
+{
+ keyboard_callbacks = cb;
+}
+
+static struct sec_keyboard_platform_data kbd_pdata = {
+ .accessory_irq_gpio = GPIO_ACCESSORY_INT,
+ .acc_power = smdk_accessory_power,
+ .check_uart_path = check_uart_path,
+ .register_cb = sec_keyboard_register_cb,
+ .wakeup_key = NULL,
+};
+
+static struct platform_device sec_keyboard = {
+ .name = "sec_keyboard",
+ .id = -1,
+ .dev = {
+ .platform_data = &kbd_pdata,
+ }
+};
+#endif
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+static void px_usb_otg_power(int active)
+{
+ smdk_accessory_power(2, active);
+}
+
+static void px_usb_otg_en(int active)
+{
+ pr_info("otg %s : %d\n", __func__, active);
+
+ usb_switch_lock();
+
+ if (active) {
+
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ehci.dev);
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ohci.dev);
+#endif
+ usb_switch_set_path(USB_PATH_AP);
+ px_usb_otg_power(1);
+
+ host_notifier_pdata.ndev.mode = NOTIFY_HOST_MODE;
+ if (host_notifier_pdata.usbhostd_start)
+ host_notifier_pdata.usbhostd_start();
+ } else {
+
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ohci.dev);
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ehci.dev);
+#endif
+
+ usb_switch_clr_path(USB_PATH_AP);
+ host_notifier_pdata.ndev.mode = NOTIFY_NONE_MODE;
+ if (host_notifier_pdata.usbhostd_stop)
+ host_notifier_pdata.usbhostd_stop();
+ px_usb_otg_power(0);
+ }
+
+ usb_switch_unlock();
+}
+#endif
+
+struct acc_con_platform_data acc_con_pdata = {
+ .otg_en = px_usb_otg_en,
+ .acc_power = smdk_accessory_power,
+ .usb_ldo_en = NULL,
+ .get_acc_state = smdk_get_acc_state,
+ .get_dock_state = smdk_get_dock_state,
+#ifdef CONFIG_SEC_KEYBOARD_DOCK
+ .check_keyboard = check_sec_keyboard_dock,
+#endif
+ .accessory_irq_gpio = GPIO_ACCESSORY_INT,
+ .dock_irq_gpio = GPIO_DOCK_INT,
+#if defined(CONFIG_SAMSUNG_MHL_9290)
+ .mhl_irq_gpio = GPIO_MHL_INT,
+ .hdmi_hpd_gpio = GPIO_HDMI_HPD,
+#endif
+};
+struct platform_device sec_device_connector = {
+ .name = "acc_con",
+ .id = -1,
+ .dev.platform_data = &acc_con_pdata,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 0x41,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 199 * 1000000, /* 160 Mhz */
+};
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+struct exynos_c2c_platdata smdk4212_c2c_pdata = {
+ .setup_gpio = NULL,
+ .shdmem_addr = C2C_SHAREDMEM_BASE,
+ .shdmem_size = C2C_MEMSIZE_64,
+ .ap_sscm_addr = NULL,
+ .cp_sscm_addr = NULL,
+ .rx_width = C2C_BUSWIDTH_16,
+ .tx_width = C2C_BUSWIDTH_16,
+ .clk_opp100 = 400,
+ .clk_opp50 = 266,
+ .clk_opp25 = 0,
+ .default_opp_mode = C2C_OPP50,
+ .get_c2c_state = NULL,
+};
+#endif
+/* BUSFREQ to control memory/bus */
+static struct device_domain busfreq;
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+
+#if defined(CONFIG_SENSORS_BH1721)
+static struct i2c_gpio_platform_data i2c9_platdata = {
+ .sda_pin = GPIO_PS_ALS_SDA_28V,
+ .scl_pin = GPIO_PS_ALS_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c9 = {
+ .name = "i2c-gpio",
+ .id = 9,
+ .dev.platform_data = &i2c9_platdata,
+};
+#endif
+
+#ifdef CONFIG_SENSORS_AK8975C
+static struct i2c_gpio_platform_data i2c10_platdata = {
+ .sda_pin = GPIO_MSENSOR_SDA_18V,
+ .scl_pin = GPIO_MSENSOR_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c10 = {
+ .name = "i2c-gpio",
+ .id = 10,
+ .dev.platform_data = &i2c10_platdata,
+};
+#endif
+
+#ifdef CONFIG_SENSORS_LPS331
+static struct i2c_gpio_platform_data i2c11_platdata = {
+ .sda_pin = GPIO_BSENSE_SDA_18V,
+ .scl_pin = GPIO_BENSE_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c11 = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &i2c11_platdata,
+};
+#endif
+
+/* IR_LED */
+#ifdef CONFIG_IR_REMOCON
+
+static struct platform_device ir_remote_device = {
+ .name = "ir_rc",
+ .id = 0,
+ .dev = {
+ },
+};
+
+static void ir_rc_init_hw(void)
+{
+ s3c_gpio_cfgpin(GPIO_IRDA_CONTROL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_IRDA_CONTROL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_IRDA_CONTROL, 0);
+}
+
+#endif
+/* IR_LED */
+
+static struct platform_device *midas_devices[] __initdata = {
+#ifdef CONFIG_ANDROID_RAM_CONSOLE
+ &ram_console_device,
+#endif
+ /* Samsung Power Domain */
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &exynos4_device_pd[PD_ISP],
+#endif
+ &exynos4_device_pd[PD_GPS_ALIVE],
+ /* legacy fimd */
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ &s3c_device_spi_gpio,
+#endif
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+ &mdnie_device,
+#endif
+
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &s3c_device_timer[2],
+ &s3c_device_timer[3],
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_PX
+ &sec_battery_device,
+#endif
+
+#ifdef CONFIG_SND_SOC_WM8994
+ &vbatt_device,
+#endif
+
+ &s3c_device_wdt,
+ &s3c_device_rtc,
+
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+#ifdef CONFIG_S3C_DEV_I2C3
+ &s3c_device_i2c3,
+#endif
+#ifdef CONFIG_S3C_DEV_I2C4
+ &s3c_device_i2c4,
+#endif
+ /* &s3c_device_i2c5, */
+#ifdef CONFIG_S3C_DEV_I2C6
+ &s3c_device_i2c6,
+#endif
+ &s3c_device_i2c7,
+#ifdef CONFIG_S3C_DEV_I2C8
+ &s3c_device_i2c8,
+#endif
+ /* &s3c_device_i2c9, */
+#ifdef CONFIG_SENSORS_AK8975C
+ &s3c_device_i2c10,
+#endif
+#ifdef CONFIG_SENSORS_LPS331
+ &s3c_device_i2c11,
+#endif
+ /* &s3c_device_i2c12, */
+#ifdef CONFIG_SMB347_CHARGER
+ &s3c_device_i2c13,
+#endif
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_PX
+ &s3c_device_i2c14,
+#endif
+
+#ifdef CONFIG_SAMSUNG_MHL
+ &s3c_device_i2c15,
+ &s3c_device_i2c16,
+#endif
+
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+ &s3c_device_i2c17,
+#endif
+
+#ifdef CONFIG_LEDS_AN30259A
+ &s3c_device_i2c21,
+#endif
+#if defined CONFIG_USB_EHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ehci,
+#endif
+#if defined CONFIG_USB_OHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &exynos4_device_fimc_is,
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ &ld9040_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_S6C1372
+ &lcd_s6c1372,
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+#ifdef CONFIG_FB_S5P_EXTDSP
+ &s3c_device_extdsp,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+/* CONFIG_VIDEO_SAMSUNG_S5P_FIMC is the feature for mainline */
+#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+ &s5p_device_fimc0,
+ &s5p_device_fimc1,
+ &s5p_device_fimc2,
+ &s5p_device_fimc3,
+#endif
+#if defined(CONFIG_VIDEO_FIMC_MIPI)
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(g2d_acp),
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(jpeg),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+ &SYSMMU_PLATDEV(tv),
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &SYSMMU_PLATDEV(is_isp),
+ &SYSMMU_PLATDEV(is_drc),
+ &SYSMMU_PLATDEV(is_fd),
+ &SYSMMU_PLATDEV(is_cpu),
+#endif
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ &exynos_device_flite0,
+ &exynos_device_flite1,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ &s5p_device_jpeg,
+#endif
+ &samsung_asoc_dma,
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+ &samsung_asoc_idma,
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ &exynos_device_c2c,
+#endif
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+ &exynos_device_spi1,
+#endif
+#if defined(CONFIG_PHONE_IPC_SPI)
+ &exynos_device_spi2,
+ &ipc_spi_device,
+#elif defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ &exynos_device_spi2,
+#endif
+#endif
+
+#ifdef CONFIG_BT_BCM4334
+ &bcm4334_bluetooth_device,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+ &exynos4_busfreq,
+#ifdef CONFIG_USB_HOST_NOTIFY
+ &host_notifier_device,
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+#ifdef CONFIG_30PIN_CONN
+ &sec_device_connector,
+#ifdef CONFIG_SEC_KEYBOARD_DOCK
+ &sec_keyboard,
+#endif
+#endif
+#if defined(CONFIG_IR_REMOCON)
+/* IR_LED */
+ &ir_remote_device,
+/* IR_LED */
+#endif
+
+};
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct s5p_platform_tmu midas_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 78,
+ .start_1st_throttle = 80,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110, /* temp to do tripping */
+ .start_emergency = 120, /* To protect chip,forcely kernel panic */
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ .stop_tc = 13,
+ .start_tc = 10,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000, /* 800MHz in KHz order */
+ .limit_2nd_throttle = 200000, /* 200MHz in KHz order */
+ },
+ .temp_compensate = {
+ .arm_volt = 900000, /* vdd_arm in uV for temp compensation */
+ .bus_volt = 900000, /* vdd_bus in uV for temp compensation */
+ .g3d_volt = 900000, /* vdd_g3d in uV for temp compensation */
+ },
+};
+#endif
+
+#if defined CONFIG_USB_OHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ohci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ohci);
+}
+late_initcall(s5p_ohci_device_initcall);
+#endif
+#if defined CONFIG_USB_EHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ehci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ehci);
+}
+late_initcall(s5p_ehci_device_initcall);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+
+};
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#if defined(CONFIG_CMA)
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ {
+ .name = "fimc_is",
+ .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0)
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE)
+ {
+ .name = "ion",
+ .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ {
+ .name = "b2",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "b1",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "fw",
+ .size = 1 << 20,
+ { .alignment = 128 << 10 },
+ },
+#endif
+#if (CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG > 0)
+ {
+ .name = "jpeg",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .start = 0x65c00000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0x64000000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL
+ {
+ .name = "mfc-normal",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL * SZ_1K,
+ .start = 0x64000000,
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ static struct cma_region regions_secure[] = {
+#ifdef CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE
+ {
+ .name = "ion",
+ .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE
+ {
+ .name = "mfc-secure",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE * SZ_1K,
+ },
+#endif
+ {
+ .name = "sectbl",
+ .size = SZ_1M,
+ },
+ {
+ .size = 0
+ },
+ };
+#else /* !CONFIG_EXYNOS_CONTENT_PATH_PROTECTION */
+ struct cma_region *regions_secure = NULL;
+#endif
+
+ static const char map[] __initconst =
+#ifdef CONFIG_EXYNOS_C2C
+ "samsung-c2c=c2c_shdmem;"
+#endif
+ "s3cfb.0=fimd;exynos4-fb.0=fimd;"
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;s3c-fimc.3=fimc3;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc.3=fimc3;"
+#ifdef CONFIG_ION_EXYNOS
+ "ion-exynos=ion;"
+#endif
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc/A=mfc0,mfc-secure;"
+ "s3c-mfc/B=mfc1,mfc-normal;"
+ "s3c-mfc/AB=mfc;"
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ "s5p-mfc/f=fw;"
+ "s5p-mfc/a=b1;"
+ "s5p-mfc/b=b2;"
+#endif
+ "samsung-rp=srp;"
+#if (CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG > 0)
+ "s5p-jpeg=jpeg;"
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ "exynos4-fimc-is=fimc_is;"
+#endif
+ "s5p-fimg2d=fimg2d;"
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ "s5p-smem/sectbl=sectbl;"
+#endif
+ "s5p-smem/mfc=mfc-secure;"
+ "s5p-smem/fimc=ion;"
+ "s5p-smem/mfc-shm=mfc-normal;"
+ "s5p-smem/fimd=fimd;";
+
+ s5p_cma_region_reserve(regions, regions_secure, 0, map);
+}
+#else
+static inline void exynos4_reserve_mem(void)
+{
+}
+#endif
+
+#ifdef CONFIG_BACKLIGHT_PWM
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk4212_bl_gpio_info = {
+ .no = EXYNOS4_GPD0(1),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk4212_bl_data = {
+ .pwm_id = 1,
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ .pwm_period_ns = 1000,
+#endif
+};
+#endif
+
+static void __init midas_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdk4212_uartcfgs, ARRAY_SIZE(smdk4212_uartcfgs));
+
+#if defined(CONFIG_S5P_MEM_CMA)
+ exynos4_reserve_mem();
+#endif
+
+ /* as soon as INFORM6 is visible, sec_debug is ready to run */
+ sec_debug_init();
+}
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+#endif
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(g2d_acp).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_MFC5X
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ ASSIGN_SYSMMU_POWERDOMAIN(is_isp, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_drc, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_fd, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_cpu, &exynos4_device_pd[PD_ISP].dev);
+
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_isp).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_drc).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_fd).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_cpu).dev,
+ &exynos4_device_fimc_is.dev);
+#endif
+}
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct platform_device s3c_device_extdsp = {
+ .name = "s3cfb_extdsp",
+ .id = 0,
+};
+
+static struct s3cfb_extdsp_lcd dummy_buffer = {
+ .width = 1920,
+ .height = 1080,
+ .bpp = 16,
+};
+
+static struct s3c_platform_fb default_extdsp_data __initdata = {
+ .hw_ver = 0x70,
+ .nr_wins = 1,
+ .default_win = 0,
+ .swap = FB_SWAP_WORD | FB_SWAP_HWORD,
+ .lcd = &dummy_buffer
+};
+
+void __init s3cfb_extdsp_set_platdata(struct s3c_platform_fb *pd)
+{
+ struct s3c_platform_fb *npd;
+ int i;
+
+ if (!pd)
+ pd = &default_extdsp_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ for (i = 0; i < npd->nr_wins; i++)
+ npd->nr_buffers[i] = 1;
+ s3c_device_extdsp.dev.platform_data = npd;
+ }
+}
+#endif
+
+static inline int need_i2c5(void)
+{
+ return 1; /* orig: system_rev != 3; */
+}
+
+static void __init midas_machine_init(void)
+{
+ struct clk *ppmu_clk = NULL;
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+ unsigned int gpio;
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi1_dev = &exynos_device_spi1.dev;
+#endif
+#if defined(CONFIG_PHONE_IPC_SPI) \
+ || defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ struct device *spi2_dev = &exynos_device_spi2.dev;
+#endif
+#endif
+
+ /*
+ * prevent 4x12 ISP power off problem
+ * ISP_SYS Register has to be 0 before ISP block power off.
+ */
+ __raw_writel(0x0, S5P_CMU_RESET_ISP_SYS);
+
+ /* initialise the gpios */
+ midas_config_gpio_table();
+ exynos4_sleep_gpio_table_set = midas_config_sleep_gpio_table;
+
+ midas_power_init();
+
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ p4_tsp_init(system_rev);
+ p4_key_init();
+#if defined(CONFIG_EPEN_WACOM_G5SP)
+ p4_wacom_init();
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+#ifdef CONFIG_LEDS_AAT1290A
+ platform_device_register(&s3c_device_aat1290a_led);
+#endif
+ midas_sound_init();
+
+#ifdef CONFIG_S3C_DEV_I2C5
+ if (need_i2c5()) {
+ s3c_i2c5_set_platdata(NULL);
+ i2c_register_board_info(5, i2c_devs5,
+ ARRAY_SIZE(i2c_devs5));
+ }
+#endif
+
+ s3c_i2c7_set_platdata(NULL);
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+
+ i2c_register_board_info(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+
+ i2c_register_board_info(10, i2c_devs10_emul,
+ ARRAY_SIZE(i2c_devs10_emul));
+
+ i2c_register_board_info(11, i2c_devs11_emul,
+ ARRAY_SIZE(i2c_devs11_emul));
+
+#ifdef CONFIG_SMB347_CHARGER
+ /* smb347 charger */
+ i2c_register_board_info(13, i2c_devs13_emul,
+ ARRAY_SIZE(i2c_devs13_emul));
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_PX
+ /* max17042 fuelgauge */
+ i2c_register_board_info(14, i2c_devs14_emul,
+ ARRAY_SIZE(i2c_devs14_emul));
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ printk(KERN_INFO "%s() register sii9234 driver\n", __func__);
+
+ i2c_register_board_info(15, i2c_devs15_emul,
+ ARRAY_SIZE(i2c_devs15_emul));
+ i2c_register_board_info(16, i2c_devs16_emul,
+ ARRAY_SIZE(i2c_devs16_emul));
+#endif
+
+#ifdef CONFIG_MOTOR_DRV_ISA1200
+ isa1200_init();
+ i2c_register_board_info(17, i2c_devs17_emul,
+ ARRAY_SIZE(i2c_devs17_emul));
+#endif
+
+#if defined(CONFIG_STMPE811_ADC) || defined(CONFIG_FM_SI4709_MODULE) \
+ || defined(CONFIG_FM_SI4705_MODULE)
+ i2c_register_board_info(19, i2c_devs19_emul,
+ ARRAY_SIZE(i2c_devs19_emul));
+#endif
+
+#ifdef CONFIG_LEDS_AN30259A
+ i2c_register_board_info(21, i2c_devs21_emul,
+ ARRAY_SIZE(i2c_devs21_emul));
+#endif
+
+#if defined(GPIO_OLED_DET)
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s5p_register_gpio_interrupt(GPIO_OLED_DET);
+ gpio_free(GPIO_OLED_DET);
+#endif
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&lms501kf03_data);
+#endif
+#if defined(CONFIG_BACKLIGHT_PWM)
+ samsung_bl_set(&smdk4212_bl_gpio_info, &smdk4212_bl_data);
+#elif defined(CONFIG_FB_S5P_S6C1372)
+ s6c1372_panel_gpio_init();
+#endif
+ s3cfb_set_platdata(&fb_platform_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdk4212_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdk4212_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdk4212_usbgadget_init();
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ exynos4_fimc_is_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ exynos4_device_fimc_is.dev.parent = &exynos4_device_pd[PD_ISP].dev;
+#endif
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdk4212_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdk4212_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdk4212_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdk4212_hsmmc3_pdata);
+#endif
+
+ midas_camera_init();
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+ s3cfb_extdsp_set_platdata(&default_extdsp_data);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+ exynos4_device_pd[PD_TV].dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ exynos4_jpeg_setup_clock(&s5p_device_jpeg.dev, 160000000);
+#endif
+#endif
+
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ);
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ exynos_c2c_set_platdata(&smdk4212_c2c_pdata);
+#endif
+
+ brcm_wlan_init();
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(&midas_tmu_data);
+#endif
+
+ exynos_sysmmu_init();
+
+ platform_add_devices(midas_devices, ARRAY_SIZE(midas_devices));
+
+#ifdef CONFIG_S3C_ADC
+ platform_device_register(&s3c_device_adc);
+#endif
+#if defined(CONFIG_STMPE811_ADC) || defined(CONFIG_FM_SI4709_MODULE) \
+ || defined(CONFIG_FM_SI4705_MODULE)
+ platform_device_register(&s3c_device_i2c19);
+#endif
+#ifdef CONFIG_SEC_THERMISTOR
+ platform_device_register(&sec_device_thermistor);
+#endif
+
+#if defined(CONFIG_S3C_DEV_I2C5)
+ if (need_i2c5())
+ platform_device_register(&s3c_device_i2c5);
+#endif
+
+#if defined(CONFIG_SENSORS_BH1721)
+ platform_device_register(&s3c_device_i2c9);
+#endif
+
+#ifdef CONFIG_30PIN_CONN
+ smdk_accessory_gpio_init();
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ acc_chk_gpio_init();
+#endif
+
+#if defined(CONFIG_SEC_DEV_JACK)
+ p4note_jack_init();
+#endif
+
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+#if defined(CONFIG_VIDEO_S5C73M3_SPI)
+ sclk = clk_get(spi1_dev, "dout_spi1");
+ if (IS_ERR(sclk))
+ dev_err(spi1_dev, "failed to get sclk for SPI-1\n");
+ prnt = clk_get(spi1_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi1_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(5), "SPI_CS1")) {
+ gpio_direction_output(EXYNOS4_GPB(5), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(5), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(5), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi1_csi));
+ }
+
+ for (gpio = EXYNOS4_GPB(4); gpio < EXYNOS4_GPB(8); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info));
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI) \
+ || defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ sclk = NULL;
+ prnt = NULL;
+
+ sclk = clk_get(spi2_dev, "dout_spi2");
+ if (IS_ERR(sclk))
+ dev_err(spi2_dev, "failed to get sclk for SPI-2\n");
+ prnt = clk_get(spi2_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi2_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPC1(2), "SPI_CS2")) {
+ gpio_direction_output(EXYNOS4_GPC1(2), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(2), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPC1(2), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi2_csi));
+ }
+ for (gpio = EXYNOS4_GPC1(1); gpio < EXYNOS4_GPC1(5); gpio++)
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+
+ spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ tdmb_dev_init();
+#endif
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+
+ /* PPMUs using for cpufreq get clk from clk_list */
+ ppmu_clk = clk_get(NULL, "ppmudmc0");
+ if (IS_ERR(ppmu_clk))
+ printk(KERN_ERR "failed to get ppmu_dmc0\n");
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_clk = clk_get(NULL, "ppmudmc1");
+ if (IS_ERR(ppmu_clk))
+ printk(KERN_ERR "failed to get ppmu_dmc1\n");
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_clk = clk_get(NULL, "ppmucpu");
+ if (IS_ERR(ppmu_clk))
+ printk(KERN_ERR "failed to get ppmu_cpu\n");
+ clk_enable(ppmu_clk);
+ clk_put(ppmu_clk);
+
+ ppmu_init(&exynos_ppmu[PPMU_DMC0], &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DMC1], &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos4_busfreq.dev);
+#endif
+
+
+ /* 400 kHz for initialization of MMC Card */
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS3) & 0xfffffff0)
+ | 0x9, EXYNOS4_CLKDIV_FSYS3);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS2) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS2);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS1) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS1);
+
+#if defined(CONFIG_IR_REMOCON)
+/* IR_LED */
+ ir_rc_init_hw();
+/* IR_LED */
+#endif
+}
+
+#ifdef CONFIG_EXYNOS_C2C
+static void __init exynos_c2c_reserve(void)
+{
+ static struct cma_region region = {
+ .name = "c2c_shdmem",
+ .size = 64 * SZ_1M,
+ { .alignment = 64 * SZ_1M },
+ .start = C2C_SHAREDMEM_BASE
+ };
+
+ BUG_ON(cma_early_region_register(&region));
+ BUG_ON(cma_early_region_reserve(&region));
+
+ pr_info("%s %10s %8x %8x\n", __func__,
+ region.name, region.start, region.size);
+}
+#endif
+
+static void __init exynos_init_reserve(void)
+{
+ sec_debug_magic_init();
+}
+
+MACHINE_START(SMDK4412, "SMDK4x12")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = midas_map_io,
+ .init_machine = midas_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+ .init_early = &exynos_init_reserve,
+MACHINE_END
+
+MACHINE_START(SMDK4212, "SMDK4x12")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = midas_map_io,
+ .init_machine = midas_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+ .init_early = &exynos_init_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-px.c b/arch/arm/mach-exynos/mach-px.c
new file mode 100644
index 0000000..8ab8c7a
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-px.c
@@ -0,0 +1,7558 @@
+/* linux/arch/arm/mach-exynos4/mach-smdkc210.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio_event.h>
+#include <linux/lcd.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <linux/switch.h>
+#include <linux/spi/spi.h>
+#include <linux/pwm_backlight.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+#include <linux/sensor/k3g.h>
+#include <linux/sensor/k3dh.h>
+#include <linux/sensor/ak8975.h>
+#include <linux/sensor/cm3663.h>
+#include <linux/pn544.h>
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+#include <linux/mfd/mc1n2_pdata.h>
+#endif
+#if defined(CONFIG_TOUCHSCREEN_MXT540E)
+#include <linux/i2c/mxt540e.h>
+#elif defined(CONFIG_TOUCHSCREEN_MXT768E)
+#include <linux/i2c/mxt768e.h>
+#elif defined(CONFIG_TOUCHSCREEN_MMS152)
+#include <linux/mms152.h>
+#else
+#include <linux/i2c/mxt224_u1.h>
+#endif
+#ifdef CONFIG_TOUCHSCREEN_MXT1386
+#include <linux/atmel_mxt1386.h>
+#endif
+#include <linux/memblock.h>
+#include <linux/power_supply.h>
+#if defined(CONFIG_S5P_MEM_CMA)
+#include <linux/cma.h>
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/exynos4.h>
+#include <plat/clock.h>
+#include <plat/hwmon.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb-s5p.h>
+#include <plat/fimc.h>
+#include <plat/csis.h>
+#include <plat/gpio-cfg.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/keypad.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/iic.h>
+#include <plat/sysmmu.h>
+#include <plat/pd.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/media.h>
+#include <plat/udc-hs.h>
+#include <plat/s5p-clock.h>
+#include <plat/tvout.h>
+#include <plat/fimg2d.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#include <plat/regs-otg.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+#include <plat/s3c64xx-spi.h>
+#include <mach/spi-clocks.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/exynos-clock.h>
+#include <mach/media.h>
+#include <plat/regs-fb.h>
+
+#include <mach/dev-sysmmu.h>
+#include <mach/dev.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos-ion.h>
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#include <mach/mipi_ddi.h>
+#include <mach/dsim.h>
+#include <plat/fb-s5p.h>
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+
+#ifdef CONFIG_VIDEO_M5MO
+#include <media/m5mo_platform.h>
+#endif
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+#include <media/s5k5ccgx_platform.h>
+#endif
+#ifdef CONFIG_VIDEO_S5K5BAFX
+#include <media/s5k5bafx_platform.h>
+#endif
+#ifdef CONFIG_VIDEO_SR200PC20
+#include <media/sr200pc20_platform.h>
+#endif
+
+#if defined(CONFIG_EXYNOS4_SETUP_THERMAL)
+#include <plat/s5p-tmu.h>
+#include <mach/regs-tmu.h>
+#endif
+
+#ifdef CONFIG_SEC_DEV_JACK
+#include <linux/sec_jack.h>
+#endif
+
+#ifdef CONFIG_SENSORS_AK8975
+#include <linux/i2c/ak8975.h>
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU3050
+#include <linux/mpu.h>
+#endif
+
+#ifdef CONFIG_OPTICAL_GP2A
+#include <linux/gp2a.h>
+#endif
+
+#ifdef CONFIG_SENSORS_BH1721FVC
+#include <linux/bh1721fvc.h>
+#endif
+
+#ifdef CONFIG_BT_BCM4330
+#include <mach/board-bluetooth-bcm.h>
+#endif
+
+#ifdef CONFIG_BT_CSR8811
+#include <mach/board-bluetooth-csr.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_LD9040
+#include <linux/ld9040.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+#include <linux/mdnie.h>
+#endif
+
+#include <../../../drivers/video/samsung/s3cfb.h>
+#include "px.h"
+
+#include <mach/sec_debug.h>
+
+#if defined(CONFIG_MHL_SII9234)
+#include <linux/mhd9234.h>
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_PX
+#include <linux/power/sec_battery_px.h>
+#endif
+
+#ifdef CONFIG_SEC_THERMISTOR
+#include <mach/sec_thermistor.h>
+#include "px_thermistor.h"
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_PX
+#include <linux/power/max17042_fuelgauge_px.h>
+#endif
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#endif
+#include <linux/pm_runtime.h>
+
+#ifdef CONFIG_SMB136_CHARGER
+#include <linux/power/smb136_charger.h>
+#endif
+
+#ifdef CONFIG_SMB347_CHARGER
+#include <linux/power/smb347_charger.h>
+#endif
+
+#ifdef CONFIG_30PIN_CONN
+#include <linux/30pin_con.h>
+#include <mach/usb_switch.h>
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+#include <linux/wacom_i2c.h>
+static struct wacom_g5_callbacks *wacom_callbacks;
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+static struct charging_status_callbacks {
+ void (*tsp_set_charging_cable) (int type);
+} charging_cbs;
+
+bool is_cable_attached;
+bool is_usb_lpm_enter;
+
+unsigned int lcdtype;
+static int __init lcdtype_setup(char *str)
+{
+ get_option(&str, &lcdtype);
+ return 1;
+}
+__setup("lcdtype=", lcdtype_setup);
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+#if defined(CONFIG_BT_BCM4330)
+ .wake_peer = bcm_bt_lpm_exit_lpm_locked,
+#elif defined(CONFIG_BT_CSR8811)
+ .wake_peer = csr_bt_lpm_exit_lpm_locked,
+#endif
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ .set_runstate = set_gps_uart_op,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+};
+
+#define WRITEBACK_ENABLED
+
+#ifdef CONFIG_MACH_PX
+
+static struct platform_device p4w_wlan_ar6000_pm_device = {
+ .name = "wlan_ar6000_pm_dev",
+ .id = 1,
+ .num_resources = 0,
+ .resource = NULL,
+};
+
+static void
+(*wlan_status_notify_cb)(struct platform_device *dev_id, int card_present);
+struct platform_device *wlan_devid;
+
+static int register_wlan_status_notify
+(void (*callback)(struct platform_device *dev_id, int card_present))
+{
+ wlan_status_notify_cb = callback;
+ return 0;
+}
+
+static int register_wlan_pdev(struct platform_device *pdev)
+{
+ wlan_devid = pdev;
+ printk(KERN_ERR "ATHR register_wlan_pdev pdev->id = %d\n", pdev->id);
+ return 0;
+}
+
+#define WLAN_HOST_WAKE
+#ifdef WLAN_HOST_WAKE
+struct wlansleep_info {
+ unsigned host_wake;
+ unsigned host_wake_irq;
+ struct wake_lock wake_lock;
+};
+
+static struct wlansleep_info *wsi;
+static struct tasklet_struct hostwake_task;
+
+static void wlan_hostwake_task(unsigned long data)
+{
+ printk(KERN_INFO "WLAN: wake lock timeout 0.5 sec...\n");
+
+ wake_lock_timeout(&wsi->wake_lock, HZ / 2);
+}
+
+static irqreturn_t wlan_hostwake_isr(int irq, void *dev_id)
+{
+ tasklet_schedule(&hostwake_task);
+ return IRQ_HANDLED;
+}
+
+static int wlan_host_wake_init(void)
+{
+ int ret;
+
+ wsi = kzalloc(sizeof(struct wlansleep_info), GFP_KERNEL);
+ if (!wsi)
+ return -ENOMEM;
+
+ wake_lock_init(&wsi->wake_lock, WAKE_LOCK_SUSPEND, "bluesleep");
+ tasklet_init(&hostwake_task, wlan_hostwake_task, 0);
+
+ wsi->host_wake = GPIO_WLAN_HOST_WAKE;
+ wsi->host_wake_irq = gpio_to_irq(GPIO_WLAN_HOST_WAKE);
+
+ ret = request_irq(wsi->host_wake_irq, wlan_hostwake_isr,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
+ "wlan hostwake", NULL);
+ if (ret < 0) {
+ printk(KERN_ERR "WLAN: Couldn't acquire WLAN_HOST_WAKE IRQ");
+ return -1;
+ }
+
+ ret = enable_irq_wake(wsi->host_wake_irq);
+ if (ret < 0) {
+ printk(KERN_ERR "WLAN: Couldn't enable WLAN_HOST_WAKE as wakeup interrupt");
+ free_irq(wsi->host_wake_irq, NULL);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void wlan_host_wake_exit(void)
+{
+ if (disable_irq_wake(wsi->host_wake_irq))
+ printk(KERN_ERR "WLAN: Couldn't disable hostwake IRQ wakeup mode\n");
+ free_irq(wsi->host_wake_irq, NULL);
+ tasklet_kill(&hostwake_task);
+ wake_lock_destroy(&wsi->wake_lock);
+ kfree(wsi);
+}
+#endif /* WLAN_HOST_WAKE */
+
+static void config_wlan_gpio(void)
+{
+ int ret = 0;
+ unsigned int gpio;
+
+ printk(KERN_ERR "ATHR - %s\n", __func__);
+ ret = gpio_request(GPIO_WLAN_HOST_WAKE, "wifi_irq");
+ if (ret < 0) {
+ printk(KERN_ERR "cannot reserve GPIO_WLAN_HOST_WAKE: %s - %d\n"\
+ , __func__, GPIO_WLAN_HOST_WAKE);
+ gpio_free(GPIO_WLAN_HOST_WAKE);
+ return;
+ }
+
+ ret = gpio_request(GPIO_WLAN_EN, "wifi_pwr_33");
+
+ if (ret < 0) {
+ printk(KERN_ERR "cannot reserve GPIO_WLAN_EN: %s - %d\n"\
+ , __func__, GPIO_WLAN_EN);
+ gpio_free(GPIO_WLAN_EN);
+ return;
+ }
+
+ if (system_rev >= 4) {
+ ret = gpio_request(GPIO_WLAN_EN2, "wifi_pwr_18");
+
+ if (ret < 0) {
+ printk(KERN_ERR "cannot reserve GPIO_WLAN_EN2: "\
+ "%s - %d\n", __func__, GPIO_WLAN_EN2);
+ gpio_free(GPIO_WLAN_EN2);
+ return;
+ }
+ }
+
+ ret = gpio_request(GPIO_WLAN_nRST, "wifi_rst");
+
+ if (ret < 0) {
+ printk(KERN_ERR "cannot reserve GPIO_WLAN_nRST: %s - %d\n"\
+ , __func__, GPIO_WLAN_nRST);
+ gpio_free(GPIO_WLAN_nRST);
+ return;
+ }
+
+ gpio_direction_output(GPIO_WLAN_nRST, 0);
+ gpio_direction_output(GPIO_WLAN_EN, 1);
+
+ if (system_rev >= 4)
+ gpio_direction_output(GPIO_WLAN_EN2, 0);
+}
+
+void
+wlan_setup_power(int on, int detect)
+{
+ printk(KERN_ERR "ATHR - %s %s --enter\n", __func__, on ? "on" : "off");
+
+ if (on) {
+ /* WAR for nRST is high */
+
+
+ if (system_rev >= 4) {
+ gpio_direction_output(GPIO_WLAN_EN2, 1);
+ udelay(10);
+ }
+ gpio_direction_output(GPIO_WLAN_nRST, 0);
+ mdelay(30);
+ gpio_direction_output(GPIO_WLAN_nRST, 1);
+
+#ifdef WLAN_HOST_WAKE
+ wlan_host_wake_init();
+#endif /* WLAN_HOST_WAKE */
+
+ } else {
+#ifdef WLAN_HOST_WAKE
+ wlan_host_wake_exit();
+#endif /* WLAN_HOST_WAKE */
+
+ gpio_direction_output(GPIO_WLAN_nRST, 0);
+ if (system_rev >= 4)
+ gpio_direction_output(GPIO_WLAN_EN2, 0);
+ }
+
+ mdelay(100);
+
+ printk(KERN_ERR "ATHR - rev : %02d\n", system_rev);
+
+ if (system_rev >= 4) {
+ printk(KERN_ERR "ATHR - GPIO_WLAN_EN1(%d: %d), "\
+ "GPIO_WLAN_EN2(%d: %d), GPIO_WALN_nRST(%d: %d)\n"\
+ , GPIO_WLAN_EN, gpio_get_value(GPIO_WLAN_EN)
+ , GPIO_WLAN_EN2, gpio_get_value(GPIO_WLAN_EN2)
+ , GPIO_WLAN_nRST, gpio_get_value(GPIO_WLAN_nRST));
+ } else {
+ printk(KERN_ERR "ATHR - GPIO_WLAN_EN(%d: %d), "\
+ " GPIO_WALN_nRST(%d: %d)\n"\
+ , GPIO_WLAN_EN, gpio_get_value(GPIO_WLAN_EN)
+ , GPIO_WLAN_nRST, gpio_get_value(GPIO_WLAN_nRST));
+ }
+
+ if (detect) {
+ if (wlan_status_notify_cb)
+ wlan_status_notify_cb(wlan_devid, on);
+ else
+ printk(KERN_ERR "ATHR - WLAN: No notify available\n");
+ }
+}
+EXPORT_SYMBOL(wlan_setup_power);
+
+#endif
+
+#ifdef CONFIG_VIDEO_FIMC
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+ */
+
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ }
+
+#define CAM_CHECK_ERR_GOTO(x, out, fmt, ...) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR fmt, ##__VA_ARGS__); \
+ goto out; \
+ }
+
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+int s3c_csis_power(int enable)
+{
+ struct regulator *regulator;
+ int ret = -ENODEV;
+
+ /* mipi_1.1v ,mipi_1.8v are always powered-on.
+ * If they are off, we then power them on.
+ */
+ if (enable) {
+ /* VMIPI_1.1V */
+ regulator = regulator_get(NULL, "vmipi_1.1v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.1v is off. so ON\n",
+ __func__);
+ ret = regulator_enable(regulator);
+ if (unlikely(ret < 0)) {
+ pr_err("%s: error, vmipi_1.1v\n", __func__);
+ return ret;
+ }
+ }
+ regulator_put(regulator);
+
+ /* VMIPI_1.8V */
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.8v is off. so ON\n",
+ __func__);
+ ret = regulator_enable(regulator);
+ if (unlikely(ret < 0)) {
+ pr_err("%s: error, vmipi_1.8v\n", __func__);
+ return ret;
+ }
+ }
+ regulator_put(regulator);
+ }
+
+ return 0;
+
+error_out:
+ printk(KERN_ERR "%s: ERROR: failed to check mipi-power\n", __func__);
+ return ret;
+}
+
+#endif
+
+
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+static int s5k5ccgx_get_i2c_busnum(void)
+{
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_S5K5CCGX_P8
+static int s5k5ccgx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in P8\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+#if !defined(CONFIG_MACH_P8LTE)
+ ret = gpio_request(GPIO_CAM_AVDD_EN, "GPJ1");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(CAM_AVDD)\n");
+ return ret;
+ }
+#endif
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+#endif
+
+ /* 2M_nSTBY low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* 2M_nRST low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* CAM_A2.8V */
+#if defined(CONFIG_MACH_P8LTE)
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+#else
+ ret = gpio_direction_output(GPIO_CAM_AVDD_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "CAM_AVDD");
+ udelay(1);
+#endif
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core");
+ udelay(1);
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(1);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ udelay(70);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ udelay(10);
+
+ /* 3M_nSTBY */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nSTBY");
+ udelay(16);
+
+ /* 3M_nRST */
+ ret = gpio_direction_output(GPIO_3M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+
+ /* 3MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3m_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3m_af_2.8v");
+ msleep(10);
+
+#ifndef USE_CAM_GPIO_CFG
+#if !defined(CONFIG_MACH_P8LTE)
+ gpio_free(GPIO_CAM_AVDD_EN);
+#endif
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+ return ret;
+}
+
+static int s5k5ccgx_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in P8\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+#if !defined(CONFIG_MACH_P8LTE)
+ ret = gpio_request(GPIO_CAM_AVDD_EN, "GPJ1");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(CAM_AVDD)\n");
+ return ret;
+ }
+#endif
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+#endif
+ /* 3MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3m_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3m_af_2.8v");
+
+ /* 3M_nRST Low*/
+ ret = gpio_direction_output(GPIO_3M_nRST, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(50);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(5);
+
+ /* 3M_nSTBY */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(1);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ udelay(1);
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+ udelay(1);
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core");
+ udelay(1);
+
+ /* CAM_A2.8V */
+#if defined(CONFIG_MACH_P8LTE)
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "CAM_A2.8V");
+#else
+ ret = gpio_direction_output(GPIO_CAM_AVDD_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "CAM_AVDD");
+#endif
+
+#ifndef USE_CAM_GPIO_CFG
+#if !defined(CONFIG_MACH_P8LTE)
+ gpio_free(GPIO_CAM_AVDD_EN);
+#endif
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+ return ret;
+}
+
+#else /* CONFIG_VIDEO_S5K5CCGX_P8 */
+
+/* Power up/down func for P4C, P2. */
+static int s5k5ccgx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in P4C,P2\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+#endif
+
+ /* 2M_nSTBY low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* 2M_nRST low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core");
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+
+ /* CAM_A2.8V, LDO13 */
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_analog_2.8v");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(20);
+
+ /* 2M_nSTBY High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(3);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ msleep(5); /* >=5ms */
+
+ /* 2M_nSTBY Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(10); /* >=10ms */
+
+ /* 2M_nRST High */
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ msleep(5);
+
+ /* 2M_nSTBY High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(2);
+
+ /* 3M_nSTBY */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nSTBY");
+ udelay(16);
+
+ /* 3M_nRST */
+ ret = gpio_direction_output(GPIO_3M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+ /* udelay(10); */
+
+ /* 3MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3m_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3m_af_2.8v");
+ msleep(10);
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+
+ return ret;
+}
+
+static int s5k5ccgx_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in P4C,P2\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+#endif
+ /* 3MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3m_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3m_af_2.8v");
+
+ /* 3M_nRST Low*/
+ ret = gpio_direction_output(GPIO_3M_nRST, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(50);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(5);
+
+ /* 3M_nSTBY */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(1);
+
+ /* 2M_nRST Low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* 2M_nSTBY Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+
+ /* CAM_A2.8V */
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_analog_2.8v");
+ /* udelay(50); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ /*udelay(50); */
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core");
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+ return ret;
+}
+#endif /* CONFIG_VIDEO_S5K5CCGX_P8 */
+
+static int s5k5ccgx_power(int enable)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s %s\n", __func__, enable ? "on" : "down");
+ if (enable) {
+#ifdef USE_CAM_GPIO_CFG
+ if (cfg_gpio_err) {
+ printk(KERN_ERR "%s: ERROR: gpio configuration",
+ __func__);
+ return cfg_gpio_err;
+ }
+#endif
+ ret = s5k5ccgx_power_on();
+ } else
+ ret = s5k5ccgx_power_down();
+
+ s3c_csis_power(enable);
+
+ return ret;
+}
+
+static void s5k5ccgx_flashtimer_handler(unsigned long data)
+{
+ int ret = -ENODEV;
+ atomic_t *flash_status = (atomic_t *)data;
+
+ pr_info("********** flashtimer_handler **********\n");
+
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN, 0);
+ atomic_set(flash_status, S5K5CCGX_FLASH_OFF);
+ if (unlikely(ret))
+ pr_err("flash_timer: ERROR, failed to oneshot flash off\n");
+}
+
+static atomic_t flash_status = ATOMIC_INIT(S5K5CCGX_FLASH_OFF);
+static int s5k5ccgx_flash_en(u32 mode, u32 onoff)
+{
+ static int flash_mode = S5K5CCGX_FLASH_MODE_NORMAL;
+ static DEFINE_MUTEX(flash_lock);
+ static DEFINE_TIMER(flash_timer, s5k5ccgx_flashtimer_handler,
+ 0, (unsigned long)&flash_status);
+ int ret = 0;
+
+ printk(KERN_DEBUG "flash_en: mode=%d, on=%d\n", mode, onoff);
+
+ if (unlikely((u32)mode >= S5K5CCGX_FLASH_MODE_MAX)) {
+ pr_err("flash_en: ERROR, invalid flash mode(%d)\n", mode);
+ return -EINVAL;
+ }
+
+ /* We could not use spin lock because of gpio kernel API.*/
+ mutex_lock(&flash_lock);
+ if (atomic_read(&flash_status) == onoff) {
+ mutex_unlock(&flash_lock);
+ pr_warn("flash_en: WARNING, already flash %s\n",
+ onoff ? "On" : "Off");
+ return 0;
+ }
+
+ switch (onoff) {
+ case S5K5CCGX_FLASH_ON:
+ if (mode == S5K5CCGX_FLASH_MODE_MOVIE)
+ ret = gpio_direction_output(GPIO_CAM_MOVIE_EN, 1);
+ else {
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN, 1);
+ flash_timer.expires = get_jiffies_64() + HZ / 2;
+ add_timer(&flash_timer);
+ }
+ CAM_CHECK_ERR_GOTO(ret, out,
+ "flash_en: ERROR, fail to turn flash on (mode:%d)\n",
+ mode);
+ flash_mode = mode;
+ break;
+
+ case S5K5CCGX_FLASH_OFF:
+ if (unlikely(flash_mode != mode)) {
+ pr_err("flash_en: ERROR, unmatched flash mode(%d, %d)\n",
+ flash_mode, mode);
+ WARN_ON(1);
+ goto out;
+ }
+
+ if (mode == S5K5CCGX_FLASH_MODE_MOVIE)
+ ret = gpio_direction_output(GPIO_CAM_MOVIE_EN, 0);
+ else {
+ if (del_timer_sync(&flash_timer)) {
+ pr_info("flash_en: terminate flash timer...\n");
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN,
+ 0);
+ }
+ }
+ CAM_CHECK_ERR_GOTO(ret, out,
+ "flash_en: ERROR, flash off (mode:%d)\n", mode);
+ break;
+
+ default:
+ pr_err("flash_en: ERROR, invalid flash cmd(%d)\n", onoff);
+ goto out;
+ break;
+ }
+
+ atomic_set(&flash_status, onoff);
+
+out:
+ mutex_unlock(&flash_lock);
+ return 0;
+}
+
+static int s5k5ccgx_is_flash_on(void)
+{
+ return atomic_read(&flash_status);
+}
+
+static int px_cam_cfg_init(void)
+{
+ int ret = -ENODEV;
+
+ /* pr_info("%s\n", __func__); */
+
+ ret = gpio_request(GPIO_CAM_MOVIE_EN, "GPL0");
+ if (unlikely(ret)) {
+ pr_err("cam_cfg_init: fail to get gpio(MOVIE_EN), "
+ "err=%d\n", ret);
+ goto out;
+ }
+
+ ret = gpio_request(GPIO_CAM_FLASH_EN, "GPL0");
+ if (unlikely(ret)) {
+ pr_err("cam_cfg_init: fail to get gpio(FLASH_EN), "
+ "err=%d\n", ret);
+ goto out_free;
+ }
+
+ return 0;
+
+out_free:
+ gpio_free(GPIO_CAM_MOVIE_EN);
+out:
+ return ret;
+}
+
+static struct s5k5ccgx_platform_data s5k5ccgx_plat = {
+ .default_width = 1024,
+ .default_height = 768,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .streamoff_delay = S5K5CCGX_STREAMOFF_DELAY,
+ .flash_en = s5k5ccgx_flash_en,
+ .is_flash_on = s5k5ccgx_is_flash_on,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+#define REAR_CAM_PLAT (s5k5ccgx_plat)
+
+static struct i2c_board_info s5k5ccgx_i2c_info = {
+ I2C_BOARD_INFO("S5K5CCGX", 0x78>>1),
+ .platform_data = &s5k5ccgx_plat,
+};
+
+static struct s3c_platform_camera s5k5ccgx = {
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .get_i2c_busnum = s5k5ccgx_get_i2c_busnum,
+ .cam_power = s5k5ccgx_power, /*smdkv310_mipi_cam0_reset,*/
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &s5k5ccgx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif /* #ifdef CONFIG_VIDEO_S5K5CCGX_COMMON */
+
+
+#ifdef CONFIG_VIDEO_S5K5BAFX
+static int s5k5bafx_get_i2c_busnum(void)
+{
+ return 0;
+}
+
+static int s5k5bafx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+#if !defined(CONFIG_MACH_P8LTE)
+ ret = gpio_request(GPIO_CAM_AVDD_EN, "GPJ1");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(CAM_AVDD)\n");
+ return ret;
+ }
+#endif
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+
+ /* 3M_nSTBY low */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "3M_nSTBY");
+
+ /* 3M_nRST low */
+ ret = gpio_direction_output(GPIO_3M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+
+ /* CAM_A2.8V */
+#if defined(CONFIG_MACH_P8LTE)
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+#else
+
+ ret = gpio_direction_output(GPIO_CAM_AVDD_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "CAM_AVDD");
+ /* udelay(1); */
+#endif
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core");
+ /* udelay(1); */
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ /* udelay(1); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ udelay(70);
+
+ /* 2M_nSTBY High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(10);
+
+ /* Mclk */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ udelay(50);
+
+ /* 2M_nRST High */
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(50);
+
+#if !defined(CONFIG_MACH_P8LTE)
+ gpio_free(GPIO_CAM_AVDD_EN);
+#endif
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+
+ return 0;
+}
+
+static int s5k5bafx_power_off(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+#if !defined(CONFIG_MACH_P8LTE)
+ ret = gpio_request(GPIO_CAM_AVDD_EN, "GPJ1");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(CAM_AVDD)\n");
+ return ret;
+ }
+#endif
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+
+ /* 2M_nRST Low*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(55);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(10);
+
+ /* 2M_nSTBY */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(1);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ /* udelay(1); */
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+ /* udelay(1); */
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core");
+
+ /* CAM_A2.8V */
+#if defined(CONFIG_MACH_P8LTE)
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "CAM_A2.8V");
+#else
+ ret = gpio_direction_output(GPIO_CAM_AVDD_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "CAM_AVDD");
+#endif
+
+#if !defined(CONFIG_MACH_P8LTE)
+ gpio_free(GPIO_CAM_AVDD_EN);
+#endif
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_2M_nSTBY);
+
+ return 0;
+}
+
+static int s5k5bafx_power(int onoff)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "%s(): %s\n", __func__, onoff ? "on" : "down");
+ if (onoff) {
+ ret = s5k5bafx_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else {
+ ret = s5k5bafx_power_off();
+ /* s3c_i2c0_force_stop();*//* DSLIM. Should be implemented */
+ }
+
+ ret = s3c_csis_power(onoff);
+
+error_out:
+ return ret;
+}
+
+static struct s5k5bafx_platform_data s5k5bafx_plat = {
+ .default_width = 800,
+ .default_height = 600,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .streamoff_delay = S5K5BAFX_STREAMOFF_DELAY,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+#define FRONT_CAM_PLAT (s5k5bafx_plat)
+
+static struct i2c_board_info s5k5bafx_i2c_info = {
+ I2C_BOARD_INFO("S5K5BAFX", 0x5A >> 1),
+ .platform_data = &s5k5bafx_plat,
+};
+
+static struct s3c_platform_camera s5k5bafx = {
+ .id = CAMERA_CSI_D,
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ .get_i2c_busnum = s5k5bafx_get_i2c_busnum,
+ .info = &s5k5bafx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_name = "sclk_cam0",
+ .clk_rate = 24000000,
+ .line_length = 800,
+ .width = 800,
+ .height = 600,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 800,
+ .height = 600,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = s5k5bafx_power,
+};
+#endif
+
+
+#ifdef CONFIG_VIDEO_SR200PC20
+static int sr200pc20_get_i2c_busnum(void)
+{
+#ifdef CONFIG_MACH_P4
+ if (system_rev >= 2)
+ return 0;
+ else
+#endif
+ return 13;
+}
+
+static int sr200pc20_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+#endif
+
+ /* 3M_nSTBY low */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "3M_nSTBY");
+
+ /* 3M_nRST low */
+ ret = gpio_direction_output(GPIO_3M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+
+ /* 2M_nSTBY low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* 2M_nRST low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core");
+ /* udelay(5); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ /*udelay(5); */
+
+ /* CAM_A2.8V */
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_analog_2.8v");
+ /* udelay(5); */
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(20);
+
+ /* ENB High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(3); /* 30 -> 3 */
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ msleep(5); /* >= 5ms */
+
+ /* ENB Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(10); /* >= 10ms */
+
+ /* 2M_nRST High*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ /*msleep(7);*/ /* >= 7ms */
+
+#if 0
+ /* ENB High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(12); /* >= 10ms */
+
+ /* ENB Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(12); /* >= 10ms */
+
+ /* 2M_nRST Low*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(10); /* >= 16 cycle */
+
+ /* 2M_nRST High */
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+#endif
+ udelay(10); /* >= 16 cycle */
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+ return 0;
+}
+
+static int sr200pc20_power_off(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+#endif
+
+#if 0
+ /* 2M_nRST */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(100);
+
+ /* 2M_nSTBY */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(100);
+#endif
+ /* Sleep command */
+ mdelay(1);
+
+ /* 2M_nRST Low*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(3);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(10);
+
+ /* ENB High*/
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ mdelay(5);
+
+ /* ENB Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_spnSTBY");
+ /* udelay(1); */
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+ /* udelay(10); */
+
+ /* CAM_A2.8V */
+ regulator = regulator_get(NULL, "cam_analog_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_analog_2.8v");
+ /* udelay(10); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ /*udelay(10); */
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+#endif
+ return 0;
+}
+
+static int sr200pc20_power(int onoff)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s(): %s\n", __func__, onoff ? "on" : "down");
+
+ if (onoff) {
+#ifdef USE_CAM_GPIO_CFG
+ if (cfg_gpio_err) {
+ printk(KERN_ERR "%s: ERROR: gpio configuration",
+ __func__);
+ return cfg_gpio_err;
+ }
+#endif
+ ret = sr200pc20_power_on();
+ } else {
+ ret = sr200pc20_power_off();
+ /* s3c_i2c0_force_stop();*/ /* DSLIM. Should be implemented */
+ }
+
+ return ret;
+}
+
+static struct sr200pc20_platform_data sr200pc20_plat = {
+ .default_width = 800,
+ .default_height = 600,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .is_mipi = 0,
+ .streamoff_delay = 0,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+#define FRONT_CAM_PLAT (sr200pc20_plat)
+
+static struct i2c_board_info sr200pc20_i2c_info = {
+ I2C_BOARD_INFO("SR200PC20", 0x40 >> 1),
+ .platform_data = &sr200pc20_plat,
+};
+
+static struct s3c_platform_camera sr200pc20 = {
+ .id = CAMERA_PAR_A,
+ .type = CAM_TYPE_ITU,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .get_i2c_busnum = sr200pc20_get_i2c_busnum,
+ .info = &sr200pc20_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_name = "sclk_cam0",
+ .clk_rate = 24000000,
+ .line_length = 800,
+ .width = 800,
+ .height = 600,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 800,
+ .height = 600,
+ },
+
+ /* Polarity */
+#if 0 /*def CONFIG_VIDEO_SR200PC20_P4W */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+#else
+ .inv_pclk = 1,
+ .inv_vsync = 0,
+#endif
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = sr200pc20_power,
+};
+#endif /* CONFIG_VIDEO_SR200PC20 */
+
+
+
+#ifdef WRITEBACK_ENABLED
+static int get_i2c_busnum_writeback(void)
+{
+ return 0;
+}
+
+static struct i2c_board_info writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .get_i2c_busnum = get_i2c_busnum_writeback,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 800,
+ .width = 480,
+ .height = 800,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 480,
+ .height = 800,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+#ifdef CONFIG_ITU_A
+ .default_cam = CAMERA_PAR_A,
+#endif
+#ifdef CONFIG_ITU_B
+ .default_cam = CAMERA_PAR_B,
+#endif
+#ifdef CONFIG_CSI_C
+ .default_cam = CAMERA_CSI_C,
+#endif
+#ifdef CONFIG_CSI_D
+ .default_cam = CAMERA_CSI_D,
+#endif
+ .camera = {
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+ &s5k5ccgx,
+#endif
+#ifdef CONFIG_VIDEO_S5K5BAFX
+ &s5k5bafx,
+#endif
+#ifdef CONFIG_VIDEO_SR200PC20
+ &sr200pc20,
+#endif
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+ },
+ .hw_ver = 0x51,
+};
+
+#if defined(CONFIG_VIDEO_S5K5CCGX_COMMON) || defined(CONFIG_VIDEO_S5K5BAFX) \
+ || defined(CONFIG_VIDEO_SR200PC20)
+ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ char temp_buf[60] = {0,};
+
+ sprintf(buf, "Log Level(Rear): ");
+ if (REAR_CAM_PLAT.dbg_level & CAMDBG_LEVEL_TRACE) {
+ sprintf(temp_buf, "trace ");
+ strcat(buf, temp_buf);
+ }
+
+ if (REAR_CAM_PLAT.dbg_level & CAMDBG_LEVEL_DEBUG) {
+ sprintf(temp_buf, "debug ");
+ strcat(buf, temp_buf);
+ }
+
+ if (REAR_CAM_PLAT.dbg_level & CAMDBG_LEVEL_INFO) {
+ sprintf(temp_buf, "info ");
+ strcat(buf, temp_buf);
+ }
+
+ sprintf(temp_buf, "\nLog Level(Front): ");
+ strcat(buf, temp_buf);
+ if (FRONT_CAM_PLAT.dbg_level & CAMDBG_LEVEL_TRACE) {
+ sprintf(temp_buf, "trace ");
+ strcat(buf, temp_buf);
+ }
+
+ if (FRONT_CAM_PLAT.dbg_level & CAMDBG_LEVEL_DEBUG) {
+ sprintf(temp_buf, "debug ");
+ strcat(buf, temp_buf);
+ }
+
+ if (FRONT_CAM_PLAT.dbg_level & CAMDBG_LEVEL_INFO) {
+ sprintf(temp_buf, "info ");
+ strcat(buf, temp_buf);
+ }
+
+ sprintf(temp_buf, "\n - Warn and Error level is always on\n\n");
+ strcat(buf, temp_buf);
+
+ return strlen(buf);
+}
+
+ssize_t cam_loglevel_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ printk(KERN_DEBUG "CAM buf=%s, count=%d\n", buf, count);
+
+ if (strstr(buf, "trace")) {
+ REAR_CAM_PLAT.dbg_level |= CAMDBG_LEVEL_TRACE;
+ FRONT_CAM_PLAT.dbg_level |= CAMDBG_LEVEL_TRACE;
+ }
+
+ if (strstr(buf, "debug")) {
+ REAR_CAM_PLAT.dbg_level |= CAMDBG_LEVEL_DEBUG;
+ FRONT_CAM_PLAT.dbg_level |= CAMDBG_LEVEL_DEBUG;
+ }
+
+ if (strstr(buf, "info")) {
+ REAR_CAM_PLAT.dbg_level |= CAMDBG_LEVEL_INFO;
+ FRONT_CAM_PLAT.dbg_level |= CAMDBG_LEVEL_INFO;
+ }
+
+ return count;
+}
+static DEVICE_ATTR(loglevel, 0664, cam_loglevel_show, cam_loglevel_store);
+#endif
+
+ssize_t rear_camera_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ /* Change camera type properly */
+ char cam_type[] = "SLSI_S5K5CCGX";
+
+ pr_info("%s\n", __func__);
+ return sprintf(buf, "%s\n", cam_type);
+}
+
+ssize_t front_camera_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ /* Change camera type properly */
+#ifdef CONFIG_MACH_P8
+ char cam_type[] = "SLSI_S5K5BAFX";
+#else
+ char cam_type[] = "SILICONFILE_SR200PC20";
+#endif
+
+ pr_info("%s\n", __func__);
+ return sprintf(buf, "%s\n", cam_type);
+}
+static DEVICE_ATTR(rear_camtype, 0664, rear_camera_type_show, NULL);
+static DEVICE_ATTR(front_camtype, 0664, front_camera_type_show, NULL);
+
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+ssize_t flash_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", s5k5ccgx_is_flash_on() ? "on" : "off");
+}
+
+ssize_t flash_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ switch (*buf) {
+ case '0':
+ s5k5ccgx_flash_en(S5K5CCGX_FLASH_MODE_MOVIE,
+ S5K5CCGX_FLASH_OFF);
+ break;
+ case '1':
+ s5k5ccgx_flash_en(S5K5CCGX_FLASH_MODE_MOVIE,
+ S5K5CCGX_FLASH_ON);
+ break;
+ default:
+ pr_err("flash: invalid data=%c(0x%X)\n", *buf, *buf);
+ break;
+ }
+
+ return count;
+}
+static DEVICE_ATTR(rear_flash, 0664, flash_show, flash_store);
+#endif
+
+
+static inline int cam_cfg_init(void)
+{
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+ return px_cam_cfg_init();
+#else
+ return 0;
+#endif
+}
+
+static int cam_create_file(struct class *cls)
+{
+ struct device *dev_rear = NULL;
+ struct device *dev_front = NULL;
+ int ret = -ENODEV;
+
+#if defined(CONFIG_VIDEO_S5K5CCGX_COMMON) || defined(CONFIG_VIDEO_S5K5BAFX) \
+ || defined(CONFIG_VIDEO_SR200PC20)
+
+ dev_rear = device_create(cls, NULL, 0, NULL, "rear");
+ if (IS_ERR(dev_rear)) {
+ pr_err("cam_init: failed to create device(rearcam_dev)\n");
+ dev_rear = NULL;
+ goto front;
+ }
+
+ ret = device_create_file(dev_rear, &dev_attr_rear_camtype);
+ if (unlikely(ret < 0)) {
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_rear_camtype.attr.name);
+ }
+
+ ret = device_create_file(dev_rear, &dev_attr_rear_flash);
+ if (unlikely(ret < 0)) {
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_rear_flash.attr.name);
+ }
+
+ ret = device_create_file(dev_rear, &dev_attr_loglevel);
+ if (unlikely(ret < 0)) {
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_loglevel.attr.name);
+ }
+
+front:
+ dev_front = device_create(cls, NULL, 0, NULL, "front");
+ if (IS_ERR(dev_front)) {
+ pr_err("cam_init: failed to create device(frontcam_dev)\n");
+ goto out_unreg_class;
+ }
+
+ ret = device_create_file(dev_front, &dev_attr_front_camtype);
+ if (unlikely(ret < 0)) {
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_front_camtype.attr.name);
+ goto out_unreg_dev_front;
+ }
+#endif
+ return 0;
+
+out_unreg_dev_front:
+ device_destroy(cls, 0);
+out_unreg_class:
+ if (!dev_rear)
+ class_destroy(cls);
+
+ return -ENODEV;
+}
+
+static struct class *camera_class;
+
+/**
+ * cam_init - Intialize something concerning camera device if needed.
+ *
+ * And excute codes about camera needed on boot-up time
+ */
+static void cam_init(void)
+{
+ /* pr_info("%s: E\n", __func__); */
+
+ cam_cfg_init();
+
+ camera_class = class_create(THIS_MODULE, "camera");
+ if (IS_ERR(camera_class)) {
+ pr_err("cam_init: failed to create class\n");
+ return;
+ }
+
+ /* create device and device file for supporting camera sysfs.*/
+ cam_create_file(camera_class);
+
+ pr_info("%s: X\n", __func__);
+}
+
+#endif /* CONFIG_VIDEO_FIMC */
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata exynos4_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata exynos4_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = EXYNOS4_GPX3(4),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .vmmc_name = "vtf_2.8v",
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata exynos4_hsmmc3_pdata __initdata = {
+/* For Wi-Fi */
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .host_caps = MMC_CAP_4_BIT_DATA,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+#ifdef CONFIG_MACH_PX
+ .ext_cd_init = register_wlan_status_notify,
+ .ext_pdev = register_wlan_pdev
+#endif
+};
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
+#endif
+ .int_power_gpio = GPIO_XMMC0_CDn,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 30,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 267 * 1000000, /* 266 Mhz */
+};
+#endif
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_LCD_AMS369FG06)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ err = gpio_request(EXYNOS4_GPX0(6), "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ msleep(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ msleep(100);
+
+ gpio_free(EXYNOS4_GPX0(6));
+
+ return 1;
+}
+
+static struct lcd_platform_data ams369fg06_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = (void *)&ams369fg06_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd0.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win2 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_WA101S)
+static void lcd_wa101s_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_wa101s_data = {
+ .set_power = lcd_wa101s_set_power,
+};
+
+static struct platform_device smdkc210_lcd_wa101s = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_wa101s_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1366,
+ .yres = 768,
+ },
+ .virtual_x = 1366,
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#ifndef CONFIG_LCD_WA101S /* temporarily disables window1 */
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1366,
+ .yres = 768,
+ },
+ .virtual_x = 1366,
+ .virtual_y = 768 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+#elif defined(CONFIG_LCD_LTE480WV)
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ msleep(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_WA101S) || \
+ defined(CONFIG_LCD_LTE480WV)
+ .win[0] = &smdkc210_fb_win0,
+#ifndef CONFIG_LCD_WA101S /* temporarily disables window1 */
+ .win[1] = &smdkc210_fb_win1,
+#endif
+#endif
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_AMS369FG06)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN |
+ VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_WA101S)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_LTE480WV)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#endif
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x0,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+};
+#endif
+
+#ifdef CONFIG_FB_S5P
+
+#ifdef CONFIG_FB_S5P_AMS369FG06
+static struct s3c_platform_fb ams369fg06_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = NULL,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+#endif
+#endif
+
+static struct resource smdkc210_smsc911x_resources[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SROM_BANK(1),
+ .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkc210_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkc210_smsc911x_resources),
+ .resource = smdkc210_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+static struct platform_device u1_regulator_consumer = {
+ .name = "u1-regulator-consumer",
+ .id = -1,
+};
+
+#ifdef CONFIG_REGULATOR_MAX8997
+static struct regulator_consumer_supply ldo1_supply[] = {
+ REGULATOR_SUPPLY("vadc_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("vusb_1.1v", "s5p-ehci"),
+ REGULATOR_SUPPLY("vusb_1.1v", "usb_otg"),
+ REGULATOR_SUPPLY("vmipi_1.1v", "m5mo"),
+ REGULATOR_SUPPLY("vmipi_1.1v", NULL),
+};
+
+static struct regulator_consumer_supply ldo4_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vhsic", NULL),
+};
+
+static struct regulator_consumer_supply ldo7_supply[] = {
+ REGULATOR_SUPPLY("vt_core_1.5v", NULL),
+ REGULATOR_SUPPLY("vt_core_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vusb_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vpll_1.1v", NULL),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("hdp_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("cam_io_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("cam_analog_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vled_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("irda_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("3m_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vddq_m1m2", NULL),
+};
+
+static struct regulator_consumer_supply buck1_supply[] = {
+ REGULATOR_SUPPLY("vdd_arm", NULL),
+};
+
+static struct regulator_consumer_supply buck2_supply[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+};
+
+static struct regulator_consumer_supply buck3_supply[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+};
+
+static struct regulator_consumer_supply buck4_supply[] = {
+ REGULATOR_SUPPLY("3mp_core", NULL),
+};
+
+static struct regulator_consumer_supply buck7_supply[] = {
+ REGULATOR_SUPPLY("vcc_sub", NULL),
+};
+
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = \
+ (_disabled == -1 ? 0 : _disabled),\
+ .enabled = \
+ (_disabled == -1 ? 0 : !(_disabled)),\
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo1, "VADC_3.3V_C210", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo3, "VUSB_1.1V", 1100000, 1100000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo4, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo5, "VHSIC_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+
+#if defined(CONFIG_MACH_P8) || defined(CONFIG_MACH_P8LTE)
+REGULATOR_INIT(ldo7, "VT_CORE_1.5V", 1500000, 1500000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo7, "VT_CORE_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+
+REGULATOR_INIT(ldo8, "VUSB_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VPLL_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo11, "VCC_2.8V_HPD", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "CAM_IO_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo13, "CAM_ANALOG_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+#if defined(CONFIG_MACH_P2)
+REGULATOR_INIT(ldo14, "VCC_3.0V_MOTOR", 2400000, 2400000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#elif defined(CONFIG_MACH_P8) || defined(CONFIG_MACH_P8LTE)
+REGULATOR_INIT(ldo14, "VCC_3.0V_MOTOR", 3100000, 3100000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo14, "VCC_3.0V_MOTOR", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+
+#if defined(CONFIG_MACH_P8)
+REGULATOR_INIT(ldo15, "VLED_3.3V", 3200000, 3200000, 1,
+ REGULATOR_CHANGE_STATUS, -1);
+#else
+REGULATOR_INIT(ldo15, "VLED_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+
+REGULATOR_INIT(ldo16, "IRDA_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "3M_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VDDQ_M1M2_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data buck1_init_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 650000,
+ .max_uV = 2225000,
+ .always_on = 1,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1250000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck1_supply[0],
+};
+
+static struct regulator_init_data buck2_init_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 650000,
+ .max_uV = 2225000,
+ .always_on = 1,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck2_supply[0],
+};
+
+static struct regulator_init_data buck3_init_data = {
+ .constraints = {
+ .name = "G3D_1.1V",
+ .min_uV = 900000,
+ .max_uV = 1200000,
+ .always_on = 0,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck3_supply[0],
+};
+
+static struct regulator_init_data buck4_init_data = {
+ .constraints = {
+ .name = "3MP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck4_supply[0],
+};
+
+static struct regulator_init_data buck5_init_data = {
+ .constraints = {
+ .name = "VMEM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .uV = 1200000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data buck7_init_data = {
+ .constraints = {
+ .name = "VCC_SUB_2.0V",
+ .min_uV = 2000000,
+ .max_uV = 2000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck7_supply[0],
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 0,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_LDO1, &ldo1_init_data, NULL, },
+ { MAX8997_LDO3, &ldo3_init_data, NULL, },
+ { MAX8997_LDO4, &ldo4_init_data, NULL, },
+ { MAX8997_LDO5, &ldo5_init_data, NULL, },
+ { MAX8997_LDO7, &ldo7_init_data, NULL, },
+ { MAX8997_LDO8, &ldo8_init_data, NULL, },
+ { MAX8997_LDO10, &ldo10_init_data, NULL, },
+ { MAX8997_LDO11, &ldo11_init_data, NULL, },
+ { MAX8997_LDO12, &ldo12_init_data, NULL, },
+ { MAX8997_LDO13, &ldo13_init_data, NULL, },
+ { MAX8997_LDO14, &ldo14_init_data, NULL, },
+ { MAX8997_LDO15, &ldo15_init_data, NULL, },
+ { MAX8997_LDO16, &ldo16_init_data, NULL, },
+ { MAX8997_LDO17, &ldo17_init_data, NULL, },
+ { MAX8997_LDO18, &ldo18_init_data, NULL, },
+ { MAX8997_LDO21, &ldo21_init_data, NULL, },
+ { MAX8997_BUCK1, &buck1_init_data, NULL, },
+ { MAX8997_BUCK2, &buck2_init_data, NULL, },
+ { MAX8997_BUCK3, &buck3_init_data, NULL, },
+ { MAX8997_BUCK4, &buck4_init_data, NULL, },
+ { MAX8997_BUCK5, &buck5_init_data, NULL, },
+ { MAX8997_BUCK7, &buck7_init_data, NULL, },
+ { MAX8997_ESAFEOUT1, &safeout1_init_data, NULL, },
+ { MAX8997_ESAFEOUT2, &safeout2_init_data, NULL, },
+};
+
+static struct max8997_power_data max8997_power = {
+ .batt_detect = 1,
+};
+
+#ifdef CONFIG_VIBETONZ
+static struct max8997_motor_data max8997_motor = {
+#if defined(CONFIG_MACH_P8) || defined(CONFIG_MACH_P8LTE)
+ .reg2 = MOTOR_LRA | EXT_PWM | DIVIDER_256,
+#else
+ .reg2 = MOTOR_LRA | EXT_PWM | DIVIDER_128,
+#endif
+ .max_timeout = 10000,
+#if defined(CONFIG_MACH_P4)
+ .duty = 37000,
+ .period = 38675,
+#elif defined(CONFIG_MACH_P2)
+ .duty = 44707,
+ .period = 45159,
+#elif defined(CONFIG_MACH_P8) || defined(CONFIG_MACH_P8LTE)
+ .duty = 38288,
+ .period = 38676,
+#else
+ .duty = 37641,
+ .period = 38022,
+#endif
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#endif
+
+static struct max8997_buck1_dvs_funcs *buck1_dvs_funcs;
+
+void max8997_set_arm_voltage_table(int *voltage_table, int arr_size)
+{
+ pr_info("%s\n", __func__);
+ if (buck1_dvs_funcs && buck1_dvs_funcs->set_buck1_dvs_table)
+ buck1_dvs_funcs->set_buck1_dvs_table(buck1_dvs_funcs,
+ voltage_table, arr_size);
+}
+
+static void max8997_register_buck1dvs_funcs(struct max8997_buck1_dvs_funcs *ptr)
+{
+ buck1_dvs_funcs = ptr;
+}
+
+static struct max8997_platform_data exynos4_max8997_info = {
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = &max8997_regulators[0],
+ .irq_base = IRQ_BOARD_START,
+ .wakeup = 1,
+ .buck1_gpiodvs = false,
+ .buck1_max_vol = 1350000,
+ .buck2_max_vol = 1150000,
+ .buck5_max_vol = 1200000,
+ .buck_set1 = GPIO_BUCK1_EN_A,
+ .buck_set2 = GPIO_BUCK1_EN_B,
+ .buck_set3 = GPIO_BUCK2_EN,
+ .buck_ramp_en = true,
+ .buck_ramp_delay = 10, /* 10.00mV /us (default) */
+ .flash_cntl_val = 0x5F, /* Flash safety timer duration: 800msec,
+ Maximum timer mode */
+ .mr_debounce_time = 8, /* 8sec */
+ .power = &max8997_power,
+#ifdef CONFIG_VIBETONZ
+ .motor = &max8997_motor,
+#endif
+ .register_buck1_dvs_funcs = max8997_register_buck1dvs_funcs,
+};
+#endif /* CONFIG_REGULATOR_MAX8997 */
+
+
+#ifdef CONFIG_MPU_SENSORS_MPU3050
+
+extern struct class *sec_class;
+
+/* we use a skeleton to provide some information needed by MPL
+ * but we don't use the suspend/resume/read functions so we
+ * don't initialize them so that mldl_cfg.c doesn't try to
+ * control it directly. we have a separate mag driver instead.
+ */
+static struct mpu3050_platform_data mpu3050_pdata = {
+ .int_config = 0x12,
+ /* Orientation for MPU. Part is mounted rotated
+ * 90 degrees counter-clockwise from natural orientation.
+ * So X & Y are swapped and Y is negated.
+ */
+#if defined(CONFIG_MACH_P8)
+ .orientation = {0, 1, 0,
+ 1, 0, 0,
+ 0, 0, -1},
+#elif defined(CONFIG_MACH_P8LTE)
+ .orientation = {0, -1, 0,
+ 1, 0, 0,
+ 0, 0, 1},
+#elif defined(CONFIG_MACH_P2)
+ .orientation = {0, 1, 0,
+ 1, 0, 0,
+ 0, 0, -1},
+#elif defined(CONFIG_MACH_P4)
+ .orientation = {1 , 0, 0,
+ 0, -1, 0,
+ 0, 0, -1},
+#else
+ .orientation = {0, -1, 0,
+ -1, 0, 0,
+ 0, 0, -1},
+#endif
+ .level_shifter = 0,
+ .accel = {
+ .get_slave_descr = kxtf9_get_slave_descr,
+ .irq = 0, /* not used */
+ .adapt_num = 1,
+ .bus = EXT_SLAVE_BUS_SECONDARY,
+ .address = 0x0F,
+ /* Orientation for the Acc. Part is mounted rotated
+ * 180 degrees from natural orientation.
+ * So X & Y are both negated.
+ */
+#if defined(CONFIG_MACH_P8)
+ .orientation = {0, 1, 0,
+ 1, 0, 0,
+ 0, 0, -1},
+#elif defined(CONFIG_MACH_P8LTE)
+ .orientation = {0, 1, 0,
+ -1, 0, 0,
+ 0, 0, 1},
+#elif defined(CONFIG_MACH_P2)
+ .orientation = {0, 1, 0,
+ 1, 0, 0,
+ 0, 0, -1},
+#elif defined(CONFIG_MACH_P4)
+ .orientation = {0, -1, 0,
+ -1, 0, 0,
+ 0, 0, -1},
+#else
+ /* Rotate Accel Orientation for CL339008 */
+ .orientation = {0, -1, 0,
+ -1, 0, 0,
+ 0, 0, -1},
+#endif
+ },
+
+ .compass = {
+ .get_slave_descr = NULL,
+ .adapt_num = 7, /*bus number 7*/
+ .bus = EXT_SLAVE_BUS_PRIMARY,
+ .address = 0x0C,
+ /* Orientation for the Mag. Part is mounted rotated
+ * 90 degrees clockwise from natural orientation.
+ * So X & Y are swapped and Y & Z are negated.
+ */
+ .orientation = {0, -1, 0,
+ 1, 0, 0,
+ 0, 0, 1},
+ },
+
+};
+
+
+static void ak8975_init(void)
+{
+ gpio_request(GPIO_MSENSE_INT, "ak8975_int");
+ gpio_direction_input(GPIO_MSENSE_INT);
+}
+
+static void mpu3050_init(void)
+{
+ gpio_request(GPIO_GYRO_INT, "mpu3050_int");
+ gpio_direction_input(GPIO_GYRO_INT);
+ /* mpu3050_pdata.sec_class = sec_class; */
+}
+
+static const struct i2c_board_info i2c_mpu_sensor_board_info[] = {
+ {
+ I2C_BOARD_INFO("mpu3050", 0x68),
+ .irq = IRQ_EINT(0),
+ .platform_data = &mpu3050_pdata,
+ },
+#if 0
+ {
+ I2C_BOARD_INFO("kxtf9", 0x0F),
+ },
+#endif
+};
+#endif /* CONFIG_MPU_SENSORS_MPU3050 */
+
+static int check_bootmode(void)
+{
+ return __raw_readl(S5P_INFORM2);
+}
+
+static int check_jig_on(void)
+{
+ return !gpio_get_value(GPIO_IF_CON_SENSE);
+}
+
+/* Bluetooth */
+#ifdef CONFIG_BT_BCM4330
+static struct platform_device bcm4330_bluetooth_device = {
+ .name = "bcm4330_bluetooth",
+ .id = -1,
+};
+#endif /* CONFIG_BT_BCM4330 */
+
+#ifdef CONFIG_BT_CSR8811
+static struct platform_device csr8811_bluetooth_device = {
+ .name = "csr8811_bluetooth",
+ .id = -1,
+};
+#endif /* CONFIG_BT_CSR8811 */
+
+#define SYSTEM_REV_SND 0x09
+
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+static DEFINE_SPINLOCK(mic_bias_lock);
+#ifndef CONFIG_MACH_P8
+static bool mc1n2_mainmic_bias;
+static bool mc1n2_submic_bias;
+static void set_shared_mic_bias(void)
+{
+ if (system_rev >= 0x03)
+ gpio_set_value(GPIO_MIC_BIAS_EN, mc1n2_mainmic_bias
+ || mc1n2_submic_bias);
+ else
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, mc1n2_mainmic_bias
+ || mc1n2_submic_bias);
+}
+#endif
+void sec_set_sub_mic_bias(bool on)
+{
+#ifdef CONFIG_MACH_P4
+ return;
+#else
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+#ifdef CONFIG_MACH_P8
+ gpio_set_value(GPIO_SUB_MIC_BIAS_EN, on);
+#else
+ unsigned long flags;
+ spin_lock_irqsave(&mic_bias_lock, flags);
+ mc1n2_submic_bias = on;
+ set_shared_mic_bias();
+ spin_unlock_irqrestore(&mic_bias_lock, flags);
+#endif
+#endif
+#endif
+}
+
+void sec_set_main_mic_bias(bool on)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+
+#ifdef CONFIG_MACH_P8
+ gpio_set_value(GPIO_MAIN_MIC_BIAS_EN, on);
+#else
+ unsigned long flags;
+ spin_lock_irqsave(&mic_bias_lock, flags);
+ mc1n2_mainmic_bias = on;
+ set_shared_mic_bias();
+ spin_unlock_irqrestore(&mic_bias_lock, flags);
+#endif
+#endif
+}
+
+int sec_set_ldo1_constraints(int disabled)
+{
+#if 0 /* VADC_3.3V_C210 is always on */
+ struct regulator *regulator;
+
+ if (!disabled) {
+ regulator = regulator_get(NULL, "vadc_3.3v");
+ if (IS_ERR(regulator))
+ return -1;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vadc_3.3v");
+ if (IS_ERR(regulator))
+ return -1;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+#endif
+ return 0;
+}
+
+static struct mc1n2_platform_data mc1n2_pdata = {
+ .set_main_mic_bias = sec_set_main_mic_bias,
+ .set_sub_mic_bias = sec_set_sub_mic_bias,
+ .set_adc_power_constraints = sec_set_ldo1_constraints,
+};
+
+static void u1_sound_init(void)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+ int err;
+
+#ifdef CONFIG_MACH_P8
+ err = gpio_request(GPIO_MAIN_MIC_BIAS_EN, "GPC0");
+ if (err) {
+ pr_err(KERN_ERR "MAIN_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+
+ gpio_direction_output(GPIO_MAIN_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_MAIN_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_MAIN_MIC_BIAS_EN);
+
+ err = gpio_request(GPIO_SUB_MIC_BIAS_EN, "GPE1");
+ if (err) {
+ pr_err(KERN_ERR "GPIO_SUB_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_SUB_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_SUB_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_SUB_MIC_BIAS_EN);
+
+#else
+ err = gpio_request(GPIO_MIC_BIAS_EN, "GPE1");
+ if (err) {
+ pr_err(KERN_ERR "MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_MIC_BIAS_EN);
+
+#endif
+
+ err = gpio_request(GPIO_EAR_MIC_BIAS_EN, "GPE2");
+ if (err) {
+ pr_err(KERN_ERR "EAR_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_EAR_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_EAR_MIC_BIAS_EN);
+#ifndef CONFIG_MACH_PX
+ if (system_rev >= SYSTEM_REV_SND) {
+ err = gpio_request(GPIO_SUB_MIC_BIAS_EN, "submic_bias");
+ if (err) {
+ pr_err(KERN_ERR "SUB_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_SUB_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_SUB_MIC_BIAS_EN);
+ }
+#endif
+#endif
+}
+#endif
+
+/* IR_LED */
+#ifdef CONFIG_IR_REMOCON
+
+static struct platform_device ir_remote_device = {
+ .name = "ir_rc",
+ .id = 0,
+ .dev = {
+ },
+};
+
+#if defined(CONFIG_MACH_P2) || defined(CONFIG_MACH_P4)
+static void ir_rc_init_hw(void)
+{
+ s3c_gpio_cfgpin(GPIO_IRDA_CONTROL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_IRDA_CONTROL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_IRDA_CONTROL, 0);
+}
+#endif
+
+#if defined(CONFIG_MACH_P8LTE) || defined(CONFIG_MACH_P8)
+static void ir_rc_init_hw(void)
+{
+ s3c_gpio_cfgpin(GPIO_IRDA_nINT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_IRDA_nINT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_IRDA_nINT, 0);
+
+ s3c_gpio_cfgpin(GPIO_IRDA_EN, S3C_GPIO_OUTPUT);
+ S3C_gpio_setpull(GPIO_IRDA_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_IRDA_EN, 0);
+}
+#endif
+
+#endif
+/* IR_LED */
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+
+
+#if defined(CONFIG_SEC_THERMISTOR)
+static struct sec_therm_platform_data sec_therm_pdata = {
+ .adc_channel = 7,
+ .adc_arr_size = ARRAY_SIZE(adc_temp_table),
+ .adc_table = adc_temp_table,
+ .polling_interval = 60 * 1000, /* msecs */
+};
+
+static struct platform_device sec_device_thermistor = {
+ .name = "sec-thermistor",
+ .id = -1,
+ .dev.platform_data = &sec_therm_pdata,
+};
+#endif /* CONFIG_SEC_THERMISTOR */
+
+#ifdef CONFIG_KEYBOARD_GPIO
+#define GPIO_KEYS(_code, _gpio, _active_low, _iswake, _hook) \
+{ \
+ .code = _code, \
+ .gpio = _gpio, \
+ .active_low = _active_low, \
+ .type = EV_KEY, \
+ .wakeup = _iswake, \
+ .debounce_interval = 10, \
+ .isr_hook = _hook \
+}
+
+struct gpio_keys_button px_buttons[] = {
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+};
+
+struct gpio_keys_platform_data px_keys_platform_data = {
+ .buttons = px_buttons,
+ .nbuttons = ARRAY_SIZE(px_buttons),
+};
+
+struct platform_device px_gpio_keys = {
+ .name = "gpio-keys",
+ .dev.platform_data = &px_keys_platform_data,
+};
+#endif
+
+#ifdef CONFIG_SEC_DEV_JACK
+static void sec_set_jack_micbias(bool on)
+{
+#ifdef CONFIG_MACH_P8
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, on);
+#else
+ if (system_rev >= 3)
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, on);
+ else
+ gpio_set_value(GPIO_MIC_BIAS_EN, on);
+#endif
+}
+
+static struct sec_jack_zone sec_jack_zones[] = {
+ {
+ /* adc == 0, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 0,
+ .delay_ms = 15,
+ .check_count = 20,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 0 < adc <= 1200, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 1200,
+ .delay_ms = 10,
+ .check_count = 80,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 950 < adc <= 2600, unstable zone, default to 4pole if it
+ * stays in this range for 800ms (10ms delays, 80 samples)
+ */
+ .adc_high = 2600,
+ .delay_ms = 10,
+ .check_count = 10,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* 2600 < adc <= 3400, 3 pole zone, default to 3pole if it
+ * stays in this range for 100ms (10ms delays, 10 samples)
+ */
+ .adc_high = 3800,
+ .delay_ms = 10,
+ .check_count = 5,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* adc > 3400, unstable zone, default to 3pole if it stays
+ * in this range for two seconds (10ms delays, 200 samples)
+ */
+ .adc_high = 0x7fffffff,
+ .delay_ms = 10,
+ .check_count = 200,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+};
+
+/* To support 3-buttons earjack */
+static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = {
+ {
+ /* 0 <= adc <=170, stable zone */
+ .code = KEY_MEDIA,
+ .adc_low = 0,
+ .adc_high = 170,
+ },
+ {
+ /* 171 <= adc <= 370, stable zone */
+ .code = KEY_VOLUMEUP,
+ .adc_low = 171,
+ .adc_high = 370,
+ },
+ {
+ /* 371 <= adc <= 850, stable zone */
+ .code = KEY_VOLUMEDOWN,
+ .adc_low = 371,
+ .adc_high = 850,
+ },
+};
+
+static struct sec_jack_platform_data sec_jack_data = {
+ .set_micbias_state = sec_set_jack_micbias,
+ .zones = sec_jack_zones,
+ .num_zones = ARRAY_SIZE(sec_jack_zones),
+ .buttons_zones = sec_jack_buttons_zones,
+ .num_buttons_zones = ARRAY_SIZE(sec_jack_buttons_zones),
+ .det_gpio = GPIO_DET_35,
+ .send_end_gpio = GPIO_EAR_SEND_END,
+};
+
+static struct platform_device sec_device_jack = {
+ .name = "sec_jack",
+ .id = 1, /* will be used also for gpio_event id */
+ .dev.platform_data = &sec_jack_data,
+};
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_MMS152
+static struct tsp_callbacks *charger_cbs;
+
+static void sec_charger_melfas_cb(bool en)
+{
+ if (charger_cbs && charger_cbs->inform_charger)
+ charger_cbs->inform_charger(charger_cbs, en);
+
+ printk(KERN_DEBUG "[TSP] %s - %s\n", __func__,
+ en ? "on" : "off");
+}
+static void register_tsp_callbacks(struct tsp_callbacks *cb)
+{
+ charger_cbs = cb;
+}
+
+static void ts_power_on(void)
+{
+/* s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+*/
+ gpio_set_value(GPIO_TSP_RST, GPIO_LEVEL_HIGH);
+ msleep(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ pr_info("[TSP] TSP POWER ON\n");
+}
+
+static void ts_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+
+/* s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+*/
+ gpio_set_value(GPIO_TSP_RST, GPIO_LEVEL_LOW);
+ pr_info("[TSP] TSP POWER OFF");
+}
+
+static void ts_read_ta_status(bool *ta_status)
+{
+ *ta_status = is_cable_attached;
+}
+
+static void ts_set_touch_i2c(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_SDA, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SCL, S3C_GPIO_PULL_UP);
+ gpio_free(GPIO_TSP_SDA);
+ gpio_free(GPIO_TSP_SCL);
+}
+
+static void ts_set_touch_i2c_to_gpio(void)
+{
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL, S3C_GPIO_PULL_UP);
+ gpio_request(GPIO_TSP_SDA, "GPIO_TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "GPIO_TSP_SCL");
+
+}
+
+static struct ts_platform_data ts_data = {
+ .gpio_read_done = GPIO_TSP_INT,
+ .gpio_int = GPIO_TSP_INT,
+ .power_on = ts_power_on,
+ .power_off = ts_power_off,
+ .register_cb = register_tsp_callbacks,
+ .read_ta_status = ts_read_ta_status,
+ .set_touch_i2c = ts_set_touch_i2c,
+ .set_touch_i2c_to_gpio = ts_set_touch_i2c_to_gpio,
+};
+
+#endif /* ifdef CONFIG_TOUCHSCREEN_MMS152 */
+
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1
+static void mxt224_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+ /* printk("mxt224_power_on is finished\n"); */
+}
+
+static void mxt224_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+ /* printk("mxt224_power_off is finished\n"); */
+}
+
+#if defined(CONFIG_MACH_U1Q1_REV02)
+|| defined(CONFIG_MACH_Q1_REV00) || defined(CONFIG_MACH_Q1_REV02)
+static u8 t7_config[] = { GEN_POWERCONFIG_T7,
+ 64, 255, 20
+};
+
+static u8 t8_config[] = { GEN_ACQUISITIONCONFIG_T8,
+ 36, 0, 20, 20, 0, 0, 10, 10, 50, 25
+};
+
+static u8 t9_config[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 18, 11, 0, 16, MXT224_THRESHOLD, 2, 1, 0, 3, 1,
+ 0, MXT224_MAX_MT_FINGERS, 10, 10, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 5, 5, 5
+};
+
+static u8 t15_config[] = { TOUCH_KEYARRAY_T15,
+ 131, 16, 11, 2, 1, 0, 0, 40, 3, 0, 0
+};
+
+static u8 t18_config[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t48_config[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 0, 2, 10, 6, 12, 18, 24, 20, 30, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+static u8 t46_config[] = { SPT_CTECONFIG_T46,
+ 0, 2, 0, 0, 0, 0, 0
+};
+static u8 end_config[] = { RESERVED_T255 };
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t15_config,
+ t18_config,
+ t46_config,
+ t48_config,
+ end_config,
+};
+#else
+/*
+ Configuration for MXT224
+*/
+static u8 t7_config[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config[] = { GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, 9, 30
+}; /*byte 3: 0 */
+
+static u8 t9_config[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, MXT224_THRESHOLD, 2, 1,
+ 0,
+ 15, /* MOVHYSTI */
+ 1, 11, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 143, 55, 143, 90, 18
+};
+
+static u8 t18_config[] = { SPT_COMCONFIG_T18,
+ 0, 1
+};
+
+static u8 t20_config[] = { PROCI_GRIPFACESUPPRESSION_T20,
+ 7, 0, 0, 0, 0, 0, 0, 30, 20, 4, 15, 10
+};
+
+static u8 t22_config[] = { PROCG_NOISESUPPRESSION_T22,
+ 143, 0, 0, 0, 0, 0, 0, 3, 30, 0, 0, 29, 34, 39,
+ 49, 58, 3
+};
+
+static u8 t28_config[] = { SPT_CTECONFIG_T28,
+ 0, 0, 3, 16, 19, 60
+};
+static u8 end_config[] = { RESERVED_T255 };
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t18_config,
+ t20_config,
+ t22_config,
+ t28_config,
+ end_config,
+};
+
+/*
+ Configuration for MXT224-E
+*/
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 25
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 8, 8, 8, 180
+};
+
+/* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 1,
+ 10, 3, 1, 11, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 188, 52, 124, 21, 188, 52, 124, 21, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 32, 120, 100, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, 35, 0, 0, 1, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 4, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 5, 0, 38, 0, 5,
+ 0, 0, 0, 0, 0, 0, 32, 50, 2, 3, 1, 11, 10, 5, 40, 10, 10,
+ 10, 10, 143, 40, 143, 80, 18, 15, 2
+};
+
+static u8 t48_config_e_ta[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 5, 0, 38, 0, 20,
+ 0, 0, 0, 0, 0, 0, 16, 70, 2, 5, 2, 46, 10, 5, 40, 10, 0,
+ 10, 10, 143, 40, 143, 80, 18, 15, 2
+};
+
+#elif defined(CONFIG_MACH_U1_NA_SPR_EPIC2_REV00)
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 15
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 4, 35, 40, 55
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, 50, 2, 7,
+ 10, 3, 1, 46, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 32, 120, 100, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, 48, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 4, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0,
+ 0, 0, 0, 0, 32, 50, 2, 3, 1, 46,
+ 10, 5, 40, 10, 10, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+
+static u8 t48_config_e_ta[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 80, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 16, 70, 2, 5, 2, 46,
+ 10, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+#else
+
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 4, 35, 40, 55
+};
+
+#if 1 /* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, 46, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 0
+};
+
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, 46, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+#endif
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 1,
+ 10,
+ 15, /* MOVHYSTI */
+ 1, 46, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 0
+};
+#endif
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 16, MXT224_THRESHOLD, 2, 1, 10, 3, 1,
+ 0, MXT224_MAX_MT_FINGERS, 10, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80, 18, 15, 50, 50
+};
+#endif
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 13, 19, 44, 0, 0, 0
+};
+#else
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 14, 23, 44, 0, 0, 0
+};
+#endif
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, 40, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t48_config_e_ta[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x52, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 10, 5, 0, 19, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 47,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x40, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#else
+static u8 t48_config_e_ta[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 15,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 2
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, 50, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+#endif /*CONFIG_MACH_U1_NA_USCC_REV05 */
+#else
+static u8 t48_config_e_ta[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x52, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 9, 5, 0, 15, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 15, /* MOVHYSTI */
+ 1, 47,
+ 10, 5, 40, 235, 235, 10, 10, 160, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x40, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD, 2,
+ 15,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 10, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#endif /*CONFIG_TARGET_LOCALE_NA */
+#endif /*CONFIG_TARGET_LOCALE_NAATT */
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt224e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t23_config_e,
+ t25_config_e,
+ t38_config_e,
+ t40_config_e,
+ t42_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ end_config_e,
+};
+#endif
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = MXT224_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+#if defined(CONFIG_MACH_U1Q1_REV02)
+|| defined(CONFIG_MACH_Q1_REV00) || defined(CONFIG_MACH_Q1_REV02)
+ .config = mxt224_config,
+#else
+ .config = mxt224_config,
+ .config_e = mxt224e_config,
+ .t48_ta_cfg = t48_config_e_ta,
+#endif
+ .min_x = 0,
+ .max_x = 479,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+};
+
+#endif /*CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1 */
+
+#if defined(CONFIG_TOUCHSCREEN_MXT540E)
+
+void tsp_register_callback(void *function)
+{
+ charging_cbs.tsp_set_charging_cable = function;
+}
+
+void tsp_read_ta_status(bool *ta_status)
+{
+ *ta_status = is_cable_attached;
+}
+
+static void mxt540e_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, GPIO_LEVEL_HIGH);
+ msleep(MXT540E_HW_RESET_TIME);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+}
+
+static void mxt540e_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, GPIO_LEVEL_LOW);
+}
+
+/*
+ Configuration for MXT540E
+*/
+#define MXT540E_MAX_MT_FINGERS 10
+#define MXT540E_CHRGTIME_BATT 68
+#define MXT540E_CHRGTIME_CHRG 60
+#define MXT540E_THRESHOLD_BATT 50
+#define MXT540E_THRESHOLD_CHRG 60
+#define MXT540E_ACTVSYNCSPERX_BATT 36
+#define MXT540E_ACTVSYNCSPERX_CHRG 24
+#define MXT540E_CALCFG_BATT 64
+#define MXT540E_CALCFG_CHRG 80
+#define MXT540E_ATCHFRCCALTHR_WAKEUP 8
+#define MXT540E_ATCHFRCCALRATIO_WAKEUP 180
+#define MXT540E_ATCHFRCCALTHR_NORMAL 40
+#define MXT540E_ATCHFRCCALRATIO_NORMAL 55
+
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 50
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT540E_CHRGTIME_BATT, 0, 5, 1, 0, 0, 4, 30,
+ MXT540E_ATCHFRCCALTHR_WAKEUP, MXT540E_ATCHFRCCALRATIO_WAKEUP
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 16, 26, 0, 176, MXT540E_THRESHOLD_BATT, 2, 6, 10, 10, 1,
+ 47, MXT540E_MAX_MT_FINGERS, 5, 20, 20, 31, 3,
+ 255, 4, 253, 3, 254, 2, 136, 60, 136, 40, 18, 12, 0, 0, 2
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t19_config_e[] = { SPT_GPIOPWM_T19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t24_config_e[] = { PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t27_config_e[] = { PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t43_config_e[] = { SPT_DIGITIZER_T43,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 0, 24, MXT540E_ACTVSYNCSPERX_BATT, 0, 0, 1, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 30, 60, 15, 2, 20, 20, 150, 0, 32
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 132, MXT540E_CALCFG_BATT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 6, 0, 46, 0, 1,
+ 0, 0, 0, 0, 0, 0, 176, MXT540E_THRESHOLD_BATT, 2, 10, 1, 47,
+ MXT540E_MAX_MT_FINGERS, 5, 20, 253, 3,
+ 254, 2, 136, 60, 136, 40, 18, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 132, MXT540E_CALCFG_CHRG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 10, 0, 46, 0, 10,
+ 0, 0, 0, 0, 0, 0, 128, MXT540E_THRESHOLD_CHRG, 2, 10, 1, 0,
+ MXT540E_MAX_MT_FINGERS, 5, 20, 240, 240,
+ 10, 10, 138, 70, 132, 0, 18, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t52_config_e[] = { TOUCH_PROXKEY_T52,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt540e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t19_config_e,
+ t24_config_e,
+ t25_config_e,
+ t27_config_e,
+ t40_config_e,
+ t42_config_e,
+ t43_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ t52_config_e,
+ end_config_e,
+};
+
+struct mxt540e_platform_data mxt540e_data = {
+ .max_finger_touches = MXT540E_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config_e = mxt540e_config,
+ .min_x = 0,
+ .max_x = 799,
+ .min_y = 0,
+ .max_y = 1279,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .chrgtime_batt = MXT540E_CHRGTIME_BATT,
+ .chrgtime_charging = MXT540E_CHRGTIME_CHRG,
+ .tchthr_batt = MXT540E_THRESHOLD_BATT,
+ .tchthr_charging = MXT540E_THRESHOLD_CHRG,
+ .actvsyncsperx_batt = MXT540E_ACTVSYNCSPERX_BATT,
+ .actvsyncsperx_charging = MXT540E_ACTVSYNCSPERX_CHRG,
+ .calcfg_batt_e = MXT540E_CALCFG_BATT,
+ .calcfg_charging_e = MXT540E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT540E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT540E_ATCHFRCCALRATIO_NORMAL,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .power_on = mxt540e_power_on,
+ .power_off = mxt540e_power_off,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_MXT768E)
+
+static void ts_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, GPIO_LEVEL_HIGH);
+ msleep(70);
+ s3c_gpio_setpull(GPIO_TSP_INT_18V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT_18V, S3C_GPIO_SFN(0xf));
+ msleep(40);
+ printk(KERN_DEBUG"mxt_power_on is finished\n");
+
+}
+
+static void ts_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT_18V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT_18V, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, GPIO_LEVEL_LOW);
+ printk(KERN_DEBUG"mxt_power_off is finished\n");
+}
+
+static void ts_register_callback(void *function)
+{
+ printk(KERN_DEBUG"mxt_register_callback\n");
+ charging_cbs.tsp_set_charging_cable = function;
+}
+
+static void ts_read_ta_status(bool *ta_status)
+{
+ *ta_status = is_cable_attached;
+}
+/*
+ Configuration for MXT768-E
+*/
+#define MXT768E_MAX_MT_FINGERS 10
+#define MXT768E_CHRGTIME_BATT 64
+#define MXT768E_CHRGTIME_CHRG 64
+#define MXT768E_THRESHOLD_BATT 50
+#define MXT768E_THRESHOLD_CHRG 48
+#define MXT768E_CALCFG_BATT 210
+#define MXT768E_CALCFG_CHRG 242
+
+#define MXT768E_ATCHCALSTHR_NORMAL 50
+#define MXT768E_ATCHFRCCALTHR_NORMAL 50
+#define MXT768E_ATCHFRCCALRATIO_NORMAL 0
+#define MXT768E_ATCHFRCCALTHR_WAKEUP 8
+#define MXT768E_ATCHFRCCALRATIO_WAKEUP 136
+
+#define MXT768E_IDLESYNCSPERX_BATT 38
+#define MXT768E_IDLESYNCSPERX_CHRG 40
+#define MXT768E_ACTVSYNCSPERX_BATT 38
+#define MXT768E_ACTVSYNCSPERX_CHRG 40
+
+#define MXT768E_IDLEACQINT_BATT 24
+#define MXT768E_IDLEACQINT_CHRG 24
+#define MXT768E_ACTACQINT_BATT 255
+#define MXT768E_ACTACQINT_CHRG 255
+
+#define MXT768E_XLOCLIP_BATT 0
+#define MXT768E_XLOCLIP_CHRG 12
+#define MXT768E_XHICLIP_BATT 0
+#define MXT768E_XHICLIP_CHRG 12
+#define MXT768E_YLOCLIP_BATT 0
+#define MXT768E_YLOCLIP_CHRG 5
+#define MXT768E_YHICLIP_BATT 0
+#define MXT768E_YHICLIP_CHRG 5
+#define MXT768E_XEDGECTRL_BATT 136
+#define MXT768E_XEDGECTRL_CHRG 128
+#define MXT768E_XEDGEDIST_BATT 50
+#define MXT768E_XEDGEDIST_CHRG 0
+#define MXT768E_YEDGECTRL_BATT 136
+#define MXT768E_YEDGECTRL_CHRG 136
+#define MXT768E_YEDGEDIST_BATT 40
+#define MXT768E_YEDGEDIST_CHRG 30
+#define MXT768E_TCHHYST_BATT 15
+#define MXT768E_TCHHYST_CHRG 15
+
+
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ MXT768E_IDLEACQINT_BATT, MXT768E_ACTACQINT_BATT, 7
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT768E_CHRGTIME_BATT, 0, 5, 1, 0, 0, 4,
+ MXT768E_ATCHCALSTHR_NORMAL,
+ MXT768E_ATCHFRCCALTHR_WAKEUP,
+ MXT768E_ATCHFRCCALRATIO_WAKEUP
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 24, 32, 0, 176, MXT768E_THRESHOLD_BATT, 2, 1,
+ 10, 10, 1, 13, MXT768E_MAX_MT_FINGERS, 20, 40, 20, 31, 3,
+ 255, 4, MXT768E_XLOCLIP_BATT, MXT768E_XHICLIP_BATT,
+ MXT768E_YLOCLIP_BATT, MXT768E_YHICLIP_BATT,
+ MXT768E_XEDGECTRL_BATT, MXT768E_XEDGEDIST_BATT,
+ MXT768E_YEDGECTRL_BATT, MXT768E_YEDGEDIST_BATT,
+ 12, MXT768E_TCHHYST_BATT, 43, 51, 0
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t19_config_e[] = { SPT_GPIOPWM_T19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 3/*51*/, 15, 100, 64, 224, 2, 0, 0, 200, 200
+};
+
+static u8 t43_config_e[] = { SPT_DIGITIZER_T43,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 0, MXT768E_IDLESYNCSPERX_BATT,
+ MXT768E_ACTVSYNCSPERX_BATT, 0, 0, 2, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_e[] = {PROCG_NOISESUPPRESSION_T48,
+ 3, 0, MXT768E_CALCFG_BATT, 0, 0, 0, 0, 0, 0, 0,
+ 176, 15, 0, 6, 6, 0, 0, 48, 4, 64,
+ 0, 0, 20, 0, 0, 0, 0, 15, 0, 0,
+ 0, 0, 0, 0, 112, MXT768E_THRESHOLD_CHRG, 2, 16, 2, 80,
+ MXT768E_MAX_MT_FINGERS, 20, 40, 250, 250, 5, 5, 143, 50, 136,
+ 30, 12, MXT768E_TCHHYST_CHRG, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static u8 t48_config_chrg_e[] = {PROCG_NOISESUPPRESSION_T48,
+ 3, 0, MXT768E_CALCFG_CHRG, 0, 0, 0, 0, 0, 0, 0,
+ 112, 15, 0, 6, 6, 0, 0, 44, 4, 64,
+ 0, 0, 20, 0, 0, 0, 0, 15, 0, 0,
+ 0, 0, 0, 0, 112, MXT768E_THRESHOLD_CHRG, 2, 16, 8, 80,
+ MXT768E_MAX_MT_FINGERS, 20, 40, 251, 251, 6, 6, 144, 50, 136,
+ 30, 12, MXT768E_TCHHYST_CHRG, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static u8 t52_config_e[] = { TOUCH_PROXIMITY_KEY_T52,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t55_config_e[] = {ADAPTIVE_T55,
+ 0, 0, 0, 0, 0
+};
+
+/* T56 used from 2.0 firmware */
+static u8 t56_config_e[] = {PROCI_SHIELDLESS_T56,
+ 1, 0, 1, 47, 14, 15, 15, 16, 15, 17,
+ 16, 16, 16, 16, 17, 16, 16, 16, 16, 16,
+ 16, 16, 15, 15, 14, 13, 12, 14, 0, 48,
+ 1, 1, 27, 4
+};
+
+static u8 t57_config_e[] = {SPT_GENERICDATA_T57,
+ 131/*0*/, 15, 0
+};
+
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt768e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t19_config_e,
+ t25_config_e,
+ t40_config_e,
+ t42_config_e,
+ t43_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ t52_config_e,
+ t55_config_e,
+ t56_config_e,
+ t57_config_e,
+ end_config_e,
+};
+
+static struct mxt_platform_data mxt_data = {
+ .max_finger_touches = MXT768E_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT_18V,
+ .config = mxt768e_config,
+ .min_x = 0,
+ .max_x = 1279,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .tchthr_batt = MXT768E_THRESHOLD_BATT,
+ .tchthr_charging = MXT768E_THRESHOLD_CHRG,
+ .calcfg_batt = MXT768E_CALCFG_BATT,
+ .calcfg_charging = MXT768E_CALCFG_CHRG,
+ .idlesyncsperx_batt = MXT768E_IDLESYNCSPERX_BATT,
+ .idlesyncsperx_charging = MXT768E_IDLESYNCSPERX_CHRG,
+ .actvsyncsperx_batt = MXT768E_ACTVSYNCSPERX_BATT,
+ .actvsyncsperx_charging = MXT768E_ACTVSYNCSPERX_CHRG,
+ .xloclip_batt = MXT768E_XLOCLIP_BATT,
+ .xloclip_charging = MXT768E_XLOCLIP_CHRG,
+ .xhiclip_batt = MXT768E_XHICLIP_BATT,
+ .xhiclip_charging = MXT768E_XHICLIP_CHRG,
+ .yloclip_batt = MXT768E_YLOCLIP_BATT,
+ .yloclip_charging = MXT768E_YLOCLIP_CHRG,
+ .yhiclip_batt = MXT768E_YHICLIP_BATT,
+ .yhiclip_charging = MXT768E_YHICLIP_CHRG,
+ .xedgectrl_batt = MXT768E_XEDGECTRL_BATT,
+ .xedgectrl_charging = MXT768E_XEDGECTRL_CHRG,
+ .xedgedist_batt = MXT768E_XEDGEDIST_BATT,
+ .xedgedist_charging = MXT768E_XEDGEDIST_CHRG,
+ .yedgectrl_batt = MXT768E_YEDGECTRL_BATT,
+ .yedgectrl_charging = MXT768E_YEDGECTRL_CHRG,
+ .yedgedist_batt = MXT768E_YEDGEDIST_BATT,
+ .yedgedist_charging = MXT768E_YEDGEDIST_CHRG,
+ .t48_config_batt = t48_config_e,
+ .t48_config_chrg = t48_config_chrg_e,
+ .power_on = ts_power_on,
+ .power_off = ts_power_off,
+ .register_cb = ts_register_callback,
+ .read_ta_status = ts_read_ta_status,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_MXT1386)
+static struct mxt_callbacks *charger_callbacks;
+static void sec_mxt1386_charger_infom(bool en)
+{
+ if (charger_callbacks && charger_callbacks->inform_charger)
+ charger_callbacks->inform_charger(charger_callbacks, en);
+
+ printk(KERN_DEBUG "[TSP] %s - %s\n", __func__,
+ en ? "on" : "off");
+}
+static void p3_register_touch_callbacks(struct mxt_callbacks *cb)
+{
+ charger_callbacks = cb;
+}
+
+static void mxt1386_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 1);
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+ printk(KERN_ERR "[TSP]mxt1386_power_on is finished\n");
+}
+
+static void mxt1386_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 0);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+ /* printk("mxt224_power_off is finished\n"); */
+}
+
+static struct mxt_platform_data p4w_touch_platform_data = {
+ .numtouch = 10,
+ .max_x = 1280,
+ .max_y = 800,
+ .init_platform_hw = mxt1386_power_on,
+ .exit_platform_hw = mxt1386_power_off,
+ .suspend_platform_hw = mxt1386_power_off,
+ .resume_platform_hw = mxt1386_power_on,
+ .register_cb = p3_register_touch_callbacks,
+ /*mxt_power_config*/
+ /* Set Idle Acquisition Interval to 32 ms. */
+ .power_config.idleacqint = 32,
+ .power_config.actvacqint = 255,
+ /* Set Active to Idle Timeout to 4 s (one unit = 200ms). */
+ .power_config.actv2idleto = 50,
+ /*acquisition_config*/
+ /* Atmel: 8 -> 10*/
+ .acquisition_config.chrgtime = 10,
+ .acquisition_config.reserved = 0,
+ .acquisition_config.tchdrift = 5,
+ /* Atmel: 0 -> 10*/
+ .acquisition_config.driftst = 10,
+ /* infinite*/
+ .acquisition_config.tchautocal = 0,
+ /* disabled*/
+ .acquisition_config.sync = 0,
+#ifdef MXT_CALIBRATE_WORKAROUND
+ /*autocal config at wakeup status*/
+ .acquisition_config.atchcalst = 9,
+ .acquisition_config.atchcalsthr = 48,
+ /* Atmel: 50 => 10 : avoid wakeup lockup : 2 or 3 finger*/
+ .acquisition_config.atchcalfrcthr = 10,
+ .acquisition_config.atchcalfrcratio = 215,
+#else
+ /* Atmel: 5 -> 0 -> 9 (to avoid ghost touch problem)*/
+ .acquisition_config.atchcalst = 9,
+ /* Atmel: 50 -> 55 -> 48 ->10 (to avoid ghost touch problem)*/
+ .acquisition_config.atchcalsthr = 10,
+ /* 50-> 20 (To avoid wakeup touch lockup) */
+ .acquisition_config.atchcalfrcthr = 20,
+ /* 25-> 0 (To avoid wakeup touch lockup */
+ .acquisition_config.atchcalfrcratio = 0,
+#endif
+ /*multitouch_config*/
+ /* enable + message-enable*/
+ .touchscreen_config.ctrl = 0x8b,
+ .touchscreen_config.xorigin = 0,
+ .touchscreen_config.yorigin = 0,
+ .touchscreen_config.xsize = 27,
+ .touchscreen_config.ysize = 42,
+ .touchscreen_config.akscfg = 0,
+ /* Atmel: 0x11 -> 0x21 -> 0x11*/
+ .touchscreen_config.blen = 0x11,
+ /* Atmel: 50 -> 55 -> 48,*/
+ .touchscreen_config.tchthr = 48,
+ .touchscreen_config.tchdi = 2,
+ /* orient : Horizontal flip */
+ .touchscreen_config.orient = 1,
+ .touchscreen_config.mrgtimeout = 0,
+ .touchscreen_config.movhysti = 10,
+ .touchscreen_config.movhystn = 1,
+ /* Atmel 0x20 ->0x21 -> 0x2e(-2)*/
+ .touchscreen_config.movfilter = 0x50,
+ .touchscreen_config.numtouch = MXT_MAX_NUM_TOUCHES,
+ .touchscreen_config.mrghyst = 5, /*Atmel 10 -> 5*/
+ /* Atmel 20 -> 5 -> 50 (To avoid One finger Pinch Zoom) */
+ .touchscreen_config.mrgthr = 50,
+ .touchscreen_config.amphyst = 10,
+ .touchscreen_config.xrange = 799,
+ .touchscreen_config.yrange = 1279,
+ .touchscreen_config.xloclip = 0,
+ .touchscreen_config.xhiclip = 0,
+ .touchscreen_config.yloclip = 0,
+ .touchscreen_config.yhiclip = 0,
+ .touchscreen_config.xedgectrl = 0,
+ .touchscreen_config.xedgedist = 0,
+ .touchscreen_config.yedgectrl = 0,
+ .touchscreen_config.yedgedist = 0,
+ .touchscreen_config.jumplimit = 18,
+ .touchscreen_config.tchhyst = 10,
+ .touchscreen_config.xpitch = 1,
+ .touchscreen_config.ypitch = 3,
+ /*noise_suppression_config*/
+ .noise_suppression_config.ctrl = 0x87,
+ .noise_suppression_config.reserved = 0,
+ .noise_suppression_config.reserved1 = 0,
+ .noise_suppression_config.reserved2 = 0,
+ .noise_suppression_config.reserved3 = 0,
+ .noise_suppression_config.reserved4 = 0,
+ .noise_suppression_config.reserved5 = 0,
+ .noise_suppression_config.reserved6 = 0,
+ .noise_suppression_config.noisethr = 30,
+ .noise_suppression_config.reserved7 = 0,/*1;*/
+ .noise_suppression_config.freqhopscale = 0,
+ .noise_suppression_config.freq[0] = 10,
+ .noise_suppression_config.freq[1] = 18,
+ .noise_suppression_config.freq[2] = 23,
+ .noise_suppression_config.freq[3] = 30,
+ .noise_suppression_config.freq[4] = 36,
+ .noise_suppression_config.reserved8 = 0, /* 3 -> 0*/
+ /*cte_config*/
+ .cte_config.ctrl = 0,
+ .cte_config.cmd = 0,
+ .cte_config.mode = 0,
+ /*16 -> 4 -> 8*/
+ .cte_config.idlegcafdepth = 8,
+ /*63 -> 16 -> 54(16ms sampling)*/
+ .cte_config.actvgcafdepth = 54,
+ .cte_config.voltage = 0x3c,
+ /* (enable + non-locking mode)*/
+ .gripsupression_config.ctrl = 0,
+ .gripsupression_config.xlogrip = 0, /*10 -> 0*/
+ .gripsupression_config.xhigrip = 0, /*10 -> 0*/
+ .gripsupression_config.ylogrip = 0, /*10 -> 15*/
+ .gripsupression_config.yhigrip = 0,/*10 -> 15*/
+ .palmsupression_config.ctrl = 1,
+ .palmsupression_config.reserved1 = 0,
+ .palmsupression_config.reserved2 = 0,
+ /* 40 -> 20(For PalmSuppression detect) */
+ .palmsupression_config.largeobjthr = 10,
+ /* 5 -> 50(For PalmSuppression detect) */
+ .palmsupression_config.distancethr = 50,
+ .palmsupression_config.supextto = 5,
+ /*config change for ta connected*/
+ .idleacqint_for_ta_connect = 255,
+ .tchthr_for_ta_connect = 80,
+ .noisethr_for_ta_connect = 50,
+ .idlegcafdepth_ta_connect = 32,
+ .fherr_cnt = 0,
+ .fherr_chg_cnt = 10,
+ .tch_blen_for_fherr = 0x11,
+ .tchthr_for_fherr = 85,
+ .noisethr_for_fherr = 50,
+ .movefilter_for_fherr = 0x57,
+ .jumplimit_for_fherr = 30,
+ .freqhopscale_for_fherr = 1,
+ .freq_for_fherr1[0] = 10,
+ .freq_for_fherr1[1] = 12,
+ .freq_for_fherr1[2] = 18,
+ .freq_for_fherr1[3] = 40,
+ .freq_for_fherr1[4] = 72,
+ .freq_for_fherr2[0] = 45,
+ .freq_for_fherr2[1] = 49,
+ .freq_for_fherr2[2] = 55,
+ .freq_for_fherr2[3] = 59,
+ .freq_for_fherr2[4] = 63,
+ .freq_for_fherr3[0] = 7,
+ .freq_for_fherr3[1] = 33,
+ .freq_for_fherr3[2] = 39,
+ .freq_for_fherr3[3] = 52,
+ .freq_for_fherr3[4] = 64,
+ .fherr_cnt_no_ta = 0,
+ .fherr_chg_cnt_no_ta = 1,
+ .tch_blen_for_fherr_no_ta = 0,
+ .tchthr_for_fherr_no_ta = 45,
+ .movfilter_fherr_no_ta = 0,
+ .noisethr_for_fherr_no_ta = 40,
+#ifdef MXT_CALIBRATE_WORKAROUND
+ /*autocal config at idle status*/
+ .atchcalst_idle = 9,
+ .atchcalsthr_idle = 10,
+ .atchcalfrcthr_idle = 50,
+ /* Atmel: 25 => 55 : avoid idle palm on lockup*/
+ .atchcalfrcratio_idle = 55,
+#endif
+};
+#endif
+
+#if defined(CONFIG_RMI4_I2C)
+static int synaptics_tsp_pre_suspend(const void *pm_data)
+{
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_INT, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+
+ return 0;
+}
+
+static int synaptics_tsp_post_resume(const void *pm_data)
+{
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 1);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_I2C_S3C2410
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ {I2C_BOARD_INFO("24c128", 0x50),}, /* Samsung S524AD0XD1 */
+ {I2C_BOARD_INFO("24c128", 0x52),}, /* Samsung S524AD0XD1 */
+};
+
+#ifdef CONFIG_S3C_DEV_I2C1
+
+#ifndef CONFIG_MPU_SENSORS_MPU3050
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("k3g", 0x69),
+ .irq = IRQ_EINT(1),
+ },
+ {
+ I2C_BOARD_INFO("k3dh", 0x19),
+ },
+};
+
+#endif /* !CONFIG_MPU_SENSORS_MPU3050 */
+
+#endif /* CONFIG_S3C_DEV_I2C1 */
+
+#ifdef CONFIG_S3C_DEV_I2C2
+/* I2C2 */
+static struct i2c_board_info i2c_devs2[] __initdata = {
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C3
+/* I2C3 */
+#if defined(CONFIG_TOUCHSCREEN_MXT1386) \
+ || defined(CONFIG_RMI4_I2C)
+#include <plat/regs-iic.h>
+static struct s3c2410_platform_i2c i2c3_data __initdata = {
+ .flags = 0,
+ .bus_num = 3,
+ .slave_addr = 0x10,
+ .frequency = 400 * 1000,
+ .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+};
+#endif
+
+#if defined(CONFIG_RMI4_I2C)
+#include <linux/rmi.h>
+#define SYNAPTICS_RMI_NAME "rmi-i2c"
+#define SYNAPTICS_RMI_ADDR 0x20
+static struct rmi_device_platform_data synaptics_pdata = {
+ .driver_name = "rmi-generic",
+ .sensor_name = "s7301",
+ .attn_gpio = GPIO_TSP_INT,
+ .attn_polarity = RMI_ATTN_ACTIVE_LOW,
+ .axis_align = { },
+ .pm_data = NULL,
+ .pre_suspend = synaptics_tsp_pre_suspend,
+ .post_resume = synaptics_tsp_post_resume,
+};
+#endif /* CONFIG_RMI4_I2C */
+
+#if defined(CONFIG_TOUCHSCREEN_MXT1386) \
+ && defined(CONFIG_RMI4_I2C)
+static struct i2c_board_info i2c_devs3_mxt[] __initdata = {
+ {
+ I2C_BOARD_INFO("sec_touchscreen", 0x4c),
+ .platform_data = &p4w_touch_platform_data,
+ },
+};
+static struct i2c_board_info i2c_devs3_syn[] __initdata = {
+ {
+ I2C_BOARD_INFO(SYNAPTICS_RMI_NAME,
+ SYNAPTICS_RMI_ADDR),
+ .platform_data = &synaptics_pdata,
+ },
+};
+
+#else /* defined(CONFIG_TOUCHSCREEN_MXT1386) \
+ && defined(CONFIG_RMI4_I2C)*/
+
+static struct i2c_board_info i2c_devs3[] __initdata = {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_MXT540E)
+ {
+ I2C_BOARD_INFO(MXT540E_DEV_NAME, 0x4c),
+ .platform_data = &mxt540e_data,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_MXT768E)
+ {
+ I2C_BOARD_INFO(MXT_DEV_NAME, 0x4c),
+ .platform_data = &mxt_data
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_MMS152)
+ {
+ I2C_BOARD_INFO(TS_DEV_NAME, TS_DEV_ADDR),
+ .platform_data = &ts_data,
+ },
+#endif
+};
+
+#endif /* defined(CONFIG_TOUCHSCREEN_MXT1386) \
+ && defined(CONFIG_RMI4_I2C)*/
+#endif /* CONFIG_S3C_DEV_I2C3 */
+
+#ifdef CONFIG_S3C_DEV_I2C4
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p4w_wacom_init_hw(void);
+static int p4w_wacom_suspend_hw(void);
+static int p4w_wacom_resume_hw(void);
+static int p4w_wacom_early_suspend_hw(void);
+static int p4w_wacom_late_resume_hw(void);
+static int p4w_wacom_reset_hw(void);
+static void p4w_wacom_register_callbacks(struct wacom_g5_callbacks *cb);
+
+static struct wacom_g5_platform_data p4w_wacom_platform_data = {
+ .x_invert = 0,
+ .y_invert = 0,
+ .xy_switch = 0,
+ .gpio_pendct = GPIO_PEN_PDCT_18V,
+ .init_platform_hw = p4w_wacom_init_hw,
+ .suspend_platform_hw = p4w_wacom_suspend_hw,
+ .resume_platform_hw = p4w_wacom_resume_hw,
+ .early_suspend_platform_hw = p4w_wacom_early_suspend_hw,
+ .late_resume_platform_hw = p4w_wacom_late_resume_hw,
+ .reset_platform_hw = p4w_wacom_reset_hw,
+ .register_cb = p4w_wacom_register_callbacks,
+};
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+/* I2C4 */
+static struct i2c_board_info i2c_devs4[] __initdata = {
+#ifdef CONFIG_EPEN_WACOM_G5SP
+ {
+ I2C_BOARD_INFO("wacom_g5sp_i2c", 0x56),
+ .platform_data = &p4w_wacom_platform_data,
+ },
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+};
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static void p4w_wacom_register_callbacks(struct wacom_g5_callbacks *cb)
+{
+ wacom_callbacks = cb;
+};
+
+static int __init p4w_wacom_init(void)
+{
+ p4w_wacom_init_hw();
+ gpio_set_value(GPIO_PEN_LDO_EN, 1);
+ printk(KERN_INFO "[E-PEN]: %s.\n", __func__);
+ return 0;
+}
+
+static int p4w_wacom_init_hw(void)
+{
+ int ret;
+ ret = gpio_request(GPIO_PEN_LDO_EN, "PEN_LDO_EN");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN]: faile to request gpio(GPIO_PEN_LDO_EN)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_LDO_EN, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_PEN_LDO_EN, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_PEN_LDO_EN, 0);
+
+ ret = gpio_request(GPIO_PEN_PDCT_18V, "PEN_PDCT");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN]: faile to request gpio(GPIO_PEN_PDCT_18V)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_PDCT_18V, S3C_GPIO_SFN(0x0));
+ s3c_gpio_setpull(GPIO_PEN_PDCT_18V, S3C_GPIO_PULL_NONE);
+ gpio_direction_input(GPIO_PEN_PDCT_18V);
+
+ ret = gpio_request(GPIO_PEN_SLP_18V, "PEN_SLP");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN]: faile to request gpio(GPIO_PEN_SLP_18V)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_SLP_18V, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_PEN_SLP_18V, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_PEN_SLP_18V, 0);
+
+ ret = gpio_request(GPIO_PEN_IRQ_18V, "PEN_IRQ");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN]: faile to request gpio(GPIO_PEN_IRQ_18V)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_IRQ_18V, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_PEN_IRQ_18V, S3C_GPIO_PULL_DOWN);
+ s5p_register_gpio_interrupt(GPIO_PEN_IRQ_18V);
+ gpio_direction_input(GPIO_PEN_IRQ_18V);
+ i2c_devs4[0].irq = gpio_to_irq(GPIO_PEN_IRQ_18V);
+ return 0;
+}
+
+static int p4w_wacom_suspend_hw(void)
+{
+ return p4w_wacom_early_suspend_hw();
+}
+
+static int p4w_wacom_resume_hw(void)
+{
+ return p4w_wacom_late_resume_hw();
+}
+
+static int p4w_wacom_early_suspend_hw(void)
+{
+#if defined(WACOM_SLEEP_WITH_PEN_SLP)
+ gpio_set_value(GPIO_PEN_SLP_18V, 1);
+#elif defined(WACOM_SLEEP_WITH_PEN_LDO_EN)
+ gpio_set_value(GPIO_PEN_LDO_EN, 0);
+#endif
+ return 0;
+}
+
+static int p4w_wacom_late_resume_hw(void)
+{
+#if defined(WACOM_SLEEP_WITH_PEN_SLP)
+ gpio_set_value(GPIO_PEN_SLP_18V, 0);
+#elif defined(WACOM_SLEEP_WITH_PEN_LDO_EN)
+ gpio_set_value(GPIO_PEN_LDO_EN, 1);
+#endif
+
+#if (WACOM_HAVE_RESET_CONTROL == 1)
+ msleep(WACOM_DELAY_FOR_RST_RISING);
+ gpio_set_value(GPIO_PEN_SLP_18V, 1);
+#endif
+ return 0;
+}
+static int p4w_wacom_reset_hw(void)
+{
+
+#if (WACOM_HAVE_RESET_CONTROL == 1)
+ gpio_set_value(OMAP_GPIO_PEN_RST, 0);
+ msleep(200);
+ gpio_set_value(OMAP_GPIO_PEN_RST, 1);
+#endif
+ printk(KERN_INFO "[E-PEN] : wacom warm reset(%d).\n",
+ WACOM_HAVE_RESET_CONTROL);
+ return 0;
+}
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+
+#ifdef CONFIG_S3C_DEV_I2C5
+/* I2C5 */
+static struct i2c_board_info i2c_devs5[] __initdata = {
+#ifdef CONFIG_MFD_MAX8998
+ {
+ I2C_BOARD_INFO("lp3974", 0x66),
+ .platform_data = &s5pv310_max8998_info,
+ },
+#endif
+#ifdef CONFIG_MFD_MAX8997
+ {
+ I2C_BOARD_INFO("max8997", (0xcc >> 1)),
+ .platform_data = &exynos4_max8997_info,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C6
+/* I2C6 */
+static struct i2c_board_info i2c_devs6[] __initdata = {
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+ {
+ I2C_BOARD_INFO("mc1n2", 0x3a), /* MC1N2 */
+ .platform_data = &mc1n2_pdata,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C7
+static struct akm8975_platform_data akm8975_pdata = {
+ .gpio_data_ready_int = GPIO_MSENSE_INT,
+};
+
+/* I2C7 */
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8975", 0x0C),
+ .platform_data = &akm8975_pdata,
+ },
+#ifdef CONFIG_VIDEO_TVOUT
+ {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+ },
+#endif
+};
+#endif
+static void s3c_i2c7_cfg_gpio_px(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_NONE);
+}
+
+struct s3c2410_platform_i2c default_i2c7_data __initdata = {
+ .bus_num = 7,
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s3c_i2c7_cfg_gpio_px,
+};
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data8 = {
+ .sda_pin = GPIO_3_TOUCH_SDA,
+ .scl_pin = GPIO_3_TOUCH_SCL,
+};
+
+struct platform_device s3c_device_i2c8 = {
+ .name = "i2c-gpio",
+ .id = 8,
+ .dev.platform_data = &gpio_i2c_data8,
+};
+
+/* I2C8 */
+static struct i2c_board_info i2c_devs8_emul[] = {
+ {
+ I2C_BOARD_INFO("sec_touchkey", 0x20),
+ },
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C9_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data9 = {
+ .sda_pin = GPIO_FUEL_SDA,
+ .scl_pin = GPIO_FUEL_SCL,
+};
+
+struct platform_device s3c_device_i2c9 = {
+ .name = "i2c-gpio",
+ .id = 9,
+ .dev.platform_data = &gpio_i2c_data9,
+};
+
+/* I2C9 */
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_PX
+static struct max17042_platform_data max17042_pdata = {
+#if defined(CONFIG_MACH_P2)
+ .sdi_capacity = 0x1EC8,
+ .sdi_vfcapacity = 0x290A,
+ .atl_capacity = 0x1FBE,
+ .atl_vfcapacity = 0x2A54,
+ .sdi_low_bat_comp_start_vol = 3550,
+ .atl_low_bat_comp_start_vol = 3450,
+ .fuel_alert_line = GPIO_FUEL_ALERT,
+#elif defined(CONFIG_MACH_P4)
+ .sdi_capacity = 0x3730,
+ .sdi_vfcapacity = 0x4996,
+ .atl_capacity = 0x3022,
+ .atl_vfcapacity = 0x4024,
+ .sdi_low_bat_comp_start_vol = 3600,
+ .atl_low_bat_comp_start_vol = 3450,
+ .fuel_alert_line = GPIO_FUEL_ALERT,
+#elif defined(CONFIG_MACH_P8) || defined(CONFIG_MACH_P8LTE)
+ .sdi_capacity = 0x2B06,
+ .sdi_vfcapacity = 0x395E,
+ .atl_capacity = 0x2B06,
+ .atl_vfcapacity = 0x395E,
+ .sdi_low_bat_comp_start_vol = 3600,
+ .atl_low_bat_comp_start_vol = 3450,
+ .fuel_alert_line = GPIO_FUEL_ALERT,
+#else /* default value */
+ .sdi_capacity = 0x1F40,
+ .sdi_vfcapacity = 0x29AC,
+ .atl_capacity = 0x1FBE,
+ .atl_vfcapacity = 0x2A54,
+ .sdi_low_bat_comp_start_vol = 3600,
+ .atl_low_bat_comp_start_vol = 3450,
+ .fuel_alert_line = GPIO_FUEL_ALERT,
+#endif
+ .check_jig_status = check_jig_on
+};
+
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("fuelgauge", 0x36),
+ .platform_data = &max17042_pdata,
+ },
+};
+#else
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17040", 0x36),
+ },
+};
+#endif
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C10_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data10 __initdata = {
+ .sda_pin = GPIO_USB_SDA,
+ .scl_pin = GPIO_USB_SCL,
+};
+
+struct platform_device s3c_device_i2c10 = {
+ .name = "i2c-gpio",
+ .id = 10,
+ .dev.platform_data = &gpio_i2c_data10,
+};
+
+/* I2C10 */
+static struct fsa9480_platform_data fsa9480_info = {
+};
+
+static struct i2c_board_info i2c_devs10_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("fsa9480", 0x25),
+ .platform_data = &fsa9480_info,
+ },
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C11_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data11 = {
+ .sda_pin = GPIO_PS_ALS_SDA,
+ .scl_pin = GPIO_PS_ALS_SCL,
+};
+
+struct platform_device s3c_device_i2c11 = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &gpio_i2c_data11,
+};
+
+#ifdef CONFIG_SENSORS_BH1721FVC
+static int light_sensor_init(void)
+{
+ int err;
+ int gpio_vout = GPIO_PS_VOUT;
+
+ #if defined(CONFIG_OPTICAL_WAKE_ENABLE)
+ if (system_rev >= 0x03) {
+ printk(KERN_INFO" BH1721 Reset GPIO = GPX0(1) (rev%02d)\n", system_rev);
+ gpio_vout = GPIO_PS_VOUT_WAKE;
+ } else
+ printk(KERN_INFO" BH1721 Reset GPIO = GPL0(6) (rev%02d)\n", system_rev);
+ #endif
+
+ printk(KERN_INFO"============================\n");
+ printk(KERN_INFO"== BH1721 Light Sensor Init ==\n");
+ printk(KERN_INFO"============================\n");
+ printk("%d %d\n", GPIO_PS_ALS_SDA, GPIO_PS_ALS_SCL);
+ err = gpio_request(gpio_vout, "LIGHT_SENSOR_RESET");
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to request the light "
+ " sensor gpio (%d)\n", err);
+ return err;
+ }
+
+ s3c_gpio_cfgpin(gpio_vout, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio_vout, S3C_GPIO_PULL_NONE);
+
+ err = gpio_direction_output(gpio_vout, 0);
+ udelay(2);
+ err = gpio_direction_output(gpio_vout, 1);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(reset)"
+ " high (%d)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int bh1721fvc_light_sensor_reset(void)
+{
+ int err;
+ int gpio_vout = GPIO_PS_VOUT;
+
+ #if defined(CONFIG_OPTICAL_WAKE_ENABLE)
+ if (system_rev >= 0x03)
+ gpio_vout = GPIO_PS_VOUT_WAKE;
+ #endif
+
+ printk(KERN_INFO" bh1721fvc_light_sensor_reset\n");
+ err = gpio_direction_output(gpio_vout, 0);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(reset)"
+ " low (%d)\n", err);
+ return err;
+ }
+
+ udelay(2);
+
+ err = gpio_direction_output(gpio_vout, 1);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(reset)"
+ " high (%d)\n", err);
+ return err;
+ }
+ return 0;
+}
+
+static int bh1721fvc_light_sensor_output(int value)
+{
+ int err;
+ int gpio_vout = GPIO_PS_VOUT;
+
+ #if defined(CONFIG_OPTICAL_WAKE_ENABLE)
+ if (system_rev >= 0x03)
+ gpio_vout = GPIO_PS_VOUT_WAKE;
+ #endif
+
+ err = gpio_direction_output(gpio_vout, value);
+ if (err) {
+ printk(KERN_INFO" bh1721fvc Failed to make the light sensor gpio(dvi)"
+ " low (%d)\n", err);
+ return err;
+ }
+ return 0;
+}
+
+static struct bh1721fvc_platform_data bh1721fvc_pdata = {
+ .reset = bh1721fvc_light_sensor_reset,
+ /* .output = bh1721fvc_light_sensor_output, */
+};
+
+static struct i2c_board_info i2c_bh1721_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("bh1721fvc", 0x23),
+ .platform_data = &bh1721fvc_pdata,
+ },
+#if defined(CONFIG_SENSORS_AL3201)
+ {
+ I2C_BOARD_INFO("AL3201", 0x1c),
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_OPTICAL_GP2A
+static int gp2a_power(bool on)
+{
+ printk("%s : %d\n", __func__, on);
+ return 0;
+}
+
+
+#if defined(CONFIG_OPTICAL_WAKE_ENABLE)
+
+static struct gp2a_platform_data gp2a_wake_pdata = {
+ .power = gp2a_power,
+ .p_out = GPIO_PS_VOUT_WAKE,
+};
+
+static struct i2c_board_info i2c_wake_devs11[] __initdata = {
+ {
+ I2C_BOARD_INFO("gp2a", (0x88 >> 1)),
+ .platform_data = &gp2a_wake_pdata,
+ },
+};
+#endif
+
+static struct gp2a_platform_data gp2a_pdata = {
+ .power = gp2a_power,
+ .p_out = GPIO_PS_VOUT,
+};
+
+static struct i2c_board_info i2c_devs11[] __initdata = {
+ {
+ I2C_BOARD_INFO("gp2a", (0x88 >> 1)),
+ .platform_data = &gp2a_pdata,
+ },
+};
+
+#endif
+
+#endif /* CONFIG_S3C_DEV_I2C11_EMUL */
+
+/* I2C13 EMUL*/
+#ifdef CONFIG_VIDEO_SR200PC20_P2
+static struct i2c_gpio_platform_data i2c13_platdata = {
+ .sda_pin = VT_CAM_SDA_18V,
+ .scl_pin = VT_CAM_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c13 = {
+ .name = "i2c-gpio",
+ .id = 13,
+ .dev.platform_data = &i2c13_platdata,
+};
+#endif /* CONFIG_VIDEO_SR200PC20_P2 */
+
+#if defined(CONFIG_MHL_SII9234)
+static void sii9234_init(void)
+{
+ int ret = gpio_request(GPIO_HDMI_EN1, "hdmi_en1");
+ if (ret) {
+ pr_err("%s: gpio_request() for HDMI_EN1 failed\n", __func__);
+ return;
+ }
+ gpio_direction_output(GPIO_HDMI_EN1, 0);
+ if (ret) {
+ pr_err("%s: gpio_direction_output() for HDMI_EN1 failed\n",
+ __func__);
+ return;
+ }
+
+ ret = gpio_request(GPIO_MHL_RST, "mhl_rst");
+ if (ret) {
+ pr_err("%s: gpio_request() for MHL_RST failed\n", __func__);
+ return;
+ }
+ ret = gpio_direction_output(GPIO_MHL_RST, 0);
+ if (ret) {
+ pr_err("%s: gpio_direction_output() for MHL_RST failed\n",
+ __func__);
+ return;
+ }
+}
+
+static void sii9234_hw_reset(void)
+{
+#if defined(CONFIG_HPD_PULL)
+ struct regulator *reg;
+ reg = regulator_get(NULL, "hdp_2.8v");
+ if (IS_ERR_OR_NULL(reg)) {
+ pr_err("%s: failed to get LDO11 regulator\n", __func__);
+ return;
+ }
+#endif
+ gpio_set_value(GPIO_MHL_RST, 0);
+ gpio_set_value(GPIO_HDMI_EN1, 1);
+
+ usleep_range(5000, 10000);
+ gpio_set_value(GPIO_MHL_RST, 1);
+#if defined(CONFIG_HPD_PULL)
+ regulator_enable(reg);
+ regulator_put(reg);
+#endif
+ printk(KERN_ERR "[MHL]sii9234_hw_reset.\n");
+ msleep(30);
+}
+
+static void sii9234_hw_off(void)
+{
+#if defined(CONFIG_HPD_PULL)
+ struct regulator *reg;
+ reg = regulator_get(NULL, "hdp_2.8v");
+ if (IS_ERR_OR_NULL(reg)) {
+ pr_err("%s: failed to get LDO11 regulator\n", __func__);
+ return;
+ }
+ regulator_disable(reg);
+ regulator_put(reg);
+#endif
+ gpio_set_value(GPIO_HDMI_EN1, 0);
+ gpio_set_value(GPIO_MHL_RST, 0);
+ printk(KERN_ERR "[MHL]sii9234_hw_off.\n");
+}
+
+struct sii9234_platform_data sii9234_pdata = {
+ .hw_reset = sii9234_hw_reset,
+ .hw_off = sii9234_hw_off
+};
+static struct i2c_board_info i2c_devs15[] __initdata = {
+ {
+ I2C_BOARD_INFO("SII9234", 0x72>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("SII9234A", 0x7A>>1),
+ },
+ {
+ I2C_BOARD_INFO("SII9234B", 0x92>>1),
+ },
+ {
+ I2C_BOARD_INFO("SII9234C", 0xC8>>1),
+ },
+};
+/* i2c-gpio emulation platform_data */
+static struct i2c_gpio_platform_data i2c15_platdata = {
+ .sda_pin = GPIO_AP_SDA_18V,
+ .scl_pin = GPIO_AP_SCL_18V,
+ .udelay = 2, /* 250 kHz*/
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c15 = {
+ .name = "i2c-gpio",
+ .id = 15,
+ .dev.platform_data = &i2c15_platdata,
+};
+
+#endif
+
+
+#ifdef CONFIG_S3C_DEV_I2C16_EMUL
+static struct i2c_gpio_platform_data i2c16_platdata = {
+ .sda_pin = GPIO_FM_SDA_28V,
+ .scl_pin = GPIO_FM_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c16 = {
+ .name = "i2c-gpio",
+ .id = 16,
+ .dev.platform_data = &i2c16_platdata,
+};
+
+static struct i2c_board_info i2c_devs16[] __initdata = {
+#ifdef CONFIG_FM_SI4709_MODULE
+ {
+ I2C_BOARD_INFO("Si4709", (0x20 >> 1)),
+ },
+#endif
+};
+#endif
+
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cal_x_max = 480,
+ .cal_y_max = 800,
+ .cal_param = {
+ 33, -9156, 34720100, 14819, 57, -4234968, 65536,
+ },
+};
+#endif
+#if defined(CONFIG_FB_S5P_S6F1202A)
+static struct s3cfb_lcd s6f1202a = {
+ .width = 1024,
+ .height = 600,
+ .p_width = 161,
+ .p_height = 98,
+ .bpp = 24,
+ .freq = 59,
+ .timing = {
+ .h_fp = 142,
+ .h_bp = 210,
+ .h_sw = 50,
+ .v_fp = 10,
+ .v_fpe = 1,
+ .v_bp = 11,
+ .v_bpe = 1,
+ .v_sw = 10,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+};
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ if (enable) {
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ mdelay(10);
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_HIGH);
+ msleep(30);
+ /* LVDS_N_SHDN to high*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_HIGH);
+ msleep(300);
+ } else {
+ /* For backlight hw spec timming(T4) */
+ msleep(220);
+ /* LVDS_nSHDN low*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_LOW);
+ msleep(20);
+ /* Disable LVDS Panel Power, 1.2, 1.8, display 3.3V */
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+ msleep(300);
+ }
+ return 0;
+}
+static struct lcd_platform_data p2_lcd_platform_data = {
+ .power_on = lcd_power_on,
+};
+#endif
+
+#if defined(CONFIG_FB_S5P_S6C1372)
+static struct s3cfb_lcd s6c1372 = {
+ .width = 1280,
+ .height = 800,
+ .p_width = 217,
+ .p_height = 135,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 18,
+ .h_bp = 36,
+ .h_sw = 16,
+ .v_fp = 4,
+ .v_fpe = 1,
+ .v_bp = 16,
+ .v_bpe = 1,
+ .v_sw = 3,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+};
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ if (enable) {
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ msleep(40);
+
+ /* LVDS_N_SHDN to high*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_HIGH);
+ msleep(300);
+
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, GPIO_LEVEL_HIGH);
+ mdelay(2);
+
+ } else {
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, GPIO_LEVEL_LOW);
+ msleep(200);
+
+ /* LVDS_nSHDN low*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_LOW);
+ msleep(40);
+
+ /* Disable LVDS Panel Power, 1.2, 1.8, display 3.3V */
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+ msleep(400);
+ }
+
+ return 0;
+}
+
+static struct lcd_platform_data p4_lcd_platform_data = {
+ .power_on = lcd_power_on,
+};
+#endif
+
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
+static struct platform_device lcd_s6c1372 = {
+ .name = "s6c1372",
+ .id = -1,
+#if defined(CONFIG_FB_S5P_S6F1202A)
+ .dev.platform_data = &p2_lcd_platform_data,
+#else
+ .dev.platform_data = &p4_lcd_platform_data,
+#endif
+};
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+#if defined(CONFIG_FB_S5P_S6F1202A)
+ .lcd = &s6f1202a
+#endif
+#if defined(CONFIG_FB_S5P_S6C1372)
+ .lcd = &s6c1372
+#endif
+};
+#endif
+#if defined(CONFIG_BACKLIGHT_PWM)
+static struct platform_pwm_backlight_data smdk_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .dft_brightness = 30,
+ .pwm_period_ns = 25000,
+};
+static struct platform_device smdk_backlight_device = {
+ .name = "backlight",
+ .id = -1,
+ .dev = {
+ .parent = &s3c_device_timer[0].dev,
+ .platform_data = &smdk_backlight_data,
+ },
+};
+static void __init smdk_backlight_register(void)
+{
+ int ret;
+ if (system_rev < 3)
+ smdk_backlight_data.pwm_id = 0;
+ ret = platform_device_register(&smdk_backlight_device);
+ if (ret)
+ printk(KERN_ERR "failed to register backlight device: %d\n",
+ ret);
+}
+#endif
+#ifdef CONFIG_FB_S5P_MDNIE
+static struct platform_mdnie_data mdnie_data = {
+ .display_type = -1,
+#if defined(CONFIG_FB_S5P_S6F1202A)
+ .lcd_pd = &p2_lcd_platform_data,
+#elif defined(CONFIG_FB_S5P_S6C1372)
+ .lcd_pd = &p4_lcd_platform_data,
+#endif
+};
+static struct platform_device mdnie_device = {
+ .name = "mdnie",
+ .id = -1,
+ .dev = {
+ .parent = &exynos4_device_pd[PD_LCD0].dev,
+ .platform_data = &mdnie_data,
+ },
+};
+static void __init mdnie_device_register(void)
+{
+ int ret;
+
+ mdnie_data.display_type = lcdtype;
+
+ ret = platform_device_register(&mdnie_device);
+ if (ret)
+ printk(KERN_ERR "failed to register mdnie device: %d\n",
+ ret);
+}
+#endif
+
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
+static int lcd_cfg_gpio(void)
+{
+ return 0;
+}
+
+int s6c1372_panel_gpio_init(void)
+{
+ int ret;
+
+ lcd_cfg_gpio();
+
+ /* GPIO Initialize for S6C1372 LVDS panel */
+ ret = gpio_request(GPIO_LCD_EN, "GPIO_LCD_EN");
+ if (ret) {
+ pr_err("failed to request LCD_EN GPIO%d\n",
+ GPIO_LCD_EN);
+ return ret;
+ }
+ ret = gpio_request(GPIO_LVDS_NSHDN, "GPIO_LVDS_NSHDN");
+ if (ret) {
+ pr_err("failed to request LVDS GPIO%d\n",
+ GPIO_LVDS_NSHDN);
+ return ret;
+ }
+
+ gpio_direction_output(GPIO_LCD_EN, 1);
+ gpio_direction_output(GPIO_LVDS_NSHDN, 1);
+
+ gpio_free(GPIO_LCD_EN);
+ gpio_free(GPIO_LVDS_NSHDN);
+
+#ifdef GPIO_LED_BACKLIGHT_RESET
+ ret = gpio_request(GPIO_LED_BACKLIGHT_RESET,
+ "GPIO_LED_BACKLIGHT_RESET");
+ if (ret) {
+ pr_err("failed to request LVDS GPIO%d\n",
+ GPIO_LED_BACKLIGHT_RESET);
+ return ret;
+ }
+ gpio_direction_output(GPIO_LED_BACKLIGHT_RESET, 1);
+ gpio_free(GPIO_LED_BACKLIGHT_RESET);
+#endif
+ s3cfb_set_platdata(&fb_platform_data);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#ifdef CONFIG_FB_S5P_S6E8AB0
+/* for Geminus based on MIPI-DSI interface */
+static struct s3cfb_lcd s6e8ab0 = {
+ .name = "s6e8ab0",
+ .width = 1280,
+ .height = 800,
+ .p_width = 165,
+ .p_height = 103,
+ .bpp = 24,
+
+ .freq = 60,
+
+ /* minumun value is 0 except for wr_act time. */
+ .cpu_timing = {
+ .cs_setup = 0,
+ .wr_setup = 0,
+ .wr_act = 1,
+ .wr_hold = 0,
+ },
+
+ .timing = {
+ .h_fp = 128,
+ .h_bp = 128,
+ .h_sw = 94,
+ .v_fp = 13,
+ .v_fpe = 1,
+ .v_bp = 3,
+ .v_bpe = 1,
+ .v_sw = 2,
+ .cmd_allow_len = 11, /*v_fp=stable_vfp + cmd_allow_len */
+ .stable_vfp = 2,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+
+static int reset_lcd(void)
+{
+ int err;
+
+ printk(KERN_INFO "%s\n", __func__);
+
+ err = gpio_request(GPIO_LCD_RST, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPF0[1] for "
+ "MLCD_RST control\n");
+ return -EPERM;
+ }
+ gpio_direction_output(GPIO_LCD_RST, 0);
+
+ /* Power Reset */
+ gpio_set_value(GPIO_LCD_RST, GPIO_LEVEL_HIGH);
+ msleep(5);
+ gpio_set_value(GPIO_LCD_RST, GPIO_LEVEL_LOW);
+ msleep(5);
+ gpio_set_value(GPIO_LCD_RST, GPIO_LEVEL_HIGH);
+
+
+ /* Release GPIO */
+ gpio_free(GPIO_LCD_RST);
+
+ return 0;
+}
+
+static void lcd_cfg_gpio(void)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(GPIO_LCD_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_LCD_RST, S3C_GPIO_PULL_NONE);
+
+ /* MLCD_ON */
+ s3c_gpio_cfgpin(GPIO_LCD_LDO_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_LCD_LDO_EN, S3C_GPIO_PULL_NONE);
+
+ /* LCD_EN */
+ s3c_gpio_cfgpin(GPIO_LCD_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_LCD_EN, S3C_GPIO_PULL_NONE);
+
+ return;
+}
+
+static int lcd_power_on(void *pdev, int enable)
+{
+ int err;
+
+ printk(KERN_INFO "%s : enable=%d\n", __func__, enable);
+
+ /* Request GPIO */
+ err = gpio_request(GPIO_LCD_LDO_EN, "MLCD_ON");
+ if (err) {
+ printk(KERN_ERR "failed to request GPK1[1] for "
+ "MLCD_ON control\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(GPIO_LCD_EN, "LCD_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request GPL0[7] for "
+ "LCD_EN control\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(GPIO_LCD_RST, "LCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPL0[7] for "
+ "LCD_EN control\n");
+ return -EPERM;
+ }
+
+ if (enable) {
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_HIGH);
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ } else {
+ gpio_set_value(GPIO_LCD_RST, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+ mdelay(10);
+ }
+
+ gpio_free(GPIO_LCD_LDO_EN);
+ gpio_free(GPIO_LCD_EN);
+ gpio_free(GPIO_LCD_RST);
+
+ return 0;
+}
+#endif
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+#ifdef CONFIG_FB_S5P_S6E8AB0
+ .lcd = &s6e8ab0
+#endif
+};
+
+static void __init mipi_fb_init(void)
+{
+ struct s5p_platform_dsim *dsim_pd = NULL;
+ struct mipi_ddi_platform_data *mipi_ddi_pd = NULL;
+ struct dsim_lcd_config *dsim_lcd_info = NULL;
+
+ /* set platform data */
+
+ /* gpio pad configuration for rgb and spi interface. */
+ lcd_cfg_gpio();
+
+ /*
+ * register lcd panel data.
+ */
+ printk(KERN_INFO "%s :: fb_platform_data.hw_ver = 0x%x\n",
+ __func__, fb_platform_data.hw_ver);
+
+ fb_platform_data.mipi_is_enabled = 1;
+ fb_platform_data.interface_mode = FIMD_CPU_INTERFACE;
+
+ dsim_pd = (struct s5p_platform_dsim *)
+ s5p_device_dsim.dev.platform_data;
+
+ dsim_pd->platform_rev = 1;
+
+ dsim_lcd_info = dsim_pd->dsim_lcd_info;
+
+#ifdef CONFIG_FB_S5P_S6E8AB0
+ dsim_lcd_info->lcd_panel_info = (void *)&s6e8ab0;
+
+ /* 500Mbps */
+ dsim_pd->dsim_info->p = 3;
+ dsim_pd->dsim_info->m = 125;
+ dsim_pd->dsim_info->s = 1;
+
+ dsim_pd->dsim_info->hs_toggle = msecs_to_jiffies(500);
+#endif
+
+ mipi_ddi_pd = (struct mipi_ddi_platform_data *)
+ dsim_lcd_info->mipi_ddi_pd;
+ mipi_ddi_pd->lcd_reset = reset_lcd;
+ mipi_ddi_pd->lcd_power_on = lcd_power_on;
+
+ platform_device_register(&s5p_device_dsim);
+
+ s3cfb_set_platdata(&fb_platform_data);
+
+ printk(KERN_INFO
+ "platform data of %s lcd panel has been registered.\n",
+ dsim_pd->lcd_panel_name);
+}
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 0,
+ .start = 0,
+ .size = 0
+};
+
+static struct android_pmem_platform_data pmem_gpu1_pdata = {
+ .name = "pmem_gpu1",
+ .no_allocator = 1,
+ .cached = 0,
+ .start = 0,
+ .size = 0,
+};
+
+static struct platform_device pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = {
+ .platform_data = &pmem_pdata},
+};
+
+static struct platform_device pmem_gpu1_device = {
+ .name = "android_pmem",
+ .id = 1,
+ .dev = {
+ .platform_data = &pmem_gpu1_pdata},
+};
+
+static void __init android_pmem_set_platdata(void)
+{
+#if defined(CONFIG_S5P_MEM_CMA)
+ pmem_pdata.size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K;
+ pmem_gpu1_pdata.size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K;
+#else
+ pmem_pdata.start = (u32) s5p_get_media_memory_bank(S5P_MDEV_PMEM, 0);
+ pmem_pdata.size = (u32) s5p_get_media_memsize_bank(S5P_MDEV_PMEM, 0);
+ pmem_gpu1_pdata.start =
+ (u32) s5p_get_media_memory_bank(S5P_MDEV_PMEM_GPU1, 0);
+ pmem_gpu1_pdata.size =
+ (u32) s5p_get_media_memsize_bank(S5P_MDEV_PMEM_GPU1, 0);
+#endif
+}
+#endif
+
+/* USB EHCI */
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdkc210_ehci_pdata;
+
+static void __init smdkc210_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdkc210_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdkc210_ohci_pdata;
+
+static void __init smdkc210_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdkc210_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdkc210_usbgadget_pdata;
+
+#include <linux/usb/android_composite.h>
+static void __init smdkc210_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdkc210_usbgadget_pdata;
+
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ struct android_usb_platform_data *android_pdata =
+ s3c_device_android_usb.dev.platform_data;
+ if (android_pdata) {
+ unsigned int newluns = 2;
+ printk(KERN_DEBUG "usb: %s: default luns=%d, new luns=%d\n",
+ __func__, android_pdata->nluns, newluns);
+ android_pdata->nluns = newluns;
+ } else {
+ printk(KERN_DEBUG "usb: %s android_pdata is not available\n",
+ __func__);
+ }
+#endif
+
+ s5p_usbgadget_set_platdata(pdata);
+
+ pdata = s3c_device_usbgadget.dev.platform_data;
+ if (pdata) {
+ /* Enables HS Transmitter pre-emphasis [20] */
+ pdata->phy_tune_mask = 0;
+ pdata->phy_tune_mask |= (0x1 << 20);
+ pdata->phy_tune |= (0x1 << 20);
+
+ /* HS DC Voltage Level Adjustment [3:0] (1011 : +16%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xb;
+
+ printk(KERN_DEBUG "usb: %s tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+ }
+
+#if defined(CONFIG_MACH_P8LTE)
+ /* squelch threshold tune [13:11] (001 : +10%) */
+ pdata->phy_tune_mask |= 0x7 << 11;
+ pdata->phy_tune |= 0x1 << 11;
+ printk(KERN_DEBUG "usb: %s apply squelch threshold tune tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+#endif
+}
+#endif
+
+#if defined(CONFIG_SMB136_CHARGER) || defined(CONFIG_SMB347_CHARGER)
+struct smb_charger_callbacks *smb_callbacks;
+
+static void smb_charger_register_callbacks(struct smb_charger_callbacks *ptr)
+{
+ smb_callbacks = ptr;
+}
+
+static void smb_charger_unregister_callbacks(void)
+{
+ smb_callbacks = NULL;
+}
+
+static struct smb_charger_data smb_charger_pdata = {
+ .register_callbacks = smb_charger_register_callbacks,
+ .unregister_callbacks = smb_charger_unregister_callbacks,
+ .enable = GPIO_TA_EN,
+ .stat = GPIO_TA_nCHG,
+#if defined(CONFIG_MACH_P4)
+ .ta_nconnected = GPIO_TA_nCONNECTED,
+#else
+ .ta_nconnected = 0,
+#endif
+};
+
+static struct i2c_board_info i2c_devs12_emul[] __initdata = {
+ {
+#if defined(CONFIG_SMB347_CHARGER)
+ I2C_BOARD_INFO("smb347-charger", 0x0C >> 1),
+#else
+ I2C_BOARD_INFO("smb136-charger", 0x9A >> 1),
+#endif
+ .platform_data = &smb_charger_pdata,
+ },
+};
+
+static void __init smb_gpio_init(void)
+{
+ s3c_gpio_cfgpin(GPIO_TA_nCHG, S3C_GPIO_SFN(0xf));
+ /* external pull up */
+ s3c_gpio_setpull(GPIO_TA_nCHG, S3C_GPIO_PULL_NONE);
+ i2c_devs12_emul[0].irq = gpio_to_irq(GPIO_TA_nCHG);
+}
+
+static struct i2c_gpio_platform_data gpio_i2c_data12 = {
+ .sda_pin = GPIO_CHG_SDA,
+ .scl_pin = GPIO_CHG_SCL,
+};
+
+static struct platform_device s3c_device_i2c12 = {
+ .name = "i2c-gpio",
+ .id = 12,
+ .dev.platform_data = &gpio_i2c_data12,
+};
+
+static void sec_bat_set_charging_state(int enable, int cable_status)
+{
+ if (smb_callbacks && smb_callbacks->set_charging_state)
+ smb_callbacks->set_charging_state(enable, cable_status);
+}
+
+static int sec_bat_get_charging_state(void)
+{
+ if (smb_callbacks && smb_callbacks->get_charging_state)
+ return smb_callbacks->get_charging_state();
+ else
+ return 0;
+}
+
+static void sec_bat_set_charging_current(int set_current)
+{
+ if (smb_callbacks && smb_callbacks->set_charging_current)
+ smb_callbacks->set_charging_current(set_current);
+}
+
+static int sec_bat_get_charging_current(void)
+{
+ if (smb_callbacks && smb_callbacks->get_charging_current)
+ return smb_callbacks->get_charging_current();
+ else
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_SMB347_CHARGER)
+static int sec_bat_get_charger_is_full(void)
+{
+ if (smb_callbacks && smb_callbacks->get_charger_is_full)
+ return smb_callbacks->get_charger_is_full();
+ else
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_PX
+void sec_bat_gpio_init(void)
+{
+
+ s3c_gpio_cfgpin(GPIO_TA_nCONNECTED, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCONNECTED, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TA_nCHG, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCHG, S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(GPIO_TA_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TA_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TA_EN, 0);
+
+#ifndef CONFIG_MACH_P2
+ s3c_gpio_cfgpin(GPIO_CURR_ADJ, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_CURR_ADJ, S3C_GPIO_PULL_NONE);
+#else
+ gpio_request(GPIO_TA_nCHG, "TA_nCHG");
+ s5p_register_gpio_interrupt(GPIO_TA_nCHG);
+#endif
+ pr_info("BAT : Battery GPIO initialized.\n");
+}
+
+static void sec_charger_cb(int set_cable_type)
+{
+ struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget);
+ bool cable_state_to_tsp;
+ bool cable_state_to_usb;
+
+ switch (set_cable_type) {
+ case CHARGER_USB:
+ cable_state_to_tsp = true;
+ cable_state_to_usb = true;
+ is_cable_attached = true;
+ is_usb_lpm_enter = false;
+ break;
+ case CHARGER_AC:
+ case CHARGER_MISC:
+ cable_state_to_tsp = true;
+ cable_state_to_usb = false;
+ is_cable_attached = true;
+ is_usb_lpm_enter = true;
+ break;
+ case CHARGER_BATTERY:
+ case CHARGER_DISCHARGE:
+ default:
+ cable_state_to_tsp = false;
+ cable_state_to_usb = false;
+ is_cable_attached = false;
+ is_usb_lpm_enter = true;
+ break;
+ }
+ pr_info("%s:cable_type=%d,tsp(%d),usb(%d),attached(%d),usblpm(%d)\n",
+ __func__, set_cable_type, cable_state_to_tsp,
+ cable_state_to_usb, is_cable_attached, is_usb_lpm_enter);
+
+/* Send charger state to TSP. TSP needs cable type what charging or not */
+#if defined(CONFIG_TOUCHSCREEN_MMS152)
+ sec_charger_melfas_cb(is_cable_attached);
+#elif defined(CONFIG_TOUCHSCREEN_MXT1386)
+ if (system_rev < 13)
+ sec_mxt1386_charger_infom(is_cable_attached);
+#else
+ if (charging_cbs.tsp_set_charging_cable)
+ charging_cbs.tsp_set_charging_cable(is_cable_attached);
+
+#endif
+
+/* Send charger state to px-switch. px-switch needs cable type what USB or not */
+ set_usb_connection_state(!is_usb_lpm_enter);
+
+/* Send charger state to USB. USB needs cable type what USB data or not */
+ if (gadget) {
+ if (cable_state_to_usb)
+ usb_gadget_vbus_connect(gadget);
+ else
+ usb_gadget_vbus_disconnect(gadget);
+ }
+
+ pr_info("%s\n", __func__);
+}
+
+static struct sec_battery_platform_data sec_battery_platform = {
+ .charger = {
+ .enable_line = GPIO_TA_EN,
+ .connect_line = GPIO_TA_nCONNECTED,
+ .fullcharge_line = GPIO_TA_nCHG,
+#ifndef CONFIG_MACH_P2
+ .currentset_line = GPIO_CURR_ADJ,
+#endif
+#if defined(CONFIG_MACH_P4)
+ .accessory_line = GPIO_ACCESSORY_INT,
+#else
+ .accessory_line = 0,
+#endif
+ },
+#if defined(CONFIG_SMB136_CHARGER) || defined(CONFIG_SMB347_CHARGER)
+ .set_charging_state = sec_bat_set_charging_state,
+ .get_charging_state = sec_bat_get_charging_state,
+ .set_charging_current = sec_bat_set_charging_current,
+ .get_charging_current = sec_bat_get_charging_current,
+#endif
+#if defined(CONFIG_SMB347_CHARGER)
+ .get_charger_is_full = sec_bat_get_charger_is_full,
+#endif
+ .init_charger_gpio = sec_bat_gpio_init,
+ .inform_charger_connection = sec_charger_cb,
+
+#if defined(CONFIG_MACH_P8LTE)
+ .temp_high_threshold = 55800, /* 55.8c */
+ .temp_high_recovery = 45700, /* 45.7c */
+ .temp_low_recovery = 2200, /* 2.2c */
+ .temp_low_threshold = -2000, /* -2c */
+ .recharge_voltage = 4130, /*4.13V */
+#else
+ .temp_high_threshold = 50000, /* 50c */
+ .temp_high_recovery = 42000, /* 42c */
+ .temp_low_recovery = 2000, /* 2c */
+ .temp_low_threshold = 0, /* 0c */
+ .recharge_voltage = 4150, /*4.15V */
+#endif
+
+ .charge_duration = 10*60*60, /* 10 hour */
+ .recharge_duration = 1.5*60*60, /* 1.5 hour */
+ .check_lp_charging_boot = check_bootmode,
+ .check_jig_status = check_jig_on
+};
+
+static struct platform_device sec_battery_device = {
+ .name = "sec-battery",
+ .id = -1,
+ .dev = {
+ .platform_data = &sec_battery_platform,
+ },
+};
+#endif /* CONFIG_BATTERY_SEC_PX */
+
+#ifdef CONFIG_30PIN_CONN
+static void smdk_accessory_gpio_init(void)
+{
+ gpio_request(GPIO_ACCESSORY_INT, "accessory");
+ s3c_gpio_cfgpin(GPIO_ACCESSORY_INT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ACCESSORY_INT, S3C_GPIO_PULL_UP);
+ gpio_direction_input(GPIO_ACCESSORY_INT);
+
+ gpio_request(GPIO_DOCK_INT, "dock");
+ s3c_gpio_cfgpin(GPIO_DOCK_INT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_DOCK_INT, S3C_GPIO_PULL_NONE);
+ gpio_direction_input(GPIO_DOCK_INT);
+
+ gpio_request(GPIO_USB_OTG_EN, "GPIO_USB_OTG_EN");
+ s3c_gpio_cfgpin(GPIO_USB_OTG_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_OTG_EN, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_USB_OTG_EN, false);
+ gpio_free(GPIO_USB_OTG_EN);
+
+ gpio_request(GPIO_ACCESSORY_EN, "GPIO_ACCESSORY_EN");
+ s3c_gpio_cfgpin(GPIO_ACCESSORY_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_ACCESSORY_EN, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_ACCESSORY_EN, false);
+ gpio_free(GPIO_ACCESSORY_EN);
+}
+
+void smdk_accessory_power(u8 token, bool active)
+{
+ int gpio_acc_en;
+ int try_cnt = 0;
+ int gpio_acc_5v = 0;
+ static bool enable;
+ static u8 acc_en_token;
+
+ /*
+ token info
+ 0 : power off,
+ 1 : Keyboard dock
+ 2 : USB
+ */
+ gpio_acc_en = GPIO_ACCESSORY_EN;
+#ifdef CONFIG_MACH_P4
+ if (system_rev >= 2)
+ gpio_acc_5v = GPIO_ACCESSORY_OUT_5V;
+#elif defined(CONFIG_MACH_P2) /* for checking p2 3g and wifi */
+ gpio_acc_5v = GPIO_ACCESSORY_OUT_5V;
+#elif defined(CONFIG_MACH_P8LTE)
+ if (system_rev >= 2)
+ gpio_acc_5v = GPIO_ACCESSORY_OUT_5V;
+#elif defined(CONFIG_MACH_P8) /* for checking p8 3g and wifi */
+ if (system_rev >= 4)
+ gpio_acc_5v = GPIO_ACCESSORY_OUT_5V;
+#endif
+
+ gpio_request(gpio_acc_en, "GPIO_ACCESSORY_EN");
+ s3c_gpio_cfgpin(gpio_acc_en, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio_acc_en, S3C_GPIO_PULL_NONE);
+
+ if (active) {
+ if (acc_en_token) {
+ pr_info("Board : Keyboard dock is connected.\n");
+ gpio_direction_output(gpio_acc_en, 0);
+ msleep(100);
+ }
+
+ acc_en_token |= (1 << token);
+ enable = true;
+ gpio_direction_output(gpio_acc_en, 1);
+
+ if (0 != gpio_acc_5v) {
+ gpio_request(gpio_acc_5v, "gpio_acc_5v");
+ s3c_gpio_cfgpin(gpio_acc_5v, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio_acc_5v, S3C_GPIO_PULL_NONE);
+ msleep(20);
+
+ /* prevent the overcurrent */
+ while (!gpio_get_value(gpio_acc_5v)) {
+ gpio_direction_output(gpio_acc_en, 0);
+ msleep(20);
+ gpio_direction_output(gpio_acc_en, 1);
+ if (try_cnt > 10) {
+ pr_err("[acc] failed to enable the accessory_en");
+ break;
+ } else
+ try_cnt++;
+ }
+ gpio_free(gpio_acc_5v);
+
+ } else
+ pr_info("[ACC] gpio_acc_5v is not set\n");
+
+ } else {
+ if (0 == token) {
+ gpio_direction_output(gpio_acc_en, 0);
+ enable = false;
+ } else {
+ acc_en_token &= ~(1 << token);
+ if (0 == acc_en_token) {
+ gpio_direction_output(gpio_acc_en, 0);
+ enable = false;
+ }
+ }
+ }
+ gpio_free(gpio_acc_en);
+ pr_info("Board : %s (%d,%d) %s\n", __func__,
+ token, active, enable ? "on" : "off");
+}
+
+static int smdk_get_acc_state(void)
+{
+ return gpio_get_value(GPIO_DOCK_INT);
+}
+
+static int smdk_get_dock_state(void)
+{
+ return gpio_get_value(GPIO_ACCESSORY_INT);
+}
+
+#ifdef CONFIG_SEC_KEYBOARD_DOCK
+static struct sec_keyboard_callbacks *keyboard_callbacks;
+static int check_sec_keyboard_dock(bool attached)
+{
+ if (keyboard_callbacks && keyboard_callbacks->check_keyboard_dock)
+ return keyboard_callbacks->
+ check_keyboard_dock(keyboard_callbacks, attached);
+ return 0;
+}
+
+static void check_uart_path(bool en)
+{
+ int gpio_uart_sel;
+#ifdef CONFIG_MACH_P8LTE
+ int gpio_uart_sel2;
+
+ gpio_uart_sel = GPIO_UART_SEL1;
+ gpio_uart_sel2 = GPIO_UART_SEL2;
+ if (en)
+ gpio_direction_output(gpio_uart_sel2, 1);
+ else
+ gpio_direction_output(gpio_uart_sel2, 0);
+ printk(KERN_DEBUG "[Keyboard] uart_sel2 : %d\n",
+ gpio_get_value(gpio_uart_sel2));
+#else
+ gpio_uart_sel = GPIO_UART_SEL;
+#endif
+
+ if (en)
+ gpio_direction_output(gpio_uart_sel, 1);
+ else
+ gpio_direction_output(gpio_uart_sel, 0);
+
+ printk(KERN_DEBUG "[Keyboard] uart_sel : %d\n",
+ gpio_get_value(gpio_uart_sel));
+}
+
+static void sec_keyboard_register_cb(struct sec_keyboard_callbacks *cb)
+{
+ keyboard_callbacks = cb;
+}
+
+static struct sec_keyboard_platform_data kbd_pdata = {
+ .accessory_irq_gpio = GPIO_ACCESSORY_INT,
+ .acc_power = smdk_accessory_power,
+ .check_uart_path = check_uart_path,
+ .register_cb = sec_keyboard_register_cb,
+ .wakeup_key = NULL,
+};
+
+static struct platform_device sec_keyboard = {
+ .name = "sec_keyboard",
+ .id = -1,
+ .dev = {
+ .platform_data = &kbd_pdata,
+ }
+};
+#endif
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+
+static void px_usb_otg_power(int active)
+{
+ smdk_accessory_power(2, active);
+}
+
+struct host_notifier_platform_data host_notifier_pdata = {
+ .ndev.name = "usb_otg",
+ .gpio = GPIO_ACCESSORY_OUT_5V,
+ .booster = px_usb_otg_power,
+ .thread_enable = 1,
+};
+
+struct platform_device host_notifier_device = {
+ .name = "host_notifier",
+ .dev.platform_data = &host_notifier_pdata,
+};
+
+static void px_usb_otg_en(int active)
+{
+ pr_info("otg %s : %d\n", __func__, active);
+
+ usb_switch_lock();
+
+ if (active) {
+
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ehci.dev);
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ohci.dev);
+#endif
+
+ usb_switch_set_path(USB_PATH_HOST);
+ smdk_accessory_power(2, 1);
+
+ host_notifier_pdata.ndev.mode = NOTIFY_HOST_MODE;
+ if (host_notifier_pdata.usbhostd_start)
+ host_notifier_pdata.usbhostd_start();
+ } else {
+
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ohci.dev);
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ehci.dev);
+#endif
+
+ usb_switch_clr_path(USB_PATH_HOST);
+ if (host_notifier_pdata.usbhostd_stop)
+ host_notifier_pdata.usbhostd_stop();
+ smdk_accessory_power(2, 0);
+
+ }
+
+ usb_switch_unlock();
+}
+#endif
+
+struct acc_con_platform_data acc_con_pdata = {
+ .otg_en = px_usb_otg_en,
+ .acc_power = smdk_accessory_power,
+ .usb_ldo_en = NULL,
+ .get_acc_state = smdk_get_acc_state,
+ .get_dock_state = smdk_get_dock_state,
+#ifdef CONFIG_SEC_KEYBOARD_DOCK
+ .check_keyboard = check_sec_keyboard_dock,
+#endif
+ .accessory_irq_gpio = GPIO_ACCESSORY_INT,
+ .dock_irq_gpio = GPIO_DOCK_INT,
+#ifdef CONFIG_MHL_SII9234
+ .mhl_irq_gpio = GPIO_MHL_INT,
+ .hdmi_hpd_gpio = GPIO_HDMI_HPD,
+#endif
+};
+struct platform_device sec_device_connector = {
+ .name = "acc_con",
+ .id = -1,
+ .dev.platform_data = &acc_con_pdata,
+};
+#endif
+
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+static struct platform_device watchdog_reset_device = {
+ .name = "watchdog-reset",
+ .id = -1,
+};
+#endif
+static struct platform_device *smdkc210_devices[] __initdata = {
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ &watchdog_reset_device,
+#endif
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_LCD1],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+
+ &smdkc210_smsc911x,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+#ifdef CONFIG_BATTERY_SEC_PX
+ &sec_battery_device,
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+ &pmem_device,
+ &pmem_gpu1_device,
+#endif
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#endif
+
+#ifdef CONFIG_I2C_S3C2410
+ &s3c_device_i2c0,
+#if defined(CONFIG_S3C_DEV_I2C1)
+ &s3c_device_i2c1,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C2)
+ &s3c_device_i2c2,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C3)
+ &s3c_device_i2c3,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C4)
+ &s3c_device_i2c4,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C5)
+ &s3c_device_i2c5,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C6)
+ &s3c_device_i2c6,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C7)
+ &s3c_device_i2c7,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C8_EMUL)
+ &s3c_device_i2c8,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C9_EMUL)
+ &s3c_device_i2c9,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C10_EMUL)
+ &s3c_device_i2c10,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C11_EMUL)
+ &s3c_device_i2c11,
+#endif
+#if defined(CONFIG_VIDEO_SR200PC20_P2)
+ &s3c_device_i2c13,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C14_EMUL)
+ &s3c_device_i2c14,
+#endif
+#if defined(CONFIG_SMB136_CHARGER)
+ &s3c_device_i2c12,
+#endif
+#if defined(CONFIG_MHL_SII9234)
+ &s3c_device_i2c15,
+#endif
+#ifdef CONFIG_S3C_DEV_I2C16_EMUL
+ &s3c_device_i2c16,
+#endif
+#endif
+
+ /* consumer driver should resume after resuming i2c drivers */
+ &u1_regulator_consumer,
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+
+#ifdef CONFIG_MACH_PX
+ &p4w_wlan_ar6000_pm_device,
+#endif
+
+#ifdef CONFIG_S3C_ADC
+ &s3c_device_adc,
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ &s3c_device_ts,
+#elif CONFIG_S3C_DEV_ADC1
+ &s3c_device_ts1,
+#endif
+#endif
+#ifdef CONFIG_KEYBOARD_GPIO
+ &px_gpio_keys,
+#endif
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(2d),
+ &SYSMMU_PLATDEV(tv),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+
+ &samsung_asoc_dma,
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+ &samsung_asoc_idma,
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+ &exynos_device_spi0,
+#endif
+
+/* mainline fimd */
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd0,
+#if defined(CONFIG_LCD_AMS369FG06)
+ &s3c_device_spi_gpio,
+#elif defined(CONFIG_LCD_WA101S)
+ &smdkc210_lcd_wa101s,
+#elif defined(CONFIG_LCD_LTE480WV)
+ &smdkc210_lcd_lte480wv,
+#endif
+#endif
+/* legacy fimd */
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ &s3c_device_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ &ld9040_spi_gpio,
+#endif
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
+ &lcd_s6c1372,
+#endif
+#ifdef CONFIG_FB_S5P_MDNIE
+/* &mdnie_device,*/
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#endif
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ &s5p_device_jpeg,
+#endif
+#if defined CONFIG_USB_EHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ehci,
+#endif
+#if defined CONFIG_USB_OHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &s3c_device_timer[2],
+ &s3c_device_timer[3],
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+#ifdef CONFIG_BT_BCM4330
+ &bcm4330_bluetooth_device,
+#endif
+#ifdef CONFIG_BT_CSR8811
+ &csr8811_bluetooth_device,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+ &exynos4_busfreq,
+#ifdef CONFIG_SEC_DEV_JACK
+ &sec_device_jack,
+#endif
+#if (defined(CONFIG_30PIN_CONN) && defined(CONFIG_USB_HOST_NOTIFY))
+ &host_notifier_device,
+#endif
+#if defined(CONFIG_IR_REMOCON)
+/* IR_LED */
+ &ir_remote_device,
+/* IR_LED */
+#endif
+#ifdef CONFIG_30PIN_CONN
+ &sec_device_connector,
+#ifdef CONFIG_SEC_KEYBOARD_DOCK
+ &sec_keyboard,
+#endif
+#endif
+};
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct s5p_platform_tmu px_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 61,
+ .start_1st_throttle = 64,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110,
+ .start_emergency = 120,
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000, /* 800MHz in KHz order */
+ .limit_2nd_throttle = 200000, /* 200MHz in KHz order */
+ },
+};
+#endif
+
+#if defined CONFIG_USB_OHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ohci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ohci);
+}
+late_initcall(s5p_ohci_device_initcall);
+#endif
+#if defined CONFIG_USB_EHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ehci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ehci);
+}
+late_initcall(s5p_ehci_device_initcall);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+
+};
+
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+static void __init smdkc210_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+#if defined(CONFIG_S5P_MEM_CMA)
+static void __init exynos4_cma_region_reserve(struct cma_region *regions_normal,
+ struct cma_region *regions_secure)
+{
+ struct cma_region *reg;
+ size_t size_secure = 0, align_secure = 0;
+ phys_addr_t paddr = 0;
+
+ for (reg = regions_normal; reg->size != 0; reg++) {
+ if (WARN_ON(cma_early_region_register(reg)))
+ continue;
+
+ if ((reg->alignment & (reg->alignment - 1)) || reg->reserved)
+ continue;
+
+ if (reg->start) {
+ if (!memblock_is_region_reserved(reg->start, reg->size)
+ && memblock_reserve(reg->start, reg->size) >= 0)
+ reg->reserved = 1;
+ } else {
+ paddr = __memblock_alloc_base(reg->size, reg->alignment,
+ MEMBLOCK_ALLOC_ACCESSIBLE);
+ if (paddr) {
+ reg->start = paddr;
+ reg->reserved = 1;
+ }
+ }
+ }
+
+ if (regions_secure && regions_secure->size) {
+ for (reg = regions_secure; reg->size != 0; reg++)
+ size_secure += reg->size;
+
+ reg--;
+
+ align_secure = reg->alignment;
+ BUG_ON(align_secure & (align_secure - 1));
+
+ paddr -= size_secure;
+ paddr &= ~(align_secure - 1);
+
+ if (!memblock_reserve(paddr, size_secure)) {
+ do {
+ reg->start = paddr;
+ reg->reserved = 1;
+ paddr += reg->size;
+
+ if (WARN_ON(cma_early_region_register(reg)))
+ memblock_free(reg->start, reg->size);
+ } while (reg-- != regions_secure);
+ }
+ }
+}
+
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM
+ {
+ .name = "pmem",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1
+ {
+ .name = "pmem_gpu1",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .name = "fimc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3
+ {
+ .name = "fimc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .name = "jpeg",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT
+ {
+ .name = "tvout",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT * SZ_1K,
+ .start = 0,
+ },
+#endif
+ {
+ .size = 0,
+ },
+ };
+
+ static const char map[] __initconst =
+ "android_pmem.0=pmem;android_pmem.1=pmem_gpu1;"
+ "s3cfb.0=fimd;exynos4-fb.0=fimd;"
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc3=fimc3;"
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc/A=mfc0,mfc-secure;"
+ "s3c-mfc/B=mfc1,mfc-normal;"
+ "s3c-mfc/AB=mfc;"
+#endif
+ "samsung-rp=srp;"
+ "s5p-jpeg=jpeg;"
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ "exynos4-fimc-is=fimc_is;"
+#endif
+ "s5p-fimg2d=fimg2d;"
+ "s5p-tvout=tvout";
+
+ cma_set_defaults(regions, map);
+ exynos4_cma_region_reserve(regions, NULL);
+
+}
+#endif
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimd0, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(2d, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(rot, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+#if defined CONFIG_VIDEO_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#elif defined CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_FB_S3C
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimd0).dev, &s5p_device_fimd0.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(2d).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+}
+
+static void __init smdkc210_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
+
+#if defined(CONFIG_S5P_MEM_CMA)
+ exynos4_reserve_mem();
+#else
+ s5p_reserve_mem(S5P_RANGE_MFC);
+#endif
+
+ /* as soon as INFORM3 is visible, sec_debug is ready to run */
+ sec_debug_init();
+}
+
+static void __init universal_tsp_init(void)
+{
+ int gpio;
+ int gpio_touch_id = 0;
+
+#if !defined(CONFIG_TOUCHSCREEN_MMS152)
+ /* TSP_LDO_ON: XMDMADDR_11 */
+ gpio = GPIO_TSP_LDO_ON;
+ gpio_request(gpio, "TSP_LDO_ON");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_MXT1386) || defined(CONFIG_TOUCHSCREEN_MMS152) \
+ || defined(CONFIG_RMI4_I2C)
+ gpio = GPIO_TSP_RST;
+ gpio_request(gpio, "TSP_RST");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+#endif
+
+#if defined(CONFIG_MACH_P8)
+ /* TSP_INT: XMDMADDR_7 */
+ gpio = GPIO_TSP_INT_18V;
+ gpio_request(gpio, "TSP_INT_18V");
+#else
+ gpio = GPIO_TSP_INT;
+ gpio_request(gpio, "TSP_INT");
+#endif
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+#if defined(CONFIG_TOUCHSCREEN_MXT1386) \
+ && defined(CONFIG_RMI4_I2C)
+ i2c_devs3_mxt[0].irq = gpio_to_irq(gpio);
+ i2c_devs3_syn[0].irq = gpio_to_irq(gpio);
+#else
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+#endif
+
+ printk(KERN_INFO "%s touch irq : %d, system_rev : %d\n",
+ __func__, gpio_to_irq(gpio), system_rev);
+
+#if defined(CONFIG_TOUCHSCREEN_MMS152)
+
+ gpio = GPIO_TSP_VENDOR1;
+ gpio_request(gpio, "GPIO_TSP_VENDOR1");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = GPIO_TSP_VENDOR2;
+ gpio_request(gpio, "GPIO_TSP_VENDOR2");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+
+ if (system_rev < 3) {
+ gpio_touch_id = gpio_get_value(GPIO_TSP_VENDOR1);
+ } else {
+ gpio_touch_id = gpio_get_value(GPIO_TSP_VENDOR1)
+ + gpio_get_value(GPIO_TSP_VENDOR2)*2;
+ }
+ printk(KERN_ERR "[TSP] %s : gpio_touch_id = %d, system_rev = %d\n",
+ __func__, gpio_touch_id, system_rev);
+ ts_data.gpio_touch_id = gpio_touch_id;
+
+#endif
+
+}
+
+static void __init smdkc210_machine_init(void)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+#endif
+
+ /* initialise the gpios */
+#if defined(CONFIG_MACH_P2)
+ p2_config_gpio_table();
+ exynos4_sleep_gpio_table_set = p2_config_sleep_gpio_table;
+#elif defined(CONFIG_MACH_P8)
+ p8_config_gpio_table();
+ exynos4_sleep_gpio_table_set = p8_config_sleep_gpio_table;
+#else /* CONFIG_MACH_P4 */
+ p4_config_gpio_table();
+ exynos4_sleep_gpio_table_set = p4_config_sleep_gpio_table;
+#endif
+
+#ifdef CONFIG_MACH_PX
+ config_wlan_gpio();
+#endif
+
+#if defined(CONFIG_EXYNOS4_DEV_PD) && defined(CONFIG_PM_RUNTIME)
+ exynos_pd_disable(&exynos4_device_pd[PD_MFC].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_G3D].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_LCD0].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_LCD1].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_CAM].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_TV].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_GPS].dev);
+
+#elif defined(CONFIG_EXYNOS_DEV_PD)
+ /*
+ * These power domains should be always on
+ * without runtime pm support.
+ */
+ exynos_pd_enable(&exynos4_device_pd[PD_MFC].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_LCD0].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_LCD1].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_CAM].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_TV].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_GPS].dev);
+#endif
+#ifdef CONFIG_I2C_S3C2410
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+#ifdef CONFIG_S3C_DEV_I2C1
+
+#ifdef CONFIG_MPU_SENSORS_MPU3050
+ ak8975_init();
+ mpu3050_init();
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_mpu_sensor_board_info
+ , ARRAY_SIZE(i2c_mpu_sensor_board_info));
+#else
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+#endif
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C2
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C3
+ universal_tsp_init();
+#if defined(CONFIG_TOUCHSCREEN_MXT1386) \
+ && defined(CONFIG_RMI4_I2C)
+ if (system_rev >= 13)
+ i2c_register_board_info(3, i2c_devs3_syn,
+ ARRAY_SIZE(i2c_devs3_syn));
+ else {
+ i2c_register_board_info(3, i2c_devs3_mxt,
+ ARRAY_SIZE(i2c_devs3_mxt));
+ i2c3_data.frequency = 100 * 1000;
+ }
+ s3c_i2c3_set_platdata(&i2c3_data);
+#else
+ s3c_i2c3_set_platdata(NULL);
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+#endif
+#endif
+#ifdef CONFIG_S3C_DEV_I2C4
+#ifdef CONFIG_EPEN_WACOM_G5SP
+ p4w_wacom_init();
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+ s3c_i2c4_set_platdata(NULL);
+ i2c_register_board_info(4, i2c_devs4, ARRAY_SIZE(i2c_devs4));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C5
+ s3c_i2c5_set_platdata(NULL);
+ s3c_gpio_cfgpin(GPIO_PMIC_IRQ, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_PMIC_IRQ, S3C_GPIO_PULL_NONE);
+ i2c_devs5[0].irq = gpio_to_irq(GPIO_PMIC_IRQ);
+ i2c_register_board_info(5, i2c_devs5, ARRAY_SIZE(i2c_devs5));
+#endif
+
+#if defined(CONFIG_MACH_P4) || defined(CONFIG_MACH_P2)
+#ifdef CONFIG_VIBETONZ
+ if (system_rev >= 3)
+ max8997_motor.pwm_id = 0;
+#endif
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C6
+ s3c_i2c6_set_platdata(NULL);
+ i2c_register_board_info(6, i2c_devs6, ARRAY_SIZE(i2c_devs6));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C7
+#ifdef CONFIG_VIDEO_TVOUT
+ s3c_i2c7_set_platdata(&default_i2c7_data);
+#else
+ s3c_i2c7_set_platdata(NULL);
+#endif
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ printk(KERN_INFO "%s() register sii9234 driver\n", __func__);
+
+ i2c_register_board_info(15, tuna_i2c15_boardinfo,
+ ARRAY_SIZE(tuna_i2c15_boardinfo));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+ i2c_register_board_info(8, i2c_devs8_emul, ARRAY_SIZE(i2c_devs8_emul));
+ gpio_request(GPIO_3_TOUCH_INT, "sec_touchkey");
+ s5p_register_gpio_interrupt(GPIO_3_TOUCH_INT);
+
+#endif
+#ifdef CONFIG_S3C_DEV_I2C9_EMUL
+ i2c_register_board_info(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C10_EMUL
+ i2c_register_board_info(10, i2c_devs10_emul,
+ ARRAY_SIZE(i2c_devs10_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C11_EMUL
+
+#ifdef CONFIG_OPTICAL_GP2A
+ #if defined(CONFIG_OPTICAL_WAKE_ENABLE)
+ if (system_rev >= 0x03)
+ i2c_register_board_info(11, i2c_wake_devs11, ARRAY_SIZE(i2c_wake_devs11));
+ else
+ i2c_register_board_info(11, i2c_devs11, ARRAY_SIZE(i2c_devs11));
+ #else
+ /* optical sensor */
+ i2c_register_board_info(11, i2c_devs11, ARRAY_SIZE(i2c_devs11));
+ #endif
+#else
+ light_sensor_init();
+ i2c_register_board_info(11, i2c_bh1721_emul, ARRAY_SIZE(i2c_bh1721_emul));
+#endif
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C14_EMUL
+ nfc_setup_gpio();
+ i2c_register_board_info(14, i2c_devs14, ARRAY_SIZE(i2c_devs14));
+#endif
+
+#if defined(CONFIG_SMB136_CHARGER)
+ /* smb charger */
+ smb_gpio_init();
+ i2c_register_board_info(12, i2c_devs12_emul,
+ ARRAY_SIZE(i2c_devs12_emul));
+#endif
+#if defined(CONFIG_SMB347_CHARGER)
+ if (system_rev >= 02) {
+ printk(KERN_INFO "%s : Add smb347 charger.\n", __func__);
+ /* smb charger */
+ smb_gpio_init();
+ i2c_register_board_info(12, i2c_devs12_emul,
+ ARRAY_SIZE(i2c_devs12_emul));
+ platform_device_register(&s3c_device_i2c12);
+ }
+#endif
+
+ /* I2C13 EMUL */
+#if 0 /*defined(CONFIG_VIDEO_SR200PC20) && defined(CONFIG_MACH_P4W_REV01)*/
+ if (system_rev < 2)
+ platform_device_register(&s3c_device_i2c13);
+#endif
+
+#if defined(CONFIG_MHL_SII9234)
+ sii9234_init();
+ i2c_register_board_info(15, i2c_devs15, ARRAY_SIZE(i2c_devs15));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C16_EMUL
+ i2c_register_board_info(16, i2c_devs16, ARRAY_SIZE(i2c_devs16));
+#endif
+#endif
+ smdkc210_smsc911x_init();
+
+ /* 400 kHz for initialization of MMC Card */
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS3) & 0xfffffff0)
+ | 0x9, EXYNOS4_CLKDIV_FSYS3);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS2) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS2);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS1) & 0xfff0fff0)
+ | 0x90009, EXYNOS4_CLKDIV_FSYS1);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&exynos4_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&exynos4_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&exynos4_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&exynos4_hsmmc3_pdata);
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+
+#ifdef CONFIG_FB_S3C
+#ifdef CONFIG_LCD_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+ s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&ams369fg06_data);
+#else
+ s3cfb_set_platdata(NULL);
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_JPEG
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+#endif
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+#endif
+#ifdef CONFIG_S3C_DEV_ADC1
+ s3c24xx_ts1_set_platdata(&s3c_ts_platform);
+#endif
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+ android_pmem_set_platdata();
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ /* fimc */
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(NULL);
+ s3c_fimc2_set_platdata(&fimc_plat);
+ s3c_fimc3_set_platdata(NULL);
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(&px_tmu_data);
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X)
+ exynos4_mfc_setup_clock(&s5p_device_fimd0.dev, 200 * MHZ);
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimg2d.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdkc210_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdkc210_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdkc210_usbgadget_init();
+#endif
+ platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+#ifdef CONFIG_BACKLIGHT_PWM
+ smdk_backlight_register();
+#endif
+#if defined(CONFIG_FB_S5P_MDNIE) && defined(CONFIG_MACH_PX)
+ mdnie_device_register();
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ ld9040_fb_init();
+#endif
+#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
+ s6c1372_panel_gpio_init();
+#endif
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+ mipi_fb_init();
+#endif
+
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+ u1_sound_init();
+#endif
+
+#ifdef CONFIG_30PIN_CONN
+ smdk_accessory_gpio_init();
+#endif
+
+ exynos_sysmmu_init();
+
+
+#ifdef CONFIG_SEC_THERMISTOR
+ platform_device_register(&sec_device_thermistor);
+#endif
+
+#ifdef CONFIG_FB_S3C
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll",
+ 800 * MHZ);
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI0
+ sclk = clk_get(spi0_dev, "sclk_spi");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+ prnt = clk_get(spi0_dev, "mout_mpll");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+ clk_set_parent(sclk, prnt);
+
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS4_GPB(1), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+#endif
+
+ cam_init();
+#if defined(CONFIG_IR_REMOCON)
+/* IR_LED */
+ ir_rc_init_hw();
+/* IR_LED */
+#endif
+}
+
+static void __init exynos_init_reserve(void)
+{
+ sec_debug_magic_init();
+}
+
+MACHINE_START(SMDKC210, "SMDK4210")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdkc210_map_io,
+ .init_machine = smdkc210_machine_init,
+ .timer = &exynos4_timer,
+ .init_early = &exynos_init_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
new file mode 100644
index 0000000..97daba2
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -0,0 +1,4388 @@
+/* linux/arch/arm/mach-exynos/mach-smdk4x12.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/clk.h>
+#include <linux/lcd.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/i2c.h>
+#include <linux/pwm_backlight.h>
+#include <linux/input.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max77686.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/memblock.h>
+#include <linux/delay.h>
+#include <linux/smsc911x.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/exynos4.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/keypad.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/fb-s5p.h>
+#include <plat/fb-core.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/backlight.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-adc.h>
+#include <plat/adc.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#include <plat/usb-switch.h>
+#include <plat/s3c64xx-spi.h>
+#if defined(CONFIG_VIDEO_FIMC)
+#include <plat/fimc.h>
+#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+#include <plat/fimc-core.h>
+#include <media/s5p_fimc.h>
+#endif
+#if defined(CONFIG_VIDEO_FIMC_MIPI)
+#include <plat/csis.h>
+#elif defined(CONFIG_VIDEO_S5P_MIPI_CSIS)
+#include <plat/mipi_csis.h>
+#endif
+#include <plat/tvout.h>
+#include <plat/media.h>
+#include <plat/regs-srom.h>
+#include <plat/s5p-sysmmu.h>
+#include <plat/tv-core.h>
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+
+#include <media/s5k4ba_platform.h>
+#include <media/s5k4ea_platform.h>
+#include <media/exynos_flite.h>
+#include <media/exynos_fimc_is.h>
+#include <video/platform_lcd.h>
+#include <media/m5mo_platform.h>
+#include <media/m5mols.h>
+#include <mach/board_rev.h>
+#include <mach/map.h>
+#include <mach/spi-clocks.h>
+#include <mach/exynos-ion.h>
+#include <mach/regs-pmu.h>
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+#include <mach/dwmci.h>
+#endif
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+#include <mach/secmem.h>
+#endif
+#include <mach/dev.h>
+#include <mach/ppmu.h>
+#ifdef CONFIG_EXYNOS_C2C
+#include <mach/c2c.h>
+#endif
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#include <mach/mipi_ddi.h>
+#include <mach/dsim.h>
+#include <../../../drivers/video/samsung/s3cfb.h>
+#endif
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct s3cfb_extdsp_lcd {
+ int width;
+ int height;
+ int bpp;
+};
+#endif
+#include <plat/fimg2d.h>
+#include <mach/dev-sysmmu.h>
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+#include <plat/fimc-core.h>
+#include <media/s5p_fimc.h>
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#include <plat/jpeg.h>
+#endif
+
+#ifdef CONFIG_REGULATOR_S5M8767
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#endif
+
+#if defined(CONFIG_EXYNOS_SETUP_THERMAL)
+#include <plat/s5p-tmu.h>
+#endif
+
+#define REG_INFORM4 (S5P_INFORM4)
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK4X12_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK4X12_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK4X12_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK4X12_UCON_DEFAULT,
+ .ulcon = SMDK4X12_ULCON_DEFAULT,
+ .ufcon = SMDK4X12_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK4X12_UCON_DEFAULT,
+ .ulcon = SMDK4X12_ULCON_DEFAULT,
+ .ufcon = SMDK4X12_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK4X12_UCON_DEFAULT,
+ .ulcon = SMDK4X12_ULCON_DEFAULT,
+ .ufcon = SMDK4X12_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK4X12_UCON_DEFAULT,
+ .ulcon = SMDK4X12_ULCON_DEFAULT,
+ .ufcon = SMDK4X12_UFCON_DEFAULT,
+ },
+};
+
+static struct resource smdk4x12_smsc911x_resources[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SROM_BANK(1),
+ .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdk4x12_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdk4x12_smsc911x_resources),
+ .resource = smdk4x12_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+struct platform_device exynos_device_md0 = {
+ .name = "exynos-mdev",
+ .id = -1,
+};
+#endif
+
+#define WRITEBACK_ENABLED
+
+#if defined(CONFIG_VIDEO_FIMC) || defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+*/
+#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C) \
+ || defined(CONFIG_S5K3H2_CSI_C) || defined(CONFIG_S5K3H7_CSI_C) \
+ || defined(CONFIG_S5K4E5_CSI_C) || defined(CONFIG_S5K6A3_CSI_C)
+static int smdk4x12_cam0_reset(int dummy)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS4_GPX1(2), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS4_GPX1(2), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS4_GPX1(2), 0);
+ gpio_direction_output(EXYNOS4_GPX1(2), 1);
+ gpio_free(EXYNOS4_GPX1(2));
+
+ return 0;
+}
+#endif
+#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D) \
+ || defined(CONFIG_S5K3H2_CSI_D) || defined(CONFIG_S5K3H7_CSI_D) \
+ || defined(CONFIG_S5K4E5_CSI_D) || defined(CONFIG_S5K6A3_CSI_D)
+static int smdk4x12_cam1_reset(int dummy)
+{
+ int err;
+
+ /* Camera B */
+ err = gpio_request(EXYNOS4_GPX1(0), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_0 ####\n");
+
+ s3c_gpio_setpull(EXYNOS4_GPX1(0), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS4_GPX1(0), 0);
+ gpio_direction_output(EXYNOS4_GPX1(0), 1);
+ gpio_free(EXYNOS4_GPX1(0));
+
+ return 0;
+}
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_FIMC
+#ifdef CONFIG_VIDEO_S5K4BA
+static struct s5k4ba_platform_data s5k4ba_plat = {
+ .default_width = 800,
+ .default_height = 600,
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .freq = 24000000,
+ .is_mipi = 0,
+};
+
+static struct i2c_board_info s5k4ba_i2c_info = {
+ I2C_BOARD_INFO("S5K4BA", 0x2d),
+ .platform_data = &s5k4ba_plat,
+};
+
+static struct s3c_platform_camera s5k4ba = {
+#ifdef CONFIG_ITU_A
+ .id = CAMERA_PAR_A,
+ .clk_name = "sclk_cam0",
+ .i2c_busnum = 4,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_ITU_B
+ .id = CAMERA_PAR_B,
+ .clk_name = "sclk_cam1",
+ .i2c_busnum = 5,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_ITU,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &s5k4ba_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 1920,
+ .width = 1600,
+ .height = 1200,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1600,
+ .height = 1200,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 1,
+ .initialized = 0,
+};
+#endif
+
+/* 2 MIPI Cameras */
+#ifdef CONFIG_VIDEO_S5K4EA
+static struct s5k4ea_platform_data s5k4ea_plat = {
+ .default_width = 1920,
+ .default_height = 1080,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+};
+
+static struct i2c_board_info s5k4ea_i2c_info = {
+ I2C_BOARD_INFO("S5K4EA", 0x2d),
+ .platform_data = &s5k4ea_plat,
+};
+
+static struct s3c_platform_camera s5k4ea = {
+#ifdef CONFIG_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .i2c_busnum = 4,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .i2c_busnum = 5,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .info = &s5k4ea_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+
+ .initialized = 0,
+};
+#endif
+
+#ifdef WRITEBACK_ENABLED
+static struct i2c_board_info writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .i2c_busnum = 0,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 800,
+ .width = 480,
+ .height = 800,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 480,
+ .height = 800,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+#ifdef CONFIG_VIDEO_S5K3H2
+static struct i2c_board_info s5k3h2_sensor_info = {
+ .type = "S5K3H2",
+};
+
+static struct s3c_platform_camera s5k3h2 = {
+#ifdef CONFIG_S5K3H2_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K3H2_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .info = &s5k3h2_sensor_info,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+
+ .initialized = 0,
+#ifdef CONFIG_S5K3H2_CSI_C
+ .flite_id = FLITE_IDX_A,
+#endif
+#ifdef CONFIG_S5K3H2_CSI_D
+ .flite_id = FLITE_IDX_B,
+#endif
+ .use_isp = true,
+#ifdef CONFIG_S5K3H2_CSI_C
+ .sensor_index = 1,
+#endif
+#ifdef CONFIG_S5K3H2_CSI_D
+ .sensor_index = 101,
+#endif
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K3H7
+static struct i2c_board_info s5k3h7_sensor_info = {
+ .type = "S5K3H7",
+};
+
+static struct s3c_platform_camera s5k3h7 = {
+#ifdef CONFIG_S5K3H7_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K3H7_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .info = &s5k3h7_sensor_info,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+
+ .initialized = 0,
+#ifdef CONFIG_S5K3H7_CSI_C
+ .flite_id = FLITE_IDX_A,
+#endif
+#ifdef CONFIG_S5K3H7_CSI_D
+ .flite_id = FLITE_IDX_B,
+#endif
+ .use_isp = true,
+#ifdef CONFIG_S5K3H7_CSI_C
+ .sensor_index = 4,
+#endif
+#ifdef CONFIG_S5K3H7_CSI_D
+ .sensor_index = 104,
+#endif
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4E5
+static struct i2c_board_info s5k4e5_sensor_info = {
+ .type = "S5K4E5",
+};
+
+static struct s3c_platform_camera s5k4e5 = {
+#ifdef CONFIG_S5K4E5_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K4E5_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .info = &s5k4e5_sensor_info,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+
+ .initialized = 0,
+#ifdef CONFIG_S5K4E5_CSI_C
+ .flite_id = FLITE_IDX_A,
+#endif
+#ifdef CONFIG_S5K4E5_CSI_D
+ .flite_id = FLITE_IDX_B,
+#endif
+ .use_isp = true,
+#ifdef CONFIG_S5K4E5_CSI_C
+ .sensor_index = 3,
+#endif
+#ifdef CONFIG_S5K4E5_CSI_D
+ .sensor_index = 103,
+#endif
+};
+#endif
+
+
+#ifdef CONFIG_VIDEO_S5K6A3
+static struct i2c_board_info s5k6a3_sensor_info = {
+ .type = "S5K6A3",
+};
+
+static struct s3c_platform_camera s5k6a3 = {
+#ifdef CONFIG_S5K6A3_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K6A3_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .info = &s5k6a3_sensor_info,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 1,
+ .mipi_settle = 18,
+ .mipi_align = 24,
+
+ .initialized = 0,
+#ifdef CONFIG_S5K6A3_CSI_C
+ .flite_id = FLITE_IDX_A,
+#endif
+#ifdef CONFIG_S5K6A3_CSI_D
+ .flite_id = FLITE_IDX_B,
+#endif
+ .use_isp = true,
+#ifdef CONFIG_S5K6A3_CSI_C
+ .sensor_index = 2,
+#endif
+#ifdef CONFIG_S5K6A3_CSI_D
+ .sensor_index = 102,
+#endif
+};
+#endif
+
+#if defined(CONFIG_VIDEO_S5K6A3) && defined(CONFIG_S5K6A3_CSI_D)
+static struct i2c_board_info s5k6a3_fd_sensor_info = {
+ .type = "S5K6A3_FD",
+};
+
+static struct s3c_platform_camera s5k6a3_fd = {
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .cam_power = smdk4x12_cam1_reset,
+
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .info = &s5k6a3_fd_sensor_info,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 1,
+ .mipi_settle = 18,
+ .mipi_align = 24,
+
+ .initialized = 0,
+ .flite_id = FLITE_IDX_B,
+ .use_isp = true,
+ .sensor_index = 200
+};
+#endif
+
+#endif
+
+/* legacy M5MOLS Camera driver configuration */
+#ifdef CONFIG_VIDEO_M5MO
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ }
+
+static int m5mo_config_isp_irq(void)
+{
+ s3c_gpio_cfgpin(EXYNOS4_GPX3(3), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS4_GPX3(3), S3C_GPIO_PULL_NONE);
+ return 0;
+}
+
+static struct m5mo_platform_data m5mo_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .config_isp_irq = m5mo_config_isp_irq,
+ .irq = IRQ_EINT(27),
+};
+
+static struct i2c_board_info m5mo_i2c_info = {
+ I2C_BOARD_INFO("M5MO", 0x1F),
+ .platform_data = &m5mo_plat,
+ .irq = IRQ_EINT(27),
+};
+
+static struct s3c_platform_camera m5mo = {
+#ifdef CONFIG_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .i2c_busnum = 4,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .i2c_busnum = 5,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .info = &m5mo_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+#ifdef CONFIG_ITU_A
+ .default_cam = CAMERA_PAR_A,
+#endif
+#ifdef CONFIG_ITU_B
+ .default_cam = CAMERA_PAR_B,
+#endif
+#ifdef CONFIG_CSI_C
+ .default_cam = CAMERA_CSI_C,
+#endif
+#ifdef CONFIG_CSI_D
+ .default_cam = CAMERA_CSI_D,
+#endif
+#ifdef WRITEBACK_ENABLED
+ .default_cam = CAMERA_WB,
+#endif
+ .camera = {
+#ifdef CONFIG_VIDEO_S5K4BA
+ &s5k4ba,
+#endif
+#ifdef CONFIG_VIDEO_S5K4EA
+ &s5k4ea,
+#endif
+#ifdef CONFIG_VIDEO_M5MO
+ &m5mo,
+#endif
+#ifdef CONFIG_VIDEO_S5K3H2
+ &s5k3h2,
+#endif
+#ifdef CONFIG_VIDEO_S5K3H7
+ &s5k3h7,
+#endif
+#ifdef CONFIG_VIDEO_S5K4E5
+ &s5k4e5,
+#endif
+#ifdef CONFIG_VIDEO_S5K6A3
+ &s5k6a3,
+#endif
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+#if defined(CONFIG_VIDEO_S5K6A3) && defined(CONFIG_S5K6A3_CSI_D)
+ &s5k6a3_fd,
+#endif
+ },
+ .hw_ver = 0x51,
+};
+#endif /* CONFIG_VIDEO_FIMC */
+
+/* for mainline fimc interface */
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+#ifdef WRITEBACK_ENABLED
+struct writeback_mbus_platform_data {
+ int id;
+ struct v4l2_mbus_framefmt fmt;
+};
+
+static struct i2c_board_info __initdata writeback_info = {
+ I2C_BOARD_INFO("writeback", 0x0),
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4BA
+static struct s5k4ba_mbus_platform_data s5k4ba_mbus_plat = {
+ .id = 0,
+ .fmt = {
+ .width = 1600,
+ .height = 1200,
+ /*.code = V4L2_MBUS_FMT_UYVY8_2X8, */
+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
+ },
+ .clk_rate = 24000000UL,
+#ifdef CONFIG_ITU_A
+ .set_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_ITU_B
+ .set_power = smdk4x12_cam1_reset,
+#endif
+};
+
+static struct i2c_board_info s5k4ba_info = {
+ I2C_BOARD_INFO("S5K4BA", 0x2d),
+ .platform_data = &s5k4ba_mbus_plat,
+};
+#endif
+
+/* 2 MIPI Cameras */
+#ifdef CONFIG_VIDEO_S5K4EA
+static struct s5k4ea_mbus_platform_data s5k4ea_mbus_plat = {
+#ifdef CONFIG_CSI_C
+ .id = 0,
+ .set_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_CSI_D
+ .id = 1,
+ .set_power = smdk4x12_cam1_reset,
+#endif
+ .fmt = {
+ .width = 1920,
+ .height = 1080,
+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
+ },
+ .clk_rate = 24000000UL,
+};
+
+static struct i2c_board_info s5k4ea_info = {
+ I2C_BOARD_INFO("S5K4EA", 0x2d),
+ .platform_data = &s5k4ea_mbus_plat,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct m5mols_platform_data m5mols_platdata = {
+#ifdef CONFIG_CSI_C
+ .gpio_rst = EXYNOS4_GPX1(2), /* ISP_RESET */
+#endif
+#ifdef CONFIG_CSI_D
+ .gpio_rst = EXYNOS4_GPX1(0), /* ISP_RESET */
+#endif
+ .enable_rst = true, /* positive reset */
+ .irq = IRQ_EINT(27),
+};
+
+static struct i2c_board_info m5mols_board_info = {
+ I2C_BOARD_INFO("M5MOLS", 0x1F),
+ .platform_data = &m5mols_platdata,
+};
+
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+#ifdef CONFIG_VIDEO_S5K3H2
+static struct i2c_board_info s5k3h2_sensor_info = {
+ .type = "S5K3H2",
+};
+#endif
+#ifdef CONFIG_VIDEO_S5K3H7
+static struct i2c_board_info s5k3h7_sensor_info = {
+ .type = "S5K3H7",
+};
+#endif
+#ifdef CONFIG_VIDEO_S5K4E5
+static struct i2c_board_info s5k4e5_sensor_info = {
+ .type = "S5K4E5",
+};
+#endif
+#ifdef CONFIG_VIDEO_S5K6A3
+static struct i2c_board_info s5k6a3_sensor_info = {
+ .type = "S5K6A3",
+};
+#endif
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+/* This is for platdata of fimc-lite */
+#ifdef CONFIG_VIDEO_S5K3H2
+static struct s3c_platform_camera s5k3h2 = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 0,
+ .inv_vsync = 0,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K3H7
+static struct s3c_platform_camera s5k3h7 = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 0,
+ .inv_vsync = 0,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4E5
+static struct s3c_platform_camera s5k4e5 = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 0,
+ .inv_vsync = 0,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+
+
+#ifdef CONFIG_VIDEO_S5K6A3
+static struct s3c_platform_camera s5k6a3 = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 0,
+ .inv_vsync = 0,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+#endif
+#endif /* CONFIG_VIDEO_SAMSUNG_S5P_FIMC */
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+};
+
+#ifndef CONFIG_FB_S5P_LMS501KF03
+static struct s3c64xx_spi_csinfo spi1_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(5),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi1_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = &spi1_csi[0],
+ }
+};
+#endif
+
+static struct s3c64xx_spi_csinfo spi2_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPC1(2),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x2,
+ },
+};
+
+static struct spi_board_info spi2_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi2_csi[0],
+ }
+};
+#endif
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_LCD_AMS369FG06)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ err = gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+
+ gpio_free(EXYNOS4_GPX0(6));
+
+ return 1;
+}
+
+static struct lcd_platform_data ams369fg06_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = (void *)&ams369fg06_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd0.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win0 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win1 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win2 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#elif defined(CONFIG_LCD_LMS501KF03)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ if (samsung_board_rev_is_0_1()) {
+ err = gpio_request_one(EXYNOS4212_GPM3(6),
+ GPIOF_OUT_INIT_HIGH, "GPM3");
+ if (err) {
+ printk(KERN_ERR "failed to request GPM3 for "
+ "lcd reset control\n");
+ return err;
+ }
+ gpio_set_value(EXYNOS4212_GPM3(6), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4212_GPM3(6), 1);
+
+ gpio_free(EXYNOS4212_GPM3(6));
+ } else {
+ err = gpio_request_one(EXYNOS4_GPX1(5),
+ GPIOF_OUT_INIT_HIGH, "GPX1");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX1 for "
+ "lcd reset control\n");
+ return err;
+ }
+ gpio_set_value(EXYNOS4_GPX1(5), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4_GPX1(5), 1);
+
+ gpio_free(EXYNOS4_GPX1(5));
+ }
+
+ return 1;
+}
+
+static struct lcd_platform_data lms501kf03_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "lms501kf03",
+ .platform_data = (void *)&lms501kf03_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data lms501kf03_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd0.dev,
+ .platform_data = &lms501kf03_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win0 = {
+ .win_mode = {
+ .left_margin = 8, /* HBPD */
+ .right_margin = 8, /* HFPD */
+ .upper_margin = 6, /* VBPD */
+ .lower_margin = 6, /* VFPD */
+ .hsync_len = 6, /* HSPW */
+ .vsync_len = 4, /* VSPW */
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win1 = {
+ .win_mode = {
+ .left_margin = 8, /* HBPD */
+ .right_margin = 8, /* HFPD */
+ .upper_margin = 6, /* VBPD */
+ .lower_margin = 6, /* VFPD */
+ .hsync_len = 6, /* HSPW */
+ .vsync_len = 4, /* VSPW */
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win2 = {
+ .win_mode = {
+ .left_margin = 8, /* HBPD */
+ .right_margin = 8, /* HFPD */
+ .upper_margin = 6, /* VBPD */
+ .lower_margin = 6, /* VFPD */
+ .hsync_len = 6, /* HSPW */
+ .vsync_len = 4, /* VSPW */
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#elif defined(CONFIG_LCD_WA101S)
+static void lcd_wa101s_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdk4x12_lcd_wa101s_data = {
+ .set_power = lcd_wa101s_set_power,
+};
+
+static struct platform_device smdk4x12_lcd_wa101s = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdk4x12_lcd_wa101s_data,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win2 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_LTE480WV)
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdk4x12_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdk4x12_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdk4x12_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .width = 104,
+ .height = 62,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win1 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .width = 104,
+ .height = 62,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win2 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .width = 104,
+ .height = 62,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#elif defined(CONFIG_LCD_MIPI_S6E63M0)
+static void mipi_lcd_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ gpio_request_one(EXYNOS4_GPX2(7), GPIOF_OUT_INIT_HIGH, "GPX2");
+
+ mdelay(100);
+ if (power) {
+ /* fire nRESET on power up */
+ gpio_set_value(EXYNOS4_GPX2(7), 0);
+ mdelay(100);
+ gpio_set_value(EXYNOS4_GPX2(7), 1);
+ mdelay(100);
+ gpio_free(EXYNOS4_GPX2(7));
+ } else {
+ /* fire nRESET on power off */
+ gpio_set_value(EXYNOS4_GPX2(7), 0);
+ mdelay(100);
+ gpio_set_value(EXYNOS4_GPX2(7), 1);
+ mdelay(100);
+ gpio_free(EXYNOS4_GPX2(7));
+ }
+}
+
+static struct plat_lcd_data smdk4x12_mipi_lcd_data = {
+ .set_power = mipi_lcd_set_power,
+};
+
+static struct platform_device smdk4x12_mipi_lcd = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdk4x12_mipi_lcd_data,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win0 = {
+ .win_mode = {
+ .left_margin = 0x16,
+ .right_margin = 0x16,
+ .upper_margin = 0x1,
+ .lower_margin = 0x28,
+ .hsync_len = 0x2,
+ .vsync_len = 0x3,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win1 = {
+ .win_mode = {
+ .left_margin = 0x16,
+ .right_margin = 0x16,
+ .upper_margin = 0x1,
+ .lower_margin = 0x28,
+ .hsync_len = 0x2,
+ .vsync_len = 0x3,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk4x12_fb_win2 = {
+ .win_mode = {
+ .left_margin = 0x16,
+ .right_margin = 0x16,
+ .upper_margin = 0x1,
+ .lower_margin = 0x28,
+ .hsync_len = 0x2,
+ .vsync_len = 0x3,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static struct s3c_fb_platdata smdk4x12_lcd0_pdata __initdata = {
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_WA101S) || \
+ defined(CONFIG_LCD_LTE480WV) || defined(CONFIG_LCD_LMS501KF03) || \
+ defined(CONFIG_LCD_MIPI_S6E63M0)
+ .win[0] = &smdk4x12_fb_win0,
+ .win[1] = &smdk4x12_fb_win1,
+ .win[2] = &smdk4x12_fb_win2,
+#endif
+ .default_win = 2,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_AMS369FG06)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN |
+ VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_LMS501KF03)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_WA101S)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC |
+ VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_LTE480WV)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#endif
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_LMS501KF03
+static struct s3c_platform_fb lms501kf03_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "lms501kf03",
+ .platform_data = NULL,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+static struct spi_gpio_platform_data lms501kf03_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lms501kf03_spi_gpio_data,
+ },
+};
+#elif defined(CONFIG_FB_S5P_DUMMY_MIPI_LCD)
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct s3cfb_lcd dummy_mipi_lcd = {
+ .width = 480,
+ .height = 800,
+ .bpp = 24,
+
+ .freq = 60,
+
+ .timing = {
+ .h_fp = 0x16,
+ .h_bp = 0x16,
+ .h_sw = 0x2,
+ .v_fp = 0x28,
+ .v_fpe = 2,
+ .v_bp = 0x1,
+ .v_bpe = 1,
+ .v_sw = 3,
+ .cmd_allow_len = 0x4,
+ },
+
+ .polarity = {
+ .rise_vclk = 0,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+static void lcd_cfg_gpio(void)
+{
+ return;
+}
+
+static int reset_lcd(void)
+{
+ int err = 0;
+
+ /* fire nRESET on power off */
+ err = gpio_request(EXYNOS4_GPX3(1), "GPX3");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for lcd reset control\n");
+ return err;
+ }
+
+#ifdef CONFIG_CPU_EXYNOS4212
+ gpio_direction_output(EXYNOS4_GPX2(7), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX2(7), 0);
+ mdelay(100);
+ gpio_set_value(EXYNOS4_GPX2(7), 1);
+ mdelay(100);
+ gpio_free(EXYNOS4_GPX2(7));
+#else
+ gpio_direction_output(EXYNOS4_GPX3(1), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX3(1), 0);
+ mdelay(100);
+ gpio_set_value(EXYNOS4_GPX3(1), 1);
+ mdelay(100);
+ gpio_free(EXYNOS4_GPX3(1));
+#endif
+ return 0;
+}
+
+static int lcd_power_on(void *pdev, int enable)
+{
+ return 1;
+}
+
+static void __init mipi_fb_init(void)
+{
+ struct s5p_platform_dsim *dsim_pd = NULL;
+ struct mipi_ddi_platform_data *mipi_ddi_pd = NULL;
+ struct dsim_lcd_config *dsim_lcd_info = NULL;
+
+ /* gpio pad configuration for rgb and spi interface. */
+ lcd_cfg_gpio();
+
+ /*
+ * register lcd panel data.
+ */
+ dsim_pd = (struct s5p_platform_dsim *)
+ s5p_device_dsim.dev.platform_data;
+
+ strcpy(dsim_pd->lcd_panel_name, "dummy_mipi_lcd");
+
+ dsim_lcd_info = dsim_pd->dsim_lcd_info;
+ dsim_lcd_info->lcd_panel_info = (void *)&dummy_mipi_lcd;
+
+ mipi_ddi_pd = (struct mipi_ddi_platform_data *)
+ dsim_lcd_info->mipi_ddi_pd;
+ mipi_ddi_pd->lcd_reset = reset_lcd;
+ mipi_ddi_pd->lcd_power_on = lcd_power_on;
+
+ platform_device_register(&s5p_device_dsim);
+
+ s3cfb_set_platdata(&fb_platform_data);
+
+ printk(KERN_INFO "platform data of %s lcd panel has been registered.\n",
+ dsim_pd->lcd_panel_name);
+}
+#endif
+#endif
+
+static int exynos4_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ int mode = 0;
+
+ if ((code == SYS_RESTART) && _cmd)
+ if (!strcmp((char *)_cmd, "recovery"))
+ mode = 0xf;
+
+ __raw_writel(mode, REG_INFORM4);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos4_reboot_notifier = {
+ .notifier_call = exynos4_notifier_call,
+};
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+static void exynos_dwmci_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_8:
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS4_GPK0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos_dwmci_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 100 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x80,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci_cfg_gpio,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdk4x12_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdk4x12_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S5P_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+ .has_wp_gpio = true,
+ .wp_gpio = 0xffffffff,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
+#endif
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdk4x12_ehci_pdata;
+
+static void __init smdk4x12_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk4x12_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdk4x12_ohci_pdata;
+
+static void __init smdk4x12_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk4x12_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdk4x12_usbgadget_pdata;
+
+static void __init smdk4x12_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdk4x12_usbgadget_pdata;
+
+ s5p_usbgadget_set_platdata(pdata);
+}
+#endif
+
+static struct regulator_consumer_supply max8952_supply =
+ REGULATOR_SUPPLY("vdd_mif", NULL);
+
+static struct regulator_init_data max8952_init_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 800000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .uV = 1100000,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8952_supply,
+};
+
+static struct max8649_platform_data exynos4_max8952_info = {
+ .mode = 1, /* VID1 = 0, VID0 = 1 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8952_init_data,
+};
+
+/* max8997 */
+static struct regulator_consumer_supply max8997_buck1 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2 =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max8997_buck3 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply __initdata ldo2_consumer =
+ REGULATOR_SUPPLY("vdd_ldo2", NULL);
+
+static struct regulator_consumer_supply __initdata ldo3_consumer =
+ REGULATOR_SUPPLY("vdd_ldo3", NULL);
+
+static struct regulator_consumer_supply __initdata ldo4_consumer =
+ REGULATOR_SUPPLY("vdd_ldo4", NULL);
+
+static struct regulator_consumer_supply __initdata ldo5_consumer =
+ REGULATOR_SUPPLY("vdd_ldo5", NULL);
+
+static struct regulator_consumer_supply __initdata ldo6_consumer =
+ REGULATOR_SUPPLY("vdd_ldo6", NULL);
+
+static struct regulator_consumer_supply __initdata ldo7_consumer =
+ REGULATOR_SUPPLY("vdd_ldo7", NULL);
+
+static struct regulator_consumer_supply __initdata ldo8_consumer =
+ REGULATOR_SUPPLY("vdd_ldo8", NULL);
+
+static struct regulator_consumer_supply __initdata ldo9_consumer =
+ REGULATOR_SUPPLY("vdd_ldo9", NULL);
+
+static struct regulator_consumer_supply __initdata ldo10_consumer =
+ REGULATOR_SUPPLY("vdd_ldo10", NULL);
+
+static struct regulator_consumer_supply __initdata ldo11_consumer =
+ REGULATOR_SUPPLY("vdd_ldo11", NULL);
+
+static struct regulator_consumer_supply __initdata ldo12_consumer =
+ REGULATOR_SUPPLY("vdd_adc", NULL);
+
+static struct regulator_consumer_supply __initdata ldo14_consumer =
+ REGULATOR_SUPPLY("vdd_ldo14", NULL);
+
+static struct regulator_consumer_supply __initdata ldo21_consumer =
+ REGULATOR_SUPPLY("vdd_ldo21", NULL);
+
+static struct regulator_init_data __initdata max8997_ldo2_data = {
+ .constraints = {
+ .name = "vdd_ldo2 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo2_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo3_data = {
+ .constraints = {
+ .name = "vdd_ldo3 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo3_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo4_data = {
+ .constraints = {
+ .name = "vdd_ldo4 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo4_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo5_data = {
+ .constraints = {
+ .name = "vdd_ldo5 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo5_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo6_data = {
+ .constraints = {
+ .name = "vdd_ldo6 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo6_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo7_data = {
+ .constraints = {
+ .name = "vdd_ldo7 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo7_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo8_data = {
+ .constraints = {
+ .name = "vdd_ldo8 range",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo8_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo9_data = {
+ .constraints = {
+ .name = "vdd_ldo9 range",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo9_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo10_data = {
+ .constraints = {
+ .name = "vdd_ldo10 range",
+ .min_uV = 1000000,
+ .max_uV = 1000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo10_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo11_data = {
+ .constraints = {
+ .name = "vdd_ldo11 range",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo11_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo12_data = {
+ .constraints = {
+ .name = "vdd_adc range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo12_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo14_data = {
+ .constraints = {
+ .name = "vdd_ldo14 range",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo14_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_ldo21_data = {
+ .constraints = {
+ .name = "vdd_ldo21 range",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldo21_consumer,
+};
+
+static struct regulator_init_data __initdata max8997_buck1_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1500000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck1,
+};
+
+static struct regulator_init_data __initdata max8997_buck2_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 800000,
+ .max_uV = 1150000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck2,
+};
+
+static struct regulator_init_data __initdata max8997_buck3_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 800000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck3,
+};
+
+static struct max8997_regulator_data __initdata max8997_regulators[] = {
+ { MAX8997_LDO2, &max8997_ldo2_data, },
+ { MAX8997_LDO3, &max8997_ldo3_data, },
+ { MAX8997_LDO4, &max8997_ldo4_data, },
+ { MAX8997_LDO5, &max8997_ldo5_data, },
+ { MAX8997_LDO6, &max8997_ldo6_data, },
+ { MAX8997_LDO7, &max8997_ldo7_data, },
+ { MAX8997_LDO8, &max8997_ldo8_data, },
+ { MAX8997_LDO9, &max8997_ldo9_data, },
+ { MAX8997_LDO10, &max8997_ldo10_data, },
+ { MAX8997_LDO11, &max8997_ldo11_data, },
+ { MAX8997_LDO12, &max8997_ldo12_data, },
+ { MAX8997_LDO14, &max8997_ldo14_data, },
+ { MAX8997_LDO21, &max8997_ldo21_data, },
+ { MAX8997_BUCK1, &max8997_buck1_data, },
+ { MAX8997_BUCK2, &max8997_buck2_data, },
+ { MAX8997_BUCK3, &max8997_buck3_data, },
+};
+
+static struct max8997_platform_data __initdata exynos4_max8997_info = {
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = max8997_regulators,
+
+ .buck1_voltage[0] = 1300000, /* 1.25V */
+ .buck1_voltage[1] = 1100000, /* 1.1V */
+ .buck1_voltage[2] = 1100000, /* 1.1V */
+ .buck1_voltage[3] = 1100000, /* 1.1V */
+ .buck1_voltage[4] = 1100000, /* 1.1V */
+ .buck1_voltage[5] = 1100000, /* 1.1V */
+ .buck1_voltage[6] = 1000000, /* 1.0V */
+ .buck1_voltage[7] = 950000, /* 0.95V */
+
+ .buck2_voltage[0] = 1037500, /* 1.0375V */
+ .buck2_voltage[1] = 1000000, /* 1.0V */
+ .buck2_voltage[2] = 950000, /* 0.95V */
+ .buck2_voltage[3] = 900000, /* 0.9V */
+ .buck2_voltage[4] = 1000000, /* 1.0V */
+ .buck2_voltage[5] = 1000000, /* 1.0V */
+ .buck2_voltage[6] = 950000, /* 0.95V */
+ .buck2_voltage[7] = 900000, /* 0.9V */
+
+ .buck5_voltage[0] = 1100000, /* 1.1V */
+ .buck5_voltage[1] = 1100000, /* 1.1V */
+ .buck5_voltage[2] = 1100000, /* 1.1V */
+ .buck5_voltage[3] = 1100000, /* 1.1V */
+ .buck5_voltage[4] = 1100000, /* 1.1V */
+ .buck5_voltage[5] = 1100000, /* 1.1V */
+ .buck5_voltage[6] = 1100000, /* 1.1V */
+ .buck5_voltage[7] = 1100000, /* 1.1V */
+};
+
+/* max77686 */
+static struct regulator_consumer_supply max77686_buck1 =
+REGULATOR_SUPPLY("vdd_mif", NULL);
+
+static struct regulator_consumer_supply max77686_buck2 =
+REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3 =
+REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max77686_buck4 =
+REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max77686_ldo11_consumer =
+REGULATOR_SUPPLY("vdd_ldo11", NULL);
+
+static struct regulator_consumer_supply max77686_ldo14_consumer =
+REGULATOR_SUPPLY("vdd_ldo14", NULL);
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 800000,
+ .max_uV = 1050000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1350000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 800000,
+ .max_uV = 1150000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1200000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck4,
+};
+
+static struct regulator_init_data max77686_ldo11_data = {
+ .constraints = {
+ .name = "vdd_ldo11 range",
+ .min_uV = 1900000,
+ .max_uV = 1900000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_ldo11_consumer,
+};
+
+static struct regulator_init_data max77686_ldo14_data = {
+ .constraints = {
+ .name = "vdd_ldo14 range",
+ .min_uV = 1900000,
+ .max_uV = 1900000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_ldo14_consumer,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_LDO11, &max77686_ldo11_data,},
+ {MAX77686_LDO14, &max77686_ldo14_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+static struct max77686_platform_data exynos4_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = 0,
+ .irq_base = 0,
+ .wakeup = 0,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+
+ .buck2_voltage[0] = 1300000, /* 1.3V */
+ .buck2_voltage[1] = 1000000, /* 1.0V */
+ .buck2_voltage[2] = 950000, /* 0.95V */
+ .buck2_voltage[3] = 900000, /* 0.9V */
+ .buck2_voltage[4] = 1000000, /* 1.0V */
+ .buck2_voltage[5] = 1000000, /* 1.0V */
+ .buck2_voltage[6] = 950000, /* 0.95V */
+ .buck2_voltage[7] = 900000, /* 0.9V */
+
+ .buck3_voltage[0] = 1037500, /* 1.0375V */
+ .buck3_voltage[1] = 1000000, /* 1.0V */
+ .buck3_voltage[2] = 950000, /* 0.95V */
+ .buck3_voltage[3] = 900000, /* 0.9V */
+ .buck3_voltage[4] = 1000000, /* 1.0V */
+ .buck3_voltage[5] = 1000000, /* 1.0V */
+ .buck3_voltage[6] = 950000, /* 0.95V */
+ .buck3_voltage[7] = 900000, /* 0.9V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1000000, /* 1.0V */
+ .buck4_voltage[2] = 950000, /* 0.95V */
+ .buck4_voltage[3] = 900000, /* 0.9V */
+ .buck4_voltage[4] = 1000000, /* 1.0V */
+ .buck4_voltage[5] = 1000000, /* 1.0V */
+ .buck4_voltage[6] = 950000, /* 0.95V */
+ .buck4_voltage[7] = 900000, /* 0.9V */
+};
+#ifdef CONFIG_REGULATOR_S5M8767
+/* S5M8767 Regulator */
+static int s5m_cfg_irq(void)
+{
+ /* AP_PMIC_IRQ: EINT26 */
+ s3c_gpio_cfgpin(EXYNOS4_GPX3(2), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS4_GPX3(2), S3C_GPIO_PULL_UP);
+ return 0;
+}
+static struct regulator_consumer_supply s5m8767_buck1_consumer =
+ REGULATOR_SUPPLY("vdd_mif", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck2_consumer =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck3_consumer =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck4_consumer =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_init_data s5m8767_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 800000,
+ .max_uV = 1100000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck1_consumer,
+};
+
+static struct regulator_init_data s5m8767_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 800000,
+ .max_uV = 1350000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck2_consumer,
+};
+
+static struct regulator_init_data s5m8767_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 800000,
+ .max_uV = 1150000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck3_consumer,
+};
+
+static struct regulator_init_data s5m8767_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck4_consumer,
+};
+
+static struct s5m_regulator_data pegasus_regulators[] = {
+ { S5M8767_BUCK1, &s5m8767_buck1_data },
+ { S5M8767_BUCK2, &s5m8767_buck2_data },
+ { S5M8767_BUCK3, &s5m8767_buck3_data },
+ { S5M8767_BUCK4, &s5m8767_buck4_data },
+};
+
+static struct s5m_platform_data exynos4_s5m8767_pdata = {
+ .device_type = S5M8767X,
+ .irq_base = IRQ_BOARD_START,
+ .num_regulators = ARRAY_SIZE(pegasus_regulators),
+ .regulators = pegasus_regulators,
+ .cfg_pmic_irq = s5m_cfg_irq,
+ .wakeup = 1,
+ .opmode_data = s5m8767_opmode_data,
+ .wtsr_smpl = 1,
+
+ .buck2_voltage[0] = 1250000,
+ .buck2_voltage[1] = 1200000,
+ .buck2_voltage[2] = 1150000,
+ .buck2_voltage[3] = 1100000,
+ .buck2_voltage[4] = 1050000,
+ .buck2_voltage[5] = 1000000,
+ .buck2_voltage[6] = 950000,
+ .buck2_voltage[7] = 900000,
+
+ .buck3_voltage[0] = 1100000,
+ .buck3_voltage[1] = 1000000,
+ .buck3_voltage[2] = 950000,
+ .buck3_voltage[3] = 900000,
+ .buck3_voltage[4] = 1100000,
+ .buck3_voltage[5] = 1000000,
+ .buck3_voltage[6] = 950000,
+ .buck3_voltage[7] = 900000,
+
+ .buck4_voltage[0] = 1200000,
+ .buck4_voltage[1] = 1150000,
+ .buck4_voltage[2] = 1200000,
+ .buck4_voltage[3] = 1100000,
+ .buck4_voltage[4] = 1100000,
+ .buck4_voltage[5] = 1100000,
+ .buck4_voltage[6] = 1100000,
+ .buck4_voltage[7] = 1100000,
+
+ .buck_default_idx = 3,
+ .buck_gpios[0] = EXYNOS4_GPX2(3),
+ .buck_gpios[1] = EXYNOS4_GPX2(4),
+ .buck_gpios[2] = EXYNOS4_GPX2(5),
+
+ .buck_ramp_delay = 25,
+ .buck2_ramp_enable = true,
+ .buck3_ramp_enable = true,
+ .buck4_ramp_enable = true,
+};
+/* End of S5M8767 */
+#endif
+
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+static struct regulator_consumer_supply mipi_csi_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.0"),
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.1"),
+};
+
+static struct regulator_init_data mipi_csi_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mipi_csi_fixed_voltage_supplies),
+ .consumer_supplies = mipi_csi_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config mipi_csi_fixed_voltage_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &mipi_csi_fixed_voltage_init_data,
+};
+
+static struct platform_device mipi_csi_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &mipi_csi_fixed_voltage_config,
+ },
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct regulator_consumer_supply m5mols_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("core", NULL),
+ REGULATOR_SUPPLY("dig_18", NULL),
+ REGULATOR_SUPPLY("d_sensor", NULL),
+ REGULATOR_SUPPLY("dig_28", NULL),
+ REGULATOR_SUPPLY("a_sensor", NULL),
+ REGULATOR_SUPPLY("dig_12", NULL),
+};
+
+static struct regulator_init_data m5mols_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(m5mols_fixed_voltage_supplies),
+ .consumer_supplies = m5mols_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config m5mols_fixed_voltage_config = {
+ .supply_name = "CAM_SENSOR",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &m5mols_fixed_voltage_init_data,
+};
+
+static struct platform_device m5mols_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &m5mols_fixed_voltage_config,
+ },
+};
+#endif
+
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ REGULATOR_SUPPLY("AVDD2", "1-001a"),
+ REGULATOR_SUPPLY("CPVDD", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage2_supplies =
+ REGULATOR_SUPPLY("DBVDD", "1-001a");
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+ .consumer_supplies = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+ .consumer_supplies = wm8994_fixed_voltage1_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage2_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_fixed_voltage2_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VDD_1.8V",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage2_config = {
+ .supply_name = "VDD_3.3V",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage2_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage2 = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage2_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+ REGULATOR_SUPPLY("AVDD1", "1-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+ REGULATOR_SUPPLY("DCVDD", "1-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* If the i2s0 and i2s2 is enabled simultaneously */
+ .gpio_defaults[7] = 0x8100, /* GPIO8 DACDAT3 in */
+ .gpio_defaults[8] = 0x0100, /* GPIO9 ADCDAT3 out */
+ .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3 out */
+ .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3 out */
+ .ldo[0] = { 0, NULL, &wm8994_ldo1_data },
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+#ifdef CONFIG_REGULATOR_S5M8767
+ {
+ I2C_BOARD_INFO("s5m87xx", 0xCC >> 1),
+ .platform_data = &exynos4_s5m8767_pdata,
+ .irq = IRQ_EINT(26),
+ },
+#else
+ {
+ I2C_BOARD_INFO("max8997", 0x66),
+ .platform_data = &exynos4_max8997_info,
+ }, {
+ I2C_BOARD_INFO("max77686", (0x12 >> 1)),
+ .platform_data = &exynos4_max77686_info,
+ },
+#endif
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
+static struct i2c_board_info i2c_devs2[] __initdata = {
+#ifdef CONFIG_VIDEO_TVOUT
+ {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+ },
+#endif
+};
+
+static struct i2c_board_info i2c_devs3[] __initdata = {
+ {
+ I2C_BOARD_INFO("max8952", 0x60),
+ .platform_data = &exynos4_max8952_info,
+ },
+};
+
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("pixcir-ts", 0x5C),
+ },
+};
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+static struct gpio_event_direct_entry smdk4x12_keypad_key_map[] = {
+ {
+ .gpio = EXYNOS4_GPX0(0),
+ .code = KEY_POWER,
+ }
+};
+
+static struct gpio_event_input_info smdk4x12_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdk4x12_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdk4x12_keypad_key_map)
+};
+
+static struct gpio_event_info *smdk4x12_input_info[] = {
+ &smdk4x12_keypad_key_info.info,
+};
+
+static struct gpio_event_platform_data smdk4x12_input_data = {
+ .names = {
+ "smdk4x12-keypad",
+ NULL,
+ },
+ .info = smdk4x12_input_info,
+ .info_count = ARRAY_SIZE(smdk4x12_input_info),
+};
+
+static struct platform_device smdk4x12_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdk4x12_input_data,
+ },
+};
+
+static void __init smdk4x12_gpio_power_init(void)
+{
+ int err = 0;
+
+ err = gpio_request_one(EXYNOS4_GPX0(0), 0, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "suspend/resume control\n");
+ return;
+ }
+ s3c_gpio_setpull(EXYNOS4_GPX0(0), S3C_GPIO_PULL_NONE);
+
+ gpio_free(EXYNOS4_GPX0(0));
+}
+
+static uint32_t smdk4x12_keymap0[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(1, 0, KEY_D), KEY(1, 1, KEY_A), KEY(1, 2, KEY_B),
+ KEY(1, 3, KEY_E), KEY(1, 4, KEY_C)
+};
+
+static struct matrix_keymap_data smdk4x12_keymap_data0 __initdata = {
+ .keymap = smdk4x12_keymap0,
+ .keymap_size = ARRAY_SIZE(smdk4x12_keymap0),
+};
+
+static struct samsung_keypad_platdata smdk4x12_keypad_data0 __initdata = {
+ .keymap_data = &smdk4x12_keymap_data0,
+ .rows = 2,
+ .cols = 5,
+};
+
+static uint32_t smdk4x12_keymap1[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(1, 3, KEY_1), KEY(1, 4, KEY_2), KEY(1, 5, KEY_3),
+ KEY(1, 6, KEY_4), KEY(1, 7, KEY_5),
+ KEY(2, 5, KEY_D), KEY(2, 6, KEY_A), KEY(2, 7, KEY_B),
+ KEY(0, 7, KEY_E), KEY(0, 5, KEY_C)
+};
+
+static struct matrix_keymap_data smdk4x12_keymap_data1 __initdata = {
+ .keymap = smdk4x12_keymap1,
+ .keymap_size = ARRAY_SIZE(smdk4x12_keymap1),
+};
+
+static struct samsung_keypad_platdata smdk4x12_keypad_data1 __initdata = {
+ .keymap_data = &smdk4x12_keymap_data1,
+ .rows = 3,
+ .cols = 8,
+};
+
+#ifdef CONFIG_WAKEUP_ASSIST
+static struct platform_device wakeup_assist_device = {
+ .name = "wakeup_assist",
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 0x41,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 201 * 1000000, /* 200 Mhz */
+};
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+struct exynos_c2c_platdata smdk4x12_c2c_pdata = {
+ .setup_gpio = NULL,
+ .shdmem_addr = C2C_SHAREDMEM_BASE,
+ .shdmem_size = C2C_MEMSIZE_64,
+ .ap_sscm_addr = NULL,
+ .cp_sscm_addr = NULL,
+ .rx_width = C2C_BUSWIDTH_16,
+ .tx_width = C2C_BUSWIDTH_16,
+ .clk_opp100 = 400,
+ .clk_opp50 = 266,
+ .clk_opp25 = 0,
+ .default_opp_mode = C2C_OPP50,
+ .get_c2c_state = NULL,
+ .c2c_sysreg = S5P_VA_CMU + 0x12000,
+};
+#endif
+
+#ifdef CONFIG_USB_EXYNOS_SWITCH
+static struct s5p_usbswitch_platdata smdk4x12_usbswitch_pdata;
+
+static void __init smdk4x12_usbswitch_init(void)
+{
+ struct s5p_usbswitch_platdata *pdata = &smdk4x12_usbswitch_pdata;
+ int err;
+
+ pdata->gpio_host_detect = EXYNOS4_GPX3(5); /* low active */
+ err = gpio_request_one(pdata->gpio_host_detect, GPIOF_IN, "HOST_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request gpio_host_detect\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_host_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_host_detect, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_host_detect);
+
+ pdata->gpio_device_detect = EXYNOS4_GPX3(4); /* high active */
+ err = gpio_request_one(pdata->gpio_device_detect, GPIOF_IN, "DEVICE_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request gpio_host_detect for\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_device_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_device_detect, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_device_detect);
+
+ if (samsung_board_rev_is_0_0())
+ pdata->gpio_host_vbus = 0;
+ else {
+ pdata->gpio_host_vbus = EXYNOS4_GPL2(0);
+ err = gpio_request_one(pdata->gpio_host_vbus, GPIOF_OUT_INIT_LOW, "HOST_VBUS_CONTROL");
+ if (err) {
+ printk(KERN_ERR "failed to request gpio_host_vbus\n");
+ return;
+ }
+
+ s3c_gpio_setpull(pdata->gpio_host_vbus, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_host_vbus);
+ }
+
+ s5p_usbswitch_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+#endif
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+
+static struct platform_device *smdk4412_devices[] __initdata = {
+ &s3c_device_adc,
+};
+
+static struct platform_device *smdk4x12_devices[] __initdata = {
+ /* Samsung Power Domain */
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+ &exynos4_device_pd[PD_GPS_ALIVE],
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &exynos4_device_pd[PD_ISP],
+#endif
+#ifdef CONFIG_FB_MIPI_DSIM
+ &s5p_device_mipi_dsim,
+#endif
+/* mainline fimd */
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd0,
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_LMS501KF03)
+ &s3c_device_spi_gpio,
+#elif defined(CONFIG_LCD_WA101S)
+ &smdk4x12_lcd_wa101s,
+#elif defined(CONFIG_LCD_LTE480WV)
+ &smdk4x12_lcd_lte480wv,
+#elif defined(CONFIG_LCD_MIPI_S6E63M0)
+ &smdk4x12_mipi_lcd,
+#endif
+#endif
+ /* legacy fimd */
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ &s3c_device_spi_gpio,
+#endif
+#endif
+ &s3c_device_wdt,
+ &s3c_device_rtc,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+ &s3c_device_i2c3,
+ &s3c_device_i2c4,
+ &s3c_device_i2c5,
+ &s3c_device_i2c7,
+#ifdef CONFIG_USB_EHCI_S5P
+ &s5p_device_ehci,
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#ifdef CONFIG_USB_ANDROID
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+#ifdef CONFIG_S5P_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ &exynos_device_dwmci,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &exynos4_device_fimc_is,
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+#ifdef CONFIG_FB_S5P_EXTDSP
+ &s3c_device_extdsp,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+ &s5p_device_i2c_hdmiphy,
+ &s5p_device_hdmi,
+ &s5p_device_sdo,
+ &s5p_device_mixer,
+ &s5p_device_cec,
+#endif
+#if defined(CONFIG_VIDEO_FIMC)
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+/* CONFIG_VIDEO_SAMSUNG_S5P_FIMC is the feature for mainline */
+#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+ &s5p_device_fimc0,
+ &s5p_device_fimc1,
+ &s5p_device_fimc2,
+ &s5p_device_fimc3,
+#endif
+#if defined(CONFIG_VIDEO_FIMC_MIPI)
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#elif defined(CONFIG_VIDEO_S5P_MIPI_CSIS)
+ &s5p_device_mipi_csis0,
+ &s5p_device_mipi_csis1,
+#endif
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+ &mipi_csi_fixed_voltage,
+#endif
+#ifdef CONFIG_VIDEO_M5MOLS
+ &m5mols_fixed_voltage,
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(g2d_acp),
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(jpeg),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+ &SYSMMU_PLATDEV(tv),
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ &SYSMMU_PLATDEV(is_isp),
+ &SYSMMU_PLATDEV(is_drc),
+ &SYSMMU_PLATDEV(is_fd),
+ &SYSMMU_PLATDEV(is_cpu),
+#endif
+#endif /* CONFIG_S5P_SYSTEM_MMU */
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ &exynos_device_flite0,
+ &exynos_device_flite1,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+ &exynos_device_md0,
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ &s5p_device_jpeg,
+#endif
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
+ &wm8994_fixed_voltage2,
+ &samsung_asoc_dma,
+ &samsung_asoc_idma,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+ &samsung_device_keypad,
+#ifdef CONFIG_WAKEUP_ASSIST
+ &wakeup_assist_device,
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ &exynos_device_c2c,
+#endif
+ &smdk4x12_input_device,
+ &smdk4x12_smsc911x,
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ &exynos_device_spi0,
+#ifndef CONFIG_FB_S5P_LMS501KF03
+ &exynos_device_spi1,
+#endif
+ &exynos_device_spi2,
+#endif
+#ifdef CONFIG_EXYNOS_SETUP_THERMAL
+ &exynos_device_tmu,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+ &exynos4_busfreq,
+};
+
+#ifdef CONFIG_EXYNOS_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct tmu_data exynos_tmu_data __initdata = {
+ .ts = {
+ .stop_throttle = 82,
+ .start_throttle = 85,
+ .stop_warning = 95,
+ .start_warning = 103,
+ .start_tripping = 110, /* temp to do tripping */
+ },
+ .efuse_value = 55,
+ .slope = 0x10008802,
+ .mode = 0,
+};
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+
+};
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+static struct s5p_fimc_isp_info isp_info[] = {
+#if defined(CONFIG_VIDEO_S5K4BA)
+ {
+ .board_info = &s5k4ba_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_ITU_601,
+#ifdef CONFIG_ITU_A
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_ITU_B
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = FIMC_CLK_INV_VSYNC,
+ },
+#endif
+#if defined(CONFIG_VIDEO_S5K4EA)
+ {
+ .board_info = &s5k4ea_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = FIMC_CLK_INV_VSYNC,
+ .csi_data_align = 32,
+ },
+#endif
+#if defined(CONFIG_VIDEO_M5MOLS)
+ {
+ .board_info = &m5mols_board_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_CSI_C
+ .i2c_bus_num = 4,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_CSI_D
+ .i2c_bus_num = 5,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = FIMC_CLK_INV_PCLK | FIMC_CLK_INV_VSYNC,
+ .csi_data_align = 32,
+ },
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+#if defined(CONFIG_VIDEO_S5K3H2)
+ {
+ .board_info = &s5k3h2_sensor_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_S5K3H2_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_A,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K3H2_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_B,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .flags = 0,
+ .csi_data_align = 24,
+ .use_isp = true,
+ },
+#endif
+#if defined(CONFIG_VIDEO_S5K3H7)
+ {
+ .board_info = &s5k3h7_sensor_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_S5K3H7_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_A,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K3H7_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_B,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .csi_data_align = 24,
+ .use_isp = true,
+ },
+#endif
+#if defined(CONFIG_VIDEO_S5K4E5)
+ {
+ .board_info = &s5k4e5_sensor_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_S5K4E5_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_A,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K4E5_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_B,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .csi_data_align = 24,
+ .use_isp = true,
+ },
+#endif
+#if defined(CONFIG_VIDEO_S5K6A3)
+ {
+ .board_info = &s5k6a3_sensor_info,
+ .clk_frequency = 12000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_S5K6A3_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_A,
+ .cam_power = smdk4x12_cam0_reset,
+#endif
+#ifdef CONFIG_S5K6A3_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+ .flite_id = FLITE_IDX_B,
+ .cam_power = smdk4x12_cam1_reset,
+#endif
+ .flags = 0,
+ .csi_data_align = 12,
+ .use_isp = true,
+ },
+#endif
+#endif
+#if defined(WRITEBACK_ENABLED)
+ {
+ .board_info = &writeback_info,
+ .bus_type = FIMC_LCD_WB,
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flags = FIMC_CLK_INV_VSYNC,
+ },
+#endif
+};
+
+static void __init smdk4x12_subdev_config(void)
+{
+ s3c_fimc0_default_data.isp_info[0] = &isp_info[0];
+ s3c_fimc0_default_data.isp_info[0]->use_cam = true;
+ s3c_fimc0_default_data.isp_info[1] = &isp_info[1];
+ s3c_fimc0_default_data.isp_info[1]->use_cam = true;
+ /* support using two fimc as one sensore */
+ {
+ static struct s5p_fimc_isp_info camcording1;
+ static struct s5p_fimc_isp_info camcording2;
+ memcpy(&camcording1, &isp_info[0], sizeof(struct s5p_fimc_isp_info));
+ memcpy(&camcording2, &isp_info[1], sizeof(struct s5p_fimc_isp_info));
+ s3c_fimc1_default_data.isp_info[0] = &camcording1;
+ s3c_fimc1_default_data.isp_info[0]->use_cam = false;
+ s3c_fimc1_default_data.isp_info[1] = &camcording2;
+ s3c_fimc1_default_data.isp_info[1]->use_cam = false;
+ }
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+#ifdef CONFIG_VIDEO_S5K3H2
+#ifdef CONFIG_S5K3H2_CSI_C
+ s5p_mipi_csis0_default_data.clk_rate = 160000000;
+ s5p_mipi_csis0_default_data.lanes = 2;
+ s5p_mipi_csis0_default_data.alignment = 24;
+ s5p_mipi_csis0_default_data.hs_settle = 12;
+#endif
+#ifdef CONFIG_S5K3H2_CSI_D
+ s5p_mipi_csis1_default_data.clk_rate = 160000000;
+ s5p_mipi_csis1_default_data.lanes = 2;
+ s5p_mipi_csis1_default_data.alignment = 24;
+ s5p_mipi_csis1_default_data.hs_settle = 12;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_S5K3H7
+#ifdef CONFIG_S5K3H7_CSI_C
+ s5p_mipi_csis0_default_data.clk_rate = 160000000;
+ s5p_mipi_csis0_default_data.lanes = 2;
+ s5p_mipi_csis0_default_data.alignment = 24;
+ s5p_mipi_csis0_default_data.hs_settle = 12;
+#endif
+#ifdef CONFIG_S5K3H7_CSI_D
+ s5p_mipi_csis1_default_data.clk_rate = 160000000;
+ s5p_mipi_csis1_default_data.lanes = 2;
+ s5p_mipi_csis1_default_data.alignment = 24;
+ s5p_mipi_csis1_default_data.hs_settle = 12;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_S5K4E5
+#ifdef CONFIG_S5K4E5_CSI_C
+ s5p_mipi_csis0_default_data.clk_rate = 160000000;
+ s5p_mipi_csis0_default_data.lanes = 2;
+ s5p_mipi_csis0_default_data.alignment = 24;
+ s5p_mipi_csis0_default_data.hs_settle = 12;
+#endif
+#ifdef CONFIG_S5K4E5_CSI_D
+ s5p_mipi_csis1_default_data.clk_rate = 160000000;
+ s5p_mipi_csis1_default_data.lanes = 2;
+ s5p_mipi_csis1_default_data.alignment = 24;
+ s5p_mipi_csis1_default_data.hs_settle = 12;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_S5K6A3
+#ifdef CONFIG_S5K6A3_CSI_C
+ s5p_mipi_csis0_default_data.clk_rate = 160000000;
+ s5p_mipi_csis0_default_data.lanes = 1;
+ s5p_mipi_csis0_default_data.alignment = 24;
+ s5p_mipi_csis0_default_data.hs_settle = 12;
+#endif
+#ifdef CONFIG_S5K6A3_CSI_D
+ s5p_mipi_csis1_default_data.clk_rate = 160000000;
+ s5p_mipi_csis1_default_data.lanes = 1;
+ s5p_mipi_csis1_default_data.alignment = 24;
+ s5p_mipi_csis1_default_data.hs_settle = 12;
+#endif
+#endif
+#endif
+}
+static void __init smdk4x12_camera_config(void)
+{
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPJ0(0), 8, S3C_GPIO_SFN(2));
+ /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPJ1(0), 5, S3C_GPIO_SFN(2));
+ /* CAM B port(b0011) : PCLK, DATA[0-6] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM0(0), 8, S3C_GPIO_SFN(3));
+ /* CAM B port(b0011) : FIELD, DATA[7]*/
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM1(0), 2, S3C_GPIO_SFN(3));
+ /* CAM B port(b0011) : VSYNC, HREF, CLKOUT*/
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM2(0), 3, S3C_GPIO_SFN(3));
+
+ /* note : driver strength to max is unnecessary */
+#ifdef CONFIG_VIDEO_M5MOLS
+ s3c_gpio_cfgpin(EXYNOS4_GPX2(6), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS4_GPX2(6), S3C_GPIO_PULL_NONE);
+#endif
+}
+#endif /* CONFIG_VIDEO_SAMSUNG_S5P_FIMC */
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+static void __set_flite_camera_config(struct exynos_platform_flite *data,
+ u32 active_index, u32 max_cam)
+{
+ data->active_cam_index = active_index;
+ data->num_clients = max_cam;
+}
+
+static void __init smdk4x12_set_camera_flite_platdata(void)
+{
+ int flite0_cam_index = 0;
+ int flite1_cam_index = 0;
+#ifdef CONFIG_VIDEO_S5K3H2
+#ifdef CONFIG_S5K3H2_CSI_C
+ exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k3h2;
+#endif
+#ifdef CONFIG_S5K3H2_CSI_D
+ exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k3h2;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_S5K3H7
+#ifdef CONFIG_S5K3H7_CSI_C
+ exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k3h7;
+#endif
+#ifdef CONFIG_S5K3H7_CSI_D
+ exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k3h7;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_S5K4E5
+#ifdef CONFIG_S5K4E5_CSI_C
+ exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k4e5;
+#endif
+#ifdef CONFIG_S5K4E5_CSI_D
+ exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k4e5;
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_S5K6A3
+#ifdef CONFIG_S5K6A3_CSI_C
+ exynos_flite0_default_data.cam[flite0_cam_index++] = &s5k6a3;
+#endif
+#ifdef CONFIG_S5K6A3_CSI_D
+ exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k6a3;
+#endif
+#endif
+ __set_flite_camera_config(&exynos_flite0_default_data, 0, flite0_cam_index);
+ __set_flite_camera_config(&exynos_flite1_default_data, 0, flite1_cam_index);
+}
+#endif
+
+#if defined(CONFIG_CMA)
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifndef CONFIG_VIDEOBUF2_ION
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV
+ {
+ .name = "tv",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .name = "jpeg",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .name = "fimc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .start = 0
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3)
+ {
+ .name = "fimc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL
+ {
+ .name = "mfc-normal",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL * SZ_1K,
+ { .alignment = 1 << 17 },
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ }
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ {
+ .name = "fimc_is",
+ .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0
+ },
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER
+ {
+ .name = "fimc_is_isp",
+ .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS_ISP * SZ_1K,
+ .start = 0
+ },
+#endif
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ {
+ .name = "b2",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "b1",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "fw",
+ .size = 1 << 20,
+ { .alignment = 128 << 10 },
+ },
+#endif
+#else /* !CONFIG_VIDEOBUF2_ION */
+#ifdef CONFIG_FB_S5P
+#error CONFIG_FB_S5P is defined. Select CONFIG_FB_S3C, instead
+#endif
+ {
+ .name = "ion",
+ .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K,
+ },
+#endif /* !CONFIG_VIDEOBUF2_ION */
+ {
+ .size = 0
+ },
+ };
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ static struct cma_region regions_secure[] = {
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3
+ {
+ .name = "fimc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD_VIDEO
+ {
+ .name = "video",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD_VIDEO * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE
+ {
+ .name = "mfc-secure",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE * SZ_1K,
+ },
+#endif
+ {
+ .name = "sectbl",
+ .size = SZ_1M,
+ },
+ {
+ .size = 0
+ },
+ };
+#else /* !CONFIG_EXYNOS_CONTENT_PATH_PROTECTION */
+ struct cma_region *regions_secure = NULL;
+#endif
+ static const char map[] __initconst =
+#ifdef CONFIG_EXYNOS_C2C
+ "samsung-c2c=c2c_shdmem;"
+#endif
+ "s3cfb.0/fimd=fimd;exynos4-fb.0/fimd=fimd;"
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ "s3cfb.0/video=video;exynos4-fb.0/video=video;"
+#endif
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;s3c-fimc.3=fimc3;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc.3=fimc3;"
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc=mfc,mfc0,mfc1;"
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ "s5p-mfc/f=fw;"
+ "s5p-mfc/a=b1;"
+ "s5p-mfc/b=b2;"
+#endif
+ "samsung-rp=srp;"
+ "s5p-jpeg=jpeg;"
+ "exynos4-fimc-is/f=fimc_is;"
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER
+ "exynos4-fimc-is/i=fimc_is_isp;"
+#endif
+ "s5p-mixer=tv;"
+ "s5p-fimg2d=fimg2d;"
+ "ion-exynos=ion,fimd,fimc0,fimc1,fimc2,fimc3,mfc,mfc0,mfc1,fw,b1,b2;"
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ "s5p-smem/video=video;"
+ "s5p-smem/sectbl=sectbl;"
+#endif
+ "s5p-smem/mfc=mfc0;"
+ "s5p-smem/fimc=fimc3;"
+ "s5p-smem/mfc-shm=mfc1,mfc-normal;"
+ "s5p-smem/fimd=fimd;";
+
+ s5p_cma_region_reserve(regions, regions_secure, 0, map);
+}
+#else
+static inline void exynos4_reserve_mem(void)
+{
+}
+#endif /* CONFIG_CMA */
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk4x12_bl_gpio_info = {
+ .no = EXYNOS4_GPD0(1),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk4x12_bl_data = {
+ .pwm_id = 1,
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ .pwm_period_ns = 1000,
+#endif
+};
+
+static void __init smdk4x12_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
+
+ exynos4_reserve_mem();
+}
+
+static void __init smdk4x12_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(g2d_acp).dev, &s5p_device_fimg2d.dev);
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+#if defined(CONFIG_VIDEO_FIMC)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#elif defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_mixer.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ ASSIGN_SYSMMU_POWERDOMAIN(is_isp, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_drc, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_fd, &exynos4_device_pd[PD_ISP].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(is_cpu, &exynos4_device_pd[PD_ISP].dev);
+
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_isp).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_drc).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_fd).dev,
+ &exynos4_device_fimc_is.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(is_cpu).dev,
+ &exynos4_device_fimc_is.dev);
+#endif
+}
+
+#ifdef CONFIG_FB_S5P_EXTDSP
+struct platform_device s3c_device_extdsp = {
+ .name = "s3cfb_extdsp",
+ .id = 0,
+};
+
+static struct s3cfb_extdsp_lcd dummy_buffer = {
+ .width = 1280,
+ .height = 720,
+ .bpp = 16,
+};
+
+static struct s3c_platform_fb default_extdsp_data __initdata = {
+ .hw_ver = 0x70,
+ .nr_wins = 1,
+ .default_win = 0,
+ .swap = FB_SWAP_WORD | FB_SWAP_HWORD,
+ .lcd = &dummy_buffer
+};
+
+void __init s3cfb_extdsp_set_platdata(struct s3c_platform_fb *pd)
+{
+ struct s3c_platform_fb *npd;
+ int i;
+
+ if (!pd)
+ pd = &default_extdsp_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ for (i = 0; i < npd->nr_wins; i++)
+ npd->nr_buffers[i] = 1;
+ s3c_device_extdsp.dev.platform_data = npd;
+ }
+}
+#endif
+
+#define SMDK4412_REV_0_0_ADC_VALUE 0
+#define SMDK4412_REV_0_1_ADC_VALUE 443
+int samsung_board_rev;
+
+static int get_samsung_board_rev(void)
+{
+ int adc_val = 0;
+ struct clk *adc_clk;
+ struct resource *res;
+ void __iomem *adc_regs;
+ unsigned int con;
+ int ret;
+
+ if ((soc_is_exynos4412() && samsung_rev() < EXYNOS4412_REV_1_0) ||
+ (soc_is_exynos4212() && samsung_rev() < EXYNOS4212_REV_1_0))
+ return SAMSUNG_BOARD_REV_0_0;
+
+ adc_clk = clk_get(NULL, "adc");
+ if (unlikely(IS_ERR(adc_clk)))
+ return SAMSUNG_BOARD_REV_0_0;
+
+ clk_enable(adc_clk);
+
+ res = platform_get_resource(&s3c_device_adc, IORESOURCE_MEM, 0);
+ if (unlikely(!res))
+ goto err_clk;
+
+ adc_regs = ioremap(res->start, resource_size(res));
+ if (unlikely(!adc_regs))
+ goto err_clk;
+
+ writel(S5PV210_ADCCON_SELMUX(3), adc_regs + S5P_ADCMUX);
+
+ con = readl(adc_regs + S3C2410_ADCCON);
+ con &= ~S3C2410_ADCCON_MUXMASK;
+ con &= ~S3C2410_ADCCON_STDBM;
+ con &= ~S3C2410_ADCCON_STARTMASK;
+ con |= S3C2410_ADCCON_PRSCEN;
+
+ con |= S3C2410_ADCCON_ENABLE_START;
+ writel(con, adc_regs + S3C2410_ADCCON);
+
+ udelay (50);
+
+ adc_val = readl(adc_regs + S3C2410_ADCDAT0) & 0xFFF;
+ writel(0, adc_regs + S3C64XX_ADCCLRINT);
+
+ iounmap(adc_regs);
+err_clk:
+ clk_disable(adc_clk);
+ clk_put(adc_clk);
+
+ ret = (adc_val < SMDK4412_REV_0_1_ADC_VALUE/2) ?
+ SAMSUNG_BOARD_REV_0_0 : SAMSUNG_BOARD_REV_0_1;
+
+ pr_info ("SMDK MAIN Board Rev 0.%d (ADC value:%d)\n", ret, adc_val);
+ return ret;
+}
+
+static void __init smdk4x12_machine_init(void)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+#ifndef CONFIG_FB_S5P_LMS501KF03
+ struct device *spi1_dev = &exynos_device_spi1.dev;
+#endif
+ struct device *spi2_dev = &exynos_device_spi2.dev;
+#endif
+ samsung_board_rev = get_samsung_board_rev();
+#if defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)
+ exynos_pd_disable(&exynos4_device_pd[PD_MFC].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_G3D].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_LCD0].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_CAM].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_TV].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_GPS].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_GPS_ALIVE].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_ISP].dev);
+#elif defined(CONFIG_EXYNOS_DEV_PD)
+ /*
+ * These power domains should be always on
+ * without runtime pm support.
+ */
+ exynos_pd_enable(&exynos4_device_pd[PD_MFC].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_LCD0].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_CAM].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_TV].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_GPS].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_GPS_ALIVE].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_ISP].dev);
+#endif
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+
+ s3c_i2c3_set_platdata(NULL);
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+
+ s3c_i2c4_set_platdata(NULL);
+ s3c_i2c5_set_platdata(NULL);
+
+ s3c_i2c7_set_platdata(NULL);
+ i2c_devs7[0].irq = samsung_board_rev_is_0_0() ? IRQ_EINT(15) : IRQ_EINT(22);
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+ mipi_fb_init();
+#endif
+#ifdef CONFIG_FB_S3C
+ dev_set_name(&s5p_device_fimd0.dev, "s3cfb.0");
+ clk_add_alias("lcd", "exynos4-fb.0", "lcd", &s5p_device_fimd0.dev);
+ clk_add_alias("sclk_fimd", "exynos4-fb.0", "sclk_fimd", &s5p_device_fimd0.dev);
+ s5p_fb_setname(0, "exynos4-fb");
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_LMS501KF03)
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+ s5p_fimd0_set_platdata(&smdk4x12_lcd0_pdata);
+#ifdef CONFIG_FB_MIPI_DSIM
+ s5p_device_mipi_dsim.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_LMS501KF03
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&lms501kf03_data);
+#else
+ s3cfb_set_platdata(NULL);
+#endif
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+ s5p_device_dsim.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdk4x12_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdk4x12_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdk4x12_usbgadget_init();
+#endif
+#ifdef CONFIG_USB_EXYNOS_SWITCH
+ smdk4x12_usbswitch_init();
+#endif
+
+ samsung_bl_set(&smdk4x12_bl_gpio_info, &smdk4x12_bl_data);
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ exynos_dwmci_set_platdata(&exynos_dwmci_pdata, 0);
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ exynos4_fimc_is_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ exynos4_device_fimc_is.dev.parent = &exynos4_device_pd[PD_ISP].dev;
+#endif
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdk4x12_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdk4x12_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdk4x12_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdk4x12_hsmmc3_pdata);
+#endif
+#ifdef CONFIG_S5P_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+#if defined(CONFIG_VIDEO_EXYNOS_TV) && defined(CONFIG_VIDEO_EXYNOS_HDMI)
+ dev_set_name(&s5p_device_hdmi.dev, "exynos4-hdmi");
+ clk_add_alias("hdmi", "s5p-hdmi", "hdmi", &s5p_device_hdmi.dev);
+ clk_add_alias("hdmiphy", "s5p-hdmi", "hdmiphy", &s5p_device_hdmi.dev);
+
+ s5p_tv_setup();
+
+ /* setup dependencies between TV devices */
+ s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
+ s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
+
+ s5p_i2c_hdmiphy_set_platdata(NULL);
+
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#endif
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ smdk4x12_set_camera_flite_platdata();
+ s3c_set_platdata(&exynos_flite0_default_data,
+ sizeof(exynos_flite0_default_data), &exynos_device_flite0);
+ s3c_set_platdata(&exynos_flite1_default_data,
+ sizeof(exynos_flite1_default_data), &exynos_device_flite1);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ exynos_device_flite0.dev.parent = &exynos4_device_pd[PD_ISP].dev;
+ exynos_device_flite1.dev.parent = &exynos4_device_pd[PD_ISP].dev;
+#endif
+#endif
+#ifdef CONFIG_EXYNOS_SETUP_THERMAL
+ s5p_tmu_set_platdata(&exynos_tmu_data);
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(&fimc_plat);
+ s3c_fimc2_set_platdata(&fimc_plat);
+ s3c_fimc3_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ secmem.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+
+#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C) \
+ || defined(CONFIG_S5K3H1_CSI_C) || defined(CONFIG_S5K3H2_CSI_C) \
+ || defined(CONFIG_S5K6A3_CSI_C)
+ smdk4x12_cam0_reset(1);
+#endif
+#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D) \
+ || defined(CONFIG_S5K3H1_CSI_D) || defined(CONFIG_S5K3H2_CSI_D) \
+ || defined(CONFIG_S5K6A3_CSI_D)
+ smdk4x12_cam1_reset(1);
+#endif
+#endif /* CONFIG_VIDEO_FIMC */
+#ifdef CONFIG_FB_S5P_EXTDSP
+ s3cfb_extdsp_set_platdata(&default_extdsp_data);
+#endif
+
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ smdk4x12_camera_config();
+ smdk4x12_subdev_config();
+
+ dev_set_name(&s5p_device_fimc0.dev, "s3c-fimc.0");
+ dev_set_name(&s5p_device_fimc1.dev, "s3c-fimc.1");
+ dev_set_name(&s5p_device_fimc2.dev, "s3c-fimc.2");
+ dev_set_name(&s5p_device_fimc3.dev, "s3c-fimc.3");
+
+ clk_add_alias("fimc", "exynos4210-fimc.0", "fimc", &s5p_device_fimc0.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.0", "sclk_fimc",
+ &s5p_device_fimc0.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.1", "fimc", &s5p_device_fimc1.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.1", "sclk_fimc",
+ &s5p_device_fimc1.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.2", "fimc", &s5p_device_fimc2.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.2", "sclk_fimc",
+ &s5p_device_fimc2.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.3", "fimc", &s5p_device_fimc3.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.3", "sclk_fimc",
+ &s5p_device_fimc3.dev);
+
+ s3c_fimc_setname(0, "exynos4210-fimc");
+ s3c_fimc_setname(1, "exynos4210-fimc");
+ s3c_fimc_setname(2, "exynos4210-fimc");
+ s3c_fimc_setname(3, "exynos4210-fimc");
+ /* FIMC */
+ s3c_set_platdata(&s3c_fimc0_default_data,
+ sizeof(s3c_fimc0_default_data), &s5p_device_fimc0);
+ s3c_set_platdata(&s3c_fimc1_default_data,
+ sizeof(s3c_fimc1_default_data), &s5p_device_fimc1);
+ s3c_set_platdata(&s3c_fimc2_default_data,
+ sizeof(s3c_fimc2_default_data), &s5p_device_fimc2);
+ s3c_set_platdata(&s3c_fimc3_default_data,
+ sizeof(s3c_fimc3_default_data), &s5p_device_fimc3);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+ dev_set_name(&s5p_device_mipi_csis0.dev, "s3c-csis.0");
+ dev_set_name(&s5p_device_mipi_csis1.dev, "s3c-csis.1");
+ clk_add_alias("csis", "s5p-mipi-csis.0", "csis",
+ &s5p_device_mipi_csis0.dev);
+ clk_add_alias("sclk_csis", "s5p-mipi-csis.0", "sclk_csis",
+ &s5p_device_mipi_csis0.dev);
+ clk_add_alias("csis", "s5p-mipi-csis.1", "csis",
+ &s5p_device_mipi_csis1.dev);
+ clk_add_alias("sclk_csis", "s5p-mipi-csis.1", "sclk_csis",
+ &s5p_device_mipi_csis1.dev);
+ dev_set_name(&s5p_device_mipi_csis0.dev, "s5p-mipi-csis.0");
+ dev_set_name(&s5p_device_mipi_csis1.dev, "s5p-mipi-csis.1");
+
+ s3c_set_platdata(&s5p_mipi_csis0_default_data,
+ sizeof(s5p_mipi_csis0_default_data), &s5p_device_mipi_csis0);
+ s3c_set_platdata(&s5p_mipi_csis1_default_data,
+ sizeof(s5p_mipi_csis1_default_data), &s5p_device_mipi_csis1);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_mipi_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C) \
+ || defined(CONFIG_S5K3H1_CSI_C) || defined(CONFIG_S5K3H2_CSI_C) \
+ || defined(CONFIG_S5K6A3_CSI_C)
+ smdk4x12_cam0_reset(1);
+#endif
+#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D) \
+ || defined(CONFIG_S5K3H1_CSI_D) || defined(CONFIG_S5K3H2_CSI_D) \
+ || defined(CONFIG_S5K6A3_CSI_D)
+ smdk4x12_cam1_reset(1);
+#endif
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+ exynos4_device_pd[PD_TV].dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ exynos4_jpeg_setup_clock(&s5p_device_jpeg.dev, 160000000);
+#endif
+#endif
+
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+ if (soc_is_exynos4412() && samsung_rev() >= EXYNOS4412_REV_1_0)
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ);
+ else
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 267 * MHZ);
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#endif
+ if (samsung_board_rev_is_0_0())
+ samsung_keypad_set_platdata(&smdk4x12_keypad_data0);
+ else
+ samsung_keypad_set_platdata(&smdk4x12_keypad_data1);
+ smdk4x12_smsc911x_init();
+#ifdef CONFIG_EXYNOS_C2C
+ exynos_c2c_set_platdata(&smdk4x12_c2c_pdata);
+#endif
+
+ exynos_sysmmu_init();
+
+ smdk4x12_gpio_power_init();
+
+ platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices));
+ if (soc_is_exynos4412())
+ platform_add_devices(smdk4412_devices, ARRAY_SIZE(smdk4412_devices));
+
+#ifdef CONFIG_FB_S3C
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll_user",
+ 800 * MHZ);
+#endif
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ sclk = clk_get(spi0_dev, "dout_spi0");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+ prnt = clk_get(spi0_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS4_GPB(1), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+#ifndef CONFIG_FB_S5P_LMS501KF03
+ sclk = clk_get(spi1_dev, "dout_spi1");
+ if (IS_ERR(sclk))
+ dev_err(spi1_dev, "failed to get sclk for SPI-1\n");
+ prnt = clk_get(spi1_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi1_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(5), "SPI_CS1")) {
+ gpio_direction_output(EXYNOS4_GPB(5), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(5), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(5), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(1, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi1_csi));
+ }
+
+ spi_register_board_info(spi1_board_info, ARRAY_SIZE(spi1_board_info));
+#endif
+
+ sclk = clk_get(spi2_dev, "dout_spi2");
+ if (IS_ERR(sclk))
+ dev_err(spi2_dev, "failed to get sclk for SPI-2\n");
+ prnt = clk_get(spi2_dev, "mout_mpll_user");
+ if (IS_ERR(prnt))
+ dev_err(spi2_dev, "failed to get prnt\n");
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+
+ clk_set_rate(sclk, 800 * 1000 * 1000);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPC1(2), "SPI_CS2")) {
+ gpio_direction_output(EXYNOS4_GPC1(2), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(2), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPC1(2), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi2_csi));
+ }
+
+ spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
+#endif
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DMC0], &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DMC1], &exynos4_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos4_busfreq.dev);
+#endif
+ register_reboot_notifier(&exynos4_reboot_notifier);
+}
+
+#ifdef CONFIG_EXYNOS_C2C
+static void __init exynos_c2c_reserve(void)
+{
+ static struct cma_region region[] = {
+ {
+ .name = "c2c_shdmem",
+ .size = 64 * SZ_1M,
+ { .alignment = 64 * SZ_1M },
+ .start = C2C_SHAREDMEM_BASE
+ }, {
+ .size = 0,
+ }
+ };
+
+ s5p_cma_region_reserve(region, NULL, 0, NULL);
+}
+#endif
+
+MACHINE_START(SMDK4212, "SMDK4X12")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdk4x12_map_io,
+ .init_machine = smdk4x12_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+MACHINE_END
+
+MACHINE_START(SMDK4412, "SMDK4X12")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdk4x12_map_io,
+ .init_machine = smdk4x12_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-smdk5210.c b/arch/arm/mach-exynos/mach-smdk5210.c
new file mode 100644
index 0000000..16ccba4
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-smdk5210.c
@@ -0,0 +1,1174 @@
+/* linux/arch/arm/mach-exynos/mach-smdk5210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/fb.h>
+#include <linux/lcd.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/delay.h>
+#include <linux/pwm_backlight.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/cma.h>
+#include <linux/memblock.h>
+#include <linux/mmc/host.h>
+#include <linux/smsc911x.h>
+#include <linux/clk.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/exynos5.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/fb-s5p.h>
+#include <plat/fb-core.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/backlight.h>
+#include <plat/dp.h>
+#include <plat/iic.h>
+#include <plat/tv-core.h>
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#include <plat/s5p-mfc.h>
+#endif
+#include <plat/sdhci.h>
+#include <plat/regs-srom.h>
+#include <plat/ehci.h>
+#include <plat/udc-ss.h>
+
+#include <mach/map.h>
+#include <mach/exynos-ion.h>
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+#include <mach/dwmci.h>
+#endif
+
+#include <video/platform_lcd.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK5210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK5210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK5210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk5210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK5210_UCON_DEFAULT,
+ .ulcon = SMDK5210_ULCON_DEFAULT,
+ .ufcon = SMDK5210_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK5210_UCON_DEFAULT,
+ .ulcon = SMDK5210_ULCON_DEFAULT,
+ .ufcon = SMDK5210_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK5210_UCON_DEFAULT,
+ .ulcon = SMDK5210_ULCON_DEFAULT,
+ .ufcon = SMDK5210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK5210_UCON_DEFAULT,
+ .ulcon = SMDK5210_ULCON_DEFAULT,
+ .ufcon = SMDK5210_UFCON_DEFAULT,
+ },
+};
+
+static struct resource smdk5210_smsc911x_resources[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SROM_BANK(1),
+ .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdk5210_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdk5210_smsc911x_resources),
+ .resource = smdk5210_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+struct platform_device exynos_device_md0 = {
+ .name = "exynos-mdev",
+ .id = 0,
+};
+
+struct platform_device exynos_device_md1 = {
+ .name = "exynos-mdev",
+ .id = 1,
+};
+#endif
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_LCD_LMS501KF03)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ err = gpio_request_one(EXYNOS5_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+ gpio_set_value(EXYNOS5_GPX0(6), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS5_GPX0(6), 1);
+
+ gpio_free(EXYNOS5_GPX0(6));
+
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_request_one(EXYNOS5_GPB2(0), GPIOF_OUT_INIT_HIGH, "GPB2");
+ gpio_free(EXYNOS5_GPB2(0));
+#endif
+
+ return 1;
+}
+
+static struct lcd_platform_data lms501kf03_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS5_GPA2(5) /*Chip select */
+#define DISPLAY_CLK EXYNOS5_GPA2(4) /* SPI clock */
+#define DISPLAY_SI EXYNOS5_GPA2(7) /* SPI MOSI */
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "lms501kf03",
+ .platform_data = (void *)&lms501kf03_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data lms501kf03_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd1.dev,
+ .platform_data = &lms501kf03_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 8, /* HBPD */
+ .right_margin = 8, /* HFPD */
+ .upper_margin = 6, /* VBPD */
+ .lower_margin = 6, /* VFPD */
+ .hsync_len = 6, /* HSPW */
+ .vsync_len = 4, /* VSPW */
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 66,
+ .height = 109,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 8, /* HBPD */
+ .right_margin = 8, /* HFPD */
+ .upper_margin = 6, /* VBPD */
+ .lower_margin = 6, /* VFPD */
+ .hsync_len = 6, /* HSPW */
+ .vsync_len = 4, /* VSPW */
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 66,
+ .height = 109,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win2 = {
+ .win_mode = {
+ .left_margin = 8, /* HBPD */
+ .right_margin = 8, /* HFPD */
+ .upper_margin = 6, /* VBPD */
+ .lower_margin = 6, /* VFPD */
+ .hsync_len = 6, /* HSPW */
+ .vsync_len = 4, /* VSPW */
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 66,
+ .height = 109,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_WA101S)
+static void lcd_wa101s_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_request_one(EXYNOS5_GPB2(0), GPIOF_OUT_INIT_HIGH, "GPB2");
+ gpio_free(EXYNOS5_GPB2(0));
+#endif
+ /* fire nRESET on power up */
+ gpio_request_one(EXYNOS5_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ mdelay(100);
+
+ gpio_set_value(EXYNOS5_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS5_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS5_GPX0(6));
+ } else {
+#ifndef CONFIG_BACKLIGHT_PWM
+ gpio_request_one(EXYNOS5_GPB2(0), GPIOF_OUT_INIT_LOW, "GPB2");
+ gpio_free(EXYNOS5_GPB2(0));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdk5210_lcd_wa101s_data = {
+ .set_power = lcd_wa101s_set_power,
+};
+
+static struct platform_device smdk5210_lcd_wa101s = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd1.dev,
+ .dev.platform_data = &smdk5210_lcd_wa101s_data,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win2 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#elif defined(CONFIG_S5P_DP)
+static struct s3c_fb_pd_win smdk5210_fb_win0 = {
+ .win_mode = {
+ .refresh = 39,
+ .left_margin = 172,
+ .right_margin = 60,
+ .upper_margin = 25,
+ .lower_margin = 10,
+ .hsync_len = 80,
+ .vsync_len = 10,
+ .xres = 1920,
+ .yres = 1080,
+ },
+ .virtual_x = 1920,
+ .virtual_y = 1080 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win1 = {
+ .win_mode = {
+ .refresh = 39,
+ .left_margin = 172,
+ .right_margin = 60,
+ .upper_margin = 25,
+ .lower_margin = 10,
+ .hsync_len = 80,
+ .vsync_len = 10,
+ .xres = 1920,
+ .yres = 1080,
+ },
+ .virtual_x = 1920,
+ .virtual_y = 1080 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdk5210_fb_win2 = {
+ .win_mode = {
+ .refresh = 39,
+ .left_margin = 172,
+ .right_margin = 60,
+ .upper_margin = 25,
+ .lower_margin = 10,
+ .hsync_len = 80,
+ .vsync_len = 10,
+ .xres = 1920,
+ .yres = 1080,
+ },
+ .virtual_x = 1920,
+ .virtual_y = 1080 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static void exynos_fimd_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+
+#if defined(CONFIG_LCD_WA101S)
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ0(0), 5, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ3(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ4(0), 2, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+#elif defined(CONFIG_LCD_LMS501KF03)
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ0(0), 5, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ3(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd_cfg_gpios(EXYNOS5210_GPJ4(0), 2, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+#endif
+
+#if defined(CONFIG_S5P_DP)
+ /* Set Hotplug detect for DP */
+ s3c_gpio_cfgpin(EXYNOS5_GPX0(7), S3C_GPIO_SFN(3));
+#endif
+
+ /*
+ * Set DISP1BLK_CFG register for Display path selection
+ * DISP1_BLK output source selection : DISP1BLK_CFG[28:27]
+ *---------------------
+ * 10 | From DISP0_BLK
+ * 01 | From DISP1_BLK : selected
+ *
+ * FIMD of DISP1_BLK Bypass selection : DISP1BLK_CFG[15]
+ * ---------------------
+ * 0 | MIE/MDNIE
+ * 1 | FIMD : selected
+ */
+ reg = __raw_readl(S3C_VA_SYS + 0x0214);
+ reg &= ~((1 << 28) | (1 << 27) | (1 << 15)); /* To save other reset values */
+ reg |= (0 << 28) | (1 << 27) | (1 << 15);
+ __raw_writel(reg, S3C_VA_SYS + 0x0214);
+}
+
+static struct s3c_fb_platdata smdk5210_lcd1_pdata __initdata = {
+#if defined(CONFIG_LCD_WA101S) || defined(CONFIG_LCD_LMS501KF03) || \
+ defined(CONFIG_S5P_DP)
+ .win[0] = &smdk5210_fb_win0,
+ .win[1] = &smdk5210_fb_win1,
+ .win[2] = &smdk5210_fb_win2,
+#endif
+ .default_win = 2,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_LMS501KF03)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_WA101S)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC |
+ VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_S5P_DP)
+ .vidcon1 = 0,
+#endif
+ .setup_gpio = exynos_fimd_gpio_setup_24bpp,
+};
+#endif
+
+#ifdef CONFIG_S5P_DP
+static struct video_info smdk5210_dp_config = {
+ .name = "DELL U2410, for SMDK TEST",
+
+ .h_total = 2222,
+ .h_active = 1920,
+ .h_sync_width = 80,
+ .h_back_porch = 172,
+ .h_front_porch = 60,
+
+ .v_total = 1125,
+ .v_active = 1080,
+ .v_sync_width = 10,
+ .v_back_porch = 25,
+ .v_front_porch = 10,
+
+ .v_sync_rate = 60,
+
+ .mvid = 0,
+ .nvid = 0,
+
+ .h_sync_polarity = 0,
+ .v_sync_polarity = 0,
+ .interlaced = 0,
+
+ .color_space = COLOR_RGB,
+ .dynamic_range = VESA,
+ .ycbcr_coeff = COLOR_YCBCR601,
+ .color_depth = COLOR_8,
+
+ .sync_clock = 0,
+ .even_field = 0,
+
+ .refresh_denominator = REFRESH_DENOMINATOR_1,
+
+ .test_pattern = COLORBAR_32,
+ .link_rate = LINK_RATE_1_62GBPS,
+ .lane_count = LANE_COUNT2,
+
+ .video_mute_on = 0,
+
+ .master_mode = 0,
+ .bist_mode = 0,
+};
+
+static struct s5p_dp_platdata smdk5210_dp_data __initdata = {
+ .video_info = &smdk5210_dp_config,
+ .phy_init = s5p_dp_phy_init,
+ .phy_exit = s5p_dp_phy_exit,
+};
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+static void exynos_dwmci_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS5_GPC0(0); gpio < EXYNOS5_GPC0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = EXYNOS5_GPC1(3); gpio <= EXYNOS5_GPC1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ case 4:
+ for (gpio = EXYNOS5_GPC0(3); gpio <= EXYNOS5_GPC0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case 1:
+ gpio = EXYNOS5_GPC0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos_dwmci_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 66 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci_cfg_gpio,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdk5210_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdk5210_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdk5210_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdk5210_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ REGULATOR_SUPPLY("AVDD2", "1-001a"),
+ REGULATOR_SUPPLY("CPVDD", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage2_supplies =
+ REGULATOR_SUPPLY("DBVDD", "1-001a");
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+ .consumer_supplies = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+ .consumer_supplies = wm8994_fixed_voltage1_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage2_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_fixed_voltage2_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VDD_1.8V",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage2_config = {
+ .supply_name = "VDD_3.3V",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage2_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage2 = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage2_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+ REGULATOR_SUPPLY("AVDD1", "1-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+ REGULATOR_SUPPLY("DCVDD", "1-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* If the i2s0 and i2s2 is enabled simultaneously */
+ .gpio_defaults[7] = 0x8100, /* GPIO8 DACDAT3 in */
+ .gpio_defaults[8] = 0x0100, /* GPIO9 ADCDAT3 out */
+ .gpio_defaults[9] = 0x0100, /* GPIO10 LRCLK3 out */
+ .gpio_defaults[10] = 0x0100,/* GPIO11 BCLK3 out */
+ .ldo[0] = { 0, NULL, &wm8994_ldo1_data },
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
+static struct i2c_board_info i2c_devs2[] __initdata = {
+ {
+ I2C_BOARD_INFO("exynos_hdcp", (0x74 >> 1)),
+ },
+};
+
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdk5210_ehci_pdata;
+
+static void __init smdk5210_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk5210_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdk5210_ohci_pdata;
+
+static void __init smdk5210_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk5210_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+static struct exynos_ss_udc_plat smdk5210_ss_udc_pdata;
+
+static void __init smdk5210_ss_udc_init(void)
+{
+ struct exynos_ss_udc_plat *pdata = &smdk5210_ss_udc_pdata;
+
+ exynos_ss_udc_set_platdata(pdata);
+}
+#endif
+
+static struct platform_device *smdk5210_devices[] __initdata = {
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+ &exynos_device_md0,
+ &exynos_device_md1,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+ &exynos5_device_gsc0,
+ &exynos5_device_gsc1,
+ &exynos5_device_gsc2,
+ &exynos5_device_gsc3,
+#endif
+#ifdef CONFIG_S5P_DP
+ &s5p_device_dp,
+#endif
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd1,
+#if defined(CONFIG_LCD_LMS501KF03)
+ &s3c_device_spi_gpio,
+#elif defined(CONFIG_LCD_WA101S)
+ &smdk5210_lcd_wa101s,
+#endif
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_RP
+ &exynos_device_srp,
+#endif
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
+ &wm8994_fixed_voltage2,
+ &samsung_asoc_dma,
+ &samsung_asoc_idma,
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ &exynos_device_dwmci,
+#endif
+ &smdk5210_smsc911x,
+
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI
+ &s5p_device_hdmi,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_HDMIPHY
+ &s5p_device_i2c_hdmiphy,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_MIXER
+ &s5p_device_mixer,
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ &s5p_device_ehci,
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+ &exynos_device_ss_udc,
+#endif
+};
+
+#ifdef CONFIG_SAMSUNG_DEV_BACKLIGHT
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk5210_bl_gpio_info = {
+ .no = EXYNOS5_GPB2(0),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk5210_bl_data = {
+ .pwm_id = 0,
+#if defined(CONFIG_LCD_LMS501KF03)
+ .pwm_period_ns = 1000,
+#endif
+};
+#endif
+
+#if defined(CONFIG_S5P_MEM_CMA)
+static void __init exynos5_cma_region_reserve(
+ struct cma_region *regions_normal,
+ struct cma_region *regions_secure)
+{
+ struct cma_region *reg;
+ size_t size_secure = 0, align_secure = 0;
+ phys_addr_t paddr = 0;
+
+ for (reg = regions_normal; reg->size != 0; reg++) {
+ if ((reg->alignment & (reg->alignment - 1)) || reg->reserved)
+ continue;
+
+ if (reg->start) {
+ if (!memblock_is_region_reserved(reg->start, reg->size)
+ && memblock_reserve(reg->start, reg->size) >= 0)
+ reg->reserved = 1;
+ } else {
+ paddr = __memblock_alloc_base(reg->size, reg->alignment,
+ MEMBLOCK_ALLOC_ACCESSIBLE);
+ if (paddr) {
+ reg->start = paddr;
+ reg->reserved = 1;
+ if (reg->size & (reg->alignment - 1))
+ memblock_free(paddr + reg->size,
+ ALIGN(reg->size, reg->alignment)
+ - reg->size);
+ }
+ }
+ }
+
+ if (regions_secure && regions_secure->size) {
+ for (reg = regions_secure; reg->size != 0; reg++)
+ size_secure += reg->size;
+
+ reg--;
+
+ align_secure = reg->alignment;
+ BUG_ON(align_secure & (align_secure - 1));
+
+ paddr -= size_secure;
+ paddr &= ~(align_secure - 1);
+
+ if (!memblock_reserve(paddr, size_secure)) {
+ do {
+ reg->start = paddr;
+ reg->reserved = 1;
+ paddr += reg->size;
+ } while (reg-- != regions_secure);
+ }
+ }
+}
+
+static void __init exynos5_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM
+ {
+ .name = "pmem",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1
+ {
+ .name = "pmem_gpu1",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC0
+ {
+ .name = "gsc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC1
+ {
+ .name = "gsc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC1 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC2
+ {
+ .name = "gsc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC2 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC3
+ {
+ .name = "gsc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC3 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ {
+ .name = "fw",
+ .size = 1 << 20,
+ { .alignment = 128 << 10 },
+ .start = 0x44000000,
+ },
+ {
+ .name = "b1",
+ .size = 32 << 20,
+ .start = 0x45000000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV
+ {
+ .name = "tv",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV * SZ_1K,
+ .start = 0
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+ static const char map[] __initconst =
+ "android_pmem.0=pmem;android_pmem.1=pmem_gpu1;"
+ "s3cfb.0=fimd;"
+ "exynos-gsc.0=gsc0;exynos-gsc.1=gsc1;exynos-gsc.2=gsc2;exynos-gsc.3=gsc3;"
+ "ion-exynos=fimd,gsc0,gsc1,gsc2,gsc3;"
+ "s5p-mfc-v6/f=fw;"
+ "s5p-mfc-v6/a=b1;"
+ "s5p-mixer=tv;";
+
+ cma_set_defaults(regions, map);
+
+ exynos5_cma_region_reserve(regions, NULL);
+}
+#else /* !CONFIG_S5P_MEM_CMA */
+static inline void exynos5_reserve_mem(void)
+{
+}
+#endif
+
+static void __init smdk5210_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdk5210_uartcfgs, ARRAY_SIZE(smdk5210_uartcfgs));
+ exynos5_reserve_mem();
+}
+
+static void __init smdk5210_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+static void s5p_tv_setup(void)
+{
+ /* direct HPD to HDMI chip */
+ gpio_request(EXYNOS5_GPX3(7), "hpd-plug");
+
+ gpio_direction_input(EXYNOS5_GPX3(7));
+ s3c_gpio_cfgpin(EXYNOS5_GPX3(7), S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(EXYNOS5_GPX3(7), S3C_GPIO_PULL_NONE);
+
+ /* setup dependencies between TV devices */
+ /* This will be added after power domain for exynos5 is developed */
+ /* s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev; */
+ /* s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev; */
+}
+
+static void __init smdk5210_machine_init(void)
+{
+#if defined(CONFIG_VIDEO_EXYNOS_TV) && defined(CONFIG_VIDEO_EXYNOS_HDMI)
+ dev_set_name(&s5p_device_hdmi.dev, "exynos5-hdmi");
+ clk_add_alias("hdmi", "s5p-hdmi", "hdmi", &s5p_device_hdmi.dev);
+ clk_add_alias("hdmiphy", "s5p-hdmi", "hdmiphy", &s5p_device_hdmi.dev);
+#endif
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+
+#ifdef CONFIG_FB_S3C
+ dev_set_name(&s5p_device_fimd1.dev, "s3cfb.1");
+ clk_add_alias("lcd", "exynos5-fb.1", "lcd", &s5p_device_fimd1.dev);
+ clk_add_alias("sclk_fimd", "exynos5-fb.1", "sclk_fimd",
+ &s5p_device_fimd1.dev);
+ s5p_fb_setname(1, "exynos5-fb");
+
+#if defined(CONFIG_LCD_LMS501KF03)
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+ s5p_fimd1_set_platdata(&smdk5210_lcd1_pdata);
+#endif
+
+#ifdef CONFIG_S5P_DP
+ s5p_dp_set_platdata(&smdk5210_dp_data);
+#endif
+
+#ifdef CONFIG_SAMSUNG_DEV_BACKLIGHT
+ samsung_bl_set(&smdk5210_bl_gpio_info, &smdk5210_bl_data);
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc-v6", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc-v6");
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ exynos_dwmci_set_platdata(&exynos_dwmci_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdk5210_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdk5210_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdk5210_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdk5210_hsmmc3_pdata);
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdk5210_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdk5210_ohci_init();
+#endif
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+ smdk5210_ss_udc_init();
+#endif
+ smdk5210_smsc911x_init();
+ platform_add_devices(smdk5210_devices, ARRAY_SIZE(smdk5210_devices));
+
+#ifdef CONFIG_FB_S3C
+ exynos4_fimd_setup_clock(&s5p_device_fimd1.dev, "sclk_fimd", "mout_mpll_user",
+ 800 * MHZ);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+ s5p_tv_setup();
+ s5p_i2c_hdmiphy_set_platdata(NULL);
+#endif
+}
+
+MACHINE_START(SMDK5210, "SMDK5210")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos5_init_irq,
+ .map_io = smdk5210_map_io,
+ .init_machine = smdk5210_machine_init,
+ .timer = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-smdk5250.c b/arch/arm/mach-exynos/mach-smdk5250.c
new file mode 100644
index 0000000..4f68120
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-smdk5250.c
@@ -0,0 +1,1316 @@
+/* linux/arch/arm/mach-exynos/mach-smdk5250.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/memblock.h>
+#include <linux/smsc911x.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <media/s5k4ba_platform.h>
+#include <media/m5mols.h>
+#include <media/exynos_gscaler.h>
+#include <media/exynos_flite.h>
+#include <media/exynos_fimc_is.h>
+#include <plat/gpio-cfg.h>
+#include <plat/adc.h>
+#include <plat/regs-serial.h>
+#include <plat/exynos5.h>
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/hwmon.h>
+#include <plat/devs.h>
+#include <plat/regs-srom.h>
+#include <plat/iic.h>
+#include <plat/pd.h>
+#include <plat/backlight.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#include <plat/usb-switch.h>
+#include <plat/s5p-mfc.h>
+#include <plat/fimg2d.h>
+#include <plat/tv-core.h>
+
+#include <plat/mipi_csis.h>
+#include <mach/map.h>
+#include <mach/exynos-ion.h>
+#include <mach/sysmmu.h>
+#include <mach/ppmu.h>
+#include <mach/dev.h>
+#include <mach/regs-pmu.h>
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+#include <mach/secmem.h>
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+#include <plat/jpeg.h>
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+#include <mach/c2c.h>
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+#include <plat/tvout.h>
+#endif
+
+#include <plat/media.h>
+
+#include "board-smdk5250.h"
+
+#define REG_INFORM4 (S5P_INFORM4)
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDK5250_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK5250_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK5250_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdk5250_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK5250_UCON_DEFAULT,
+ .ulcon = SMDK5250_ULCON_DEFAULT,
+ .ufcon = SMDK5250_UFCON_DEFAULT,
+ },
+};
+
+static struct resource smdk5250_smsc911x_resources[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SROM_BANK(1),
+ .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdk5250_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdk5250_smsc911x_resources),
+ .resource = smdk5250_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+struct platform_device exynos_device_md0 = {
+ .name = "exynos-mdev",
+ .id = 0,
+};
+
+struct platform_device exynos_device_md1 = {
+ .name = "exynos-mdev",
+ .id = 1,
+};
+
+struct platform_device exynos_device_md2 = {
+ .name = "exynos-mdev",
+ .id = 2,
+};
+#endif
+
+#if defined CONFIG_VIDEO_EXYNOS5_FIMC_IS
+static struct exynos5_platform_fimc_is exynos5_fimc_is_data;
+
+#if defined CONFIG_VIDEO_S5K4E5
+static struct exynos5_fimc_is_sensor_info s5k4e5= {
+ .sensor_name = "S5K4E5",
+ .sensor_id = SENSOR_NAME_S5K4E5,
+#if defined CONFIG_S5K4E5_POSITION_FRONT
+ .sensor_position = SENSOR_POSITION_FRONT,
+#elif defined CONFIG_S5K4E5_POSITION_REAR
+ .sensor_position = SENSOR_POSITION_REAR,
+#endif
+#if defined CONFIG_S5K4E5_CSI_C
+ .csi_id = CSI_ID_A,
+ .flite_id = FLITE_ID_A,
+ .i2c_channel = SENSOR_CONTROL_I2C0,
+#elif defined CONFIG_S5K4E5_CSI_D
+ .csi_id = CSI_ID_B,
+ .flite_id = FLITE_ID_B,
+ .i2c_channel = SENSOR_CONTROL_I2C1,
+#endif
+
+ .max_width = 2560,
+ .max_height = 1920,
+ .max_frame_rate = 30,
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+};
+#endif
+
+#if defined CONFIG_VIDEO_S5K6A3
+static struct exynos5_fimc_is_sensor_info s5k6a3= {
+ .sensor_name = "S5K6A3",
+ .sensor_id = SENSOR_NAME_S5K6A3,
+#if defined CONFIG_S5K6A3_POSITION_FRONT
+ .sensor_position = SENSOR_POSITION_FRONT,
+#elif defined CONFIG_S5K6A3_POSITION_REAR
+ .sensor_position = SENSOR_POSITION_REAR,
+#endif
+#if defined CONFIG_S5K6A3_CSI_C
+ .csi_id = CSI_ID_A,
+ .flite_id = FLITE_ID_A,
+ .i2c_channel = SENSOR_CONTROL_I2C0,
+#elif defined CONFIG_S5K6A3_CSI_D
+ .csi_id = CSI_ID_B,
+ .flite_id = FLITE_ID_B,
+ .i2c_channel = SENSOR_CONTROL_I2C1,
+#endif
+
+ .max_width = 1280,
+ .max_height = 720,
+ .max_frame_rate = 30,
+
+ .mipi_lanes = 1,
+ .mipi_settle = 12,
+ .mipi_align = 24,
+};
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_C2C
+struct exynos_c2c_platdata smdk5250_c2c_pdata = {
+ .setup_gpio = NULL,
+ .shdmem_addr = C2C_SHAREDMEM_BASE,
+ .shdmem_size = C2C_MEMSIZE_64,
+ .ap_sscm_addr = NULL,
+ .cp_sscm_addr = NULL,
+ .rx_width = C2C_BUSWIDTH_16,
+ .tx_width = C2C_BUSWIDTH_16,
+ .clk_opp100 = 400,
+ .clk_opp50 = 200,
+ .clk_opp25 = 100,
+ .default_opp_mode = C2C_OPP50,
+ .get_c2c_state = NULL,
+ .c2c_sysreg = S5P_VA_CMU + 0x6000,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 0x42,
+ .gate_clkname = "fimg2d",
+};
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+#if defined(CONFIG_ITU_A)
+static int smdk5250_cam0_reset(int dummy)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS5_GPX1(2), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPX1(2), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPX1(2), 0);
+ gpio_direction_output(EXYNOS5_GPX1(2), 1);
+ gpio_free(EXYNOS5_GPX1(2));
+
+ return 0;
+}
+#endif
+#if defined(CONFIG_ITU_B)
+static int smdk5250_cam1_reset(int dummy)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS5_GPX1(0), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPX1(0), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPX1(0), 0);
+ gpio_direction_output(EXYNOS5_GPX1(0), 1);
+ gpio_free(EXYNOS5_GPX1(0));
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4BA
+static struct s5k4ba_mbus_platform_data s5k4ba_mbus_plat = {
+ .id = 0,
+ .fmt = {
+ .width = 1600,
+ .height = 1200,
+ /*.code = V4L2_MBUS_FMT_UYVY8_2X8,*/
+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
+ },
+ .clk_rate = 24000000UL,
+#ifdef CONFIG_ITU_A
+ .set_power = smdk5250_cam0_reset,
+#endif
+#ifdef CONFIG_ITU_B
+ .set_power = smdk5250_cam1_reset,
+#endif
+};
+
+static struct i2c_board_info s5k4ba_info = {
+ I2C_BOARD_INFO("S5K4BA", 0x2d),
+ .platform_data = &s5k4ba_mbus_plat,
+};
+#endif
+
+/* 1 MIPI Cameras */
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct m5mols_platform_data m5mols_platdata = {
+#ifdef CONFIG_CSI_C
+ .gpio_rst = EXYNOS5_GPX1(2), /* ISP_RESET */
+#endif
+#ifdef CONFIG_CSI_D
+ .gpio_rst = EXYNOS5_GPX1(0), /* ISP_RESET */
+#endif
+ .enable_rst = true, /* positive reset */
+ .irq = IRQ_EINT(22),
+};
+
+static struct i2c_board_info m5mols_board_info = {
+ I2C_BOARD_INFO("M5MOLS", 0x1F),
+ .platform_data = &m5mols_platdata,
+};
+#endif
+#endif /* CONFIG_VIDEO_EXYNOS_FIMC_LITE */
+
+#ifdef CONFIG_VIDEO_EXYNOS_MIPI_CSIS
+static struct regulator_consumer_supply mipi_csi_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.0"),
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.1"),
+};
+
+static struct regulator_init_data mipi_csi_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mipi_csi_fixed_voltage_supplies),
+ .consumer_supplies = mipi_csi_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config mipi_csi_fixed_voltage_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &mipi_csi_fixed_voltage_init_data,
+};
+
+static struct platform_device mipi_csi_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &mipi_csi_fixed_voltage_config,
+ },
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct regulator_consumer_supply m5mols_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("core", NULL),
+ REGULATOR_SUPPLY("dig_18", NULL),
+ REGULATOR_SUPPLY("d_sensor", NULL),
+ REGULATOR_SUPPLY("dig_28", NULL),
+ REGULATOR_SUPPLY("a_sensor", NULL),
+ REGULATOR_SUPPLY("dig_12", NULL),
+};
+
+static struct regulator_init_data m5mols_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(m5mols_fixed_voltage_supplies),
+ .consumer_supplies = m5mols_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config m5mols_fixed_voltage_config = {
+ .supply_name = "CAM_SENSOR",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &m5mols_fixed_voltage_init_data,
+};
+
+static struct platform_device m5mols_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &m5mols_fixed_voltage_config,
+ },
+};
+#endif
+
+static struct i2c_board_info i2c_devs2[] __initdata = {
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+ {
+ I2C_BOARD_INFO("exynos_hdcp", (0x74 >> 1)),
+ },
+#endif
+};
+
+#ifdef CONFIG_S3C_DEV_HWMON
+static struct s3c_hwmon_pdata smdk5250_hwmon_pdata __initdata = {
+ /* Reference voltage (1.2V) */
+ .in[0] = &(struct s3c_hwmon_chcfg) {
+ .name = "smdk:reference-voltage",
+ .mult = 3300,
+ .div = 4096,
+ },
+};
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdk5250_ehci_pdata;
+
+static void __init smdk5250_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdk5250_ehci_pdata;
+
+#ifndef CONFIG_USB_EXYNOS_SWITCH
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ if (gpio_request_one(EXYNOS5_GPX2(6), GPIOF_OUT_INIT_HIGH,
+ "HOST_VBUS_CONTROL"))
+ printk(KERN_ERR "failed to request gpio_host_vbus\n");
+ else {
+ s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPX2(6));
+ }
+ }
+#endif
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdk5250_ohci_pdata;
+
+static void __init smdk5250_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdk5250_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_S3C_OTGD
+static struct s5p_usbgadget_platdata smdk5250_usbgadget_pdata;
+
+static void __init smdk5250_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdk5250_usbgadget_pdata;
+
+ s5p_usbgadget_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+static struct exynos_usb3_drd_pdata smdk5250_ss_udc_pdata;
+
+static void __init smdk5250_ss_udc_init(void)
+{
+ struct exynos_usb3_drd_pdata *pdata = &smdk5250_ss_udc_pdata;
+
+ exynos_ss_udc_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_XHCI_EXYNOS
+static struct exynos_usb3_drd_pdata smdk5250_xhci_pdata;
+
+static void __init smdk5250_xhci_init(void)
+{
+ struct exynos_usb3_drd_pdata *pdata = &smdk5250_xhci_pdata;
+
+ exynos_xhci_set_platdata(pdata);
+}
+#endif
+
+static struct s5p_usbswitch_platdata smdk5250_usbswitch_pdata;
+
+static void __init smdk5250_usbswitch_init(void)
+{
+ struct s5p_usbswitch_platdata *pdata = &smdk5250_usbswitch_pdata;
+ int err;
+
+ /* USB 2.0 detect GPIO */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ pdata->gpio_device_detect = 0;
+ pdata->gpio_host_vbus = 0;
+ } else {
+ pdata->gpio_host_detect = EXYNOS5_GPX1(6);
+ err = gpio_request_one(pdata->gpio_host_detect, GPIOF_IN,
+ "HOST_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request host gpio\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_host_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_host_detect, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_host_detect);
+
+ pdata->gpio_device_detect = EXYNOS5_GPX3(4);
+ err = gpio_request_one(pdata->gpio_device_detect, GPIOF_IN,
+ "DEVICE_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request device gpio\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_device_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_device_detect, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_device_detect);
+
+ pdata->gpio_host_vbus = EXYNOS5_GPX2(6);
+ err = gpio_request_one(pdata->gpio_host_vbus,
+ GPIOF_OUT_INIT_LOW,
+ "HOST_VBUS_CONTROL");
+ if (err) {
+ printk(KERN_ERR "failed to request host_vbus gpio\n");
+ return;
+ }
+
+ s3c_gpio_setpull(pdata->gpio_host_vbus, S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_host_vbus);
+ }
+
+ /* USB 3.0 DRD detect GPIO */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ pdata->gpio_drd_host_detect = 0;
+ pdata->gpio_drd_device_detect = 0;
+ } else {
+ pdata->gpio_drd_host_detect = EXYNOS5_GPX1(7);
+ err = gpio_request_one(pdata->gpio_drd_host_detect, GPIOF_IN,
+ "DRD_HOST_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request drd_host gpio\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_drd_host_detect, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_drd_host_detect,
+ S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_drd_host_detect);
+
+ pdata->gpio_drd_device_detect = EXYNOS5_GPX0(6);
+ err = gpio_request_one(pdata->gpio_drd_device_detect, GPIOF_IN,
+ "DRD_DEVICE_DETECT");
+ if (err) {
+ printk(KERN_ERR "failed to request drd_device\n");
+ return;
+ }
+
+ s3c_gpio_cfgpin(pdata->gpio_drd_device_detect,
+ S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(pdata->gpio_drd_device_detect,
+ S3C_GPIO_PULL_NONE);
+ gpio_free(pdata->gpio_drd_device_detect);
+ }
+
+ s5p_usbswitch_set_platdata(pdata);
+}
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+static struct gpio_event_direct_entry smdk5250_keypad_key_map[] = {
+ {
+ .gpio = EXYNOS5_GPX0(0),
+ .code = KEY_POWER,
+ }
+};
+
+static struct gpio_event_input_info smdk5250_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdk5250_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdk5250_keypad_key_map)
+};
+
+static struct gpio_event_info *smdk5250_input_info[] = {
+ &smdk5250_keypad_key_info.info,
+};
+
+static struct gpio_event_platform_data smdk5250_input_data = {
+ .names = {
+ "smdk5250-keypad",
+ NULL,
+ },
+ .info = smdk5250_input_info,
+ .info_count = ARRAY_SIZE(smdk5250_input_info),
+};
+
+static struct platform_device smdk5250_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdk5250_input_data,
+ },
+};
+
+static void __init smdk5250_gpio_power_init(void)
+{
+ int err = 0;
+
+ err = gpio_request_one(EXYNOS5_GPX0(0), 0, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "suspend/resume control\n");
+ return;
+ }
+ s3c_gpio_setpull(EXYNOS5_GPX0(0), S3C_GPIO_PULL_NONE);
+
+ gpio_free(EXYNOS5_GPX0(0));
+}
+
+#ifdef CONFIG_WAKEUP_ASSIST
+static struct platform_device wakeup_assist_device = {
+ .name = "wakeup_assist",
+};
+#endif
+
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("egalax_i2c", 0x04),
+ .irq = IRQ_EINT(25),
+ .platform_data = &exynos5_egalax_data,
+ },
+};
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+#endif
+
+static struct platform_device exynos5_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+
+static struct platform_device *smdk5250_devices[] __initdata = {
+ &s3c_device_wdt,
+ &s3c_device_i2c2,
+ &s3c_device_i2c4,
+ &s3c_device_i2c5,
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ &s5p_device_jpeg,
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+#ifdef CONFIG_EXYNOS_MEDIA_DEVICE
+ &exynos_device_md0,
+ &exynos_device_md1,
+ &exynos_device_md2,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ &exynos5_device_fimc_is,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+ &exynos5_device_gsc0,
+ &exynos5_device_gsc1,
+ &exynos5_device_gsc2,
+ &exynos5_device_gsc3,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ &exynos_device_flite0,
+ &exynos_device_flite1,
+ &exynos_device_flite2,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_MIPI_CSIS
+ &s5p_device_mipi_csis0,
+ &s5p_device_mipi_csis1,
+ &mipi_csi_fixed_voltage,
+#endif
+#ifdef CONFIG_VIDEO_M5MOLS
+ &m5mols_fixed_voltage,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ &exynos_device_rotator,
+#endif
+ &s3c_device_rtc,
+ &smdk5250_smsc911x,
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI
+ &s5p_device_hdmi,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_HDMIPHY
+ &s5p_device_i2c_hdmiphy,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_MIXER
+ &s5p_device_mixer,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+ &s5p_device_cec,
+#endif
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ &exynos_device_c2c,
+#endif
+ &exynos5_device_ahci,
+};
+
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#if defined(CONFIG_CMA)
+static void __init exynos_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+ {
+ .name = "ion",
+ .size = 30 * SZ_1M,
+ .start = 0
+ },
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC0
+ {
+ .name = "gsc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC1
+ {
+ .name = "gsc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC1 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC2
+ {
+ .name = "gsc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC2 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC3
+ {
+ .name = "gsc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_GSC3 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE0
+ {
+ .name = "flite0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE1
+ {
+ .name = "flite1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FLITE1 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ {
+ .name = "fw",
+ .size = 2 << 20,
+ { .alignment = 128 << 10 },
+ .start = 0x44000000,
+ },
+ {
+ .name = "b1",
+ .size = 64 << 20,
+ .start = 0x45000000,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV
+ {
+ .name = "tv",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TV * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_ROT
+ {
+ .name = "rot",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_ROT * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ {
+ .name = "fimc_is",
+ .size = CONFIG_VIDEO_EXYNOS_MEMSIZE_FIMC_IS * SZ_1K,
+ {
+ .alignment = 1 << 26,
+ },
+ .start = 0
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+ static const char map[] __initconst =
+#ifdef CONFIG_EXYNOS_C2C
+ "samsung-c2c=c2c_shdmem;"
+#endif
+ "s3cfb.0=fimd;exynos5-fb.1=fimd;"
+ "samsung-rp=srp;"
+ "exynos-gsc.0=gsc0;exynos-gsc.1=gsc1;exynos-gsc.2=gsc2;exynos-gsc.3=gsc3;"
+ "exynos-fimc-lite.0=flite0;exynos-fimc-lite.1=flite1;"
+ "ion-exynos=ion,gsc0,gsc1,gsc2,gsc3,flite0,flite1,fimd,fw,b1,rot;"
+ "exynos-rot=rot;"
+ "s5p-mfc-v6/f=fw;"
+ "s5p-mfc-v6/a=b1;"
+ "s5p-mixer=tv;"
+ "exynos5-fimc-is=fimc_is;"
+ "s5p-smem/mfc_sh=drm_mfc_sh;"
+ "s5p-smem/video=drm_video;"
+ "s5p-smem/mfc_fw=drm_mfc_fw;"
+ "s5p-smem/sectbl=drm_sectbl;";
+
+ s5p_cma_region_reserve(regions, NULL, 0, map);
+}
+#else /* !CONFIG_CMA*/
+static inline void exynos_reserve_mem(void)
+{
+}
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+static void __init smdk5250_camera_gpio_cfg(void)
+{
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, CLK_OUT */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPH0(0), 4, S3C_GPIO_SFN(2));
+ /* CAM A port(b0010) : DATA[0-7] */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPH1(0), 8, S3C_GPIO_SFN(2));
+ /* CAM B port(b0010) : PCLK, BAY_RGB[0-6] */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPG0(0), 8, S3C_GPIO_SFN(2));
+ /* CAM B port(b0010) : BAY_Vsync, BAY_RGB[7-13] */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPG1(0), 8, S3C_GPIO_SFN(2));
+ /* CAM B port(b0010) : BAY_Hsync, BAY_MCLK */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPG2(0), 2, S3C_GPIO_SFN(2));
+ /* This is externel interrupt for m5mo */
+#ifdef CONFIG_VIDEO_M5MOLS
+ s3c_gpio_cfgpin(EXYNOS5_GPX2(6), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS5_GPX2(6), S3C_GPIO_PULL_NONE);
+#endif
+}
+#endif
+
+#if defined(CONFIG_VIDEO_EXYNOS_GSCALER) && defined(CONFIG_VIDEO_EXYNOS_FIMC_LITE)
+#if defined(CONFIG_VIDEO_S5K4BA)
+static struct exynos_isp_info s5k4ba = {
+ .board_info = &s5k4ba_info,
+ .cam_srclk_name = "xxti",
+ .clk_frequency = 24000000UL,
+ .bus_type = CAM_TYPE_ITU,
+#ifdef CONFIG_ITU_A
+ .cam_clk_name = "sclk_cam0",
+ .i2c_bus_num = 4,
+ .cam_port = CAM_PORT_A, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_ITU_B
+ .cam_clk_name = "sclk_cam1",
+ .i2c_bus_num = 5,
+ .cam_port = CAM_PORT_B, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = CAM_CLK_INV_VSYNC,
+};
+/* This is for platdata of fimc-lite */
+static struct s3c_platform_camera flite_s5k4ba = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+#if defined(CONFIG_VIDEO_M5MOLS)
+static struct exynos_isp_info m5mols = {
+ .board_info = &m5mols_board_info,
+ .cam_srclk_name = "xxti",
+ .clk_frequency = 24000000UL,
+ .bus_type = CAM_TYPE_MIPI,
+#ifdef CONFIG_CSI_C
+ .cam_clk_name = "sclk_cam0",
+ .i2c_bus_num = 4,
+ .cam_port = CAM_PORT_A, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_CSI_D
+ .cam_clk_name = "sclk_cam1",
+ .i2c_bus_num = 5,
+ .cam_port = CAM_PORT_B, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = CAM_CLK_INV_PCLK | CAM_CLK_INV_VSYNC,
+ .csi_data_align = 32,
+};
+/* This is for platdata of fimc-lite */
+static struct s3c_platform_camera flite_m5mo = {
+ .type = CAM_TYPE_MIPI,
+ .use_isp = true,
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+};
+#endif
+
+static void __set_gsc_camera_config(struct exynos_platform_gscaler *data,
+ u32 active_index, u32 preview,
+ u32 camcording, u32 max_cam)
+{
+ data->active_cam_index = active_index;
+ data->cam_preview = preview;
+ data->cam_camcording = camcording;
+ data->num_clients = max_cam;
+}
+
+static void __set_flite_camera_config(struct exynos_platform_flite *data,
+ u32 active_index, u32 max_cam)
+{
+ data->active_cam_index = active_index;
+ data->num_clients = max_cam;
+}
+
+static void __init smdk5250_set_camera_platdata(void)
+{
+ int gsc_cam_index = 0;
+ int flite0_cam_index = 0;
+ int flite1_cam_index = 0;
+#if defined(CONFIG_VIDEO_M5MOLS)
+ exynos_gsc0_default_data.isp_info[gsc_cam_index++] = &m5mols;
+#if defined(CONFIG_CSI_C)
+ exynos_flite0_default_data.cam[flite0_cam_index] = &flite_m5mo;
+ exynos_flite0_default_data.isp_info[flite0_cam_index] = &m5mols;
+ flite0_cam_index++;
+#endif
+#if defined(CONFIG_CSI_D)
+ exynos_flite1_default_data.cam[flite1_cam_index] = &flite_m5mo;
+ exynos_flite1_default_data.isp_info[flite1_cam_index] = &m5mols;
+ flite1_cam_index++;
+#endif
+#endif
+ /* flite platdata register */
+ __set_flite_camera_config(&exynos_flite0_default_data, 0, flite0_cam_index);
+ __set_flite_camera_config(&exynos_flite1_default_data, 0, flite1_cam_index);
+
+ /* gscaler platdata register */
+ /* GSC-0 */
+ __set_gsc_camera_config(&exynos_gsc0_default_data, 0, 1, 0, gsc_cam_index);
+
+ /* GSC-1 */
+ /* GSC-2 */
+ /* GSC-3 */
+}
+#endif /* CONFIG_VIDEO_EXYNOS_GSCALER */
+
+static void __init smdk5250_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+static struct s5p_mfc_platdata smdk5250_mfc_pd = {
+ .clock_rate = 333000000,
+};
+#endif
+
+static void __init smdk5250_map_io(void)
+{
+ clk_xxti.rate = 24000000;
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdk5250_uartcfgs, ARRAY_SIZE(smdk5250_uartcfgs));
+ exynos_reserve_mem();
+}
+
+#ifdef CONFIG_EXYNOS_DEV_SYSMMU
+static void __init exynos_sysmmu_init(void)
+{
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ platform_set_sysmmu(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_lr).dev, &s5p_device_mfc.dev);
+#endif
+#if defined(CONFIG_VIDEO_EXYNOS_TV)
+ platform_set_sysmmu(&SYSMMU_PLATDEV(tv).dev, &s5p_device_mixer.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc0).dev,
+ &exynos5_device_gsc0.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc1).dev,
+ &exynos5_device_gsc1.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc2).dev,
+ &exynos5_device_gsc2.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(gsc3).dev,
+ &exynos5_device_gsc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ platform_set_sysmmu(&SYSMMU_PLATDEV(camif0).dev,
+ &exynos_device_flite0.dev);
+ platform_set_sysmmu(&SYSMMU_PLATDEV(camif1).dev,
+ &exynos_device_flite1.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ platform_set_sysmmu(&SYSMMU_PLATDEV(rot).dev,
+ &exynos_device_rotator.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ platform_set_sysmmu(&SYSMMU_PLATDEV(2d).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ platform_set_sysmmu(&SYSMMU_PLATDEV(isp).dev,
+ &exynos5_device_fimc_is.dev);
+#endif
+}
+#else /* !CONFIG_EXYNOS_DEV_SYSMMU */
+static inline void exynos_sysmmu_init(void)
+{
+}
+#endif
+
+static void __init smdk5250_machine_init(void)
+{
+ exynos5_smdk5250_mmc_init();
+ exynos5_smdk5250_power_init();
+ exynos5_smdk5250_audio_init();
+ exynos5_smdk5250_usb_init();
+ exynos5_smdk5250_input_init();
+#if defined(CONFIG_S3C64XX_DEV_SPI)
+ exynos5_smdk5250_spi_init();
+#endif
+
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+
+ s3c_i2c4_set_platdata(NULL);
+ s3c_i2c5_set_platdata(NULL);
+
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ platform_device_register(&s3c_device_adc);
+#ifdef CONFIG_S3C_DEV_HWMON
+ platform_device_register(&s3c_device_hwmon);
+#endif
+ }
+
+#ifdef CONFIG_S3C_DEV_HWMON
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ s3c_hwmon_set_platdata(&smdk5250_hwmon_pdata);
+#endif
+
+#ifdef CONFIG_SAMSUNG_DEV_BACKLIGHT
+ samsung_bl_set(&smdk5250_bl_gpio_info, &smdk5250_bl_data);
+#endif
+
+#ifdef CONFIG_FB_S3C
+ dev_set_name(&s5p_device_fimd1.dev, "s3cfb.1");
+ clk_add_alias("lcd", "exynos5-fb.1", "lcd", &s5p_device_fimd1.dev);
+ clk_add_alias("sclk_fimd", "exynos5-fb.1", "sclk_fimd",
+ &s5p_device_fimd1.dev);
+ s5p_fb_setname(1, "exynos5-fb");
+
+ s5p_fimd1_set_platdata(&smdk5250_lcd1_pdata);
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdk5250_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdk5250_ohci_init();
+#endif
+#ifdef CONFIG_USB_S3C_OTGD
+ smdk5250_usbgadget_init();
+#endif
+#ifdef CONFIG_EXYNOS_DEV_SS_UDC
+ smdk5250_ss_udc_init();
+#endif
+#ifdef CONFIG_USB_XHCI_EXYNOS
+ smdk5250_xhci_init();
+#endif
+ smdk5250_usbswitch_init();
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ s5p_device_mfc.dev.parent = &exynos5_device_pd[PD_MFC].dev;
+#endif
+ s5p_mfc_set_platdata(&smdk5250_mfc_pd);
+
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc-v6", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc-v6");
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#endif
+ exynos_sysmmu_init();
+
+ platform_add_devices(smdk5250_devices, ARRAY_SIZE(smdk5250_devices));
+
+ exynos5_smdk5250_display_init();
+
+#ifdef CONFIG_VIDEO_EXYNOS_MIPI_CSIS
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ s5p_device_mipi_csis0.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ s5p_device_mipi_csis1.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+ s3c_set_platdata(&s5p_mipi_csis0_default_data,
+ sizeof(s5p_mipi_csis0_default_data), &s5p_device_mipi_csis0);
+ s3c_set_platdata(&s5p_mipi_csis1_default_data,
+ sizeof(s5p_mipi_csis1_default_data), &s5p_device_mipi_csis1);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ exynos_device_flite0.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos_device_flite1.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos_device_flite2.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+ smdk5250_camera_gpio_cfg();
+ smdk5250_set_camera_platdata();
+ s3c_set_platdata(&exynos_flite0_default_data,
+ sizeof(exynos_flite0_default_data), &exynos_device_flite0);
+ s3c_set_platdata(&exynos_flite1_default_data,
+ sizeof(exynos_flite1_default_data), &exynos_device_flite1);
+ s3c_set_platdata(&exynos_flite2_default_data,
+ sizeof(exynos_flite2_default_data), &exynos_device_flite2);
+/* In EVT0, for using camclk, gscaler clock should be enabled */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ dev_set_name(&exynos_device_flite0.dev, "exynos-gsc.0");
+ clk_add_alias("gscl", "exynos-fimc-lite.0", "gscl",
+ &exynos_device_flite0.dev);
+ dev_set_name(&exynos_device_flite0.dev, "exynos-fimc-lite.0");
+
+ dev_set_name(&exynos_device_flite1.dev, "exynos-gsc.0");
+ clk_add_alias("gscl", "exynos-fimc-lite.1", "gscl",
+ &exynos_device_flite1.dev);
+ dev_set_name(&exynos_device_flite1.dev, "exynos-fimc-lite.1");
+ }
+#endif
+#if defined CONFIG_VIDEO_EXYNOS5_FIMC_IS
+ dev_set_name(&exynos5_device_fimc_is.dev, "s5p-mipi-csis.0");
+ clk_add_alias("gscl_wrap0", "exynos5-fimc-is", "gscl_wrap0", &exynos5_device_fimc_is.dev);
+ clk_add_alias("sclk_gscl_wrap0", "exynos5-fimc-is", "sclk_gscl_wrap0", &exynos5_device_fimc_is.dev);
+ dev_set_name(&exynos5_device_fimc_is.dev, "s5p-mipi-csis.1");
+ clk_add_alias("gscl_wrap1", "exynos5-fimc-is", "gscl_wrap1", &exynos5_device_fimc_is.dev);
+ clk_add_alias("sclk_gscl_wrap1", "exynos5-fimc-is", "sclk_gscl_wrap1", &exynos5_device_fimc_is.dev);
+ dev_set_name(&exynos5_device_fimc_is.dev, "exynos-gsc.0");
+ clk_add_alias("gscl", "exynos5-fimc-is", "gscl", &exynos5_device_fimc_is.dev);
+ dev_set_name(&exynos5_device_fimc_is.dev, "exynos5-fimc-is");
+
+#if defined CONFIG_VIDEO_S5K6A3
+ exynos5_fimc_is_data.sensor_info[s5k6a3.sensor_position] = &s5k6a3;
+ printk("add s5k6a3 sensor info(pos : %d)\n", s5k6a3.sensor_position);
+#endif
+#if defined CONFIG_VIDEO_S5K4E5
+ exynos5_fimc_is_data.sensor_info[s5k4e5.sensor_position] = &s5k4e5;
+ printk("add s5k4e5 sensor info(pos : %d)\n", s5k4e5.sensor_position);
+#endif
+
+ exynos5_fimc_is_set_platdata(&exynos5_fimc_is_data);
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ exynos5_device_pd[PD_ISP].dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_fimc_is.dev.parent = &exynos5_device_pd[PD_ISP].dev;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_GSCALER
+#if defined(CONFIG_EXYNOS_DEV_PD)
+ exynos5_device_gsc0.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_gsc1.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_gsc2.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+ exynos5_device_gsc3.dev.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ secmem.parent = &exynos5_device_pd[PD_GSCL].dev;
+#endif
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ exynos5_gsc_set_pdev_name(0, "exynos5250-gsc");
+ exynos5_gsc_set_pdev_name(1, "exynos5250-gsc");
+ exynos5_gsc_set_pdev_name(2, "exynos5250-gsc");
+ exynos5_gsc_set_pdev_name(3, "exynos5250-gsc");
+ }
+
+ s3c_set_platdata(&exynos_gsc0_default_data, sizeof(exynos_gsc0_default_data),
+ &exynos5_device_gsc0);
+ s3c_set_platdata(&exynos_gsc1_default_data, sizeof(exynos_gsc1_default_data),
+ &exynos5_device_gsc1);
+ s3c_set_platdata(&exynos_gsc2_default_data, sizeof(exynos_gsc2_default_data),
+ &exynos5_device_gsc2);
+ s3c_set_platdata(&exynos_gsc3_default_data, sizeof(exynos_gsc3_default_data),
+ &exynos5_device_gsc3);
+ exynos5_gsc_set_parent_clock("mout_aclk_300_gscl_mid", "mout_mpll_user");
+ exynos5_gsc_set_parent_clock("mout_aclk_300_gscl", "mout_aclk_300_gscl_mid");
+ exynos5_gsc_set_parent_clock("aclk_300_gscl", "dout_aclk_300_gscl");
+ exynos5_gsc_set_clock_rate("dout_aclk_300_gscl", 310000000);
+#endif
+#ifdef CONFIG_EXYNOS_C2C
+ exynos_c2c_set_platdata(&smdk5250_c2c_pdata);
+#endif
+#ifdef CONFIG_VIDEO_JPEG_V2X
+ exynos5_jpeg_setup_clock(&s5p_device_jpeg.dev, 150000000);
+#endif
+
+#if defined(CONFIG_VIDEO_EXYNOS_TV) && defined(CONFIG_VIDEO_EXYNOS_HDMI)
+ dev_set_name(&s5p_device_hdmi.dev, "exynos5-hdmi");
+ clk_add_alias("hdmi", "s5p-hdmi", "hdmi", &s5p_device_hdmi.dev);
+ clk_add_alias("hdmiphy", "s5p-hdmi", "hdmiphy", &s5p_device_hdmi.dev);
+
+ s5p_tv_setup();
+
+/* setup dependencies between TV devices */
+ /* This will be added after power domain for exynos5 is developed */
+ s5p_device_hdmi.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+ s5p_device_mixer.dev.parent = &exynos5_device_pd[PD_DISP1].dev;
+
+ s5p_i2c_hdmiphy_set_platdata(NULL);
+#ifdef CONFIG_VIDEO_EXYNOS_HDMI_CEC
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#endif
+#endif
+
+ smdk5250_smsc911x_init();
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_CPU], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_C], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_R1], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_DDR_L], &exynos5_busfreq.dev);
+ ppmu_init(&exynos_ppmu[PPMU_RIGHT0_BUS], &exynos5_busfreq.dev
+#endif
+ register_reboot_notifier(&exynos5_reboot_notifier);
+}
+
+#ifdef CONFIG_EXYNOS_C2C
+static void __init exynos_c2c_reserve(void)
+{
+ static struct cma_region regions[] = {
+ {
+ .name = "c2c_shdmem",
+ .size = 64 * SZ_1M,
+ { .alignment = 64 * SZ_1M },
+ .start = C2C_SHAREDMEM_BASE
+ }, {
+ .size = 0,
+ }
+ };
+
+ s5p_cma_region_reserve(regions, NULL, 0, NULL);
+}
+#endif
+
+MACHINE_START(SMDK5250, "SMDK5250")
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos5_init_irq,
+ .map_io = smdk5250_map_io,
+ .init_machine = smdk5250_machine_init,
+ .timer = &exynos4_timer,
+#ifdef CONFIG_EXYNOS_C2C
+ .reserve = &exynos_c2c_reserve,
+#endif
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
new file mode 100644
index 0000000..3bb14d5
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -0,0 +1,2680 @@
+/* linux/arch/arm/mach-exynos/mach-smdkv310.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/lcd.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/pwm_backlight.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/max8997.h>
+#include <linux/v4l2-mediabus.h>
+#include <linux/memblock.h>
+#if defined(CONFIG_CMA)
+#include <linux/cma.h>
+#endif
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/exynos4.h>
+#include <plat/clock.h>
+#include <plat/hwmon.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/fb-s5p.h>
+#ifdef CONFIG_VIDEO_FIMC
+#include <plat/fimc.h>
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+#include <media/s5p_fimc.h>
+#include <plat/fimc-core.h>
+#endif
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+#include <plat/csis.h>
+#endif
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+#include <plat/mipi_csis.h>
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+#include <plat/gpio-cfg.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/keypad.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/iic.h>
+#include <plat/sysmmu.h>
+#include <plat/pd.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/media.h>
+#include <plat/s5p-clock.h>
+#include <plat/tvout.h>
+#include <plat/fimg2d.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+#ifdef CONFIG_S3C64XX_DEV_SPI
+#include <plat/s3c64xx-spi.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/media.h>
+#include <mach/dev-sysmmu.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos-ion.h>
+#ifdef CONFIG_S3C64XX_DEV_SPI
+#include <mach/spi-clocks.h>
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+#include <mach/dwmci.h>
+#endif
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+#include <mach/secmem.h>
+#endif
+#include <mach/dev.h>
+
+#include <media/s5k4ba_platform.h>
+#include <media/s5k4ea_platform.h>
+#include <media/m5mo_platform.h>
+#include <media/m5mols.h>
+
+#if defined(CONFIG_EXYNOS4_SETUP_THERMAL)
+#include <plat/s5p-tmu.h>
+#endif
+
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+#include <mach/mipi_ddi.h>
+#include <mach/dsim.h>
+#include <../../../drivers/video/samsung/s3cfb.h>
+#endif
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKV310_UCON_DEFAULT,
+ .ulcon = SMDKV310_ULCON_DEFAULT,
+ .ufcon = SMDKV310_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKV310_UCON_DEFAULT,
+ .ulcon = SMDKV310_ULCON_DEFAULT,
+ .ufcon = SMDKV310_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKV310_UCON_DEFAULT,
+ .ulcon = SMDKV310_ULCON_DEFAULT,
+ .ufcon = SMDKV310_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKV310_UCON_DEFAULT,
+ .ulcon = SMDKV310_ULCON_DEFAULT,
+ .ufcon = SMDKV310_UFCON_DEFAULT,
+ },
+};
+
+#define WRITEBACK_ENABLED
+
+#if defined(CONFIG_VIDEO_FIMC) || defined(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+*/
+#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C)
+static int smdkv310_cam0_reset(int dummy)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS4_GPX1(2), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS4_GPX1(2), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS4_GPX1(2), 0);
+ gpio_direction_output(EXYNOS4_GPX1(2), 1);
+ gpio_free(EXYNOS4_GPX1(2));
+
+ return 0;
+}
+#endif
+#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D)
+static int smdkv310_cam1_reset(int dummy)
+{
+ int err;
+
+ /* Camera B */
+ err = gpio_request(EXYNOS4_GPX1(0), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_0 ####\n");
+
+ s3c_gpio_setpull(EXYNOS4_GPX1(0), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS4_GPX1(0), 0);
+ gpio_direction_output(EXYNOS4_GPX1(0), 1);
+ gpio_free(EXYNOS4_GPX1(0));
+
+ return 0;
+}
+#endif
+/* for 12M camera */
+#ifdef CE143_MONACO
+static int smdkv310_cam0_standby(void)
+{
+ int err;
+ /* Camera A */
+ err = gpio_request(EXYNOS4_GPX3(3), "GPX3");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX3_3 ####\n");
+ s3c_gpio_setpull(EXYNOS4_GPX3(3), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS4_GPX3(3), 0);
+ gpio_direction_output(EXYNOS4_GPX3(3), 1);
+ gpio_free(EXYNOS4_GPX3(3));
+
+ return 0;
+}
+
+static int smdkv310_cam1_standby(void)
+{
+ int err;
+
+ /* Camera B */
+ err = gpio_request(EXYNOS4_GPX1(1), "GPX1");
+ if (err)
+ printk(KERN_ERR "#### failed to request GPX1_1 ####\n");
+ s3c_gpio_setpull(EXYNOS4_GPX1(1), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS4_GPX1(1), 0);
+ gpio_direction_output(EXYNOS4_GPX1(1), 1);
+ gpio_free(EXYNOS4_GPX1(1));
+
+ return 0;
+}
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_FIMC
+#ifdef CONFIG_VIDEO_S5K4BA
+static struct s5k4ba_platform_data s5k4ba_plat = {
+ .default_width = 800,
+ .default_height = 600,
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .freq = 24000000,
+ .is_mipi = 0,
+};
+
+static struct i2c_board_info s5k4ba_i2c_info = {
+ I2C_BOARD_INFO("S5K4BA", 0x2d),
+ .platform_data = &s5k4ba_plat,
+};
+
+static struct s3c_platform_camera s5k4ba = {
+#ifdef CONFIG_ITU_A
+ .id = CAMERA_PAR_A,
+ .clk_name = "sclk_cam0",
+ .i2c_busnum = 0,
+ .cam_power = smdkv310_cam0_reset,
+#endif
+#ifdef CONFIG_ITU_B
+ .id = CAMERA_PAR_B,
+ .clk_name = "sclk_cam1",
+ .i2c_busnum = 1,
+ .cam_power = smdkv310_cam1_reset,
+#endif
+ .type = CAM_TYPE_ITU,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &s5k4ba_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUYV,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 1920,
+ .width = 1600,
+ .height = 1200,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1600,
+ .height = 1200,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 1,
+ .initialized = 0,
+};
+#endif
+
+/* 2 MIPI Cameras */
+#ifdef CONFIG_VIDEO_S5K4EA
+static struct s5k4ea_platform_data s5k4ea_plat = {
+ .default_width = 1920,
+ .default_height = 1080,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+};
+
+static struct i2c_board_info s5k4ea_i2c_info = {
+ I2C_BOARD_INFO("S5K4EA", 0x2d),
+ .platform_data = &s5k4ea_plat,
+};
+
+static struct s3c_platform_camera s5k4ea = {
+#ifdef CONFIG_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .i2c_busnum = 0,
+ .cam_power = smdkv310_cam0_reset,
+#endif
+#ifdef CONFIG_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .i2c_busnum = 1,
+ .cam_power = smdkv310_mipi_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &s5k4ea_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "mout_mpll",
+ .clk_rate = 48000000,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+
+ .initialized = 0,
+};
+#endif
+
+#ifdef WRITEBACK_ENABLED
+static struct i2c_board_info __initdata writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .i2c_busnum = 0,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 800,
+ .width = 480,
+ .height = 800,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 480,
+ .height = 800,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+/* legacy M5MOLS Camera driver configuration */
+#ifdef CONFIG_VIDEO_M5MO
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ }
+
+static int m5mo_config_isp_irq(void)
+{
+ s3c_gpio_cfgpin(EXYNOS4_GPX0(5), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS4_GPX0(5), S3C_GPIO_PULL_NONE);
+ return 0;
+}
+
+static struct m5mo_platform_data m5mo_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .config_isp_irq = m5mo_config_isp_irq,
+ .irq = IRQ_EINT(5),
+};
+
+static struct i2c_board_info m5mo_i2c_info = {
+ I2C_BOARD_INFO("M5MO", 0x1F),
+ .platform_data = &m5mo_plat,
+ .irq = IRQ_EINT(5),
+};
+
+static struct s3c_platform_camera m5mo = {
+#ifdef CONFIG_CSI_C
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .i2c_busnum = 0,
+ .cam_power = smdkv310_cam0_reset,
+#endif
+#ifdef CONFIG_CSI_D
+ .id = CAMERA_CSI_D,
+ .clk_name = "sclk_cam1",
+ .i2c_busnum = 1,
+ .cam_power = smdkv310_mipi_cam1_reset,
+#endif
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .info = &m5mo_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+#ifdef CONFIG_ITU_A
+ .default_cam = CAMERA_PAR_A,
+#endif
+#ifdef CONFIG_ITU_B
+ .default_cam = CAMERA_PAR_B,
+#endif
+#ifdef CONFIG_CSI_C
+ .default_cam = CAMERA_CSI_C,
+#endif
+#ifdef CONFIG_CSI_D
+ .default_cam = CAMERA_CSI_D,
+#endif
+#ifdef WRITEBACK_ENABLED
+ .default_cam = CAMERA_WB,
+#endif
+ .camera = {
+#ifdef CONFIG_VIDEO_S5K4BA
+ &s5k4ba,
+#endif
+#ifdef CONFIG_VIDEO_S5K4EA
+ &s5k4ea,
+#endif
+#ifdef CONFIG_VIDEO_M5MO
+ &m5mo,
+#endif
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+ },
+ .hw_ver = 0x51,
+};
+#endif /* CONFIG_VIDEO_FIMC */
+
+/* for mainline fimc interface */
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+#ifdef WRITEBACK_ENABLED
+struct writeback_mbus_platform_data {
+ int id;
+ struct v4l2_mbus_framefmt fmt;
+};
+
+static struct i2c_board_info __initdata writeback_info = {
+ I2C_BOARD_INFO("writeback", 0x0),
+};
+#endif
+
+#ifdef CONFIG_VIDEO_S5K4BA
+static struct s5k4ba_mbus_platform_data s5k4ba_mbus_plat = {
+ .id = 0,
+ .fmt = {
+ .width = 1600,
+ .height = 1200,
+ /*.code = V4L2_MBUS_FMT_UYVY8_2X8,*/
+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
+ },
+ .clk_rate = 24000000UL,
+#ifdef CONFIG_ITU_A
+ .set_power = smdkv310_cam0_reset,
+#endif
+#ifdef CONFIG_ITU_B
+ .set_power = smdkv310_cam1_reset,
+#endif
+};
+
+static struct i2c_board_info s5k4ba_info = {
+ I2C_BOARD_INFO("S5K4BA", 0x2d),
+ .platform_data = &s5k4ba_mbus_plat,
+};
+#endif
+
+/* 2 MIPI Cameras */
+#ifdef CONFIG_VIDEO_S5K4EA
+static struct s5k4ea_mbus_platform_data s5k4ea_mbus_plat = {
+#ifdef CONFIG_CSI_C
+ .id = 0,
+ .set_power = smdkv310_cam0_reset,
+#endif
+#ifdef CONFIG_CSI_D
+ .id = 1,
+ .set_power = smdkv310_cam1_reset,
+#endif
+ .fmt = {
+ .width = 1920,
+ .height = 1080,
+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
+ },
+ .clk_rate = 24000000UL,
+};
+
+static struct i2c_board_info s5k4ea_info = {
+ I2C_BOARD_INFO("S5K4EA", 0x2d),
+ .platform_data = &s5k4ea_mbus_plat,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct m5mols_platform_data m5mols_platdata = {
+#ifdef CONFIG_CSI_C
+ .gpio_rst = EXYNOS4_GPX1(2), /* ISP_RESET */
+#endif
+#ifdef CONFIG_CSI_D
+ .gpio_rst = EXYNOS4_GPX1(0), /* ISP_RESET */
+#endif
+ .enable_rst = true, /* positive reset */
+ .irq = IRQ_EINT(5),
+};
+
+static struct i2c_board_info m5mols_board_info = {
+ I2C_BOARD_INFO("M5MOLS", 0x1F),
+ .platform_data = &m5mols_platdata,
+};
+
+#endif
+#endif /* CONFIG_VIDEO_SAMSUNG_S5P_FIMC */
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+static void exynos_dwmci_cfg_gpio(int width)
+{
+ unsigned int gpio;
+
+ for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+
+ switch (width) {
+ case MMC_BUS_WIDTH_8:
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ case MMC_BUS_WIDTH_4:
+ for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+ break;
+ case MMC_BUS_WIDTH_1:
+ gpio = EXYNOS4_GPK0(3);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ default:
+ break;
+ }
+}
+
+static struct dw_mci_board exynos_dwmci_pdata __initdata = {
+ .num_slots = 1,
+ .quirks = DW_MCI_QUIRK_BROKEN_CARD_DETECTION | DW_MCI_QUIRK_HIGHSPEED,
+ .bus_hz = 80 * 1000 * 1000,
+ .caps = MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+ MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+ .fifo_depth = 0x20,
+ .detect_delay_ms = 200,
+ .hclk_name = "dwmci",
+ .cclk_name = "sclk_dwmci",
+ .cfg_gpio = exynos_dwmci_cfg_gpio,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+#endif
+
+#ifdef CONFIG_S5P_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+ .has_wp_gpio = true,
+ .wp_gpio = 0xffffffff,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50,
+#endif
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 30,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 267 * 1000000, /* 266 Mhz */
+};
+#endif
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_LCD_AMS369FG06)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ err = gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+
+ gpio_free(EXYNOS4_GPX0(6));
+
+ return 1;
+}
+
+static struct lcd_platform_data ams369fg06_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = (void *)&ams369fg06_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd0.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win1 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win2 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_WA101S)
+static void lcd_wa101s_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkv310_lcd_wa101s_data = {
+ .set_power = lcd_wa101s_set_power,
+};
+
+static struct platform_device smdkv310_lcd_wa101s = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkv310_lcd_wa101s_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win2 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1360, /* real size : 1366 */
+ .yres = 768,
+ },
+ .virtual_x = 1360, /* real size : 1366 */
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_LTE480WV)
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkv310_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkv310_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkv310_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .width = 104,
+ .height = 62,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win1 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .width = 104,
+ .height = 62,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkv310_fb_win2 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .width = 104,
+ .height = 62,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static struct s3c_fb_platdata smdkv310_lcd0_pdata __initdata = {
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_WA101S) || \
+ defined(CONFIG_LCD_LTE480WV)
+ .win[0] = &smdkv310_fb_win0,
+ .win[1] = &smdkv310_fb_win1,
+ .win[2] = &smdkv310_fb_win2,
+#endif
+ .default_win = 2,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_AMS369FG06)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN |
+ VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_WA101S)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC |
+ VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_LTE480WV)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#endif
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x0,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+};
+
+static struct s3c64xx_spi_csinfo spi2_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPC1(2),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x1,
+ },
+};
+
+static struct spi_board_info spi2_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10*1000*1000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi2_csi[0],
+ }
+};
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_AMS369FG06
+static struct s3c_platform_fb ams369fg06_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = NULL,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+#elif defined(CONFIG_FB_S5P_DUMMY_MIPI_LCD)
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct s3cfb_lcd dummy_mipi_lcd = {
+ .width = 480,
+ .height = 800,
+ .bpp = 24,
+
+ .freq = 60,
+
+ .timing = {
+ .h_fp = 0x16,
+ .h_bp = 0x16,
+ .h_sw = 0x2,
+ .v_fp = 0x28,
+ .v_fpe = 2,
+ .v_bp = 0x1,
+ .v_bpe = 1,
+ .v_sw = 3,
+ .cmd_allow_len = 4,
+ },
+
+ .polarity = {
+ .rise_vclk = 0,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#if defined(CONFIG_FB_S5P_DEFAULT_WINDOW)
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+static void lcd_cfg_gpio(void)
+{
+ return;
+}
+
+static int reset_lcd(void)
+{
+ int err = 0;
+ /* fire nRESET on power off */
+ err = gpio_request_one(EXYNOS4_GPX3(1), GPIOF_OUT_INIT_HIGH, "GPX3");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX3(1), 0);
+ mdelay(100);
+ gpio_set_value(EXYNOS4_GPX3(1), 1);
+ mdelay(100);
+ gpio_free(EXYNOS4_GPX3(1));
+
+ return 0;
+}
+
+static int lcd_power_on(void *pdev, int enable)
+{
+ return 1;
+}
+
+static void __init mipi_fb_init(void)
+{
+ struct s5p_platform_dsim *dsim_pd = NULL;
+ struct mipi_ddi_platform_data *mipi_ddi_pd = NULL;
+ struct dsim_lcd_config *dsim_lcd_info = NULL;
+
+ /* gpio pad configuration for rgb and spi interface. */
+ lcd_cfg_gpio();
+
+ /* register lcd panel data. */
+ dsim_pd = (struct s5p_platform_dsim *)
+ s5p_device_dsim.dev.platform_data;
+
+ strcpy(dsim_pd->lcd_panel_name, "dummy_mipi_lcd");
+
+ dsim_lcd_info = dsim_pd->dsim_lcd_info;
+ dsim_lcd_info->lcd_panel_info = (void *)&dummy_mipi_lcd;
+
+ mipi_ddi_pd = (struct mipi_ddi_platform_data *)
+ dsim_lcd_info->mipi_ddi_pd;
+ mipi_ddi_pd->lcd_reset = reset_lcd;
+ mipi_ddi_pd->lcd_power_on = lcd_power_on;
+
+ platform_device_register(&s5p_device_dsim);
+
+ s3cfb_set_platdata(&fb_platform_data);
+
+ printk(KERN_INFO "platform data of %s lcd panel has been registered.\n",
+ dsim_pd->lcd_panel_name);
+}
+#endif
+#endif
+
+static struct resource smdkv310_smsc911x_resources[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SROM_BANK(1),
+ .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(5),
+ .end = IRQ_EINT(5),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device smdkv310_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
+ .resource = smdkv310_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+/* max8649 */
+static struct regulator_consumer_supply max8952_supply =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8649_supply =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max8649a_supply =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_init_data max8952_init_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 770000,
+ .max_uV = 1400000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .uV = 1200000,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8952_supply,
+};
+
+static struct regulator_init_data max8649_init_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 750000,
+ .max_uV = 1380000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .uV = 1100000,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8649_supply,
+};
+
+static struct regulator_init_data max8649a_init_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 750000,
+ .max_uV = 1380000,
+ .always_on = 0,
+ .boot_on = 0,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1200000,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8649a_supply,
+};
+
+static struct max8649_platform_data exynos4_max8952_info = {
+ .mode = 3, /* VID1 = 1, VID0 = 1 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8952_init_data,
+};
+
+static struct max8649_platform_data exynos4_max8649_info = {
+ .mode = 2, /* VID1 = 1, VID0 = 0 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8649_init_data,
+};
+
+static struct max8649_platform_data exynos4_max8649a_info = {
+ .mode = 2, /* VID1 = 1, VID0 = 0 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8649a_init_data,
+};
+
+/* max8997 */
+static struct regulator_consumer_supply max8997_buck1 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2 =
+ REGULATOR_SUPPLY("vdd_int", NULL);
+
+static struct regulator_consumer_supply max8997_buck3 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_init_data max8997_buck1_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 925000,
+ .max_uV = 1350000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck1,
+};
+
+static struct regulator_init_data max8997_buck2_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 950000,
+ .max_uV = 1150000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck2,
+};
+
+static struct regulator_init_data max8997_buck3_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 950000,
+ .max_uV = 1150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck3,
+};
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_BUCK1, &max8997_buck1_data, },
+ { MAX8997_BUCK2, &max8997_buck2_data, },
+ { MAX8997_BUCK3, &max8997_buck3_data, },
+};
+
+static struct max8997_platform_data exynos4_max8997_info = {
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = max8997_regulators,
+
+ .buck1_voltage[0] = 1350000, /* 1.35V */
+ .buck1_voltage[1] = 1300000, /* 1.3V */
+ .buck1_voltage[2] = 1250000, /* 1.25V */
+ .buck1_voltage[3] = 1200000, /* 1.2V */
+ .buck1_voltage[4] = 1150000, /* 1.15V */
+ .buck1_voltage[5] = 1100000, /* 1.1V */
+ .buck1_voltage[6] = 1000000, /* 1.0V */
+ .buck1_voltage[7] = 950000, /* 0.95V */
+
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1000000, /* 1.0V */
+ .buck2_voltage[2] = 950000, /* 0.95V */
+ .buck2_voltage[3] = 900000, /* 0.9V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1000000, /* 1.0V */
+ .buck2_voltage[6] = 950000, /* 0.95V */
+ .buck2_voltage[7] = 900000, /* 0.9V */
+
+ .buck5_voltage[0] = 1100000, /* 1.1V */
+ .buck5_voltage[1] = 1100000, /* 1.1V */
+ .buck5_voltage[2] = 1100000, /* 1.1V */
+ .buck5_voltage[3] = 1100000, /* 1.1V */
+ .buck5_voltage[4] = 1100000, /* 1.1V */
+ .buck5_voltage[5] = 1100000, /* 1.1V */
+ .buck5_voltage[6] = 1100000, /* 1.1V */
+ .buck5_voltage[7] = 1100000, /* 1.1V */
+};
+
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+static struct regulator_consumer_supply mipi_csi_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.0"),
+ REGULATOR_SUPPLY("mipi_csi", "s5p-mipi-csis.1"),
+};
+
+static struct regulator_init_data mipi_csi_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mipi_csi_fixed_voltage_supplies),
+ .consumer_supplies = mipi_csi_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config mipi_csi_fixed_voltage_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &mipi_csi_fixed_voltage_init_data,
+};
+
+static struct platform_device mipi_csi_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &mipi_csi_fixed_voltage_config,
+ },
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MOLS
+static struct regulator_consumer_supply m5mols_fixed_voltage_supplies[] = {
+ REGULATOR_SUPPLY("core", NULL),
+ REGULATOR_SUPPLY("dig_18", NULL),
+ REGULATOR_SUPPLY("d_sensor", NULL),
+ REGULATOR_SUPPLY("dig_28", NULL),
+ REGULATOR_SUPPLY("a_sensor", NULL),
+ REGULATOR_SUPPLY("dig_12", NULL),
+};
+
+static struct regulator_init_data m5mols_fixed_voltage_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(m5mols_fixed_voltage_supplies),
+ .consumer_supplies = m5mols_fixed_voltage_supplies,
+};
+
+static struct fixed_voltage_config m5mols_fixed_voltage_config = {
+ .supply_name = "CAM_SENSOR",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &m5mols_fixed_voltage_init_data,
+};
+
+static struct platform_device m5mols_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &m5mols_fixed_voltage_config,
+ },
+};
+#endif
+
+static struct gpio_event_direct_entry smdkv310_keypad_key_map[] = {
+ {
+ .gpio = EXYNOS4_GPX0(0),
+ .code = KEY_POWER,
+ }
+};
+
+static struct gpio_event_input_info smdkv310_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdkv310_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdkv310_keypad_key_map)
+};
+
+static struct gpio_event_info *smdkv310_input_info[] = {
+ &smdkv310_keypad_key_info.info,
+};
+
+static struct gpio_event_platform_data smdkv310_input_data = {
+ .names = {
+ "smdkv310-keypad",
+ NULL,
+ },
+ .info = smdkv310_input_info,
+ .info_count = ARRAY_SIZE(smdkv310_input_info),
+};
+
+static struct platform_device smdkv310_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdkv310_input_data,
+ },
+};
+
+#ifdef CONFIG_WAKEUP_ASSIST
+static struct platform_device wakeup_assist_device = {
+ .name = "wakeup_assist",
+};
+#endif
+
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ REGULATOR_SUPPLY("AVDD2", "1-001a"),
+ REGULATOR_SUPPLY("CPVDD", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage2_supplies =
+ REGULATOR_SUPPLY("DBVDD", "1-001a");
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+ .consumer_supplies = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+ .consumer_supplies = wm8994_fixed_voltage1_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage2_init_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_fixed_voltage2_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VDD_1.8V",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "DC_5V",
+ .microvolts = 5000000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage2_config = {
+ .supply_name = "VDD_3.3V",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage2_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage2 = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage2_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+ REGULATOR_SUPPLY("AVDD1", "1-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+ REGULATOR_SUPPLY("DCVDD", "1-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* configure gpio3/4/5/7 function for AIF2 voice */
+ .gpio_defaults[2] = 0x8100,/* BCLK2 in */
+ .gpio_defaults[3] = 0x8100,/* LRCLK2 in */
+ .gpio_defaults[4] = 0x8100,/* DACDAT2 in */
+ /* configure gpio6 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[5] = 0x0001,
+ .gpio_defaults[6] = 0x0100,/* ADCDAT2 out */
+ .ldo[0] = { 0, NULL, &wm8994_ldo1_data },
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
+static uint32_t smdkv310_keymap[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
+ KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
+ KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
+ KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
+};
+
+static struct matrix_keymap_data smdkv310_keymap_data __initdata = {
+ .keymap = smdkv310_keymap,
+ .keymap_size = ARRAY_SIZE(smdkv310_keymap),
+};
+
+static struct samsung_keypad_platdata smdkv310_keypad_data __initdata = {
+ .keymap_data = &smdkv310_keymap_data,
+ .rows = 2,
+ .cols = 8,
+};
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ {
+ I2C_BOARD_INFO("max8649", 0x62),
+ .platform_data = &exynos4_max8649a_info,
+ }, {
+ I2C_BOARD_INFO("max8952", 0x60),
+ .platform_data = &exynos4_max8952_info,
+ }, {
+ I2C_BOARD_INFO("max8997", 0x66),
+ .platform_data = &exynos4_max8997_info,
+ }
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ }, {
+ I2C_BOARD_INFO("max8649", 0x60),
+ .platform_data = &exynos4_max8649_info,
+ },
+#ifdef CONFIG_VIDEO_TVOUT
+ {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+ },
+#endif
+};
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cal_x_max = 480,
+ .cal_y_max = 800,
+ .cal_param = {
+ 33, -9156, 34720100, 14819, 57, -4234968, 65536
+ },
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HWMON
+static struct s3c_hwmon_pdata smdkv310_hwmon_pdata __initdata = {
+ /* Reference voltage (1.2V) */
+ .in[0] = &(struct s3c_hwmon_chcfg) {
+ .name = "smdk:reference-voltage",
+ .mult = 3300,
+ .div = 4096,
+ },
+};
+#endif
+
+/* USB EHCI */
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdkv310_ehci_pdata;
+
+static void __init smdkv310_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdkv310_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdkv310_ohci_pdata;
+
+static void __init smdkv310_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdkv310_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdkv310_usbgadget_pdata;
+
+static void __init smdkv310_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdkv310_usbgadget_pdata;
+
+ s5p_usbgadget_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+#endif
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+
+static struct platform_device *smdkv310_devices[] __initdata = {
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+#ifdef CONFIG_S5P_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ &exynos_device_dwmci,
+#endif
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_adc,
+#ifdef CONFIG_S3C_DEV_HWMON
+ &s3c_device_hwmon,
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ &s3c_device_ts,
+#elif CONFIG_S3C_DEV_ADC1
+ &s3c_device_ts1,
+#endif
+#endif
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+ &exynos_device_ac97,
+ &exynos_device_i2s0,
+ &exynos_device_pcm0,
+ &exynos_device_spdif,
+#ifdef CONFIG_SND_SAMSUNG_RP
+ &exynos_device_srp,
+#endif
+ &samsung_device_keypad,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_LCD1],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(sss),
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(jpeg),
+ &SYSMMU_PLATDEV(fimd0),
+ &SYSMMU_PLATDEV(fimd1),
+ &SYSMMU_PLATDEV(pcie),
+ &SYSMMU_PLATDEV(2d),
+ &SYSMMU_PLATDEV(rot),
+ &SYSMMU_PLATDEV(mdma),
+ &SYSMMU_PLATDEV(tv),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
+ &wm8994_fixed_voltage2,
+ &samsung_asoc_dma,
+ &samsung_asoc_idma,
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ &exynos_device_spi0,
+ &exynos_device_spi2,
+#endif
+/* mainline fimd */
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd0,
+#if defined(CONFIG_LCD_AMS369FG06)
+ &s3c_device_spi_gpio,
+#elif defined(CONFIG_LCD_WA101S)
+ &smdkv310_lcd_wa101s,
+#elif defined(CONFIG_LCD_LTE480WV)
+ &smdkv310_lcd_lte480wv,
+#endif
+#endif
+/* legacy fimd */
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ &s3c_device_spi_gpio,
+#endif
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+ &smdkv310_smsc911x,
+ &smdkv310_input_device,
+#ifdef CONFIG_WAKEUP_ASSIST
+ &wakeup_assist_device,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+#endif
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#endif
+/* CONFIG_VIDEO_SAMSUNG_S5P_FIMC & CONFIG_VIDEO_SAMSUNG_S5P_FIMC are the
+ * feature for mainline */
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ &s5p_device_fimc0,
+ &s5p_device_fimc1,
+ &s5p_device_fimc2,
+ &s5p_device_fimc3,
+#endif
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+ &s5p_device_mipi_csis0,
+ &s5p_device_mipi_csis1,
+#endif
+
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+ &mipi_csi_fixed_voltage,
+#endif
+#ifdef CONFIG_VIDEO_M5MOLS
+ &m5mols_fixed_voltage,
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ &exynos_device_rotator,
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ &s5p_device_jpeg,
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ &s5p_device_ehci,
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#ifdef CONFIG_USB_ANDROID
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+ &exynos4_device_ahci,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+ &exynos4_busfreq,
+};
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+
+};
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+static void __init smdkv310_button_init(void)
+{
+ s3c_gpio_cfgpin(EXYNOS4_GPX0(0), (0xf << 0));
+ s3c_gpio_setpull(EXYNOS4_GPX0(0), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(EXYNOS4_GPX3(7), (0xf << 28));
+ s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
+}
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+static struct s5p_fimc_isp_info isp_info[] = {
+#if defined(CONFIG_VIDEO_S5K4BA)
+ {
+ .board_info = &s5k4ba_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_ITU_601,
+#ifdef CONFIG_ITU_A
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_ITU_B
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = FIMC_CLK_INV_VSYNC,
+ },
+#endif
+#if defined(CONFIG_VIDEO_S5K4EA)
+ {
+ .board_info = &s5k4ea_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = FIMC_CLK_INV_VSYNC,
+ .csi_data_align = 32,
+ },
+#endif
+#if defined(CONFIG_VIDEO_M5MOLS)
+ {
+ .board_info = &m5mols_board_info,
+ .clk_frequency = 24000000UL,
+ .bus_type = FIMC_MIPI_CSI2,
+#ifdef CONFIG_CSI_C
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+#endif
+#ifdef CONFIG_CSI_D
+ .i2c_bus_num = 1,
+ .mux_id = 1, /* A-Port : 0, B-Port : 1 */
+#endif
+ .flags = FIMC_CLK_INV_PCLK | FIMC_CLK_INV_VSYNC,
+ .csi_data_align = 32,
+ },
+#endif
+
+#if defined(WRITEBACK_ENABLED)
+ {
+ .board_info = &writeback_info,
+ .bus_type = FIMC_LCD_WB,
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flags = FIMC_CLK_INV_VSYNC,
+ },
+#endif
+};
+
+static void __init smdkv310_subdev_config(void)
+{
+ s3c_fimc0_default_data.isp_info[0] = &isp_info[0];
+ s3c_fimc0_default_data.isp_info[0]->use_cam = true;
+ /* support using two fimc as one sensore */
+ {
+ static struct s5p_fimc_isp_info camcording;
+ memcpy(&camcording, &isp_info[0], sizeof(struct s5p_fimc_isp_info));
+ s3c_fimc2_default_data.isp_info[0] = &camcording;
+ s3c_fimc2_default_data.isp_info[0]->use_cam = false;
+ }
+}
+
+static void __init smdkv310_camera_config(void)
+{
+ int i = 0;
+
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4210_GPJ0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4210_GPJ0(i), S3C_GPIO_PULL_NONE);
+ }
+ /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
+ for (i = 0; i < 5; i++) {
+ s3c_gpio_cfgpin(EXYNOS4210_GPJ1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4210_GPJ1(i), S3C_GPIO_PULL_NONE);
+ }
+ /* CAM B port(b0011) : DATA[0-7] */
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4210_GPE1(i), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(EXYNOS4210_GPE1(i), S3C_GPIO_PULL_NONE);
+ }
+ /* CAM B port(b0011) : PCLK, VSYNC, HREF, FIELD, CLCKOUT */
+ for (i = 0; i < 5; i++) {
+ s3c_gpio_cfgpin(EXYNOS4210_GPE0(i), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(EXYNOS4210_GPE0(i), S3C_GPIO_PULL_NONE);
+ }
+ /* note : driver strength to max is unnecessary */
+#ifdef CONFIG_VIDEO_M5MOLS
+ s3c_gpio_cfgpin(EXYNOS4_GPX0(5), S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(EXYNOS4_GPX0(5), S3C_GPIO_PULL_NONE);
+#endif
+}
+#endif
+
+static void __init smdkv310_smsc911x_init(void)
+{
+ u32 cs1;
+
+ /* configure nCS1 width to 16 bits */
+ cs1 = __raw_readl(S5P_SROM_BW) &
+ ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S5P_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S5P_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
+ (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
+ (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
+ (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
+ (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
+}
+
+#if defined(CONFIG_CMA)
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .name = "jpeg",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .name = "fimc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3
+ {
+ .name = "fimc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ .start = 0
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0
+ },
+#endif
+#if !defined(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION) && \
+ defined(CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1)
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL
+ {
+ .name = "mfc-normal",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_NORMAL * SZ_1K,
+ { .alignment = 1 << 17 },
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ { .alignment = 1 << 17 },
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ { .alignment = 1 << 17 },
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ { .alignment = 1 << 17 },
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_ROT
+ {
+ .name = "rot",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_ROT * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ {
+ .name = "b2",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "b1",
+ .size = 32 << 20,
+ { .alignment = 128 << 10 },
+ },
+ {
+ .name = "fw",
+ .size = 1 << 20,
+ { .alignment = 128 << 10 },
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT
+ {
+ .name = "tvout",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT * SZ_1K,
+ .start = 0
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ static struct cma_region regions_secure[] = {
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE
+ {
+ .name = "mfc-secure",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC_SECURE * SZ_1K,
+ {
+ .alignment = SZ_64M,
+ },
+ },
+#endif
+ {
+ .size = 0
+ },
+ };
+#else /* !CONFIG_EXYNOS_CONTENT_PATH_PROTECTION */
+ struct cma_region *regions_secure = NULL;
+#endif
+ static const char map[] __initconst =
+ "s3cfb.0=fimd;exynos4-fb.0=fimd;"
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;s3c-fimc.3=fimc3;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc.3=fimc3;"
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ "exynos-rot=rot;"
+#endif
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc/A=mfc0,mfc-secure;"
+ "s3c-mfc/B=mfc1,mfc-normal;"
+ "s3c-mfc/AB=mfc;"
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MFC
+ "s5p-mfc/f=fw;"
+ "s5p-mfc/a=b1;"
+ "s5p-mfc/b=b2;"
+#endif
+ "samsung-rp=srp;"
+ "s5p-jpeg=jpeg;"
+ "s5p-fimg2d=fimg2d;"
+ "s5p-tvout=tvout;"
+ "s5p-smem/mfc=mfc0,mfc-secure;"
+ "s5p-smem/fimc=fimc1;"
+ "s5p-smem/mfc-shm=mfc1,mfc-normal;"
+ "ion-exynos=fimd,fimc0,fimc1,fimc2,fimc3,fw,b1,b2;";
+
+ s5p_cma_region_reserve(regions, regions_secure, SZ_64M, map);
+}
+#endif
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkv310_bl_gpio_info = {
+ .no = EXYNOS4_GPD0(1),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkv310_bl_data = {
+ .pwm_id = 1,
+#if defined(CONFIG_LCD_LTE480WV)
+ .pwm_period_ns = 1000,
+#endif
+};
+
+static void __init smdkv310_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
+
+#if defined(CONFIG_CMA)
+ exynos4_reserve_mem();
+#else
+ s5p_reserve_mem(S5P_RANGE_MFC);
+#endif
+}
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimd0, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(2d, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(rot, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+#if defined CONFIG_VIDEO_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#elif defined CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_FB_S3C
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimd0).dev, &s5p_device_fimd0.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(2d).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ sysmmu_set_owner(&SYSMMU_PLATDEV(rot).dev, &exynos_device_rotator.dev);
+#endif
+}
+
+static void __init smdkv310_machine_init(void)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+ struct device *spi2_dev = &exynos_device_spi2.dev;
+#endif
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+ mipi_fb_init();
+#endif
+
+#if defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)
+ exynos_pd_disable(&exynos4_device_pd[PD_MFC].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_G3D].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_LCD0].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_LCD1].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_CAM].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_TV].dev);
+ exynos_pd_disable(&exynos4_device_pd[PD_GPS].dev);
+#elif defined(CONFIG_EXYNOS_DEV_PD)
+ /*
+ * These power domains should be always on
+ * without runtime pm support.
+ */
+ exynos_pd_enable(&exynos4_device_pd[PD_MFC].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_LCD0].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_LCD1].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_CAM].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_TV].dev);
+ exynos_pd_enable(&exynos4_device_pd[PD_GPS].dev);
+#endif
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ smdkv310_button_init();
+ smdkv310_smsc911x_init();
+
+#ifdef CONFIG_EXYNOS4_DEV_DWMCI
+ if (samsung_rev() != EXYNOS4210_REV_1_1)
+ exynos_dwmci_pdata.caps &= ~(MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR);
+ exynos_dwmci_set_platdata(&exynos_dwmci_pdata. 0);
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
+#endif
+#ifdef CONFIG_S5P_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HWMON
+ s3c_hwmon_set_platdata(&smdkv310_hwmon_pdata);
+#endif
+
+#ifdef CONFIG_FB_S3C
+ dev_set_name(&s5p_device_fimd0.dev, "s3cfb.0");
+ clk_add_alias("lcd", "exynos4-fb.0", "lcd", &s5p_device_fimd0.dev);
+ clk_add_alias("sclk_fimd", "exynos4-fb.0", "sclk_fimd", &s5p_device_fimd0.dev);
+#ifdef CONFIG_LCD_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+ s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&ams369fg06_data);
+#elif defined(CONFIG_FB_S5P_DUMMY_MIPI_LCD)
+ exynos4_fimd0_gpio_setup_24bpp();
+#else
+ s3cfb_set_platdata(NULL);
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_JPEG
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+ s5p_device_dsim.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+#endif
+#endif
+ samsung_bl_set(&smdkv310_bl_gpio_info, &smdkv310_bl_data);
+
+ samsung_keypad_set_platdata(&smdkv310_keypad_data);
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+#endif
+#ifdef CONFIG_S3C_DEV_ADC1
+ s3c24xx_ts1_set_platdata(&s3c_ts_platform);
+#endif
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(NULL);
+ s3c_fimc2_set_platdata(&fimc_plat);
+ s3c_fimc3_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ secmem.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C)
+ smdkv310_cam0_reset(1);
+#endif
+#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D)
+ smdkv310_cam1_reset(1);
+#endif
+#endif /* CONFIG_VIDEO_FIMC */
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ smdkv310_camera_config();
+ smdkv310_subdev_config();
+
+ dev_set_name(&s5p_device_fimc0.dev, "s3c-fimc.0");
+ dev_set_name(&s5p_device_fimc1.dev, "s3c-fimc.1");
+ dev_set_name(&s5p_device_fimc2.dev, "s3c-fimc.2");
+ dev_set_name(&s5p_device_fimc3.dev, "s3c-fimc.3");
+
+ clk_add_alias("fimc", "exynos4210-fimc.0", "fimc", &s5p_device_fimc0.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.0", "sclk_fimc",
+ &s5p_device_fimc0.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.1", "fimc", &s5p_device_fimc1.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.1", "sclk_fimc",
+ &s5p_device_fimc1.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.2", "fimc", &s5p_device_fimc2.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.2", "sclk_fimc",
+ &s5p_device_fimc2.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.3", "fimc", &s5p_device_fimc3.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.3", "sclk_fimc",
+ &s5p_device_fimc3.dev);
+
+ s3c_fimc_setname(0, "exynos4210-fimc");
+ s3c_fimc_setname(1, "exynos4210-fimc");
+ s3c_fimc_setname(2, "exynos4210-fimc");
+ s3c_fimc_setname(3, "exynos4210-fimc");
+ /* FIMC */
+ s3c_set_platdata(&s3c_fimc0_default_data,
+ sizeof(s3c_fimc0_default_data), &s5p_device_fimc0);
+ s3c_set_platdata(&s3c_fimc1_default_data,
+ sizeof(s3c_fimc1_default_data), &s5p_device_fimc1);
+ s3c_set_platdata(&s3c_fimc2_default_data,
+ sizeof(s3c_fimc2_default_data), &s5p_device_fimc2);
+ s3c_set_platdata(&s3c_fimc3_default_data,
+ sizeof(s3c_fimc3_default_data), &s5p_device_fimc3);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#ifdef CONFIG_VIDEO_S5P_MIPI_CSIS
+ s3c_set_platdata(&s5p_mipi_csis0_default_data,
+ sizeof(s5p_mipi_csis0_default_data), &s5p_device_mipi_csis0);
+ s3c_set_platdata(&s5p_mipi_csis1_default_data,
+ sizeof(s5p_mipi_csis1_default_data), &s5p_device_mipi_csis1);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_mipi_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#if defined(CONFIG_ITU_A) || defined(CONFIG_CSI_C)
+ smdkv310_cam0_reset(1);
+#endif
+#if defined(CONFIG_ITU_B) || defined(CONFIG_CSI_D)
+ smdkv310_cam1_reset(1);
+#endif
+#endif
+
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(NULL);
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X)
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ);
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimg2d.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_ROTATOR
+ exynos_device_rotator.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+
+#ifdef CONFIG_USB_EHCI_S5P
+ smdkv310_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdkv310_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdkv310_usbgadget_init();
+#endif
+
+ exynos_sysmmu_init();
+
+ platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
+
+#ifdef CONFIG_FB_S3C
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll",
+ 800 * MHZ);
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ sclk = clk_get(spi0_dev, "sclk_spi");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+
+ prnt = clk_get(spi0_dev, "mout_mpll");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+
+ if (!IS_ERR(sclk) && !IS_ERR(prnt))
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS4_GPB(1), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+ sclk = clk_get(spi2_dev, "sclk_spi");
+ if (IS_ERR(sclk))
+ dev_err(spi2_dev, "failed to get sclk for SPI-2\n");
+
+ prnt = clk_get(spi2_dev, "mout_mpll");
+ if (IS_ERR(prnt))
+ dev_err(spi2_dev, "failed to get prnt\n");
+
+ if (!IS_ERR(sclk) && !IS_ERR(prnt))
+ if (clk_set_parent(sclk, prnt))
+ printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
+ prnt->name, sclk->name);
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPC1(2), "SPI_CS2")) {
+ gpio_direction_output(EXYNOS4_GPC1(2), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPC1(2), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPC1(2), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(2, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi2_csi));
+ }
+ spi_register_board_info(spi2_board_info, ARRAY_SIZE(spi2_board_info));
+#endif
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+#endif
+}
+
+MACHINE_START(SMDKC210, "SMDKC210")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdkv310_map_io,
+ .init_machine = smdkv310_machine_init,
+ .timer = &exynos4_timer,
+MACHINE_END
+
+MACHINE_START(SMDKV310, "SMDKV310")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdkv310_map_io,
+ .init_machine = smdkv310_machine_init,
+ .timer = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-u1.c b/arch/arm/mach-exynos/mach-u1.c
new file mode 100644
index 0000000..9c026e0
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-u1.c
@@ -0,0 +1,7497 @@
+/* linux/arch/arm/mach-exynos4/mach-smdkc210.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio_event.h>
+#include <linux/lcd.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <linux/switch.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+#include <linux/sensor/k3g.h>
+#include <linux/sensor/k3dh.h>
+#include <linux/sensor/ak8975.h>
+#ifdef CONFIG_MACH_U1_BD
+#include <linux/sensor/cm3663.h>
+#include <linux/sensor/pas2m110.h>
+#endif
+#ifdef CONFIG_MACH_Q1_BD
+#include <linux/sensor/gp2a_analog.h>
+#endif
+#include <linux/pn544.h>
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+#include <linux/mfd/mc1n2_pdata.h>
+#endif
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT540E)
+#include <linux/i2c/mxt540e.h>
+#else
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC
+#include <linux/i2c/mxt224_gc.h>
+#else
+#include <linux/i2c/mxt224_u1.h>
+#endif
+#endif
+#include <linux/memblock.h>
+#include <linux/power_supply.h>
+#if defined(CONFIG_S5P_MEM_CMA)
+#include <linux/cma.h>
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/exynos4.h>
+#include <plat/clock.h>
+#include <plat/hwmon.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb-s5p.h>
+#include <plat/fimc.h>
+#include <plat/csis.h>
+#include <plat/gpio-cfg.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/keypad.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/iic.h>
+#include <plat/sysmmu.h>
+#include <plat/pd.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/media.h>
+#include <plat/udc-hs.h>
+#include <plat/s5p-clock.h>
+#include <plat/tvout.h>
+#include <plat/fimg2d.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+#include <plat/s3c64xx-spi.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/exynos-clock.h>
+#include <mach/media.h>
+#include <plat/regs-fb.h>
+
+#include <mach/dev-sysmmu.h>
+#include <mach/dev.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos-ion.h>
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#include <mach/mipi_ddi.h>
+#include <mach/dsim.h>
+#include <plat/fb-s5p.h>
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+#include <mach/spi-clocks.h>
+#endif
+
+#ifdef CONFIG_VIDEO_M5MO
+#include <media/m5mo_platform.h>
+#endif
+#ifdef CONFIG_VIDEO_S5K5BAFX
+#include <media/s5k5bafx_platform.h>
+#endif
+
+#if defined(CONFIG_EXYNOS4_SETUP_THERMAL)
+#include <plat/s5p-tmu.h>
+#include <mach/regs-tmu.h>
+#endif
+
+#ifdef CONFIG_SEC_DEV_JACK
+#include <linux/sec_jack.h>
+#endif
+
+#ifdef CONFIG_BT_BCM4330
+#include <mach/board-bluetooth-bcm.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_LD9040
+#include <linux/ld9040.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+#include <linux/mdnie.h>
+#endif
+
+#include <../../../drivers/video/samsung/s3cfb.h>
+#include "u1.h"
+
+#include <mach/sec_debug.h>
+
+#ifdef CONFIG_SAMSUNG_MHL
+#include <linux/irq.h>
+#include <linux/sii9234.h>
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_U1
+#include <linux/power/sec_battery_u1.h>
+#endif
+
+#ifdef CONFIG_SEC_THERMISTOR
+#include <mach/sec_thermistor.h>
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_U1
+#include <linux/power/max17042_fuelgauge_u1.h>
+#endif
+
+#ifdef CONFIG_CHARGER_MAX8922_U1
+#include <linux/power/max8922_charger_u1.h>
+#endif
+
+#ifdef CONFIG_SMB136_CHARGER_Q1
+#include <linux/power/smb136_charger_q1.h>
+#endif
+
+#ifdef CONFIG_SMB328_CHARGER
+#include <linux/power/smb328_charger.h>
+#endif
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+#include <linux/wacom_i2c.h>
+static struct wacom_g5_callbacks *wacom_callbacks;
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+#include <linux/i2c/touchkey_i2c.h>
+#endif
+
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#include <mach/tdmb_pdata.h>
+#endif
+
+#ifdef CONFIG_LEDS_MAX8997
+#include <linux/leds-max8997.h>
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI)
+#include <linux/phone_svn/ipc_spi.h>
+#include <linux/irq.h>
+#endif
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+#ifdef CONFIG_BT_BCM4330
+ .wake_peer = bcm_bt_lpm_exit_lpm_locked,
+#endif
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ .set_runstate = set_gps_uart_op,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+};
+
+#define WRITEBACK_ENABLED
+
+#ifdef CONFIG_VIDEO_FIMC
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+ */
+
+#ifdef CONFIG_VIDEO_M5MO
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ }
+
+static int m5mo_get_i2c_busnum(void)
+{
+#ifdef CONFIG_VIDEO_M5MO_USE_SWI2C
+ return 25;
+#else
+ return 0;
+#endif
+}
+
+static int m5mo_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_CAM_VGA_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_SENSOR_CORE, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_IO_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_15V, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_VT_CAM_15V)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_RESET, "ISP_RESET");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(ISP_RESET)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_8M_AF_EN, "GPK1");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(8M_AF_EN)\n");
+ return ret;
+ }
+
+ /* CAM_VT_nSTBY low */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "output VGA_nSTBY");
+
+ /* CAM_VT_nRST low */
+ gpio_direction_output(GPIO_CAM_VGA_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "output VGA_nRST");
+ udelay(10);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core");
+ /* No delay */
+
+ /* CAM_SENSOR_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_CAM_SENSOR_CORE, 1);
+ CAM_CHECK_ERR_RET(ret, "output senser_core");
+
+#if defined(CONFIG_MACH_Q1_BD)
+ udelay(120);
+#else
+ udelay(10);
+#endif
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output IO_EN");
+ /* it takes about 100us at least during level transition. */
+ udelay(160); /* 130us -> 160us */
+
+ /* VT_CORE_1.5V */
+ ret = gpio_direction_output(GPIO_VT_CAM_15V, 1);
+ CAM_CHECK_ERR_RET(ret, "output VT_CAM_1.5V");
+ udelay(20);
+
+#if defined(CONFIG_MACH_Q1_BD)
+ udelay(120);
+#endif
+
+ /* CAM_AF_2.8V */
+ ret = gpio_direction_output(GPIO_8M_AF_EN, 1);
+ CAM_CHECK_ERR(ret, "output AF");
+ mdelay(7);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_1.8v");
+ udelay(10);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp");
+ udelay(120); /* at least */
+
+ /* CAM_SENSOR_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_sensor_io");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable sensor_io");
+ udelay(30);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ udelay(70);
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ mdelay(4);
+
+ gpio_free(GPIO_CAM_VGA_nSTBY);
+ gpio_free(GPIO_CAM_VGA_nRST);
+ gpio_free(GPIO_CAM_SENSOR_CORE);
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_VT_CAM_15V);
+ gpio_free(GPIO_ISP_RESET);
+ gpio_free(GPIO_8M_AF_EN);
+ printk(KERN_DEBUG "%s: out\n", __func__);
+
+ return ret;
+}
+#ifdef CONFIG_SAMSUNG_MHL
+
+
+static void sii9234_cfg_gpio(void)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_AP_SDA_18V, S3C_GPIO_SFN(0x0));
+ s3c_gpio_setpull(GPIO_AP_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_AP_SCL_18V, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_AP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_MHL_WAKE_UP, S3C_GPIO_INPUT);
+ irq_set_irq_type(MHL_WAKEUP_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_setpull(GPIO_MHL_WAKE_UP, S3C_GPIO_PULL_DOWN);
+
+ gpio_request(GPIO_MHL_INT, "MHL_INT");
+ s5p_register_gpio_interrupt(GPIO_MHL_INT);
+ s3c_gpio_setpull(GPIO_MHL_INT, S3C_GPIO_PULL_DOWN);
+ irq_set_irq_type(MHL_INT_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_cfgpin(GPIO_MHL_INT, GPIO_MHL_INT_AF);
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+#else
+ if (system_rev < 7) {
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+ } else {
+ s3c_gpio_cfgpin(GPIO_HDMI_EN_REV07, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_HDMI_EN_REV07, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN_REV07, S3C_GPIO_PULL_NONE);
+ }
+#endif
+
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_MHL_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_SEL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_LOW);
+
+}
+
+void sii9234_power_onoff(bool on)
+{
+ pr_info("%s(%d)\n", __func__, on);
+
+ if (on) {
+ /*s3c_gpio_cfgpin(GPIO_HDMI_EN,S3C_GPIO_OUTPUT);*/
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+#else
+ if (system_rev < 7)
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+ else
+ gpio_set_value(GPIO_HDMI_EN_REV07, GPIO_LEVEL_HIGH);
+#endif
+
+ s3c_gpio_setpull(GPIO_AP_SCL_18V, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_AP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ } else {
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+#else
+ if (system_rev < 7)
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ else
+ gpio_set_value(GPIO_HDMI_EN_REV07, GPIO_LEVEL_LOW);
+#endif
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ }
+ pr_info("[MHL]%s : %d\n", __func__, on);
+}
+
+void sii9234_reset(void)
+{
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+
+}
+
+void mhl_usb_switch_control(bool on)
+{
+ pr_info("%s() [MHL] USB path change : %s\n",
+ __func__, on ? "MHL" : "USB");
+ if (on == 1) {
+ if (gpio_get_value(GPIO_MHL_SEL))
+ pr_info("[MHL] GPIO_MHL_SEL :already 1\n");
+ else {
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_HIGH);
+ /* sii9234_cfg_power(1); // onegun */
+ /* sii9234_init(); // onegun */
+ }
+ } else {
+ if (!gpio_get_value(GPIO_MHL_SEL))
+ pr_info("[MHL] GPIO_MHL_SEL :already0\n");
+ else {
+ /* sii9234_cfg_power(0); // onegun */
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_LOW);
+ }
+ }
+}
+
+static struct sii9234_platform_data sii9234_pdata = {
+ .init = sii9234_cfg_gpio,
+ .mhl_sel = mhl_usb_switch_control,
+ .hw_onoff = sii9234_power_onoff,
+ .hw_reset = sii9234_reset,
+ .enable_vbus = NULL,
+ .vbus_present = NULL,
+};
+
+static struct i2c_board_info __initdata tuna_i2c15_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("sii9234_mhl_tx", 0x72>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_tpi", 0x7A>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_hdmi_rx", 0x92>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_cbus", 0xC8>>1),
+ .platform_data = &sii9234_pdata,
+ },
+};
+
+#define I2C_BUS_ID_MHL 15
+static struct i2c_gpio_platform_data gpio_i2c_data15 = {
+ .sda_pin = GPIO_MHL_SDA_18V,
+ .scl_pin = GPIO_MHL_SCL_18V,
+ .udelay = 2,
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+struct platform_device s3c_device_i2c15 = {
+ .name = "i2c-gpio",
+ .id = I2C_BUS_ID_MHL,
+ .dev = {
+ .platform_data = &gpio_i2c_data15,
+ }
+};
+
+#endif
+
+static int m5mo_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_8M_AF_EN, "GPK1");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(8M_AF_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_RESET, "ISP_RESET");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(ISP_RESET)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_SENSOR_CORE, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_COR)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_15V, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_VT_CAM_15V)\n");
+ return ret;
+ }
+
+ /* s3c_i2c0_force_stop(); */
+
+ mdelay(3);
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR(ret, "output reset");
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ mdelay(3); /* fix without seeing signal form for kor. */
+#else
+ mdelay(2);
+#endif
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_AF_2.8V */
+ /* 8M_AF_2.8V_EN */
+ ret = gpio_direction_output(GPIO_8M_AF_EN, 0);
+ CAM_CHECK_ERR(ret, "output AF");
+
+ /* CAM_SENSOR_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_sensor_io");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable, sensor_io");
+ udelay(10);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp");
+ udelay(500); /* 100us -> 500us */
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_1.8v");
+ udelay(250); /* 10us -> 250us */
+
+ /* VT_CORE_1.5V */
+ ret = gpio_direction_output(GPIO_VT_CAM_15V, 0);
+ CAM_CHECK_ERR(ret, "output VT_CAM_1.5V");
+ udelay(300); /*10 -> 300 us */
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 0);
+ CAM_CHECK_ERR(ret, "output IO_EN");
+ udelay(800);
+
+ /* CAM_SENSOR_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_CAM_SENSOR_CORE, 0);
+ CAM_CHECK_ERR(ret, "output SENSOR_CORE");
+ udelay(5);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable isp_core");
+
+#if defined(CONFIG_MACH_Q1_BD)
+ mdelay(250);
+#endif
+
+ gpio_free(GPIO_8M_AF_EN);
+ gpio_free(GPIO_ISP_RESET);
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_CAM_SENSOR_CORE);
+ gpio_free(GPIO_VT_CAM_15V);
+
+ return ret;
+}
+
+int s3c_csis_power(int enable)
+{
+ struct regulator *regulator;
+ int ret = 0;
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ /* mipi_1.1v ,mipi_1.8v are always powered-on.
+ * If they are off, we then power them on.
+ */
+ if (enable) {
+ /* VMIPI_1.1V */
+ regulator = regulator_get(NULL, "vmipi_1.1v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.1v is off. so ON\n",
+ __func__);
+ ret = regulator_enable(regulator);
+ CAM_CHECK_ERR(ret, "enable vmipi_1.1v");
+ }
+ regulator_put(regulator);
+
+ /* VMIPI_1.8V */
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.8v is off. so ON\n",
+ __func__);
+ ret = regulator_enable(regulator);
+ CAM_CHECK_ERR(ret, "enable vmipi_1.8v");
+ }
+ regulator_put(regulator);
+ }
+ printk(KERN_DEBUG "%s: out\n", __func__);
+
+ return 0;
+
+error_out:
+ printk(KERN_ERR "%s: ERROR: failed to check mipi-power\n", __func__);
+ return 0;
+}
+
+#if defined(CONFIG_MACH_Q1_BD)
+static bool is_torch;
+#endif
+
+static int m5mo_flash_power(int enable)
+{
+ struct regulator *flash = regulator_get(NULL, "led_flash");
+ struct regulator *movie = regulator_get(NULL, "led_movie");
+
+ if (enable) {
+
+#if defined(CONFIG_MACH_Q1_BD)
+ if (regulator_is_enabled(movie)) {
+ printk(KERN_DEBUG "%s: m5mo_torch set~~~~", __func__);
+ is_torch = true;
+ goto torch_exit;
+ }
+ is_torch = false;
+#endif
+ regulator_set_current_limit(flash, 490000, 530000);
+ regulator_enable(flash);
+ regulator_set_current_limit(movie, 90000, 110000);
+ regulator_enable(movie);
+ } else {
+
+#if defined(CONFIG_MACH_Q1_BD)
+ if (is_torch)
+ goto torch_exit;
+#endif
+
+ if (regulator_is_enabled(flash))
+ regulator_disable(flash);
+ if (regulator_is_enabled(movie))
+ regulator_disable(movie);
+ }
+torch_exit:
+ regulator_put(flash);
+ regulator_put(movie);
+
+ return 0;
+}
+
+static int m5mo_power(int enable)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s %s\n", __func__, enable ? "on" : "down");
+ if (enable) {
+ ret = m5mo_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = m5mo_power_down();
+
+ ret = s3c_csis_power(enable);
+ m5mo_flash_power(enable);
+
+error_out:
+ return ret;
+}
+
+static int m5mo_config_isp_irq(void)
+{
+ s3c_gpio_cfgpin(GPIO_ISP_INT, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_ISP_INT, S3C_GPIO_PULL_NONE);
+ return 0;
+}
+
+static struct m5mo_platform_data m5mo_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .config_isp_irq = m5mo_config_isp_irq,
+ .irq = IRQ_EINT(13),
+};
+
+static struct i2c_board_info m5mo_i2c_info = {
+ I2C_BOARD_INFO("M5MO", 0x1F),
+ .platform_data = &m5mo_plat,
+};
+
+static struct s3c_platform_camera m5mo = {
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .get_i2c_busnum = m5mo_get_i2c_busnum,
+ .cam_power = m5mo_power, /*smdkv310_mipi_cam0_reset, */
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT */
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &m5mo_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif /* #ifdef CONFIG_VIDEO_M5MO */
+
+#ifdef CONFIG_VIDEO_S5K5BAFX
+static int s5k5bafx_get_i2c_busnum(void)
+{
+ return 12;
+}
+
+static int s5k5bafx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ /* printk("%s: in\n", __func__); */
+
+ ret = gpio_request(GPIO_ISP_RESET, "ISP_RESET");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(ISP_RESET)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_15V, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_VT_CAM_15V)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ if (system_rev >= 9) {
+#endif
+ s3c_gpio_setpull(VT_CAM_SDA_18V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(VT_CAM_SCL_18V, S3C_GPIO_PULL_NONE);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ }
+#endif
+
+ /* ISP_RESET low */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ udelay(100);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable isp_core");
+ udelay(10);
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output io_en");
+ udelay(300); /* don't change me */
+
+ /* VT_CORE_1.5V */
+ ret = gpio_direction_output(GPIO_VT_CAM_15V, 1);
+ CAM_CHECK_ERR_RET(ret, "output vt_15v");
+ udelay(100);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp");
+ udelay(10);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_1.8v");
+ udelay(10);
+
+ /* CAM_VGA_nSTBY */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "output VGA_nSTBY");
+ udelay(50);
+
+ /* Mclk */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ udelay(100);
+
+ /* CAM_VGA_nRST */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "output VGA_nRST");
+ mdelay(2);
+
+ gpio_free(GPIO_ISP_RESET);
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_VT_CAM_15V);
+ gpio_free(GPIO_CAM_VGA_nSTBY);
+ gpio_free(GPIO_CAM_VGA_nRST);
+
+ return 0;
+}
+
+static int s5k5bafx_power_off(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ /* printk("n%s: in\n", __func__); */
+
+ ret = gpio_request(GPIO_CAM_VGA_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_15V, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_VT_CAM_15V)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+
+ /* CAM_VGA_nRST */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nRST, 0);
+ CAM_CHECK_ERR(ret, "output VGA_nRST");
+ udelay(100);
+
+ /* Mclk */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_VGA_nSTBY */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "output VGA_nSTBY");
+ udelay(20);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_1.8v");
+ udelay(10);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp");
+ udelay(10);
+
+ /* VT_CORE_1.5V */
+ ret = gpio_direction_output(GPIO_VT_CAM_15V, 0);
+ CAM_CHECK_ERR(ret, "output vt_1.5v");
+ udelay(10);
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 0);
+ CAM_CHECK_ERR(ret, "output io_en");
+ udelay(10);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable isp_core");
+
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ if (system_rev >= 9) {
+#endif
+ gpio_direction_input(VT_CAM_SDA_18V);
+ s3c_gpio_setpull(VT_CAM_SDA_18V, S3C_GPIO_PULL_DOWN);
+ gpio_direction_input(VT_CAM_SCL_18V);
+ s3c_gpio_setpull(VT_CAM_SCL_18V, S3C_GPIO_PULL_DOWN);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ }
+#endif
+
+#if defined(CONFIG_MACH_Q1_BD)
+ mdelay(350);
+#endif
+
+ gpio_free(GPIO_CAM_VGA_nRST);
+ gpio_free(GPIO_CAM_VGA_nSTBY);
+ gpio_free(GPIO_VT_CAM_15V);
+ gpio_free(GPIO_CAM_IO_EN);
+
+ return 0;
+}
+
+static int s5k5bafx_power(int onoff)
+{
+ int ret = 0;
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ u32 cfg = 0;
+#endif
+ printk(KERN_INFO "%s(): %s\n", __func__, onoff ? "on" : "down");
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ cfg = readl(S5P_VA_GPIO2 + 0x002c);
+#endif
+
+ if (onoff) {
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ writel(cfg | 0x0080, S5P_VA_GPIO2 + 0x002c);
+#endif
+
+ ret = s5k5bafx_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else {
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ writel(cfg & 0xff3f, S5P_VA_GPIO2 + 0x002c);
+#endif
+ ret = s5k5bafx_power_off();
+ /* s3c_i2c0_force_stop(); *//* DSLIM. Should be implemented */
+ }
+
+ ret = s3c_csis_power(onoff);
+
+error_out:
+ return ret;
+}
+
+static struct s5k5bafx_platform_data s5k5bafx_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+};
+
+static struct i2c_board_info s5k5bafx_i2c_info = {
+ I2C_BOARD_INFO("S5K5BAFX", 0x5A >> 1),
+ .platform_data = &s5k5bafx_plat,
+};
+
+static struct s3c_platform_camera s5k5bafx = {
+ .id = CAMERA_CSI_D,
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ .get_i2c_busnum = s5k5bafx_get_i2c_busnum,
+ .info = &s5k5bafx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_name = "sclk_cam0",
+ .clk_rate = 24000000,
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = s5k5bafx_power,
+};
+#endif
+
+#ifdef WRITEBACK_ENABLED
+static int get_i2c_busnum_writeback(void)
+{
+ return 0;
+}
+
+static struct i2c_board_info writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .get_i2c_busnum = get_i2c_busnum_writeback,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 800,
+ .width = 480,
+ .height = 800,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 480,
+ .height = 800,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+void cam_cfg_gpio(struct platform_device *pdev)
+{
+ int ret = 0;
+ printk(KERN_INFO "\n\n\n%s: pdev->id=%d\n", __func__, pdev->id);
+
+ if (pdev->id != 0)
+ return;
+
+#ifdef CONFIG_VIDEO_S5K5BAFX
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ if (system_rev >= 9) {
+#endif
+ /* Rev0.9 */
+ ret = gpio_direction_input(VT_CAM_SDA_18V);
+ CAM_CHECK_ERR(ret, "VT_CAM_SDA_18V");
+ s3c_gpio_setpull(VT_CAM_SDA_18V, S3C_GPIO_PULL_DOWN);
+
+ ret = gpio_direction_input(VT_CAM_SCL_18V);
+ CAM_CHECK_ERR(ret, "VT_CAM_SCL_18V");
+ s3c_gpio_setpull(VT_CAM_SCL_18V, S3C_GPIO_PULL_DOWN);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ }
+#endif
+#endif
+}
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+#ifdef CONFIG_ITU_A
+ .default_cam = CAMERA_PAR_A,
+#endif
+#ifdef CONFIG_ITU_B
+ .default_cam = CAMERA_PAR_B,
+#endif
+#ifdef CONFIG_CSI_C
+ .default_cam = CAMERA_CSI_C,
+#endif
+#ifdef CONFIG_CSI_D
+ .default_cam = CAMERA_CSI_D,
+#endif
+ .camera = {
+#ifdef CONFIG_VIDEO_M5MO
+ &m5mo,
+#endif
+#ifdef CONFIG_VIDEO_S5K5BAFX
+ &s5k5bafx,
+#endif
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+ },
+ .hw_ver = 0x51,
+ .cfg_gpio = cam_cfg_gpio,
+};
+#endif /* CONFIG_VIDEO_FIMC */
+
+static DEFINE_MUTEX(notify_lock);
+
+#define DEFINE_MMC_CARD_NOTIFIER(num) \
+static void (*hsmmc##num##_notify_func)(struct platform_device *, int state); \
+static int ext_cd_init_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func); \
+ hsmmc##num##_notify_func = notify_func; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+} \
+static int ext_cd_cleanup_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func != notify_func); \
+ hsmmc##num##_notify_func = NULL; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+}
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ DEFINE_MMC_CARD_NOTIFIER(3)
+#endif
+
+/*
+ * call this when you need sd stack to recognize insertion or removal of card
+ * that can't be told by SDHCI regs
+ */
+
+void mmc_force_presence_change(struct platform_device *pdev)
+{
+ void (*notify_func)(struct platform_device *, int state) = NULL;
+ mutex_lock(&notify_lock);
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ printk("---------test logs pdev : %p s3c_device_hsmmc3 %p \n",
+ pdev, &s3c_device_hsmmc3);
+ if (pdev == &s3c_device_hsmmc3) {
+ notify_func = hsmmc3_notify_func;
+ printk("---------test logs notify_func : %p \n", notify_func);
+ }
+#endif
+
+ if (notify_func)
+ notify_func(pdev, 1);
+ else
+ pr_warn("%s: called for device with no notifier\n", __func__);
+ mutex_unlock(&notify_lock);
+}
+EXPORT_SYMBOL_GPL(mmc_force_presence_change);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata exynos4_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata exynos4_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = EXYNOS4_GPX3(4),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .vmmc_name = "vtf_2.8v",
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata exynos4_hsmmc3_pdata __initdata = {
+/* For Wi-Fi */
+#if 0
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+#else
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+ .ext_cd_init = ext_cd_init_hsmmc3,
+ .ext_cd_cleanup = ext_cd_cleanup_hsmmc3,
+#endif
+};
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50 | MMC_CAP_CMD23,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_CMD23,
+#endif
+ .int_power_gpio = GPIO_XMMC0_CDn,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 30,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 267 * 1000000, /* 266 Mhz */
+};
+#endif
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_LCD_AMS369FG06)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ err = gpio_request(EXYNOS4_GPX0(6), "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_free(EXYNOS4_GPX0(6));
+
+ return 1;
+}
+
+static struct lcd_platform_data ams369fg06_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = (void *)&ams369fg06_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd0.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win2 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_WA101S)
+static void lcd_wa101s_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_wa101s_data = {
+ .set_power = lcd_wa101s_set_power,
+};
+
+static struct platform_device smdkc210_lcd_wa101s = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_wa101s_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1366,
+ .yres = 768,
+ },
+ .virtual_x = 1366,
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#ifndef CONFIG_LCD_WA101S /* temporarily disables window1 */
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1366,
+ .yres = 768,
+ },
+ .virtual_x = 1366,
+ .virtual_y = 768 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+#elif defined(CONFIG_LCD_LTE480WV)
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_WA101S) || \
+ defined(CONFIG_LCD_LTE480WV)
+ .win[0] = &smdkc210_fb_win0,
+#ifndef CONFIG_LCD_WA101S /* temporarily disables window1 */
+ .win[1] = &smdkc210_fb_win1,
+#endif
+#endif
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_AMS369FG06)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN |
+ VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_WA101S)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_LTE480WV)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#endif
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x0,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {
+ .modalias = "tdmbspi",
+ .platform_data = NULL,
+ .max_speed_hz = 5000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ },
+#elif defined(CONFIG_ISDBT_FC8100)
+ {
+ .modalias = "isdbtspi",
+ .platform_data = NULL,
+ .max_speed_hz = 400000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = (SPI_MODE_0|SPI_CS_HIGH),
+ .controller_data = &spi0_csi[0],
+ },
+
+#elif defined(CONFIG_PHONE_IPC_SPI)
+ {
+ .modalias = "ipc_spi",
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 12*1000*1000,
+ .mode = SPI_MODE_1,
+ .controller_data = &spi0_csi[0],
+ },
+#else
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+#endif
+};
+#endif
+
+#if defined(CONFIG_PHONE_IPC_SPI)
+static void ipc_spi_cfg_gpio(void);
+
+static struct ipc_spi_platform_data ipc_spi_data = {
+ .gpio_ipc_mrdy = GPIO_IPC_MRDY,
+ .gpio_ipc_srdy = GPIO_IPC_SRDY,
+ .gpio_ipc_sub_mrdy = GPIO_IPC_SUB_MRDY,
+ .gpio_ipc_sub_srdy = GPIO_IPC_SUB_SRDY,
+
+ .cfg_gpio = ipc_spi_cfg_gpio,
+};
+
+static struct resource ipc_spi_res[] = {
+ [0] = {
+ .start = IRQ_IPC_SRDY,
+ .end = IRQ_IPC_SRDY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ipc_spi_device = {
+ .name = "onedram",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ipc_spi_res),
+ .resource = ipc_spi_res,
+ .dev = {
+ .platform_data = &ipc_spi_data,
+ },
+};
+
+static void ipc_spi_cfg_gpio(void)
+{
+ int err = 0;
+
+ unsigned gpio_ipc_mrdy = ipc_spi_data.gpio_ipc_mrdy;
+ unsigned gpio_ipc_srdy = ipc_spi_data.gpio_ipc_srdy;
+ unsigned gpio_ipc_sub_mrdy = ipc_spi_data.gpio_ipc_sub_mrdy;
+ unsigned gpio_ipc_sub_srdy = ipc_spi_data.gpio_ipc_sub_srdy;
+
+ err = gpio_request(gpio_ipc_mrdy, "IPC_MRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_MRDY", err);
+ } else {
+ gpio_direction_output(gpio_ipc_mrdy, 0);
+ s3c_gpio_setpull(gpio_ipc_mrdy, S3C_GPIO_PULL_DOWN);
+ }
+
+ err = gpio_request(gpio_ipc_srdy, "IPC_SRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SRDY", err);
+ } else {
+ gpio_direction_input(gpio_ipc_srdy);
+ s3c_gpio_cfgpin(gpio_ipc_srdy, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_srdy, S3C_GPIO_PULL_NONE);
+ }
+
+ err = gpio_request(gpio_ipc_sub_mrdy, "IPC_SUB_MRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SUB_MRDY", err);
+ } else {
+ gpio_direction_output(gpio_ipc_sub_mrdy, 0);
+ s3c_gpio_setpull(gpio_ipc_sub_mrdy, S3C_GPIO_PULL_DOWN);
+ }
+
+ err = gpio_request(gpio_ipc_sub_srdy, "IPC_SUB_SRDY");
+ if (err) {
+ printk(KERN_ERR "ipc_spi_cfg_gpio - fail to request gpio %s : %d\n",
+ "IPC_SUB_SRDY", err);
+ } else {
+ gpio_direction_input(gpio_ipc_sub_srdy);
+ s3c_gpio_cfgpin(gpio_ipc_sub_srdy, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(gpio_ipc_sub_srdy, S3C_GPIO_PULL_NONE);
+ }
+
+ irq_set_irq_type(gpio_to_irq(GPIO_IPC_SRDY), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(GPIO_IPC_SUB_SRDY), IRQ_TYPE_EDGE_RISING);
+}
+#endif
+
+#ifdef CONFIG_FB_S5P
+unsigned int lcdtype;
+static int __init lcdtype_setup(char *str)
+{
+ get_option(&str, &lcdtype);
+ return 1;
+}
+__setup("lcdtype=", lcdtype_setup);
+
+#ifdef CONFIG_FB_S5P_LD9040
+unsigned int ld9040_lcdtype;
+static int __init ld9040_lcdtype_setup(char *str)
+{
+ get_option(&str, &ld9040_lcdtype);
+ return 1;
+}
+
+__setup("ld9040.get_lcdtype=0x", ld9040_lcdtype_setup);
+
+static int lcd_cfg_gpio(void)
+{
+ int i, f3_end = 4;
+
+ for (i = 0; i < 8; i++) {
+ /* set GPF0,1,2[0:7] for RGB Interface and Data line (32bit) */
+ s3c_gpio_cfgpin(EXYNOS4_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF0(i), S3C_GPIO_PULL_NONE);
+
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < f3_end; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+#ifdef MAX_DRVSTR
+ /* drive strength to max */
+ writel(0xffffffff, S5P_VA_GPIO + 0x18c);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1ac);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xffffff, S5P_VA_GPIO + 0x1ec);
+#else
+ /* drive strength to 2X */
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x18c);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1ac);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xaaaaaa, S5P_VA_GPIO + 0x1ec);
+#endif
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+#else
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(3), S3C_GPIO_PULL_NONE);
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY0(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4210_GPE2(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4210_GPE2(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(1), S3C_GPIO_PULL_NONE);
+#endif
+
+ return 0;
+}
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ struct regulator *regulator;
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return 0;
+ }
+
+ if (enable) {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+ }
+
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ reset_gpio = EXYNOS4_GPY4(5);
+#else
+ reset_gpio = EXYNOS4_GPX1(3);
+#endif
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_request(reset_gpio, "MLCD_RST");
+
+ gpio_direction_output(reset_gpio, 1);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 1);
+
+ gpio_free(reset_gpio);
+
+ return 1;
+}
+
+static int lcd_gpio_cfg_earlysuspend(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ reset_gpio = EXYNOS4_GPY4(5);
+#else
+ reset_gpio = EXYNOS4_GPX1(3);
+#endif
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+
+ gpio_free(reset_gpio);
+
+ return 0;
+}
+
+static int lcd_gpio_cfg_lateresume(struct lcd_device *ld)
+{
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+#else
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(3), S3C_GPIO_PULL_NONE);
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY0(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4210_GPE2(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4210_GPE2(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(1), S3C_GPIO_PULL_NONE);
+#endif
+
+ return 0;
+}
+
+static struct s3cfb_lcd ld9040_info = {
+ .width = 480,
+ .height = 800,
+ .p_width = 56,
+ .p_height = 93,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 16,
+ .h_bp = 14,
+ .h_sw = 2,
+ .v_fp = 10,
+ .v_fpe = 1,
+ .v_bp = 4,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+static struct lcd_platform_data ld9040_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .gpio_cfg_earlysuspend = lcd_gpio_cfg_earlysuspend,
+ .gpio_cfg_lateresume = lcd_gpio_cfg_lateresume,
+ /* it indicates whether lcd panel is enabled from u-boot. */
+ .lcd_enabled = 1,
+ .reset_delay = 20, /* 10ms */
+ .power_on_delay = 20, /* 20ms */
+ .power_off_delay = 200, /* 120ms */
+ .pdata = &u1_panel_data,
+};
+
+#define LCD_BUS_NUM 3
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define DISPLAY_CS EXYNOS4_GPY4(3)
+#else
+#define DISPLAY_CS EXYNOS4_GPY0(3)
+#endif
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define DISPLAY_CLK EXYNOS4_GPY3(1)
+#define DISPLAY_SI EXYNOS4_GPY3(3)
+#else
+#define DISPLAY_CLK EXYNOS4210_GPE2(3)
+#define DISPLAY_SI EXYNOS4_GPX1(1)
+#endif
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device ld9040_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+ .lcd = &ld9040_info,
+};
+
+/* reading with 3-WIRE SPI with GPIO */
+static inline void setcs(u8 is_on)
+{
+ gpio_set_value(DISPLAY_CS, is_on);
+}
+
+static inline void setsck(u8 is_on)
+{
+ gpio_set_value(DISPLAY_CLK, is_on);
+}
+
+static inline void setmosi(u8 is_on)
+{
+ gpio_set_value(DISPLAY_SI, is_on);
+}
+
+static inline unsigned int getmiso(void)
+{
+ return !!gpio_get_value(DISPLAY_SI);
+}
+
+static inline void setmosi2miso(u8 is_on)
+{
+ if (is_on)
+ s3c_gpio_cfgpin(DISPLAY_SI, S3C_GPIO_INPUT);
+ else
+ s3c_gpio_cfgpin(DISPLAY_SI, S3C_GPIO_OUTPUT);
+}
+
+struct spi_ops ops = {
+ .setcs = setcs,
+ .setsck = setsck,
+ .setmosi = setmosi,
+ .setmosi2miso = setmosi2miso,
+ .getmiso = getmiso,
+};
+
+static void __init ld9040_fb_init(void)
+{
+ struct ld9040_panel_data *pdata;
+
+ strcpy(spi_board_info[0].modalias, "ld9040");
+ spi_board_info[0].platform_data = (void *)&ld9040_platform_data;
+
+ lcdtype = max(ld9040_lcdtype, lcdtype);
+
+ if (lcdtype == LCDTYPE_SM2_A2)
+ ld9040_platform_data.pdata = &u1_panel_data_a2;
+ else if (lcdtype == LCDTYPE_M2)
+ ld9040_platform_data.pdata = &u1_panel_data_m2;
+
+ pdata = ld9040_platform_data.pdata;
+ pdata->ops = &ops;
+
+ printk(KERN_INFO "%s :: lcdtype=%d\n", __func__, lcdtype);
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ if (!ld9040_platform_data.lcd_enabled)
+ lcd_cfg_gpio();
+ s3cfb_set_platdata(&fb_platform_data);
+}
+#endif
+
+#ifdef CONFIG_FB_S5P_NT35560
+static int lcd_cfg_gpio(void)
+{
+ int i, f3_end = 4;
+
+ for (i = 0; i < 8; i++) {
+ /* set GPF0,1,2[0:7] for RGB Interface and Data line (32bit) */
+ s3c_gpio_cfgpin(EXYNOS4_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF0(i), S3C_GPIO_PULL_NONE);
+
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < f3_end; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+#ifdef MAX_DRVSTR
+ /* drive strength to max */
+ writel(0xffffffff, S5P_VA_GPIO + 0x18c);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1ac);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xffffff, S5P_VA_GPIO + 0x1ec);
+#else
+ /* drive strength to 2X */
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x18c);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1ac);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xaaaaaa, S5P_VA_GPIO + 0x1ec);
+#endif
+
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ struct regulator *regulator;
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return 0;
+ }
+
+ if (enable) {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "vlcd_1.8v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_1.8v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+ }
+
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+ reset_gpio = EXYNOS4_GPY4(5);
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_request(reset_gpio, "MLCD_RST");
+
+ gpio_direction_output(reset_gpio, 1);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 1);
+
+ gpio_free(reset_gpio);
+
+ return 1;
+}
+
+static int lcd_gpio_cfg_earlysuspend(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+ reset_gpio = EXYNOS4_GPY4(5);
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+
+ gpio_free(reset_gpio);
+
+ return 0;
+}
+
+static int lcd_gpio_cfg_lateresume(struct lcd_device *ld)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static struct s3cfb_lcd nt35560_info = {
+ .width = 480,
+ .height = 800,
+ .p_width = 52,
+ .p_height = 86,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 10,
+ .h_bp = 10,
+ .h_sw = 10,
+ .v_fp = 9,
+ .v_fpe = 1,
+ .v_bp = 4,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+static struct lcd_platform_data nt35560_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .gpio_cfg_earlysuspend = lcd_gpio_cfg_earlysuspend,
+ .gpio_cfg_lateresume = lcd_gpio_cfg_lateresume,
+ /* it indicates whether lcd panel is enabled from u-boot. */
+ .lcd_enabled = 1,
+ .reset_delay = 10, /* 10ms */
+ .power_on_delay = 10, /* 10ms */
+ .power_off_delay = 150, /* 150ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPY4(3)
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+#define DISPLAY_CLK EXYNOS4_GPY3(1)
+#define DISPLAY_SI EXYNOS4_GPY3(3)
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device nt35560_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+ .lcd = &nt35560_info,
+};
+
+static void __init nt35560_fb_init(void)
+{
+ struct ld9040_panel_data *pdata;
+
+ strcpy(spi_board_info[0].modalias, "nt35560");
+ spi_board_info[0].platform_data = (void *)&nt35560_platform_data;
+
+ pdata = nt35560_platform_data.pdata;
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ if (!nt35560_platform_data.lcd_enabled)
+ lcd_cfg_gpio();
+ s3cfb_set_platdata(&fb_platform_data);
+}
+#endif
+
+#ifdef CONFIG_FB_S5P_AMS369FG06
+static struct s3c_platform_fb ams369fg06_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = NULL,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+static struct platform_device mdnie_device = {
+ .name = "mdnie",
+ .id = -1,
+ .dev = {
+ .parent = &exynos4_device_pd[PD_LCD0].dev,
+ },
+};
+#endif
+
+#endif
+
+static struct platform_device u1_regulator_consumer = {
+ .name = "u1-regulator-consumer",
+ .id = -1,
+};
+
+#ifdef CONFIG_REGULATOR_MAX8997
+static struct regulator_consumer_supply ldo1_supply[] = {
+ REGULATOR_SUPPLY("vadc_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("vusb_1.1v", "usb_otg"),
+ REGULATOR_SUPPLY("vmipi_1.1v", "m5mo"),
+ REGULATOR_SUPPLY("vmipi_1.1v", NULL),
+};
+
+static struct regulator_consumer_supply ldo4_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vhsic", NULL),
+};
+
+static struct regulator_consumer_supply ldo7_supply[] = {
+ REGULATOR_SUPPLY("cam_isp", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vusb_3.3v", NULL),
+};
+
+#if defined(CONFIG_S5PV310_HI_ARMCLK_THAN_1_2GHZ)
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vpll_1.2v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vpll_1.1v", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.0v", NULL),
+};
+
+#ifdef CONFIG_MACH_Q1_BD
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vlcd_2.2v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vled", NULL),
+};
+
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_io", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("touch_led", NULL),
+};
+
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vddq_m1m2", NULL),
+};
+
+static struct regulator_consumer_supply buck1_supply[] = {
+ REGULATOR_SUPPLY("vdd_arm", NULL),
+};
+
+static struct regulator_consumer_supply buck2_supply[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+};
+
+static struct regulator_consumer_supply buck3_supply[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+};
+
+static struct regulator_consumer_supply buck4_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_core", NULL),
+};
+
+static struct regulator_consumer_supply buck7_supply[] = {
+ REGULATOR_SUPPLY("vcc_sub", NULL),
+};
+
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+static struct regulator_consumer_supply led_flash_supply[] = {
+ REGULATOR_SUPPLY("led_flash", NULL),
+};
+
+static struct regulator_consumer_supply led_movie_supply[] = {
+ REGULATOR_SUPPLY("led_movie", NULL),
+};
+
+#if defined(CONFIG_MACH_Q1_BD)
+static struct regulator_consumer_supply led_torch_supply[] = {
+ REGULATOR_SUPPLY("led_torch", NULL),
+};
+#endif /* CONFIG_MACH_Q1_BD */
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = \
+ (_disabled == -1 ? 0 : _disabled),\
+ .enabled = \
+ (_disabled == -1 ? 0 : !(_disabled)),\
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo1, "VADC_3.3V_C210", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo3, "VUSB_1.1V", 1100000, 1100000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo4, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+REGULATOR_INIT(ldo5, "VHSIC_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo5, "VHSIC_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo7, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VUSB_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_S5PV310_HI_ARMCLK_THAN_1_2GHZ)
+REGULATOR_INIT(ldo10, "VPLL_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo10, "VPLL_1.1V", 1100000, 1100000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo11, "TOUCH_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_Q1_BD)
+REGULATOR_INIT(ldo13, "VCC_3.0V_LCD", 3100000, 3100000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo13, "VCC_3.0V_LCD", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+#if defined(CONFIG_MACH_Q1_BD)
+REGULATOR_INIT(ldo14, "VCC_2.2V_LCD", 2200000, 2200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo14, "VCC_2.8V_MOTOR", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo15, "LED_A_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, -1);
+REGULATOR_INIT(ldo16, "CAM_SENSOR_IO_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_Q1_BD)
+REGULATOR_INIT(ldo18, "TOUCH_LED_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo18, "TOUCH_LED_3.3V", 3000000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, 1);
+#endif
+REGULATOR_INIT(ldo21, "VDDQ_M1M2_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+
+
+static struct regulator_init_data buck1_init_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 650000,
+ .max_uV = 2225000,
+ .always_on = 1,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck1_supply[0],
+};
+
+static struct regulator_init_data buck2_init_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 650000,
+ .max_uV = 2225000,
+ .always_on = 1,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck2_supply[0],
+};
+
+static struct regulator_init_data buck3_init_data = {
+ .constraints = {
+ .name = "G3D_1.1V",
+ .min_uV = 900000,
+ .max_uV = 1200000,
+ .always_on = 0,
+ .boot_on = 0,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck3_supply[0],
+};
+
+static struct regulator_init_data buck4_init_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck4_supply[0],
+};
+
+static struct regulator_init_data buck5_init_data = {
+ .constraints = {
+ .name = "VMEM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .uV = 1200000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data buck7_init_data = {
+ .constraints = {
+ .name = "VCC_SUB_2.0V",
+ .min_uV = 2000000,
+ .max_uV = 2000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck7_supply[0],
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct regulator_init_data led_flash_init_data = {
+ .constraints = {
+ .name = "FLASH_CUR",
+ .min_uA = 23440,
+ .max_uA = 750080,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
+#if !defined(CONFIG_MACH_Q1_BD)
+ .state_mem = {
+ .disabled = 1,
+ },
+#endif
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &led_flash_supply[0],
+};
+
+static struct regulator_init_data led_movie_init_data = {
+ .constraints = {
+ .name = "MOVIE_CUR",
+ .min_uA = 15625,
+ .max_uA = 250000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
+#if !defined(CONFIG_MACH_Q1_BD)
+ .state_mem = {
+ .disabled = 1,
+ },
+#endif
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &led_movie_supply[0],
+};
+
+#if defined(CONFIG_MACH_Q1_BD)
+static struct regulator_init_data led_torch_init_data = {
+ .constraints = {
+ .name = "FLASH_TORCH",
+ .min_uA = 15625,
+ .max_uA = 250000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &led_torch_supply[0],
+};
+#endif /* CONFIG_MACH_Q1_BD */
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_LDO1, &ldo1_init_data, NULL, },
+ { MAX8997_LDO3, &ldo3_init_data, NULL, },
+ { MAX8997_LDO4, &ldo4_init_data, NULL, },
+ { MAX8997_LDO5, &ldo5_init_data, NULL, },
+ { MAX8997_LDO7, &ldo7_init_data, NULL, },
+ { MAX8997_LDO8, &ldo8_init_data, NULL, },
+ { MAX8997_LDO10, &ldo10_init_data, NULL, },
+ { MAX8997_LDO11, &ldo11_init_data, NULL, },
+ { MAX8997_LDO12, &ldo12_init_data, NULL, },
+ { MAX8997_LDO13, &ldo13_init_data, NULL, },
+ { MAX8997_LDO14, &ldo14_init_data, NULL, },
+ { MAX8997_LDO15, &ldo15_init_data, NULL, },
+ { MAX8997_LDO16, &ldo16_init_data, NULL, },
+ { MAX8997_LDO17, &ldo17_init_data, NULL, },
+ { MAX8997_LDO18, &ldo18_init_data, NULL, },
+ { MAX8997_LDO21, &ldo21_init_data, NULL, },
+ { MAX8997_BUCK1, &buck1_init_data, NULL, },
+ { MAX8997_BUCK2, &buck2_init_data, NULL, },
+ { MAX8997_BUCK3, &buck3_init_data, NULL, },
+ { MAX8997_BUCK4, &buck4_init_data, NULL, },
+ { MAX8997_BUCK5, &buck5_init_data, NULL, },
+ { MAX8997_BUCK7, &buck7_init_data, NULL, },
+ { MAX8997_ESAFEOUT1, &safeout1_init_data, NULL, },
+ { MAX8997_ESAFEOUT2, &safeout2_init_data, NULL, },
+ { MAX8997_FLASH_CUR, &led_flash_init_data, NULL, },
+ { MAX8997_MOVIE_CUR, &led_movie_init_data, NULL, },
+#if defined CONFIG_MACH_Q1_BD
+ { MAX8997_FLASH_TORCH, &led_torch_init_data, NULL, },
+#endif /* CONFIG_MACH_Q1_BD */
+};
+
+static struct max8997_power_data max8997_power = {
+ .batt_detect = 1,
+};
+
+#if defined(CONFIG_MACH_Q1_BD)
+static void motor_init_hw(void)
+{
+ if (gpio_request(GPIO_MOTOR_EN, "MOTOR_EN") < 0)
+ pr_err("[VIB] Failed to request GPIO_MOTOR_EN\n");
+}
+
+static void motor_en(bool enable)
+{
+ gpio_direction_output(GPIO_MOTOR_EN, enable);
+}
+#endif
+
+#ifdef CONFIG_VIBETONZ
+#ifdef CONFIG_TARGET_LOCALE_NTT
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 43696,
+ .period = 44138,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#elif defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_TARGET_LOCALE_NA)
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 44196,
+ .period = 44643,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#elif defined(CONFIG_MACH_Q1_BD)
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 37641,
+ .period = 38022,
+ .init_hw = motor_init_hw,
+ .motor_en = motor_en,
+ .pwm_id = 1,
+};
+#else
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 37641,
+ .period = 38022,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#endif
+#endif
+
+#ifdef CONFIG_MACH_U1_KOR_LGT
+static int max8997_muic_set_safeout(int path)
+{
+ static int safeout2_enabled;
+ struct regulator *regulator;
+
+ pr_info("%s: path = %d\n", __func__, path);
+
+ if (path == CP_USB_MODE) {
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!safeout2_enabled) {
+ pr_info("%s: enable safeout2\n", __func__);
+ regulator_enable(regulator);
+ safeout2_enabled = 1;
+ } else
+ pr_info("%s: safeout2 is already enabled\n",
+ __func__);
+ regulator_put(regulator);
+ } else {
+ /* AP_USB_MODE || AUDIO_MODE */
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (safeout2_enabled) {
+ pr_info("%s: disable safeout2\n", __func__);
+ regulator_disable(regulator);
+ safeout2_enabled = 0;
+ } else
+ pr_info("%s: safeout2 is already disabled\n",
+ __func__);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+#else
+static int max8997_muic_set_safeout(int path)
+{
+ struct regulator *regulator;
+
+ if (path == CP_USB_MODE) {
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ /* AP_USB_MODE || AUDIO_MODE */
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+#endif
+
+static struct charging_status_callbacks {
+ void (*tsp_set_charging_cable) (int type);
+} charging_cbs;
+
+bool is_cable_attached;
+static int connected_cable_type = CABLE_TYPE_NONE;
+
+static int max8997_muic_charger_cb(int cable_type)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ connected_cable_type = cable_type;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+#if defined(CONFIG_MACH_Q1_BD)
+ return 0;
+#else
+ return -ENODEV;
+#endif
+ }
+
+ switch (cable_type) {
+ case CABLE_TYPE_NONE:
+ case CABLE_TYPE_OTG:
+ case CABLE_TYPE_JIG_UART_OFF:
+ case CABLE_TYPE_MHL:
+ value.intval = POWER_SUPPLY_TYPE_BATTERY;
+ is_cable_attached = false;
+ break;
+ case CABLE_TYPE_USB:
+ case CABLE_TYPE_JIG_USB_OFF:
+ case CABLE_TYPE_JIG_USB_ON:
+ value.intval = POWER_SUPPLY_TYPE_USB;
+ is_cable_attached = true;
+ break;
+ case CABLE_TYPE_MHL_VB:
+ value.intval = POWER_SUPPLY_TYPE_MISC;
+ is_cable_attached = true;
+ break;
+ case CABLE_TYPE_TA:
+ case CABLE_TYPE_CARDOCK:
+ case CABLE_TYPE_DESKDOCK:
+ case CABLE_TYPE_JIG_UART_OFF_VB:
+ value.intval = POWER_SUPPLY_TYPE_MAINS;
+ is_cable_attached = true;
+ break;
+ default:
+ pr_err("%s: invalid type:%d\n", __func__, cable_type);
+ return -EINVAL;
+ }
+
+ if (charging_cbs.tsp_set_charging_cable)
+ charging_cbs.tsp_set_charging_cable(value.intval);
+
+ return psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value);
+}
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+static void usb_otg_accessory_power(int enable)
+{
+#ifdef CONFIG_SMB328_CHARGER /* Q1_EUR_OPEN */
+ u8 on = (u8)!!enable;
+ struct power_supply *psy_sub =
+ power_supply_get_by_name("smb328-charger");
+ union power_supply_propval value;
+ int ret;
+
+ if (!psy_sub) {
+ pr_info("%s: fail to get charger ps\n", __func__);
+ return;
+ }
+
+ value.intval = on;
+ ret = psy_sub->set_property(psy_sub,
+ POWER_SUPPLY_PROP_CHARGE_TYPE, /* only for OTG */
+ &value);
+ if (ret) {
+ pr_info("%s: fail to set OTG (%d)\n",
+ __func__, ret);
+ return;
+ }
+ pr_info("%s: otg power = %d\n", __func__, on);
+#else
+ u8 on = (u8)!!enable;
+
+ gpio_request(GPIO_USB_OTG_EN, "USB_OTG_EN");
+ gpio_direction_output(GPIO_USB_OTG_EN, on);
+ gpio_free(GPIO_USB_OTG_EN);
+ pr_info("%s: otg accessory power = %d\n", __func__, on);
+#endif
+}
+
+static struct host_notifier_platform_data host_notifier_pdata = {
+ .ndev.name = "usb_otg",
+ .booster = usb_otg_accessory_power,
+};
+
+struct platform_device host_notifier_device = {
+ .name = "host_notifier",
+ .dev.platform_data = &host_notifier_pdata,
+};
+
+#include "u1-otg.c"
+static void max8997_muic_usb_cb(u8 usb_mode)
+{
+ struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget);
+ int ret = 0;
+
+ pr_info("otg %s: usb mode=%d\n", __func__, usb_mode);
+
+#if 0
+ u32 lpcharging = __raw_readl(S5P_INFORM2);
+ if (lpcharging == 1) {
+ struct regulator *regulator;
+ pr_info("%s: lpcharging: disable USB\n", __func__);
+
+ ret = c210_change_usb_mode(udc, USB_CABLE_DETACHED);
+ if (ret < 0)
+ pr_warn("%s: fail to change mode!!!\n", __func__);
+
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator)) {
+ pr_err("%s: fail to get regulator\n", __func__);
+ return;
+ }
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ return;
+ }
+#endif
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ if (u1_switch_get_usb_lock_state()) {
+ pr_info("%s: usb locked by mdm\n", __func__);
+ return;
+ }
+#endif
+
+ if (udc) {
+ if (usb_mode == USB_OTGHOST_ATTACHED) {
+ usb_otg_accessory_power(1);
+ max8997_muic_charger_cb(CABLE_TYPE_OTG);
+ }
+
+ ret = c210_change_usb_mode(udc, usb_mode);
+ if (ret < 0)
+ pr_err("%s: fail to change mode!!!\n", __func__);
+
+ if (usb_mode == USB_OTGHOST_DETACHED)
+ usb_otg_accessory_power(0);
+ } else
+ pr_info("otg error s3c_udc is null.\n");
+}
+#endif
+
+static void max8997_muic_mhl_cb(int attached)
+{
+ pr_info("%s(%d)\n", __func__, attached);
+
+ if (attached == MAX8997_MUIC_ATTACHED) {
+#ifdef CONFIG_SAMSUNG_MHL
+ mhl_onoff_ex(true);
+ } else if (attached == MAX8997_MUIC_DETACHED) {
+ mhl_onoff_ex(false);
+#endif
+ }
+}
+
+static bool max8997_muic_is_mhl_attached(void)
+{
+ int val;
+
+ gpio_request(GPIO_MHL_SEL, "MHL_SEL");
+ val = gpio_get_value(GPIO_MHL_SEL);
+ gpio_free(GPIO_MHL_SEL);
+
+ return !!val;
+}
+
+static struct switch_dev switch_dock = {
+ .name = "dock",
+};
+
+static void max8997_muic_deskdock_cb(bool attached)
+{
+ if (attached)
+ switch_set_state(&switch_dock, 1);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+static void max8997_muic_cardock_cb(bool attached)
+{
+ if (attached)
+ switch_set_state(&switch_dock, 2);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+static void max8997_muic_init_cb(void)
+{
+ int ret;
+
+ /* for CarDock, DeskDock */
+ ret = switch_dev_register(&switch_dock);
+ if (ret < 0)
+ pr_err("Failed to register dock switch. %d\n", ret);
+}
+
+static int max8997_muic_cfg_uart_gpio(void)
+{
+ int val, path;
+
+ val = gpio_get_value(GPIO_UART_SEL);
+ path = val ? UART_PATH_AP : UART_PATH_CP;
+#if 0
+ /* Workaround
+ * Sometimes sleep current is 15 ~ 20mA if UART path was CP.
+ */
+ if (path == UART_PATH_CP)
+ gpio_set_value(GPIO_UART_SEL, GPIO_LEVEL_HIGH);
+#endif
+ pr_info("%s: path=%d\n", __func__, path);
+ return path;
+}
+
+static void max8997_muic_jig_uart_cb(int path)
+{
+ int val;
+
+ val = path == UART_PATH_AP ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
+ gpio_set_value(GPIO_UART_SEL, val);
+ pr_info("%s: val:%d\n", __func__, val);
+}
+
+static int max8997_muic_host_notify_cb(int enable)
+{
+ struct host_notify_dev *ndev = &host_notifier_pdata.ndev;
+
+ if (ndev) {
+ ndev->booster = enable ? NOTIFY_POWER_ON : NOTIFY_POWER_OFF;
+ pr_info("%s: mode %d, enable %d\n", __func__,
+ ndev->mode, enable);
+ return ndev->mode;
+ } else
+ pr_info("%s: host_notify_dev is null, enable %d\n",
+ __func__, enable);
+
+ return -1;
+}
+
+static struct max8997_muic_data max8997_muic = {
+ .usb_cb = max8997_muic_usb_cb,
+ .charger_cb = max8997_muic_charger_cb,
+ .mhl_cb = max8997_muic_mhl_cb,
+ .is_mhl_attached = max8997_muic_is_mhl_attached,
+ .set_safeout = max8997_muic_set_safeout,
+ .init_cb = max8997_muic_init_cb,
+ .deskdock_cb = max8997_muic_deskdock_cb,
+ .cardock_cb = max8997_muic_cardock_cb,
+ .cfg_uart_gpio = max8997_muic_cfg_uart_gpio,
+ .jig_uart_cb = max8997_muic_jig_uart_cb,
+ .host_notify_cb = max8997_muic_host_notify_cb,
+ .gpio_usb_sel = GPIO_USB_SEL,
+};
+
+static struct max8997_buck1_dvs_funcs *buck1_dvs_funcs;
+
+void max8997_set_arm_voltage_table(int *voltage_table, int arr_size)
+{
+ pr_info("%s\n", __func__);
+ if (buck1_dvs_funcs && buck1_dvs_funcs->set_buck1_dvs_table)
+ buck1_dvs_funcs->set_buck1_dvs_table(buck1_dvs_funcs,
+ voltage_table, arr_size);
+}
+
+static void max8997_register_buck1dvs_funcs(struct max8997_buck1_dvs_funcs *ptr)
+{
+ buck1_dvs_funcs = ptr;
+}
+
+
+static struct max8997_platform_data exynos4_max8997_info = {
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = &max8997_regulators[0],
+ .irq_base = IRQ_BOARD_START,
+ .wakeup = 1,
+ .buck1_gpiodvs = false,
+ .buck1_max_vol = 1350000,
+ .buck2_max_vol = 1150000,
+ .buck5_max_vol = 1200000,
+ .buck_set1 = GPIO_BUCK1_EN_A,
+ .buck_set2 = GPIO_BUCK1_EN_B,
+ .buck_set3 = GPIO_BUCK2_EN,
+ .buck_ramp_en = true,
+ .buck_ramp_delay = 10, /* 10.00mV /us (default) */
+ .flash_cntl_val = 0x5F, /* Flash safety timer duration: 800msec,
+ Maximum timer mode */
+ .power = &max8997_power,
+#ifdef CONFIG_VIBETONZ
+ .motor = &max8997_motor,
+#endif
+ .muic = &max8997_muic,
+ .register_buck1_dvs_funcs = max8997_register_buck1dvs_funcs,
+};
+#endif /* CONFIG_REGULATOR_MAX8997 */
+
+/* Bluetooth */
+#ifdef CONFIG_BT_BCM4330
+static struct platform_device bcm4330_bluetooth_device = {
+ .name = "bcm4330_bluetooth",
+ .id = -1,
+};
+#endif /* CONFIG_BT_BCM4330 */
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+#define SYSTEM_REV_SND 0x05
+#else
+#define SYSTEM_REV_SND 0x09
+#endif
+
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+static DEFINE_SPINLOCK(mic_bias_lock);
+static bool mc1n2_mainmic_bias;
+static bool mc1n2_submic_bias;
+
+static void set_shared_mic_bias(void)
+{
+ if (system_rev >= 0x03)
+ gpio_set_value(GPIO_MIC_BIAS_EN, mc1n2_mainmic_bias
+ || mc1n2_submic_bias);
+ else
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, mc1n2_mainmic_bias
+ || mc1n2_submic_bias);
+}
+
+void sec_set_sub_mic_bias(bool on)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+#if defined(CONFIG_MACH_Q1_BD)
+ gpio_set_value(GPIO_SUB_MIC_BIAS_EN, on);
+#else
+ if (system_rev < SYSTEM_REV_SND) {
+ unsigned long flags;
+ spin_lock_irqsave(&mic_bias_lock, flags);
+ mc1n2_submic_bias = on;
+ set_shared_mic_bias();
+ spin_unlock_irqrestore(&mic_bias_lock, flags);
+ } else
+ gpio_set_value(GPIO_SUB_MIC_BIAS_EN, on);
+#endif /* #if defined(CONFIG_MACH_Q1_BD) */
+#endif
+}
+
+void sec_set_main_mic_bias(bool on)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+#if defined(CONFIG_MACH_Q1_BD)
+ gpio_set_value(GPIO_MIC_BIAS_EN, on);
+#else
+ if (system_rev < SYSTEM_REV_SND) {
+ unsigned long flags;
+ spin_lock_irqsave(&mic_bias_lock, flags);
+ mc1n2_mainmic_bias = on;
+ set_shared_mic_bias();
+ spin_unlock_irqrestore(&mic_bias_lock, flags);
+ } else
+ gpio_set_value(GPIO_MIC_BIAS_EN, on);
+#endif /* #if defined(CONFIG_MACH_Q1_BD) */
+#endif
+}
+
+int sec_set_ldo1_constraints(int disabled)
+{
+ struct regulator *regulator;
+
+ if (!disabled) {
+ regulator = regulator_get(NULL, "vadc_3.3v");
+ if (IS_ERR(regulator))
+ return -1;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vadc_3.3v");
+ if (IS_ERR(regulator))
+ return -1;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+static struct mc1n2_platform_data mc1n2_pdata = {
+ .set_main_mic_bias = sec_set_main_mic_bias,
+ .set_sub_mic_bias = sec_set_sub_mic_bias,
+ .set_adc_power_constraints = sec_set_ldo1_constraints,
+};
+
+static void u1_sound_init(void)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+ int err;
+
+ err = gpio_request(GPIO_MIC_BIAS_EN, "GPE1");
+ if (err) {
+ pr_err(KERN_ERR "MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_MIC_BIAS_EN);
+
+ err = gpio_request(GPIO_EAR_MIC_BIAS_EN, "GPE2");
+ if (err) {
+ pr_err(KERN_ERR "EAR_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_EAR_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_EAR_MIC_BIAS_EN);
+
+#if defined(CONFIG_MACH_Q1_BD)
+ err = gpio_request(GPIO_SUB_MIC_BIAS_EN, "submic_bias");
+ if (err) {
+ pr_err(KERN_ERR "SUB_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_SUB_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_SUB_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_SUB_MIC_BIAS_EN);
+
+#else
+ if (system_rev >= SYSTEM_REV_SND) {
+ err = gpio_request(GPIO_SUB_MIC_BIAS_EN, "submic_bias");
+ if (err) {
+ pr_err(KERN_ERR "SUB_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_SUB_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_SUB_MIC_BIAS_EN);
+ }
+#endif /* #if defined(CONFIG_MACH_Q1_BD) */
+#endif
+}
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+static void tdmb_set_config_poweron(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_RST_N, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_RST_N, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_SFN(GPIO_TDMB_INT_AF));
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+}
+static void tdmb_set_config_poweroff(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_RST_N, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_RST_N, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_INT, GPIO_LEVEL_LOW);
+}
+
+static void tdmb_gpio_on(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_on\n");
+
+ tdmb_set_config_poweron();
+
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_HIGH);
+ usleep_range(10000, 10000);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+ usleep_range(2000, 2000);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_HIGH);
+ usleep_range(10000, 10000);
+}
+
+static void tdmb_gpio_off(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_off\n");
+
+ tdmb_set_config_poweroff();
+
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+ usleep_range(1000, 1000);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+}
+
+static struct tdmb_platform_data tdmb_pdata = {
+ .gpio_on = tdmb_gpio_on,
+ .gpio_off = tdmb_gpio_off,
+};
+
+static struct platform_device tdmb_device = {
+ .name = "tdmb",
+ .id = -1,
+ .dev = {
+ .platform_data = &tdmb_pdata,
+ },
+};
+
+static int __init tdmb_dev_init(void)
+{
+ tdmb_set_config_poweroff();
+ s5p_register_gpio_interrupt(GPIO_TDMB_INT);
+ tdmb_pdata.irq = GPIO_TDMB_IRQ;
+ platform_device_register(&tdmb_device);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_U1
+static int c1_charger_topoff_cb(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ value.intval = POWER_SUPPLY_STATUS_FULL;
+ return psy->set_property(psy, POWER_SUPPLY_PROP_STATUS, &value);
+}
+#endif
+
+#if defined(CONFIG_MACH_Q1_CHN) && \
+ (defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER))
+static int c1_charger_ovp_cb(bool is_ovp)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ if (is_ovp)
+ value.intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ else
+ value.intval = POWER_SUPPLY_HEALTH_GOOD;
+
+ return psy->set_property(psy, POWER_SUPPLY_PROP_VOLTAGE_MAX, &value);
+}
+#endif
+
+#ifdef CONFIG_LEDS_MAX8997
+struct led_max8997_platform_data led_max8997_platform_data = {
+ .name = "leds-sec",
+ .brightness = 0,
+};
+
+struct platform_device sec_device_leds_max8997 = {
+ .name = "leds-max8997",
+ .id = -1,
+ .dev = { .platform_data = &led_max8997_platform_data},
+};
+#endif /* CONFIG_LEDS_MAX8997 */
+
+#ifdef CONFIG_CHARGER_MAX8922_U1
+static int max8922_cfg_gpio(void)
+{
+ if (system_rev < HWREV_FOR_BATTERY)
+ return -ENODEV;
+
+ s3c_gpio_cfgpin(GPIO_CHG_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_CHG_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CHG_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_CHG_ING_N, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CHG_ING_N, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TA_nCONNECTED, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCONNECTED, S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static struct max8922_platform_data max8922_pdata = {
+#ifdef CONFIG_BATTERY_SEC_U1
+ .topoff_cb = c1_charger_topoff_cb,
+#endif
+ .cfg_gpio = max8922_cfg_gpio,
+ .gpio_chg_en = GPIO_CHG_EN,
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+ .gpio_ta_nconnected = GPIO_TA_nCONNECTED,
+};
+
+static struct platform_device max8922_device_charger = {
+ .name = "max8922-charger",
+ .id = -1,
+ .dev.platform_data = &max8922_pdata,
+};
+#endif /* CONFIG_CHARGER_MAX8922_U1 */
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_U1
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+/* temperature table for ADC 6 */
+static struct sec_bat_adc_table_data temper_table[] = {
+ { 264, 500 },
+ { 275, 490 },
+ { 286, 480 },
+ { 293, 480 },
+ { 299, 470 },
+ { 306, 460 },
+ { 324, 450 },
+ { 341, 450 },
+ { 354, 440 },
+ { 368, 430 },
+ { 381, 420 },
+ { 396, 420 },
+ { 411, 410 },
+ { 427, 400 },
+ { 442, 390 },
+ { 457, 390 },
+ { 472, 380 },
+ { 487, 370 },
+ { 503, 370 },
+ { 518, 360 },
+ { 533, 350 },
+ { 554, 340 },
+ { 574, 330 },
+ { 595, 330 },
+ { 615, 320 },
+ { 636, 310 },
+ { 656, 310 },
+ { 677, 300 },
+ { 697, 290 },
+ { 718, 280 },
+ { 738, 270 },
+ { 761, 270 },
+ { 784, 260 },
+ { 806, 250 },
+ { 829, 240 },
+ { 852, 230 },
+ { 875, 220 },
+ { 898, 210 },
+ { 920, 200 },
+ { 943, 190 },
+ { 966, 180 },
+ { 990, 170 },
+ { 1013, 160 },
+ { 1037, 150 },
+ { 1060, 140 },
+ { 1084, 130 },
+ { 1108, 120 },
+ { 1131, 110 },
+ { 1155, 100 },
+ { 1178, 90 },
+ { 1202, 80 },
+ { 1226, 70 },
+ { 1251, 60 },
+ { 1275, 50 },
+ { 1299, 40 },
+ { 1324, 30 },
+ { 1348, 20 },
+ { 1372, 10 },
+ { 1396, 0 },
+ { 1421, -10 },
+ { 1445, -20 },
+ { 1468, -30 },
+ { 1491, -40 },
+ { 1513, -50 },
+ { 1536, -60 },
+ { 1559, -70 },
+ { 1577, -80 },
+ { 1596, -90 },
+ { 1614, -100 },
+ { 1619, -110 },
+ { 1632, -120 },
+ { 1658, -130 },
+ { 1667, -140 },
+};
+#elif defined(CONFIG_TARGET_LOCALE_NTT)
+/* temperature table for ADC 6 */
+static struct sec_bat_adc_table_data temper_table[] = {
+ { 273, 670 },
+ { 289, 660 },
+ { 304, 650 },
+ { 314, 640 },
+ { 325, 630 },
+ { 337, 620 },
+ { 347, 610 },
+ { 361, 600 },
+ { 376, 590 },
+ { 391, 580 },
+ { 406, 570 },
+ { 417, 560 },
+ { 431, 550 },
+ { 447, 540 },
+ { 474, 530 },
+ { 491, 520 },
+ { 499, 510 },
+ { 511, 500 },
+ { 519, 490 },
+ { 547, 480 },
+ { 568, 470 },
+ { 585, 460 },
+ { 597, 450 },
+ { 614, 440 },
+ { 629, 430 },
+ { 647, 420 },
+ { 672, 410 },
+ { 690, 400 },
+ { 720, 390 },
+ { 735, 380 },
+ { 755, 370 },
+ { 775, 360 },
+ { 795, 350 },
+ { 818, 340 },
+ { 841, 330 },
+ { 864, 320 },
+ { 887, 310 },
+ { 909, 300 },
+ { 932, 290 },
+ { 954, 280 },
+ { 976, 270 },
+ { 999, 260 },
+ { 1021, 250 },
+ { 1051, 240 },
+ { 1077, 230 },
+ { 1103, 220 },
+ { 1129, 210 },
+ { 1155, 200 },
+ { 1177, 190 },
+ { 1199, 180 },
+ { 1220, 170 },
+ { 1242, 160 },
+ { 1263, 150 },
+ { 1284, 140 },
+ { 1306, 130 },
+ { 1326, 120 },
+ { 1349, 110 },
+ { 1369, 100 },
+ { 1390, 90 },
+ { 1411, 80 },
+ { 1433, 70 },
+ { 1454, 60 },
+ { 1474, 50 },
+ { 1486, 40 },
+ { 1499, 30 },
+ { 1512, 20 },
+ { 1531, 10 },
+ { 1548, 0 },
+ { 1570, -10 },
+ { 1597, -20 },
+ { 1624, -30 },
+ { 1633, -40 },
+ { 1643, -50 },
+ { 1652, -60 },
+ { 1663, -70 },
+};
+#else
+/* temperature table for ADC 6 */
+static struct sec_bat_adc_table_data temper_table[] = {
+ { 165, 800 },
+ { 171, 790 },
+ { 177, 780 },
+ { 183, 770 },
+ { 189, 760 },
+ { 196, 750 },
+ { 202, 740 },
+ { 208, 730 },
+ { 214, 720 },
+ { 220, 710 },
+ { 227, 700 },
+ { 237, 690 },
+ { 247, 680 },
+ { 258, 670 },
+ { 269, 660 },
+ { 281, 650 },
+ { 296, 640 },
+ { 311, 630 },
+ { 326, 620 },
+ { 341, 610 },
+ { 356, 600 },
+ { 370, 590 },
+ { 384, 580 },
+ { 398, 570 },
+ { 412, 560 },
+ { 427, 550 },
+ { 443, 540 },
+ { 457, 530 },
+ { 471, 520 },
+ { 485, 510 },
+ { 498, 500 },
+ { 507, 490 },
+ { 516, 480 },
+ { 525, 470 },
+ { 535, 460 },
+ { 544, 450 },
+ { 553, 440 },
+ { 562, 430 },
+ { 579, 420 },
+ { 596, 410 },
+ { 613, 400 },
+ { 630, 390 },
+ { 648, 380 },
+ { 665, 370 },
+ { 684, 360 },
+ { 702, 350 },
+ { 726, 340 },
+ { 750, 330 },
+ { 774, 320 },
+ { 798, 310 },
+ { 821, 300 },
+ { 844, 290 },
+ { 867, 280 },
+ { 891, 270 },
+ { 914, 260 },
+ { 937, 250 },
+ { 960, 240 },
+ { 983, 230 },
+ { 1007, 220 },
+ { 1030, 210 },
+ { 1054, 200 },
+ { 1083, 190 },
+ { 1113, 180 },
+ { 1143, 170 },
+ { 1173, 160 },
+ { 1202, 150 },
+ { 1232, 140 },
+ { 1262, 130 },
+ { 1291, 120 },
+ { 1321, 110 },
+ { 1351, 100 },
+ { 1357, 90 },
+ { 1363, 80 },
+ { 1369, 70 },
+ { 1375, 60 },
+ { 1382, 50 },
+ { 1402, 40 },
+ { 1422, 30 },
+ { 1442, 20 },
+ { 1462, 10 },
+ { 1482, 0 },
+ { 1519, -10 },
+ { 1528, -20 },
+ { 1546, -30 },
+ { 1563, -40 },
+ { 1587, -50 },
+ { 1601, -60 },
+ { 1614, -70 },
+ { 1625, -80 },
+ { 1641, -90 },
+ { 1663, -100 },
+ { 1678, -110 },
+ { 1693, -120 },
+ { 1705, -130 },
+ { 1720, -140 },
+ { 1736, -150 },
+ { 1751, -160 },
+ { 1767, -170 },
+ { 1782, -180 },
+ { 1798, -190 },
+ { 1815, -200 },
+};
+#endif
+#ifdef CONFIG_TARGET_LOCALE_NTT
+/* temperature table for ADC 7 */
+static struct sec_bat_adc_table_data temper_table_ADC7[] = {
+ { 300, 670 },
+ { 310, 660 },
+ { 324, 650 },
+ { 330, 640 },
+ { 340, 630 },
+ { 353, 620 },
+ { 368, 610 },
+ { 394, 600 },
+ { 394, 590 },
+ { 401, 580 },
+ { 418, 570 },
+ { 431, 560 },
+ { 445, 550 },
+ { 460, 540 },
+ { 478, 530 },
+ { 496, 520 },
+ { 507, 510 },
+ { 513, 500 },
+ { 531, 490 },
+ { 553, 480 },
+ { 571, 470 },
+ { 586, 460 },
+ { 604, 450 },
+ { 614, 440 },
+ { 640, 430 },
+ { 659, 420 },
+ { 669, 410 },
+ { 707, 400 },
+ { 722, 390 },
+ { 740, 380 },
+ { 769, 370 },
+ { 783, 360 },
+ { 816, 350 },
+ { 818, 340 },
+ { 845, 330 },
+ { 859, 320 },
+ { 889, 310 },
+ { 929, 300 },
+ { 942, 290 },
+ { 955, 280 },
+ { 972, 270 },
+ { 996, 260 },
+ { 1040, 250 },
+ { 1049, 240 },
+ { 1073, 230 },
+ { 1096, 220 },
+ { 1114, 210 },
+ { 1159, 200 },
+ { 1165, 190 },
+ { 1206, 180 },
+ { 1214, 170 },
+ { 1227, 160 },
+ { 1256, 150 },
+ { 1275, 140 },
+ { 1301, 130 },
+ { 1308, 120 },
+ { 1357, 110 },
+ { 1388, 100 },
+ { 1396, 90 },
+ { 1430, 80 },
+ { 1448, 70 },
+ { 1468, 60 },
+ { 1499, 50 },
+ { 1506, 40 },
+ { 1522, 30 },
+ { 1535, 20 },
+ { 1561, 10 },
+ { 1567, 0 },
+ { 1595, -10 },
+ { 1620, -20 },
+ { 1637, -30 },
+ { 1640, -40 },
+ { 1668, -50 },
+ { 1669, -60 },
+ { 1688, -70 },
+};
+#else
+/* temperature table for ADC 7 */
+static struct sec_bat_adc_table_data temper_table_ADC7[] = {
+ { 193, 800 },
+ { 200, 790 },
+ { 207, 780 },
+ { 215, 770 },
+ { 223, 760 },
+ { 230, 750 },
+ { 238, 740 },
+ { 245, 730 },
+ { 252, 720 },
+ { 259, 710 },
+ { 266, 700 },
+ { 277, 690 },
+ { 288, 680 },
+ { 300, 670 },
+ { 311, 660 },
+ { 326, 650 },
+ { 340, 640 },
+ { 354, 630 },
+ { 368, 620 },
+ { 382, 610 },
+ { 397, 600 },
+ { 410, 590 },
+ { 423, 580 },
+ { 436, 570 },
+ { 449, 560 },
+ { 462, 550 },
+ { 475, 540 },
+ { 488, 530 },
+ { 491, 520 },
+ { 503, 510 },
+ { 535, 500 },
+ { 548, 490 },
+ { 562, 480 },
+ { 576, 470 },
+ { 590, 460 },
+ { 603, 450 },
+ { 616, 440 },
+ { 630, 430 },
+ { 646, 420 },
+ { 663, 410 },
+ { 679, 400 },
+ { 696, 390 },
+ { 712, 380 },
+ { 728, 370 },
+ { 745, 360 },
+ { 762, 350 },
+ { 784, 340 },
+ { 806, 330 },
+ { 828, 320 },
+ { 850, 310 },
+ { 872, 300 },
+ { 895, 290 },
+ { 919, 280 },
+ { 942, 270 },
+ { 966, 260 },
+ { 989, 250 },
+ { 1013, 240 },
+ { 1036, 230 },
+ { 1060, 220 },
+ { 1083, 210 },
+ { 1107, 200 },
+ { 1133, 190 },
+ { 1159, 180 },
+ { 1186, 170 },
+ { 1212, 160 },
+ { 1238, 150 },
+ { 1265, 140 },
+ { 1291, 130 },
+ { 1316, 120 },
+ { 1343, 110 },
+ { 1370, 100 },
+ { 1381, 90 },
+ { 1393, 80 },
+ { 1404, 70 },
+ { 1416, 60 },
+ { 1427, 50 },
+ { 1453, 40 },
+ { 1479, 30 },
+ { 1505, 20 },
+ { 1531, 10 },
+ { 1557, 0 },
+ { 1565, -10 },
+ { 1577, -20 },
+ { 1601, -30 },
+ { 1620, -40 },
+ { 1633, -50 },
+ { 1642, -60 },
+ { 1656, -70 },
+ { 1667, -80 },
+ { 1674, -90 },
+ { 1689, -100 },
+ { 1704, -110 },
+ { 1719, -120 },
+ { 1734, -130 },
+ { 1749, -140 },
+ { 1763, -150 },
+ { 1778, -160 },
+ { 1793, -170 },
+ { 1818, -180 },
+ { 1823, -190 },
+ { 1838, -200 },
+};
+#endif
+
+#define ADC_CH_TEMPERATURE_PMIC 6
+#define ADC_CH_TEMPERATURE_LCD 7
+
+static unsigned int sec_bat_get_lpcharging_state(void)
+{
+ u32 val = __raw_readl(S5P_INFORM2);
+ struct power_supply *psy = power_supply_get_by_name("max8997-charger");
+ union power_supply_propval value;
+
+ BUG_ON(!psy);
+
+ if (val == 1) {
+ psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &value);
+ pr_info("%s: charging status: %d\n", __func__, value.intval);
+ if (value.intval == POWER_SUPPLY_STATUS_DISCHARGING)
+ pr_warn("%s: DISCHARGING\n", __func__);
+ }
+
+ pr_info("%s: LP charging:%d\n", __func__, val);
+ return val;
+}
+
+static void sec_bat_initial_check(void)
+{
+ pr_info("%s: connected_cable_type:%d\n",
+ __func__, connected_cable_type);
+ if (connected_cable_type != CABLE_TYPE_NONE)
+ max8997_muic_charger_cb(connected_cable_type);
+}
+
+static struct sec_bat_platform_data sec_bat_pdata = {
+ .fuel_gauge_name = "fuelgauge",
+ .charger_name = "max8997-charger",
+#ifdef CONFIG_CHARGER_MAX8922_U1
+ .sub_charger_name = "max8922-charger",
+#elif defined(CONFIG_MAX8903_CHARGER)
+ .sub_charger_name = "max8903-charger",
+#endif
+ /* TODO: should provide temperature table */
+ .adc_arr_size = ARRAY_SIZE(temper_table),
+ .adc_table = temper_table,
+ .adc_channel = ADC_CH_TEMPERATURE_PMIC,
+ .adc_sub_arr_size = ARRAY_SIZE(temper_table_ADC7),
+ .adc_sub_table = temper_table_ADC7,
+ .adc_sub_channel = ADC_CH_TEMPERATURE_LCD,
+ .get_lpcharging_state = sec_bat_get_lpcharging_state,
+#if defined(CONFIG_MACH_Q1_BD)
+ .initial_check = sec_bat_initial_check,
+#else
+ .initial_check = NULL,
+#endif
+};
+
+static struct platform_device sec_device_battery = {
+ .name = "sec-battery",
+ .id = -1,
+ .dev.platform_data = &sec_bat_pdata,
+};
+#endif /* CONFIG_BATTERY_SEC_U1 */
+
+#ifdef CONFIG_SMB136_CHARGER_Q1
+static void smb136_set_charger_name(void)
+{
+ sec_bat_pdata.sub_charger_name = "smb136-charger";
+}
+
+static struct smb136_platform_data smb136_pdata = {
+ .topoff_cb = c1_charger_topoff_cb,
+#if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
+ .ovp_cb = c1_charger_ovp_cb,
+#endif
+ .set_charger_name = smb136_set_charger_name,
+ .gpio_chg_en = GPIO_CHG_EN,
+ .gpio_otg_en = GPIO_OTG_EN,
+#if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+#endif
+ .gpio_ta_nconnected = 0, /*GPIO_TA_nCONNECTED,*/
+};
+#endif /* CONFIG_SMB136_CHARGER_Q1 */
+
+#ifdef CONFIG_SMB328_CHARGER
+static void smb328_set_charger_name(void)
+{
+ sec_bat_pdata.sub_charger_name = "smb328-charger";
+}
+
+static struct smb328_platform_data smb328_pdata = {
+ .topoff_cb = c1_charger_topoff_cb,
+#if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB328_CHARGER)
+ .ovp_cb = c1_charger_ovp_cb,
+#endif
+ .set_charger_name = smb328_set_charger_name,
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+ .gpio_ta_nconnected = 0, /*GPIO_TA_nCONNECTED,*/
+};
+#endif /* CONFIG_SMB328_CHARGER */
+
+#if defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER)
+static struct i2c_gpio_platform_data gpio_i2c_data19 = {
+ .sda_pin = GPIO_CHG_SDA,
+ .scl_pin = GPIO_CHG_SCL,
+};
+
+static struct platform_device s3c_device_i2c19 = {
+ .name = "i2c-gpio",
+ .id = 19,
+ .dev.platform_data = &gpio_i2c_data19,
+};
+
+static struct i2c_board_info i2c_devs19_emul[] = {
+#ifdef CONFIG_SMB136_CHARGER_Q1
+ {
+ I2C_BOARD_INFO("smb136-charger", SMB136_SLAVE_ADDR>>1),
+ .platform_data = &smb136_pdata,
+ },
+#endif
+#ifdef CONFIG_SMB328_CHARGER
+ {
+ I2C_BOARD_INFO("smb328-charger", SMB328_SLAVE_ADDR>>1),
+ .platform_data = &smb328_pdata,
+ },
+#endif
+};
+#endif
+
+#if defined(CONFIG_SEC_THERMISTOR)
+#if defined(CONFIG_MACH_Q1_BD)
+/* temperature table for ADC CH 6 */
+static struct sec_therm_adc_table adc_ch6_table[] = {
+ /* ADC, Temperature */
+ { 165, 800 },
+ { 173, 790 },
+ { 179, 780 },
+ { 185, 770 },
+ { 191, 760 },
+ { 197, 750 },
+ { 203, 740 },
+ { 209, 730 },
+ { 215, 720 },
+ { 221, 710 },
+ { 227, 700 },
+ { 236, 690 },
+ { 247, 680 },
+ { 258, 670 },
+ { 269, 660 },
+ { 281, 650 },
+ { 296, 640 },
+ { 311, 630 },
+ { 326, 620 },
+ { 341, 610 },
+ { 356, 600 },
+ { 372, 590 },
+ { 386, 580 },
+ { 400, 570 },
+ { 414, 560 },
+ { 428, 550 },
+ { 442, 540 },
+ { 456, 530 },
+ { 470, 520 },
+ { 484, 510 },
+ { 498, 500 },
+ { 508, 490 },
+ { 517, 480 },
+ { 526, 470 },
+ { 535, 460 },
+ { 544, 450 },
+ { 553, 440 },
+ { 562, 430 },
+ { 576, 420 },
+ { 594, 410 },
+ { 612, 400 },
+ { 630, 390 },
+ { 648, 380 },
+ { 666, 370 },
+ { 684, 360 },
+ { 702, 350 },
+ { 725, 340 },
+ { 749, 330 },
+ { 773, 320 },
+ { 797, 310 },
+ { 821, 300 },
+ { 847, 290 },
+ { 870, 280 },
+ { 893, 270 },
+ { 916, 260 },
+ { 939, 250 },
+ { 962, 240 },
+ { 985, 230 },
+ { 1008, 220 },
+ { 1031, 210 },
+ { 1054, 200 },
+ { 1081, 190 },
+ { 1111, 180 },
+ { 1141, 170 },
+ { 1171, 160 },
+ { 1201, 150 },
+ { 1231, 140 },
+ { 1261, 130 },
+ { 1291, 120 },
+ { 1321, 110 },
+ { 1351, 100 },
+ { 1358, 90 },
+ { 1364, 80 },
+ { 1370, 70 },
+ { 1376, 60 },
+ { 1382, 50 },
+ { 1402, 40 },
+ { 1422, 30 },
+ { 1442, 20 },
+ { 1462, 10 },
+ { 1482, 0 },
+ { 1519, -10 },
+ { 1528, -20 },
+ { 1546, -30 },
+ { 1563, -40 },
+ { 1587, -50 },
+ { 1601, -60 },
+ { 1614, -70 },
+ { 1625, -80 },
+ { 1641, -90 },
+ { 1663, -100 },
+ { 1680, -110 },
+ { 1695, -120 },
+ { 1710, -130 },
+ { 1725, -140 },
+ { 1740, -150 },
+ { 1755, -160 },
+ { 1770, -170 },
+ { 1785, -180 },
+ { 1800, -190 },
+ { 1815, -200 },
+};
+#else
+/* temperature table for ADC CH 6 */
+static struct sec_therm_adc_table adc_ch6_table[] = {
+ /* ADC, Temperature */
+ { 173, 800 },
+ { 180, 790 },
+ { 188, 780 },
+ { 196, 770 },
+ { 204, 760 },
+ { 212, 750 },
+ { 220, 740 },
+ { 228, 730 },
+ { 236, 720 },
+ { 244, 710 },
+ { 252, 700 },
+ { 259, 690 },
+ { 266, 680 },
+ { 273, 670 },
+ { 289, 660 },
+ { 304, 650 },
+ { 314, 640 },
+ { 325, 630 },
+ { 337, 620 },
+ { 347, 610 },
+ { 361, 600 },
+ { 376, 590 },
+ { 391, 580 },
+ { 406, 570 },
+ { 417, 560 },
+ { 431, 550 },
+ { 447, 540 },
+ { 474, 530 },
+ { 491, 520 },
+ { 499, 510 },
+ { 511, 500 },
+ { 519, 490 },
+ { 547, 480 },
+ { 568, 470 },
+ { 585, 460 },
+ { 597, 450 },
+ { 614, 440 },
+ { 629, 430 },
+ { 647, 420 },
+ { 672, 410 },
+ { 690, 400 },
+ { 720, 390 },
+ { 735, 380 },
+ { 755, 370 },
+ { 775, 360 },
+ { 795, 350 },
+ { 818, 340 },
+ { 841, 330 },
+ { 864, 320 },
+ { 887, 310 },
+ { 909, 300 },
+ { 932, 290 },
+ { 954, 280 },
+ { 976, 270 },
+ { 999, 260 },
+ { 1021, 250 },
+ { 1051, 240 },
+ { 1077, 230 },
+ { 1103, 220 },
+ { 1129, 210 },
+ { 1155, 200 },
+ { 1177, 190 },
+ { 1199, 180 },
+ { 1220, 170 },
+ { 1242, 160 },
+ { 1263, 150 },
+ { 1284, 140 },
+ { 1306, 130 },
+ { 1326, 120 },
+ { 1349, 110 },
+ { 1369, 100 },
+ { 1390, 90 },
+ { 1411, 80 },
+ { 1433, 70 },
+ { 1454, 60 },
+ { 1474, 50 },
+ { 1486, 40 },
+ { 1499, 30 },
+ { 1512, 20 },
+ { 1531, 10 },
+ { 1548, 0 },
+ { 1570, -10 },
+ { 1597, -20 },
+ { 1624, -30 },
+ { 1633, -40 },
+ { 1643, -50 },
+ { 1652, -60 },
+ { 1663, -70 },
+ { 1687, -80 },
+ { 1711, -90 },
+ { 1735, -100 },
+ { 1746, -110 },
+ { 1757, -120 },
+ { 1768, -130 },
+ { 1779, -140 },
+ { 1790, -150 },
+ { 1801, -160 },
+ { 1812, -170 },
+ { 1823, -180 },
+ { 1834, -190 },
+ { 1845, -200 },
+};
+#endif
+
+static struct sec_therm_platform_data sec_therm_pdata = {
+ .adc_channel = 6,
+ .adc_arr_size = ARRAY_SIZE(adc_ch6_table),
+ .adc_table = adc_ch6_table,
+ .polling_interval = 30 * 1000, /* msecs */
+};
+
+static struct platform_device sec_device_thermistor = {
+ .name = "sec-thermistor",
+ .id = -1,
+ .dev.platform_data = &sec_therm_pdata,
+};
+#endif /* CONFIG_SEC_THERMISTOR */
+
+
+struct gpio_keys_button u1_buttons[] = {
+ {
+ .code = KEY_VOLUMEUP,
+ .gpio = GPIO_VOL_UP,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ .debounce_interval = 10,
+ }, /* vol up */
+ {
+ .code = KEY_VOLUMEDOWN,
+ .gpio = GPIO_VOL_DOWN,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ .debounce_interval = 10,
+ }, /* vol down */
+ {
+ .code = KEY_POWER,
+ .gpio = GPIO_nPOWER,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ .debounce_interval = 10,
+ }, /* power key */
+ {
+ .code = KEY_HOME,
+ .gpio = GPIO_OK_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .debounce_interval = 10,
+ }, /* ok key */
+};
+
+struct gpio_keys_platform_data u1_keypad_platform_data = {
+ u1_buttons,
+ ARRAY_SIZE(u1_buttons),
+};
+
+struct platform_device u1_keypad = {
+ .name = "gpio-keys",
+ .dev.platform_data = &u1_keypad_platform_data,
+};
+
+#ifdef CONFIG_SEC_DEV_JACK
+static void sec_set_jack_micbias(bool on)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+#if defined(CONFIG_MACH_Q1_BD)
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, on);
+#else
+ if (system_rev >= 3)
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, on);
+ else
+ gpio_set_value(GPIO_MIC_BIAS_EN, on);
+#endif /* #if defined(CONFIG_MACH_Q1_BD) */
+#endif /* #ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS */
+}
+
+static struct sec_jack_zone sec_jack_zones[] = {
+ {
+ /* adc == 0, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 0,
+ .delay_ms = 15,
+ .check_count = 20,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 0 < adc <= 1200, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 1200,
+ .delay_ms = 10,
+ .check_count = 80,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 950 < adc <= 2600, unstable zone, default to 4pole if it
+ * stays in this range for 800ms (10ms delays, 80 samples)
+ */
+ .adc_high = 2600,
+ .delay_ms = 10,
+ .check_count = 10,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* 2600 < adc <= 3400, 3 pole zone, default to 3pole if it
+ * stays in this range for 100ms (10ms delays, 10 samples)
+ */
+ .adc_high = 3800,
+#if defined(CONFIG_MACH_Q1_BD)
+ .delay_ms = 15,
+ .check_count = 20,
+#else
+ .delay_ms = 10,
+ .check_count = 5,
+#endif
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* adc > 3400, unstable zone, default to 3pole if it stays
+ * in this range for two seconds (10ms delays, 200 samples)
+ */
+ .adc_high = 0x7fffffff,
+ .delay_ms = 10,
+ .check_count = 200,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+};
+
+/* To support 3-buttons earjack */
+static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = {
+ {
+ /* 0 <= adc <=170, stable zone */
+ .code = KEY_MEDIA,
+ .adc_low = 0,
+#if defined(CONFIG_TARGET_LOCALE_NTT)
+ .adc_high = 150,
+#else
+ .adc_high = 170,
+#endif
+ },
+ {
+ /* 171 <= adc <= 370, stable zone */
+ .code = KEY_VOLUMEUP,
+#if defined(CONFIG_TARGET_LOCALE_NTT)
+ .adc_low = 151,
+#else
+ .adc_low = 171,
+#endif
+ .adc_high = 370,
+ },
+ {
+ /* 371 <= adc <= 850, stable zone */
+ .code = KEY_VOLUMEDOWN,
+ .adc_low = 371,
+ .adc_high = 850,
+ },
+};
+
+static struct sec_jack_platform_data sec_jack_data = {
+ .set_micbias_state = sec_set_jack_micbias,
+ .zones = sec_jack_zones,
+ .num_zones = ARRAY_SIZE(sec_jack_zones),
+ .buttons_zones = sec_jack_buttons_zones,
+ .num_buttons_zones = ARRAY_SIZE(sec_jack_buttons_zones),
+ .det_gpio = GPIO_DET_35,
+ .send_end_gpio = GPIO_EAR_SEND_END,
+};
+
+static struct platform_device sec_device_jack = {
+ .name = "sec_jack",
+ .id = 1, /* will be used also for gpio_event id */
+ .dev.platform_data = &sec_jack_data,
+};
+#endif
+
+void tsp_register_callback(void *function)
+{
+ charging_cbs.tsp_set_charging_cable = function;
+}
+
+void tsp_read_ta_status(void *ta_status)
+{
+ *(bool *)ta_status = is_cable_attached;
+}
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC
+static void mxt224_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+}
+
+static void mxt224_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+}
+
+static u8 t7_config[] = {GEN_POWERCONFIG_T7,
+ 64, 255, 50
+};
+static u8 t8_config[] = {GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, 9, 27
+};
+static u8 t9_config[] = {TOUCH_MULTITOUCHSCREEN_T9,
+ 143, 0, 0, 18, 11, 0, 16, 32, 2, 0,
+ 0, 3, 1, 46, 10, 5, 40, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 18
+};
+static u8 t15_config[] = {TOUCH_KEYARRAY_T15,
+ 131, 16, 11, 2, 1, 0, 0, 45, 4, 0,
+ 0
+};
+static u8 t18_config[] = {SPT_COMCONFIG_T18,
+ 0, 0
+};
+static u8 t19_config[] = {SPT_GPIOPWM_T19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+static u8 t20_config[] = {PROCI_GRIPFACESUPPRESSION_T20,
+ 19, 0, 0, 5, 5, 0, 0, 30, 20, 4, 15,
+ 10
+};
+static u8 t22_config[] = {PROCG_NOISESUPPRESSION_T22,
+ 5, 0, 0, 0, 0, 0, 0, 3, 27, 0,
+ 0, 29, 34, 39, 49, 58, 3
+};
+static u8 t23_config[] = {TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+};
+static u8 t24_config[] = {PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static u8 t25_config[] = {SPT_SELFTEST_T25,
+ 0, 0
+};
+static u8 t27_config[] = {PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ 0, 0, 0, 0, 0, 0, 0
+};
+static u8 t28_config[] = {SPT_CTECONFIG_T28,
+ 1, 0, 2, 16, 63, 60
+};
+static u8 end_config[] = {RESERVED_T255};
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t15_config,
+ t18_config,
+ t19_config,
+ t20_config,
+ t22_config,
+ t23_config,
+ t24_config,
+ t25_config,
+ t27_config,
+ t28_config,
+ end_config,
+};
+
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = 10,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config = mxt224_config,
+ .min_x = 0,
+ .max_x = 479,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+};
+
+
+#endif
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1
+static void mxt224_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+ /* printk("mxt224_power_on is finished\n"); */
+}
+
+static void mxt224_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+ /* printk("mxt224_power_off is finished\n"); */
+}
+
+/*
+ Configuration for MXT224
+*/
+#define MXT224_THRESHOLD_BATT 40
+#define MXT224_THRESHOLD_BATT_INIT 55
+#define MXT224_THRESHOLD_CHRG 70
+#define MXT224_NOISE_THRESHOLD_BATT 30
+#define MXT224_NOISE_THRESHOLD_CHRG 40
+#define MXT224_MOVFILTER_BATT 11
+#define MXT224_MOVFILTER_CHRG 47
+#define MXT224_ATCHCALST 4
+#define MXT224_ATCHCALTHR 35
+
+static u8 t7_config[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config[] = { GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, MXT224_ATCHCALST, MXT224_ATCHCALTHR
+}; /*byte 3: 0 */
+
+static u8 t9_config[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, MXT224_THRESHOLD_BATT, 2, 1,
+ 0,
+ 15, /* MOVHYSTI */
+ 1, MXT224_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 143, 55, 143, 90, 18
+};
+
+static u8 t18_config[] = { SPT_COMCONFIG_T18,
+ 0, 1
+};
+
+static u8 t20_config[] = { PROCI_GRIPFACESUPPRESSION_T20,
+ 7, 0, 0, 0, 0, 0, 0, 30, 20, 4, 15, 10
+};
+
+static u8 t22_config[] = { PROCG_NOISESUPPRESSION_T22,
+ 143, 0, 0, 0, 0, 0, 0, 3, MXT224_NOISE_THRESHOLD_BATT, 0,
+ 0, 29, 34, 39, 49, 58, 3
+};
+
+static u8 t28_config[] = { SPT_CTECONFIG_T28,
+ 0, 0, 3, 16, 19, 60
+};
+static u8 end_config[] = { RESERVED_T255 };
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t18_config,
+ t20_config,
+ t22_config,
+ t28_config,
+ end_config,
+};
+
+/*
+ Configuration for MXT224-E
+*/
+#ifdef CONFIG_TARGET_LOCALE_NAATT_TEMP
+#define MXT224E_THRESHOLD_BATT 50
+#define MXT224E_THRESHOLD_CHRG 40
+#define MXT224E_T48_THRESHOLD_BATT 33
+#define MXT224E_CALCFG_BATT 0x72
+#define MXT224E_CALCFG_CHRG 0x72
+#define MXT224E_ATCHFRCCALTHR_NORMAL 40
+#define MXT224E_ATCHFRCCALRATIO_NORMAL 55
+#define MXT224E_GHRGTIME_BATT 22
+#define MXT224E_GHRGTIME_CHRG 22
+#define MXT224E_ATCHCALST 4
+#define MXT224E_ATCHCALTHR 35
+#define MXT224E_BLEN_BATT 32
+#define MXT224E_T48_BLEN_BATT 0
+#define MXT224E_BLEN_CHRG 0
+#define MXT224E_MOVFILTER_BATT 14
+#define MXT224E_MOVFILTER_CHRG 46
+#define MXT224E_ACTVSYNCSPERX_NORMAL 29
+#define MXT224E_NEXTTCHDI_NORMAL 0
+#define MXT224E_NEXTTCHDI_CHRG 1
+#else
+#define MXT224E_THRESHOLD_BATT 50
+#define MXT224E_THRESHOLD_CHRG 40
+#define MXT224E_CALCFG_BATT 0x42
+#define MXT224E_CALCFG_CHRG 0x52
+#if defined(CONFIG_TARGET_LOCALE_NA)
+#define MXT224E_ATCHFRCCALTHR_NORMAL 45
+#define MXT224E_ATCHFRCCALRATIO_NORMAL 60
+#else
+#define MXT224E_ATCHFRCCALTHR_NORMAL 40
+#define MXT224E_ATCHFRCCALRATIO_NORMAL 55
+#endif
+#define MXT224E_GHRGTIME_BATT 27
+#define MXT224E_GHRGTIME_CHRG 22
+#define MXT224E_ATCHCALST 4
+#define MXT224E_ATCHCALTHR 35
+#define MXT224E_BLEN_BATT 32
+#define MXT224E_BLEN_CHRG 16
+#define MXT224E_MOVFILTER_BATT 13
+#define MXT224E_MOVFILTER_CHRG 46
+#define MXT224E_ACTVSYNCSPERX_NORMAL 32
+#define MXT224E_NEXTTCHDI_NORMAL 0
+#endif
+
+#if defined(CONFIG_TARGET_LOCALE_NAATT_TEMP)
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 25
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT224E_GHRGTIME_BATT, 0, 5, 1, 0, 0,
+ MXT224E_ATCHCALST, MXT224E_ATCHCALTHR,
+ MXT224E_ATCHFRCCALTHR_NORMAL,
+ MXT224E_ATCHFRCCALRATIO_NORMAL
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 15, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, MXT224E_NEXTTCHDI_NORMAL
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, MXT224E_ACTVSYNCSPERX_NORMAL, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_BATT, 20, 0, 0, 0, 0, 1, 2,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 10, 5, 0, 20, 0, 5, 0, 0,
+ 0, 0, 0, 0, MXT224E_T48_BLEN_BATT, MXT224E_T48_THRESHOLD_BATT, 2,
+ 15,
+ 1, MXT224E_MOVFILTER_BATT,
+ MXT224_MAX_MT_FINGERS, 5, 40, 235, 235, 10, 10, 160, 50, 143,
+ 80, 18, 15, MXT224E_NEXTTCHDI_NORMAL
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_CHRG, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 9, 5, 0, 15, 0, 20, 0, 0,
+ 0, 0, 0, 0, MXT224E_BLEN_CHRG, MXT224E_THRESHOLD_CHRG, 2,
+ 15, /* MOVHYSTI */
+ 1, 47,
+ MXT224_MAX_MT_FINGERS, 5, 40, 235, 235, 10, 10, 160, 50, 143,
+ 80, 18, 10, MXT224E_NEXTTCHDI_CHRG
+};
+
+#else
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT224E_GHRGTIME_BATT, 0, 5, 1, 0, 0,
+ MXT224E_ATCHCALST, MXT224E_ATCHCALTHR,
+ MXT224E_ATCHFRCCALTHR_NORMAL,
+ MXT224E_ATCHFRCCALRATIO_NORMAL
+};
+
+/* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 0
+};
+
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+#endif
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 15, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, MXT224E_NEXTTCHDI_NORMAL
+};
+#endif
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 13, 19, 44, 0, 0, 0
+};
+#else
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 14, 23, 44, 0, 0, 0
+};
+#endif
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, MXT224E_ACTVSYNCSPERX_NORMAL, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x52, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 10, 5, 0, 19, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 47,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x40, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#else
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 15,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 2
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, 50, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+#endif /*CONFIG_MACH_U1_NA_USCC_REV05 */
+#else
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_CHRG, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 9, 5, 0, 15, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, MXT224E_THRESHOLD_CHRG, 2,
+ 15, /* MOVHYSTI */
+ 1, 47,
+ MXT224_MAX_MT_FINGERS, 5, 40, 235, 235, 10, 10, 160, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_BATT, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 48, 4, 48,
+ 10, 0, 10, 5, 0, 20, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD_BATT, 2,
+ 15,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 10, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#endif /*CONFIG_TARGET_LOCALE_NA */
+#endif /*CONFIG_TARGET_LOCALE_NAATT */
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt224e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t23_config_e,
+ t25_config_e,
+ t38_config_e,
+ t40_config_e,
+ t42_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ end_config_e,
+};
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = MXT224_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config = mxt224_config,
+ .config_e = mxt224e_config,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .min_x = 0,
+ .max_x = 479,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .atchcalst = MXT224_ATCHCALST,
+ .atchcalsthr = MXT224_ATCHCALTHR,
+ .tchthr_batt = MXT224_THRESHOLD_BATT,
+ .tchthr_batt_init = MXT224_THRESHOLD_BATT_INIT,
+ .tchthr_charging = MXT224_THRESHOLD_CHRG,
+ .noisethr_batt = MXT224_NOISE_THRESHOLD_BATT,
+ .noisethr_charging = MXT224_NOISE_THRESHOLD_CHRG,
+ .movfilter_batt = MXT224_MOVFILTER_BATT,
+ .movfilter_charging = MXT224_MOVFILTER_CHRG,
+ .atchcalst_e = MXT224E_ATCHCALST,
+ .atchcalsthr_e = MXT224E_ATCHCALTHR,
+ .tchthr_batt_e = MXT224E_THRESHOLD_BATT,
+ .tchthr_charging_e = MXT224E_THRESHOLD_CHRG,
+ .calcfg_batt_e = MXT224E_CALCFG_BATT,
+ .calcfg_charging_e = MXT224E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT224E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT224E_ATCHFRCCALRATIO_NORMAL,
+ .chrgtime_batt_e = MXT224E_GHRGTIME_BATT,
+ .chrgtime_charging_e = MXT224E_GHRGTIME_CHRG,
+ .blen_batt_e = MXT224E_BLEN_BATT,
+ .blen_charging_e = MXT224E_BLEN_CHRG,
+ .movfilter_batt_e = MXT224E_MOVFILTER_BATT,
+ .movfilter_charging_e = MXT224E_MOVFILTER_CHRG,
+ .actvsyncsperx_e = MXT224E_ACTVSYNCSPERX_NORMAL,
+ .nexttchdi_e = MXT224E_NEXTTCHDI_NORMAL,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+
+#endif /*CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1 */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT540E)
+static void mxt540e_power_on(void)
+{
+ gpio_request(GPIO_TSP_SDA, "TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "TSP_SCL");
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA, S3C_GPIO_SFN(3));
+ s3c_gpio_cfgpin(GPIO_TSP_SCL, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA, S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(GPIO_TSP_SCL, S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_TSP_LDO_ON, GPIO_LEVEL_HIGH);
+ msleep(MXT540E_HW_RESET_TIME);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+
+ gpio_free(GPIO_TSP_SDA);
+ gpio_free(GPIO_TSP_SCL);
+}
+
+static void mxt540e_power_off(void)
+{
+ gpio_request(GPIO_TSP_SDA, "TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "TSP_SCL");
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA, S3C_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA, S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(GPIO_TSP_SCL, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_TSP_SDA, GPIO_LEVEL_LOW);
+ gpio_direction_output(GPIO_TSP_SCL, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_TSP_LDO_ON, GPIO_LEVEL_LOW);
+
+ gpio_free(GPIO_TSP_SDA);
+ gpio_free(GPIO_TSP_SCL);
+}
+
+static void mxt540e_power_on_oled(void)
+{
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+
+ mxt540e_power_on();
+
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+
+ gpio_free(GPIO_OLED_DET);
+
+ printk(KERN_INFO "[TSP] %s\n", __func__);
+}
+
+static void mxt540e_power_off_oled(void)
+{
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+
+ mxt540e_power_off();
+
+ gpio_free(GPIO_OLED_DET);
+
+ printk(KERN_INFO "[TSP] %s\n", __func__);
+}
+
+/*
+ Configuration for MXT540E
+*/
+#define MXT540E_MAX_MT_FINGERS 10
+#define MXT540E_CHRGTIME_BATT 48
+#define MXT540E_CHRGTIME_CHRG 48
+#define MXT540E_THRESHOLD_BATT 50
+#define MXT540E_THRESHOLD_CHRG 40
+#define MXT540E_ACTVSYNCSPERX_BATT 34
+#define MXT540E_ACTVSYNCSPERX_CHRG 34
+#define MXT540E_CALCFG_BATT 98
+#define MXT540E_CALCFG_CHRG 114
+#define MXT540E_ATCHFRCCALTHR_WAKEUP 8
+#define MXT540E_ATCHFRCCALRATIO_WAKEUP 180
+#define MXT540E_ATCHFRCCALTHR_NORMAL 40
+#define MXT540E_ATCHFRCCALRATIO_NORMAL 55
+
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 50
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT540E_CHRGTIME_BATT, 0, 5, 1, 0, 0, 4, 20,
+ MXT540E_ATCHFRCCALTHR_WAKEUP, MXT540E_ATCHFRCCALRATIO_WAKEUP
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 16, 26, 0, 192, MXT540E_THRESHOLD_BATT, 2, 6,
+ 10, 10, 10, 80, MXT540E_MAX_MT_FINGERS, 20, 40, 20, 31, 3,
+ 255, 4, 3, 3, 2, 2, 136, 60, 136, 40,
+ 18, 15, 0, 0, 0
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t19_config_e[] = { SPT_GPIOPWM_T19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t24_config_e[] = { PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t27_config_e[] = { PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t43_config_e[] = { SPT_DIGITIZER_T43,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 0, 16, MXT540E_ACTVSYNCSPERX_BATT, 0, 0, 1, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT540E_CALCFG_BATT, 0, 0, 0, 0, 0, 1, 2,
+ 0, 0, 0, 6, 6, 0, 0, 28, 4, 64,
+ 10, 0, 20, 6, 0, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 192, MXT540E_THRESHOLD_BATT, 2, 10, 10, 47,
+ MXT540E_MAX_MT_FINGERS, 5, 20, 253, 0, 7, 7, 160, 55, 136,
+ 0, 18, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT540E_CALCFG_CHRG, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 36, 4, 64,
+ 10, 0, 10, 6, 0, 20, 0, 0, 0, 0,
+ 0, 0, 0, 0, 112, MXT540E_THRESHOLD_CHRG, 2, 10, 5, 47,
+ MXT540E_MAX_MT_FINGERS, 5, 20, 253, 0, 7, 7, 160, 55, 136,
+ 0, 18, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static u8 t52_config_e[] = { TOUCH_PROXKEY_T52,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t55_config_e[] = {ADAPTIVE_T55,
+ 0, 0, 0, 0, 0, 0
+};
+
+static u8 t57_config_e[] = {SPT_GENERICDATA_T57,
+ 243, 25, 1
+};
+
+static u8 t61_config_e[] = {SPT_TIMER_T61,
+ 0, 0, 0, 0, 0
+};
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt540e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t19_config_e,
+ t24_config_e,
+ t25_config_e,
+ t27_config_e,
+ t40_config_e,
+ t42_config_e,
+ t43_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ t52_config_e,
+ t55_config_e,
+ t57_config_e,
+ t61_config_e,
+ end_config_e,
+};
+
+struct mxt540e_platform_data mxt540e_data = {
+ .max_finger_touches = MXT540E_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config_e = mxt540e_config,
+ .min_x = 0,
+ .max_x = 799,
+ .min_y = 0,
+ .max_y = 1279,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .chrgtime_batt = MXT540E_CHRGTIME_BATT,
+ .chrgtime_charging = MXT540E_CHRGTIME_CHRG,
+ .tchthr_batt = MXT540E_THRESHOLD_BATT,
+ .tchthr_charging = MXT540E_THRESHOLD_CHRG,
+ .actvsyncsperx_batt = MXT540E_ACTVSYNCSPERX_BATT,
+ .actvsyncsperx_charging = MXT540E_ACTVSYNCSPERX_CHRG,
+ .calcfg_batt_e = MXT540E_CALCFG_BATT,
+ .calcfg_charging_e = MXT540E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT540E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT540E_ATCHFRCCALRATIO_NORMAL,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .power_on = mxt540e_power_on,
+ .power_off = mxt540e_power_off,
+ .power_on_with_oleddet = mxt540e_power_on_oled,
+ .power_off_with_oleddet = mxt540e_power_off_oled,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p6_wacom_init_hw(void);
+static int p6_wacom_exit_hw(void);
+static int p6_wacom_suspend_hw(void);
+static int p6_wacom_resume_hw(void);
+static int p6_wacom_early_suspend_hw(void);
+static int p6_wacom_late_resume_hw(void);
+static int p6_wacom_reset_hw(void);
+static void p6_wacom_register_callbacks(struct wacom_g5_callbacks *cb);
+
+static struct wacom_g5_platform_data p6_wacom_platform_data = {
+ .x_invert = 1,
+ .y_invert = 0,
+ .xy_switch = 1,
+ .min_x = 0,
+ .max_x = WACOM_POSX_MAX,
+ .min_y = 0,
+ .max_y = WACOM_POSY_MAX,
+ .min_pressure = 0,
+ .max_pressure = WACOM_PRESSURE_MAX,
+ .gpio_pendct = GPIO_PEN_PDCT,
+ .init_platform_hw = p6_wacom_init_hw,
+/* .exit_platform_hw =, */
+ .suspend_platform_hw = p6_wacom_suspend_hw,
+ .resume_platform_hw = p6_wacom_resume_hw,
+ .early_suspend_platform_hw = p6_wacom_early_suspend_hw,
+ .late_resume_platform_hw = p6_wacom_late_resume_hw,
+ .reset_platform_hw = p6_wacom_reset_hw,
+ .register_cb = p6_wacom_register_callbacks,
+};
+
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p6_wacom_suspend_hw(void)
+{
+ return p6_wacom_early_suspend_hw();
+}
+
+static int p6_wacom_resume_hw(void)
+{
+ return p6_wacom_late_resume_hw();
+}
+
+static int p6_wacom_early_suspend_hw(void)
+{
+ gpio_direction_input(GPIO_PEN_PDCT);
+ gpio_set_value(GPIO_PEN_RESET, 0);
+ return 0;
+}
+
+static int p6_wacom_late_resume_hw(void)
+{
+ gpio_direction_output(GPIO_PEN_PDCT, 1);
+ gpio_set_value(GPIO_PEN_RESET, 1);
+ return 0;
+}
+
+static int p6_wacom_reset_hw(void)
+{
+ p6_wacom_early_suspend_hw();
+ msleep(200);
+ p6_wacom_late_resume_hw();
+
+ return 0;
+}
+
+static void p6_wacom_register_callbacks(struct wacom_g5_callbacks *cb)
+{
+ wacom_callbacks = cb;
+};
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+static struct i2c_board_info i2c_devs8_emul[];
+#endif
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+static void touchkey_init_hw(void)
+{
+ gpio_request(GPIO_3_TOUCH_INT, "3_TOUCH_INT");
+ s3c_gpio_setpull(GPIO_3_TOUCH_INT, S3C_GPIO_PULL_NONE);
+ s5p_register_gpio_interrupt(GPIO_3_TOUCH_INT);
+ gpio_direction_input(GPIO_3_TOUCH_INT);
+
+ i2c_devs8_emul[0].irq = gpio_to_irq(GPIO_3_TOUCH_INT);
+ irq_set_irq_type(gpio_to_irq(GPIO_3_TOUCH_INT), IRQF_TRIGGER_FALLING);
+ s3c_gpio_cfgpin(GPIO_3_TOUCH_INT, S3C_GPIO_SFN(0xf));
+}
+
+static int touchkey_suspend(void)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, TK_REGULATOR_NAME);
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+
+ return 1;
+}
+
+static int touchkey_resume(void)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, TK_REGULATOR_NAME);
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ return 1;
+}
+
+static int touchkey_power_on(bool on)
+{
+ int ret;
+
+ if (on) {
+ gpio_direction_output(GPIO_3_TOUCH_INT, 1);
+ irq_set_irq_type(gpio_to_irq(GPIO_3_TOUCH_INT), IRQF_TRIGGER_FALLING);
+ s3c_gpio_cfgpin(GPIO_3_TOUCH_INT, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_3_TOUCH_INT, S3C_GPIO_PULL_NONE);
+ }
+ else
+ gpio_direction_input(GPIO_3_TOUCH_INT);
+
+ if (on)
+ ret = touchkey_resume();
+ else
+ ret = touchkey_suspend();
+
+ return ret;
+}
+
+static int touchkey_led_power_on(bool on)
+{
+#if defined(LED_LDO_WITH_EN_PIN)
+ if (on) {
+ gpio_direction_output(GPIO_3_TOUCH_EN, 1);
+ } else {
+ gpio_direction_output(GPIO_3_TOUCH_EN, 0);
+ }
+#else
+ struct regulator *regulator;
+
+ if (on) {
+ regulator = regulator_get(NULL, "touch_led");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "touch_led");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+#endif
+ return 1;
+}
+
+static struct touchkey_platform_data touchkey_pdata = {
+ .gpio_sda = GPIO_3_TOUCH_SDA,
+ .gpio_scl = GPIO_3_TOUCH_SCL,
+ .gpio_int = GPIO_3_TOUCH_INT,
+ .init_platform_hw = touchkey_init_hw,
+ .suspend = touchkey_suspend,
+ .resume = touchkey_resume,
+ .power_on = touchkey_power_on,
+ .led_power_on = touchkey_led_power_on,
+};
+#endif /*CONFIG_KEYBOARD_CYPRESS_TOUCH*/
+
+
+
+#ifdef CONFIG_I2C_S3C2410
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ {I2C_BOARD_INFO("24c128", 0x50),}, /* Samsung S524AD0XD1 */
+ {I2C_BOARD_INFO("24c128", 0x52),}, /* Samsung S524AD0XD1 */
+};
+
+#ifdef CONFIG_S3C_DEV_I2C1
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("k3g", 0x69),
+ .irq = IRQ_EINT(1),
+ },
+ {
+ I2C_BOARD_INFO("k3dh", 0x19),
+ },
+#ifdef CONFIG_MACH_Q1_BD
+ {
+ I2C_BOARD_INFO("bmp180", 0x77),
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C2
+/* I2C2 */
+static struct i2c_board_info i2c_devs2[] __initdata = {
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C3
+/* I2C3 */
+static struct i2c_board_info i2c_devs3[] __initdata = {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data,
+ },
+#endif
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT540E
+ {
+ I2C_BOARD_INFO(MXT540E_DEV_NAME, 0x4c),
+ .platform_data = &mxt540e_data,
+ },
+#endif
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C4
+/* I2C4 */
+static struct i2c_board_info i2c_devs4[] __initdata = {
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C5
+/* I2C5 */
+static struct i2c_board_info i2c_devs5[] __initdata = {
+#ifdef CONFIG_MFD_MAX8998
+ {
+ I2C_BOARD_INFO("lp3974", 0x66),
+ .platform_data = &s5pv310_max8998_info,
+ },
+#endif
+#ifdef CONFIG_MFD_MAX8997
+ {
+ I2C_BOARD_INFO("max8997", (0xcc >> 1)),
+ .platform_data = &exynos4_max8997_info,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C6
+/* I2C6 */
+static struct i2c_board_info i2c_devs6[] __initdata = {
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+ {
+ I2C_BOARD_INFO("mc1n2", 0x3a), /* MC1N2 */
+ .platform_data = &mc1n2_pdata,
+ },
+#endif
+#ifdef CONFIG_EPEN_WACOM_G5SP
+ {
+ I2C_BOARD_INFO("wacom_g5sp_i2c", 0x56),
+ .platform_data = &p6_wacom_platform_data,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C7
+static struct akm8975_platform_data akm8975_pdata = {
+ .gpio_data_ready_int = GPIO_MSENSE_INT,
+};
+
+/* I2C7 */
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8975", 0x0C),
+ .platform_data = &akm8975_pdata,
+ },
+#ifdef CONFIG_VIDEO_TVOUT
+ {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+ },
+#endif
+};
+
+static void s3c_i2c7_cfg_gpio_u1(struct platform_device *dev)
+{
+ /* u1 magnetic sensor & MHL are using i2c7
+ * and the i2c line has external pull-resistors.
+ */
+ s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_NONE);
+}
+
+static struct s3c2410_platform_i2c default_i2c7_data __initdata = {
+ .bus_num = 7,
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s3c_i2c7_cfg_gpio_u1,
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data8 = {
+ .sda_pin = GPIO_3_TOUCH_SDA,
+ .scl_pin = GPIO_3_TOUCH_SCL,
+};
+
+struct platform_device s3c_device_i2c8 = {
+ .name = "i2c-gpio",
+ .id = 8,
+ .dev.platform_data = &gpio_i2c_data8,
+};
+
+/* I2C8 */
+static struct i2c_board_info i2c_devs8_emul[] = {
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+ {
+ I2C_BOARD_INFO("sec_touchkey", 0x20),
+ .platform_data = &touchkey_pdata,
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C9_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data9 = {
+ .sda_pin = GPIO_FUEL_SDA,
+ .scl_pin = GPIO_FUEL_SCL,
+};
+
+struct platform_device s3c_device_i2c9 = {
+ .name = "i2c-gpio",
+ .id = 9,
+ .dev.platform_data = &gpio_i2c_data9,
+};
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_U1
+
+struct max17042_reg_data max17042_init_data[] = {
+ { MAX17042_REG_CGAIN, 0x00, 0x00 },
+ { MAX17042_REG_MISCCFG, 0x03, 0x00 },
+ { MAX17042_REG_LEARNCFG, 0x07, 0x00 },
+ /* RCOMP: 0x0050 2011.02.29 from MAXIM */
+ { MAX17042_REG_RCOMP, 0x50, 0x00 },
+};
+
+struct max17042_reg_data max17042_alert_init_data[] = {
+#ifdef CONFIG_MACH_Q1_BD
+ /* SALRT Threshold setting to 1% wake lock */
+ { MAX17042_REG_SALRT_TH, 0x01, 0xFF },
+#elif defined(CONFIG_TARGET_LOCALE_KOR)
+ /* SALRT Threshold setting to 1% wake lock */
+ { MAX17042_REG_SALRT_TH, 0x01, 0xFF },
+#else
+ /* SALRT Threshold setting to 2% => 1% wake lock */
+ { MAX17042_REG_SALRT_TH, 0x02, 0xFF },
+#endif
+ /* VALRT Threshold setting (disable) */
+ { MAX17042_REG_VALRT_TH, 0x00, 0xFF },
+ /* TALRT Threshold setting (disable) */
+ { MAX17042_REG_TALRT_TH, 0x80, 0x7F },
+};
+
+bool max17042_is_low_batt(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!(psy->get_property(psy, POWER_SUPPLY_PROP_CAPACITY, &value)))
+ if (value.intval > SEC_BATTERY_SOC_3_6)
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(max17042_is_low_batt);
+
+static int max17042_low_batt_cb(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ value.intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
+ return psy->set_property(psy, POWER_SUPPLY_PROP_CAPACITY_LEVEL, &value);
+}
+
+#ifdef RECAL_SOC_FOR_MAXIM
+static bool max17042_need_soc_recal(void)
+{
+ pr_info("%s: HW(0x%x)\n", __func__, system_rev);
+
+ if (system_rev >= NO_NEED_RECAL_SOC_HW_REV)
+ return false;
+ else
+ return true;
+}
+#endif
+
+static struct max17042_platform_data s5pv310_max17042_info = {
+ .low_batt_cb = max17042_low_batt_cb,
+ .init = max17042_init_data,
+ .init_size = sizeof(max17042_init_data),
+ .alert_init = max17042_alert_init_data,
+ .alert_init_size = sizeof(max17042_alert_init_data),
+ .alert_gpio = GPIO_FUEL_ALERT,
+ .alert_irq = 0,
+ .enable_current_sense = false,
+ .enable_gauging_temperature = true,
+#ifdef RECAL_SOC_FOR_MAXIM
+ .need_soc_recal = max17042_need_soc_recal,
+#endif
+};
+#endif /* CONFIG_BATTERY_MAX17042_U1 */
+
+/* I2C9 */
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_U1
+ {
+ I2C_BOARD_INFO("max17042", 0x36),
+ .platform_data = &s5pv310_max17042_info,
+ .irq = IRQ_EINT(19),
+ },
+#endif
+#ifdef CONFIG_BATTERY_MAX17040
+ {
+ I2C_BOARD_INFO("max17040", 0x36),
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C10_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data10 __initdata = {
+ .sda_pin = GPIO_USB_SDA,
+ .scl_pin = GPIO_USB_SCL,
+};
+
+struct platform_device s3c_device_i2c10 = {
+ .name = "i2c-gpio",
+ .id = 10,
+ .dev.platform_data = &gpio_i2c_data10,
+};
+
+/* I2C10 */
+static struct fsa9480_platform_data fsa9480_info = {
+};
+
+static struct i2c_board_info i2c_devs10_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("fsa9480", 0x25),
+ .platform_data = &fsa9480_info,
+ },
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C11_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data11 = {
+ .sda_pin = GPIO_PS_ALS_SDA,
+ .scl_pin = GPIO_PS_ALS_SCL,
+};
+
+struct platform_device s3c_device_i2c11 = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &gpio_i2c_data11,
+};
+
+/* I2C11 */
+#ifdef CONFIG_SENSORS_CM3663
+static int cm3663_ldo(bool on)
+{
+ struct regulator *regulator;
+
+ if (on) {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+static struct cm3663_platform_data cm3663_pdata = {
+ .proximity_power = cm3663_ldo,
+};
+#ifdef CONFIG_SENSORS_PAS2M110
+static struct pas2m110_platform_data pas2m110_pdata = {
+ .proximity_power = cm3663_ldo,
+};
+#endif
+#endif
+#ifdef CONFIG_SENSORS_GP2A_ANALOG
+static int gp2a_power(bool on)
+{
+ struct regulator *regulator;
+
+ if (on) {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+static struct gp2a_platform_data gp2a_pdata = {
+ .p_out = GPIO_PS_ALS_INT,
+ .power = gp2a_power,
+};
+#endif
+
+static struct i2c_board_info i2c_devs11_emul[] __initdata = {
+#ifdef CONFIG_MACH_U1_BD
+ {
+ I2C_BOARD_INFO("cm3663", 0x20),
+ .irq = GPIO_PS_ALS_INT,
+ .platform_data = &cm3663_pdata,
+ },
+#ifdef CONFIG_SENSORS_PAS2M110
+ {
+ I2C_BOARD_INFO("pas2m110", (0x88>>1)),
+ .irq = GPIO_PS_ALS_INT,
+ .platform_data = &pas2m110_pdata,
+ },
+#endif
+#endif
+#ifdef CONFIG_MACH_Q1_BD
+ {
+ I2C_BOARD_INFO("gp2a", (0x88 >> 1)),
+ .platform_data = &gp2a_pdata,
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C14_EMUL
+static struct i2c_gpio_platform_data i2c14_platdata = {
+ .sda_pin = GPIO_NFC_SDA,
+ .scl_pin = GPIO_NFC_SCL,
+ .udelay = 2,
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c14 = {
+ .name = "i2c-gpio",
+ .id = 14,
+ .dev.platform_data = &i2c14_platdata,
+};
+
+static struct pn544_i2c_platform_data pn544_pdata = {
+ .irq_gpio = GPIO_NFC_IRQ,
+ .ven_gpio = GPIO_NFC_EN,
+ .firm_gpio = GPIO_NFC_FIRM,
+};
+
+static struct i2c_board_info i2c_devs14[] __initdata = {
+ {
+ I2C_BOARD_INFO("pn544", 0x2b),
+ .irq = IRQ_EINT(15),
+ .platform_data = &pn544_pdata,
+ },
+};
+
+static unsigned int nfc_gpio_table[][4] = {
+ {GPIO_NFC_IRQ, S3C_GPIO_INPUT, GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+ {GPIO_NFC_EN, S3C_GPIO_OUTPUT, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_NFC_FIRM, S3C_GPIO_OUTPUT, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+/* {GPIO_NFC_SCL, S3C_GPIO_INPUT, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, */
+/* {GPIO_NFC_SDA, S3C_GPIO_INPUT, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, */
+};
+
+void nfc_setup_gpio(void)
+{
+ /* s3c_config_gpio_alive_table(ARRAY_SIZE(nfc_gpio_table),
+ nfc_gpio_table); */
+ int array_size = ARRAY_SIZE(nfc_gpio_table);
+ u32 i, gpio;
+ for (i = 0; i < array_size; i++) {
+ gpio = nfc_gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(nfc_gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, nfc_gpio_table[i][3]);
+ if (nfc_gpio_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(gpio, nfc_gpio_table[i][2]);
+ }
+
+ /* s3c_gpio_cfgpin(GPIO_NFC_IRQ, EINT_MODE); */
+ /* s3c_gpio_setpull(GPIO_NFC_IRQ, S3C_GPIO_PULL_DOWN); */
+}
+#endif
+
+#if defined(CONFIG_VIDEO_S5K5BAFX)
+static struct i2c_gpio_platform_data i2c12_platdata = {
+ .sda_pin = VT_CAM_SDA_18V,
+ .scl_pin = VT_CAM_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c12 = {
+ .name = "i2c-gpio",
+ .id = 12,
+ .dev.platform_data = &i2c12_platdata,
+};
+
+/* I2C12 */
+static struct i2c_board_info i2c_devs12_emul[] __initdata = {
+ /* need to work here */
+};
+#endif
+
+#ifdef CONFIG_FM_SI4709_MODULE
+static struct i2c_gpio_platform_data i2c16_platdata = {
+ .sda_pin = GPIO_FM_SDA_28V,
+ .scl_pin = GPIO_FM_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c16 = {
+ .name = "i2c-gpio",
+ .id = 16,
+ .dev.platform_data = &i2c16_platdata,
+};
+
+static struct i2c_board_info i2c_devs16[] __initdata = {
+ {
+ I2C_BOARD_INFO("Si4709", (0x20 >> 1)),
+ },
+};
+#endif
+
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cal_x_max = 480,
+ .cal_y_max = 800,
+ .cal_param = {
+ 33, -9156, 34720100, 14819, 57, -4234968, 65536,
+ },
+};
+#endif
+
+#ifdef CONFIG_ISDBT_FC8100
+static struct i2c_board_info i2c_devs17[] __initdata = {
+ {
+ I2C_BOARD_INFO("isdbti2c", 0x77),
+ },
+};
+
+static struct i2c_gpio_platform_data i2c17_platdata = {
+ .sda_pin = GPIO_ISDBT_SDA_28V,
+ .scl_pin = GPIO_ISDBT_SCL_28V,
+ .udelay = 3, /* kHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c17 = {
+ .name = "i2c-gpio",
+ .id = 17,
+ .dev.platform_data = &i2c17_platdata,
+};
+#endif
+
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#ifdef CONFIG_FB_S5P_S6E8AA0
+/* for Geminus based on MIPI-DSI interface */
+static struct s3cfb_lcd s6e8aa0 = {
+ .name = "s6e8aa0",
+ .width = 800,
+ .height = 1280,
+ .p_width = 64,
+ .p_height = 106,
+ .bpp = 24,
+
+ .freq = 57,
+
+ /* minumun value is 0 except for wr_act time. */
+ .cpu_timing = {
+ .cs_setup = 0,
+ .wr_setup = 0,
+ .wr_act = 1,
+ .wr_hold = 0,
+ },
+
+ .timing = {
+ .h_fp = 10,
+ .h_bp = 10,
+ .h_sw = 10,
+ .v_fp = 13,
+ .v_fpe = 1,
+ .v_bp = 1,
+ .v_bpe = 1,
+ .v_sw = 2,
+ .cmd_allow_len = 11, /*v_fp=stable_vfp + cmd_allow_len */
+ .stable_vfp = 2,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+#endif
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+#ifdef CONFIG_FB_S5P_S6E8AA0
+ .lcd = &s6e8aa0
+#endif
+};
+
+#ifdef CONFIG_FB_S5P_S6E8AA0
+static int reset_lcd(void)
+{
+ int err;
+
+ /* Set GPY4[5] OUTPUT HIGH */
+ err = gpio_request(EXYNOS4_GPY4(5), "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY4(5) for "
+ "lcd reset control\n");
+ return -EPERM;
+ }
+
+ gpio_direction_output(EXYNOS4_GPY4(5), 1);
+ msleep(5);
+ gpio_set_value(EXYNOS4_GPY4(5), 0);
+ msleep(5);
+ gpio_set_value(EXYNOS4_GPY4(5), 1);
+ msleep(5);
+
+ gpio_free(EXYNOS4_GPY4(5));
+
+ return 0;
+}
+#endif
+static void lcd_cfg_gpio(void)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_EN */
+ s3c_gpio_cfgpin(GPIO_LCD_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_LCD_EN, S3C_GPIO_PULL_NONE);
+
+ return;
+}
+
+static int lcd_power_on(void *ld, int enable)
+{
+ struct regulator *regulator;
+ int err;
+
+ printk(KERN_INFO "%s : enable=%d\n", __func__, enable);
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(EXYNOS4_GPY4(5), "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY4[5] for "
+ "MLCD_RST control\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(GPIO_LCD_EN, "LCD_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY3[1] for "
+ "LCD_EN control\n");
+ return -EPERM;
+ }
+
+ if (enable) {
+#ifdef CONFIG_MACH_Q1_BD
+ if (system_rev < 8) {
+ regulator = regulator_get(NULL, "vlcd_2.2v");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+#endif
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+#ifdef CONFIG_MACH_Q1_BD
+ if (system_rev < 8) {
+ regulator = regulator_get(NULL, "vlcd_2.2v");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ } else
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+#endif
+
+ gpio_set_value(EXYNOS4_GPY4(5), 0);
+ }
+
+ /* Release GPIO */
+ gpio_free(EXYNOS4_GPY4(5));
+ gpio_free(GPIO_LCD_EN);
+
+ return 0;
+}
+
+static void __init mipi_fb_init(void)
+{
+ struct s5p_platform_dsim *dsim_pd = NULL;
+ struct mipi_ddi_platform_data *mipi_ddi_pd = NULL;
+ struct dsim_lcd_config *dsim_lcd_info = NULL;
+
+ /* set platform data */
+
+ /* gpio pad configuration for rgb and spi interface. */
+ lcd_cfg_gpio();
+
+ /*
+ * register lcd panel data.
+ */
+ printk(KERN_INFO "%s :: fb_platform_data.hw_ver = 0x%x\n",
+ __func__, fb_platform_data.hw_ver);
+
+ fb_platform_data.mipi_is_enabled = 1;
+ fb_platform_data.interface_mode = FIMD_CPU_INTERFACE;
+
+ dsim_pd = (struct s5p_platform_dsim *)
+ s5p_device_dsim.dev.platform_data;
+
+ dsim_pd->platform_rev = 1;
+
+ dsim_lcd_info = dsim_pd->dsim_lcd_info;
+
+#ifdef CONFIG_FB_S5P_S6E8AA0
+ dsim_lcd_info->lcd_panel_info = (void *)&s6e8aa0;
+
+ /* 483Mbps for Q1 */
+ dsim_pd->dsim_info->p = 4;
+ dsim_pd->dsim_info->m = 161;
+ dsim_pd->dsim_info->s = 1;
+#endif
+
+ mipi_ddi_pd = (struct mipi_ddi_platform_data *)
+ dsim_lcd_info->mipi_ddi_pd;
+ mipi_ddi_pd->lcd_reset = reset_lcd;
+ mipi_ddi_pd->lcd_power_on = lcd_power_on;
+
+ platform_device_register(&s5p_device_dsim);
+
+ s3cfb_set_platdata(&fb_platform_data);
+
+ printk(KERN_INFO
+ "platform data of %s lcd panel has been registered.\n",
+ dsim_pd->lcd_panel_name);
+}
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 0,
+ .start = 0,
+ .size = 0
+};
+
+static struct android_pmem_platform_data pmem_gpu1_pdata = {
+ .name = "pmem_gpu1",
+ .no_allocator = 1,
+ .cached = 0,
+ .start = 0,
+ .size = 0,
+};
+
+static struct platform_device pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = {
+ .platform_data = &pmem_pdata},
+};
+
+static struct platform_device pmem_gpu1_device = {
+ .name = "android_pmem",
+ .id = 1,
+ .dev = {
+ .platform_data = &pmem_gpu1_pdata},
+};
+
+static void __init android_pmem_set_platdata(void)
+{
+#if defined(CONFIG_S5P_MEM_CMA)
+ pmem_pdata.size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K;
+ pmem_gpu1_pdata.size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K;
+#else
+ pmem_pdata.start = (u32) s5p_get_media_memory_bank(S5P_MDEV_PMEM, 0);
+ pmem_pdata.size = (u32) s5p_get_media_memsize_bank(S5P_MDEV_PMEM, 0);
+ pmem_gpu1_pdata.start =
+ (u32) s5p_get_media_memory_bank(S5P_MDEV_PMEM_GPU1, 0);
+ pmem_gpu1_pdata.size =
+ (u32) s5p_get_media_memsize_bank(S5P_MDEV_PMEM_GPU1, 0);
+#endif
+}
+#endif
+
+/* USB EHCI */
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdkc210_ehci_pdata;
+
+static void __init smdkc210_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdkc210_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdkc210_ohci_pdata;
+
+static void __init smdkc210_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdkc210_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdkc210_usbgadget_pdata;
+
+#include <linux/usb/android_composite.h>
+static void __init smdkc210_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdkc210_usbgadget_pdata;
+
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ struct android_usb_platform_data *android_pdata =
+ s3c_device_android_usb.dev.platform_data;
+ if (android_pdata) {
+ unsigned int newluns = 2;
+ printk(KERN_DEBUG "usb: %s: default luns=%d, new luns=%d\n",
+ __func__, android_pdata->nluns, newluns);
+ android_pdata->nluns = newluns;
+ } else {
+ printk(KERN_DEBUG "usb: %s android_pdata is not available\n",
+ __func__);
+ }
+#endif
+
+ s5p_usbgadget_set_platdata(pdata);
+
+ pdata = s3c_device_usbgadget.dev.platform_data;
+ if (pdata) {
+ /* Enables HS Transmitter pre-emphasis [20] */
+ pdata->phy_tune_mask = 0;
+ pdata->phy_tune_mask |= (0x1 << 20);
+ pdata->phy_tune |= (0x1 << 20);
+
+#if defined(CONFIG_MACH_U1_KOR_SKT) || defined(CONFIG_MACH_U1_KOR_KT)
+ /* Squelch Threshold Tune [13:11] (101 : -10%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x5 << 11);
+
+ /* HS DC Voltage Level Adjustment [3:0] (1011 : +16%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xb;
+#elif defined(CONFIG_MACH_U1_KOR_LGT)
+ /* Squelch Threshold Tune [13:11] (100 : -5%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x4 << 11);
+
+ /* HS DC Voltage Level Adjustment [3:0] (1100 : +18%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xc;
+#else
+ /* Squelch Threshold Tune [13:11] (101 : -10%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x5 << 11);
+ /* HS DC Voltage Level Adjustment [3:0] (1011 : +16%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xb;
+#endif
+
+ printk(KERN_DEBUG "usb: %s tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+ }
+}
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+#endif
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+static struct platform_device watchdog_reset_device = {
+ .name = "watchdog-reset",
+ .id = -1,
+};
+#endif
+
+static struct platform_device *smdkc210_devices[] __initdata = {
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ &watchdog_reset_device,
+#endif
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_LCD1],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#endif
+
+#ifdef CONFIG_I2C_S3C2410
+ &s3c_device_i2c0,
+#if defined(CONFIG_S3C_DEV_I2C1)
+ &s3c_device_i2c1,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C2)
+ &s3c_device_i2c2,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C3)
+ &s3c_device_i2c3,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C4)
+ &s3c_device_i2c4,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C5)
+ &s3c_device_i2c5,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C6)
+ &s3c_device_i2c6,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C7)
+ &s3c_device_i2c7,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C8_EMUL)
+ &s3c_device_i2c8,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C9_EMUL)
+ &s3c_device_i2c9,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C10_EMUL)
+ &s3c_device_i2c10,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C11_EMUL)
+ &s3c_device_i2c11,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C14_EMUL)
+ &s3c_device_i2c14,
+#endif
+#if defined(CONFIG_VIDEO_S5K5BAFX)
+ &s3c_device_i2c12,
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ &s3c_device_i2c15,
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+ &s3c_device_i2c16,
+#endif
+#ifdef CONFIG_ISDBT_FC8100
+ &s3c_device_i2c17, /* ISDBT */
+#endif
+#if defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER)
+ &s3c_device_i2c19, /* SMB136, SMB328 */
+#endif
+#endif
+
+ /* consumer driver should resume after resuming i2c drivers */
+ &u1_regulator_consumer,
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+#ifdef CONFIG_S3C_ADC
+ &s3c_device_adc,
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ &s3c_device_ts,
+#elif CONFIG_S3C_DEV_ADC1
+ &s3c_device_ts1,
+#endif
+#endif
+ &u1_keypad,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#ifdef CONFIG_BATTERY_SEC_U1
+ &sec_device_battery,
+#endif
+#ifdef CONFIG_LEDS_MAX8997
+ &sec_device_leds_max8997,
+#endif
+#ifdef CONFIG_CHARGER_MAX8922_U1
+ &max8922_device_charger,
+#endif
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(2d),
+ &SYSMMU_PLATDEV(tv),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+
+ &samsung_asoc_dma,
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+ &samsung_asoc_idma,
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ &exynos_device_spi0,
+#endif
+
+#ifdef CONFIG_PHONE_IPC_SPI
+ &ipc_spi_device,
+#endif
+
+/* mainline fimd */
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd0,
+#if defined(CONFIG_LCD_AMS369FG06)
+ &s3c_device_spi_gpio,
+#elif defined(CONFIG_LCD_WA101S)
+ &smdkc210_lcd_wa101s,
+#elif defined(CONFIG_LCD_LTE480WV)
+ &smdkc210_lcd_lte480wv,
+#endif
+#endif
+/* legacy fimd */
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ &s3c_device_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ &ld9040_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_NT35560
+ &nt35560_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_MDNIE
+ &mdnie_device,
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+ &pmem_device,
+ &pmem_gpu1_device,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#endif
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ &s5p_device_jpeg,
+#endif
+#if defined CONFIG_USB_EHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ehci,
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &s3c_device_timer[2],
+ &s3c_device_timer[3],
+#endif
+#ifdef CONFIG_VIDEO_TSI
+ &s3c_device_tsi,
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+#ifdef CONFIG_BT_BCM4330
+ &bcm4330_bluetooth_device,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+#ifdef CONFIG_BUSFREQ_OPP
+ &exynos4_busfreq,
+#endif
+#ifdef CONFIG_SEC_DEV_JACK
+ &sec_device_jack,
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ &host_notifier_device,
+#endif
+ &s3c_device_usb_otghcd,
+};
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct s5p_platform_tmu u1_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 61,
+ .start_1st_throttle = 64,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110,
+ .start_emergency = 120,
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000, /* 800MHz in KHz order */
+ .limit_2nd_throttle = 200000, /* 200MHz in KHz order */
+ },
+};
+#endif
+
+#if defined CONFIG_USB_EHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ehci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ehci);
+}
+late_initcall(s5p_ehci_device_initcall);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+
+};
+
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#if defined(CONFIG_S5P_MEM_CMA)
+static void __init exynos4_cma_region_reserve(struct cma_region *regions_normal,
+ struct cma_region *regions_secure)
+{
+ struct cma_region *reg;
+ size_t size_secure = 0, align_secure = 0;
+ phys_addr_t paddr = 0;
+
+ for (reg = regions_normal; reg->size != 0; reg++) {
+ if (WARN_ON(cma_early_region_register(reg)))
+ continue;
+
+ if ((reg->alignment & (reg->alignment - 1)) || reg->reserved)
+ continue;
+
+ if (reg->start) {
+ if (!memblock_is_region_reserved(reg->start, reg->size)
+ && memblock_reserve(reg->start, reg->size) >= 0)
+ reg->reserved = 1;
+ } else {
+ paddr = __memblock_alloc_base(reg->size, reg->alignment,
+ MEMBLOCK_ALLOC_ACCESSIBLE);
+ if (paddr) {
+ reg->start = paddr;
+ reg->reserved = 1;
+ }
+ }
+ }
+
+ if (regions_secure && regions_secure->size) {
+ for (reg = regions_secure; reg->size != 0; reg++)
+ size_secure += reg->size;
+
+ reg--;
+
+ align_secure = reg->alignment;
+ BUG_ON(align_secure & (align_secure - 1));
+
+ paddr -= size_secure;
+ paddr &= ~(align_secure - 1);
+
+ if (!memblock_reserve(paddr, size_secure)) {
+ do {
+ reg->start = paddr;
+ reg->reserved = 1;
+ paddr += reg->size;
+
+ if (WARN_ON(cma_early_region_register(reg)))
+ memblock_free(reg->start, reg->size);
+ } while (reg-- != regions_secure);
+ }
+ }
+}
+
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM
+ {
+ .name = "pmem",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1
+ {
+ .name = "pmem_gpu1",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifndef CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .name = "fimc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3
+ {
+ .name = "fimc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE
+ {
+ .name = "ion",
+ .size = CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE * SZ_1K,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .name = "jpeg",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT
+ {
+ .name = "tvout",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT * SZ_1K,
+ .start = 0,
+ },
+#endif
+ {
+ .size = 0,
+ },
+ };
+
+ static const char map[] __initconst =
+ "android_pmem.0=pmem;android_pmem.1=pmem_gpu1;"
+ "s3cfb.0=fimd;exynos4-fb.0=fimd;"
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc3=fimc3;"
+#ifdef CONFIG_ION_EXYNOS
+ "ion-exynos=ion;"
+#endif
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc/A=mfc0,mfc-secure;"
+ "s3c-mfc/B=mfc1,mfc-normal;"
+ "s3c-mfc/AB=mfc;"
+#endif
+ "samsung-rp=srp;"
+ "s5p-jpeg=jpeg;"
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ "exynos4-fimc-is=fimc_is;"
+#endif
+ "s5p-fimg2d=fimg2d;"
+ "s5p-tvout=tvout";
+
+ cma_set_defaults(regions, map);
+ exynos4_cma_region_reserve(regions, NULL);
+
+}
+#endif
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimd0, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(2d, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(rot, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+#if defined CONFIG_VIDEO_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#elif defined CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_FB_S3C
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimd0).dev, &s5p_device_fimd0.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(2d).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+}
+
+static void __init smdkc210_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
+
+#if defined(CONFIG_S5P_MEM_CMA)
+ exynos4_reserve_mem();
+#else
+ s5p_reserve_mem(S5P_RANGE_MFC);
+#endif
+
+ /* as soon as INFORM3 is visible, sec_debug is ready to run */
+ sec_debug_init();
+}
+
+static void __init universal_tsp_init(void)
+{
+ int gpio;
+
+ /* TSP_LDO_ON: XMDMADDR_11 */
+ gpio = GPIO_TSP_LDO_ON;
+ gpio_request(gpio, "TSP_LDO_ON");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+
+ /* TSP_INT: XMDMADDR_7 */
+ gpio = GPIO_TSP_INT;
+ gpio_request(gpio, "TSP_INT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+
+ printk(KERN_INFO "%s touch : %d\n", __func__, i2c_devs3[0].irq);
+#ifdef CONFIG_MACH_Q1_BD
+ gpio_request(GPIO_TSP_SDA, "TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "TSP_SCL");
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+#endif
+}
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p6_wacom_init_hw(void)
+{
+ int gpio;
+ int ret;
+
+ gpio = GPIO_PEN_RESET;
+ ret = gpio_request(gpio, "PEN_RESET");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ gpio_direction_output(gpio, 1);
+
+ gpio = GPIO_PEN_SLP;
+ ret = gpio_request(gpio, "PEN_SLP");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_direction_output(gpio, 0);
+
+ gpio = GPIO_PEN_PDCT;
+ ret = gpio_request(gpio, "PEN_PDCT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_register_gpio_interrupt(gpio);
+ gpio_direction_input(gpio);
+
+ irq_set_irq_type(gpio_to_irq(gpio), IRQ_TYPE_EDGE_BOTH);
+
+ gpio = GPIO_PEN_IRQ;
+ ret = gpio_request(gpio, "PEN_IRQ");
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_register_gpio_interrupt(gpio);
+ gpio_direction_input(gpio);
+
+ i2c_devs6[1].irq = gpio_to_irq(gpio);
+ irq_set_irq_type(i2c_devs6[1].irq, IRQ_TYPE_EDGE_RISING);
+
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+
+ return 0;
+}
+
+static int __init p6_wacom_init(void)
+{
+ p6_wacom_init_hw();
+ printk(KERN_INFO "[E-PEN] : wacom IC initialized.\n");
+ return 0;
+}
+#endif
+
+static void __init smdkc210_machine_init(void)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+#endif
+ /* initialise the gpios */
+ u1_config_gpio_table();
+ exynos4_sleep_gpio_table_set = u1_config_sleep_gpio_table;
+
+#ifdef CONFIG_I2C_S3C2410
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+#ifdef CONFIG_S3C_DEV_I2C1
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C2
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C3
+ universal_tsp_init();
+ s3c_i2c3_set_platdata(NULL);
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C4
+ s3c_i2c4_set_platdata(NULL);
+ i2c_register_board_info(4, i2c_devs4, ARRAY_SIZE(i2c_devs4));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C5
+ s3c_i2c5_set_platdata(NULL);
+ s3c_gpio_cfgpin(GPIO_PMIC_IRQ, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_PMIC_IRQ, S3C_GPIO_PULL_NONE);
+ i2c_devs5[0].irq = gpio_to_irq(GPIO_PMIC_IRQ);
+ i2c_register_board_info(5, i2c_devs5, ARRAY_SIZE(i2c_devs5));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C6
+#ifdef CONFIG_EPEN_WACOM_G5SP
+ p6_wacom_init();
+#endif
+ s3c_i2c6_set_platdata(NULL);
+ i2c_register_board_info(6, i2c_devs6, ARRAY_SIZE(i2c_devs6));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C7
+ s3c_i2c7_set_platdata(&default_i2c7_data);
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ printk(KERN_INFO "%s() register sii9234 driver\n", __func__);
+
+ i2c_register_board_info(15, tuna_i2c15_boardinfo,
+ ARRAY_SIZE(tuna_i2c15_boardinfo));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+#ifdef CONFIG_KEYBOARD_CYPRESS_TOUCH
+ touchkey_init_hw();
+#endif
+ i2c_register_board_info(8, i2c_devs8_emul, ARRAY_SIZE(i2c_devs8_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C9_EMUL
+ i2c_register_board_info(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C10_EMUL
+ i2c_register_board_info(10, i2c_devs10_emul,
+ ARRAY_SIZE(i2c_devs10_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C11_EMUL
+ s3c_gpio_setpull(GPIO_PS_ALS_INT, S3C_GPIO_PULL_NONE);
+ i2c_register_board_info(11, i2c_devs11_emul,
+ ARRAY_SIZE(i2c_devs11_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C14_EMUL
+ nfc_setup_gpio();
+ i2c_register_board_info(14, i2c_devs14, ARRAY_SIZE(i2c_devs14));
+#endif
+#if defined(CONFIG_VIDEO_S5K5BAFX)
+ i2c_register_board_info(12, i2c_devs12_emul,
+ ARRAY_SIZE(i2c_devs12_emul));
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+ i2c_register_board_info(16, i2c_devs16, ARRAY_SIZE(i2c_devs16));
+#endif
+#ifdef CONFIG_ISDBT_FC8100
+ i2c_register_board_info(17, i2c_devs17, ARRAY_SIZE(i2c_devs17));
+#endif
+
+#if defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER)
+ i2c_register_board_info(19, i2c_devs19_emul,
+ ARRAY_SIZE(i2c_devs19_emul));
+#endif
+#endif
+
+ /* 400 kHz for initialization of MMC Card */
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS3) & 0xfffffff0)
+ | 0x9, EXYNOS4_CLKDIV_FSYS3);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS2) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS2);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS1) & 0xfff0fff0)
+ | 0x90009, EXYNOS4_CLKDIV_FSYS1);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&exynos4_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&exynos4_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&exynos4_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&exynos4_hsmmc3_pdata);
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+
+#ifdef CONFIG_FB_S3C
+#ifdef CONFIG_LCD_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+ s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&ams369fg06_data);
+#else
+ s3cfb_set_platdata(NULL);
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_JPEG
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+#endif
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+#endif
+#ifdef CONFIG_S3C_DEV_ADC1
+ s3c24xx_ts1_set_platdata(&s3c_ts_platform);
+#endif
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+ android_pmem_set_platdata();
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ /* fimc */
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(NULL);
+ s3c_fimc2_set_platdata(&fimc_plat);
+ s3c_fimc3_set_platdata(NULL);
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(&u1_tmu_data);
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X)
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ);
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimg2d.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdkc210_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdkc210_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdkc210_usbgadget_init();
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ ld9040_fb_init();
+#endif
+#ifdef CONFIG_FB_S5P_NT35560
+ nt35560_fb_init();
+#endif
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+ mipi_fb_init();
+#endif
+
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+ u1_sound_init();
+#endif
+
+ brcm_wlan_init();
+
+ exynos_sysmmu_init();
+
+ platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+#ifdef CONFIG_SEC_THERMISTOR
+ platform_device_register(&sec_device_thermistor);
+#endif
+
+#ifdef CONFIG_FB_S3C
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll",
+ 800 * MHZ);
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ sclk = clk_get(spi0_dev, "dout_spi0");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+ prnt = clk_get(spi0_dev, "mout_mpll");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+ clk_set_parent(sclk, prnt);
+
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS4_GPB(1), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ tdmb_dev_init();
+#endif
+
+}
+
+static void __init exynos_init_reserve(void)
+{
+ sec_debug_magic_init();
+}
+
+#ifdef CONFIG_MACH_U1_KOR_SKT
+#define MODEL_NAME "SHW-M250S"
+#elif defined(CONFIG_MACH_U1_KOR_KT)
+#define MODEL_NAME "SHW-M250K"
+#elif defined(CONFIG_MACH_U1_KOR_LGT)
+#define MODEL_NAME "SHW-M250L"
+#else
+#define MODEL_NAME "SMDK4210"
+#endif
+
+MACHINE_START(SMDKC210, MODEL_NAME)
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdkc210_map_io,
+ .init_machine = smdkc210_machine_init,
+ .timer = &exynos4_timer,
+ .init_early = &exynos_init_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/mach-u1cam.c b/arch/arm/mach-exynos/mach-u1cam.c
new file mode 100644
index 0000000..b5ddf3b
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-u1cam.c
@@ -0,0 +1,6993 @@
+/* linux/arch/arm/mach-exynos/mach-u1cam.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_core.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio_event.h>
+#include <linux/lcd.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <linux/switch.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+#include <linux/sensor/k3g.h>
+#include <linux/sensor/k3dh.h>
+#include <linux/sensor/ak8975.h>
+#ifdef CONFIG_MACH_U1_BD
+#include <linux/sensor/cm3663.h>
+#include <linux/sensor/pas2m110.h>
+#endif
+#ifdef CONFIG_MACH_Q1_BD
+#include <linux/sensor/gp2a_analog.h>
+#endif
+#include <linux/pn544.h>
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+#include <linux/mfd/mc1n2_pdata.h>
+#endif
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT540E)
+#include <linux/i2c/mxt540e.h>
+#else
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC
+#include <linux/i2c/mxt224_gc.h>
+#else
+#include <linux/i2c/mxt224_u1.h>
+#endif
+#endif
+#include <linux/memblock.h>
+#include <linux/power_supply.h>
+#if defined(CONFIG_S5P_MEM_CMA)
+#include <linux/cma.h>
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+#include <linux/android_pmem.h>
+#endif
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <video/platform_lcd.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/exynos4.h>
+#include <plat/clock.h>
+#include <plat/hwmon.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb-s5p.h>
+#include <plat/fimc.h>
+#include <plat/csis.h>
+#include <plat/gpio-cfg.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/keypad.h>
+#include <plat/sdhci.h>
+#include <plat/mshci.h>
+#include <plat/iic.h>
+#include <plat/sysmmu.h>
+#include <plat/pd.h>
+#include <plat/regs-fb-v4.h>
+#include <plat/media.h>
+#include <plat/udc-hs.h>
+#include <plat/s5p-clock.h>
+#include <plat/tvout.h>
+#include <plat/fimg2d.h>
+#include <plat/ehci.h>
+#include <plat/usbgadget.h>
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+#include <plat/s3c64xx-spi.h>
+#endif
+
+#include <mach/map.h>
+#include <mach/exynos-clock.h>
+#include <mach/media.h>
+#include <plat/regs-fb.h>
+
+#include <mach/dev-sysmmu.h>
+#include <mach/dev.h>
+#include <mach/regs-clock.h>
+#include <mach/exynos-ion.h>
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#include <mach/mipi_ddi.h>
+#include <mach/dsim.h>
+#include <plat/fb-s5p.h>
+#endif
+
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC) || defined(CONFIG_VIDEO_MFC5X)
+#include <plat/s5p-mfc.h>
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+#include <mach/spi-clocks.h>
+#endif
+
+#ifdef CONFIG_VIDEO_M9MO
+#include <media/m9mo_platform.h>
+#endif
+#ifdef CONFIG_VIDEO_S5K5BAFX
+#include <media/s5k5bafx_platform.h>
+#endif
+
+#if defined(CONFIG_EXYNOS4_SETUP_THERMAL)
+#include <plat/s5p-tmu.h>
+#include <mach/regs-tmu.h>
+#endif
+
+#ifdef CONFIG_SEC_DEV_JACK
+#include <linux/sec_jack.h>
+#endif
+
+#ifdef CONFIG_BT_BCM4330
+#include <mach/board-bluetooth-bcm.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_LD9040
+#include <linux/ld9040.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+#include <linux/mdnie.h>
+#endif
+
+#include <../../../drivers/video/samsung/s3cfb.h>
+#include "u1.h"
+
+#include <mach/sec_debug.h>
+
+#ifdef CONFIG_SAMSUNG_MHL
+#include <linux/irq.h>
+#include <linux/sii9234.h>
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_U1
+#include <linux/power/sec_battery_u1.h>
+#endif
+
+#ifdef CONFIG_SEC_THERMISTOR
+#include <mach/sec_thermistor.h>
+#endif
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_U1
+#include <linux/power/max17042_fuelgauge_u1.h>
+#endif
+
+#ifdef CONFIG_CHARGER_MAX8922_U1
+#include <linux/power/max8922_charger_u1.h>
+#endif
+
+#ifdef CONFIG_SMB136_CHARGER_Q1
+#include <linux/power/smb136_charger_q1.h>
+#endif
+
+#ifdef CONFIG_SMB328_CHARGER
+#include <linux/power/smb328_charger.h>
+#endif
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+#include <linux/wacom_i2c.h>
+static struct wacom_g5_callbacks *wacom_callbacks;
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+#include <mach/tdmb_pdata.h>
+#endif
+
+#ifdef CONFIG_LEDS_MAX8997
+#include <linux/leds-max8997.h>
+#endif
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+#define SMDKC210_UFCON_GPS (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG8 | \
+ S5PV210_UFCON_RXTRIG32)
+
+static struct s3c2410_uartcfg smdk4212_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+#ifdef CONFIG_BT_BCM4330
+ .wake_peer = bcm_bt_lpm_exit_lpm_locked,
+#endif
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_GPS,
+ .set_runstate = set_gps_uart_op,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKC210_UCON_DEFAULT,
+ .ulcon = SMDKC210_ULCON_DEFAULT,
+ .ufcon = SMDKC210_UFCON_DEFAULT,
+ },
+};
+
+#define WRITEBACK_ENABLED
+
+#ifdef CONFIG_VIDEO_FIMC
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+ */
+
+#ifdef CONFIG_VIDEO_M9MO
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ }
+
+static int m9mo_get_i2c_busnum(void)
+{
+#ifdef CONFIG_VIDEO_M9MO_USE_SWI2C
+ return 25;
+#else
+ return 0;
+#endif
+}
+
+static int m9mo_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_ERR "%s: in\n", __func__);
+
+ /* CIS_LDO_1.8V_EN -> CIS 1.2 */
+ ret = gpio_request(GPIO_CAM_SENSOR_CORE, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_ISP_RESET, "ISP_RESET");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(ISP_RESET)\n");
+ return ret;
+ }
+
+ /* CIS 1.8V */
+ regulator = regulator_get(NULL, "cis_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cis_1.8v");
+ udelay(10);
+
+ /* CIS_2.8 */
+ regulator = regulator_get(NULL, "cis_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cis_2.8v");
+ udelay(10);
+
+ /* CIS_1.2V */
+ ret = gpio_direction_output(GPIO_CAM_SENSOR_CORE, 1);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ udelay(10);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core");
+
+ udelay(10);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp");
+ udelay(120); /* at least */
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ udelay(70);
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ mdelay(4);
+
+ gpio_free(GPIO_CAM_SENSOR_CORE);
+ gpio_free(GPIO_ISP_RESET);
+
+ printk(KERN_DEBUG "%s: out\n", __func__);
+
+ return ret;
+}
+#ifdef CONFIG_SAMSUNG_MHL
+
+
+static void sii9234_cfg_gpio(void)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_AP_SDA_18V, S3C_GPIO_SFN(0x0));
+ s3c_gpio_setpull(GPIO_AP_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_AP_SCL_18V, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_AP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_MHL_WAKE_UP, S3C_GPIO_INPUT);
+ irq_set_irq_type(MHL_WAKEUP_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_setpull(GPIO_MHL_WAKE_UP, S3C_GPIO_PULL_DOWN);
+
+ gpio_request(GPIO_MHL_INT, "MHL_INT");
+ s5p_register_gpio_interrupt(GPIO_MHL_INT);
+ s3c_gpio_setpull(GPIO_MHL_INT, S3C_GPIO_PULL_DOWN);
+ irq_set_irq_type(MHL_INT_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_cfgpin(GPIO_MHL_INT, GPIO_MHL_INT_AF);
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+#else
+ if (system_rev < 7) {
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+ } else {
+ s3c_gpio_cfgpin(GPIO_HDMI_EN_REV07, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_HDMI_EN_REV07, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN_REV07, S3C_GPIO_PULL_NONE);
+ }
+#endif
+
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_MHL_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_SEL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_LOW);
+
+}
+
+void sii9234_power_onoff(bool on)
+{
+ pr_info("%s(%d)\n", __func__, on);
+
+ if (on) {
+ /*s3c_gpio_cfgpin(GPIO_HDMI_EN,S3C_GPIO_OUTPUT);*/
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+#else
+ if (system_rev < 7)
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+ else
+ gpio_set_value(GPIO_HDMI_EN_REV07, GPIO_LEVEL_HIGH);
+#endif
+
+ s3c_gpio_setpull(GPIO_AP_SCL_18V, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_AP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ } else {
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+#else
+ if (system_rev < 7)
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ else
+ gpio_set_value(GPIO_HDMI_EN_REV07, GPIO_LEVEL_LOW);
+#endif
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ }
+ pr_info("[MHL]%s : %d\n", __func__, on);
+}
+
+void sii9234_reset(void)
+{
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+
+}
+
+void mhl_usb_switch_control(bool on)
+{
+ pr_info("%s() [MHL] USB path change : %s\n",
+ __func__, on ? "MHL" : "USB");
+ if (on == 1) {
+ if (gpio_get_value(GPIO_MHL_SEL))
+ pr_info("[MHL] GPIO_MHL_SEL :already 1\n");
+ else {
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_HIGH);
+ /* sii9234_cfg_power(1); // onegun */
+ /* sii9234_init(); // onegun */
+ }
+ } else {
+ if (!gpio_get_value(GPIO_MHL_SEL))
+ pr_info("[MHL] GPIO_MHL_SEL :already0\n");
+ else {
+ /* sii9234_cfg_power(0); // onegun */
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_LOW);
+ }
+ }
+}
+
+static struct sii9234_platform_data sii9234_pdata = {
+ .init = sii9234_cfg_gpio,
+ .mhl_sel = mhl_usb_switch_control,
+ .hw_onoff = sii9234_power_onoff,
+ .hw_reset = sii9234_reset,
+ .enable_vbus = NULL,
+ .vbus_present = NULL,
+};
+
+static struct i2c_board_info __initdata tuna_i2c15_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("sii9234_mhl_tx", 0x72>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_tpi", 0x7A>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_hdmi_rx", 0x92>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_cbus", 0xC8>>1),
+ .platform_data = &sii9234_pdata,
+ },
+};
+
+#define I2C_BUS_ID_MHL 15
+static struct i2c_gpio_platform_data gpio_i2c_data15 = {
+ .sda_pin = GPIO_MHL_SDA_18V,
+ .scl_pin = GPIO_MHL_SCL_18V,
+ .udelay = 2,
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+struct platform_device s3c_device_i2c15 = {
+ .name = "i2c-gpio",
+ .id = I2C_BUS_ID_MHL,
+ .dev = {
+ .platform_data = &gpio_i2c_data15,
+ }
+};
+
+#endif
+
+static int m9mo_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_ISP_RESET, "ISP_RESET");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(ISP_RESET)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_CAM_SENSOR_CORE, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR(ret, "output reset");
+
+ mdelay(2);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp");
+ udelay(500); /* 100us -> 500us */
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable isp_core");
+
+ ret = gpio_direction_output(GPIO_CAM_SENSOR_CORE, 0);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ udelay(10);
+
+ regulator = regulator_get(NULL, "cis_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cis_2.8v");
+ udelay(500); /* 100us -> 500us */
+
+ regulator = regulator_get(NULL, "cis_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cis_1.8v");
+ udelay(500); /* 100us -> 500us */
+
+ gpio_free(GPIO_ISP_RESET);
+ gpio_free(GPIO_CAM_SENSOR_CORE);
+
+ return ret;
+}
+
+int s3c_csis_power(int enable)
+{
+ struct regulator *regulator;
+ int ret = 0;
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ /* mipi_1.1v ,mipi_1.8v are always powered-on.
+ * If they are off, we then power them on.
+ */
+ if (enable) {
+ /* VMIPI_1.1V */
+ regulator = regulator_get(NULL, "vmipi_1.1v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.1v is off. so ON\n",
+ __func__);
+ ret = regulator_enable(regulator);
+ CAM_CHECK_ERR(ret, "enable vmipi_1.1v");
+ }
+ regulator_put(regulator);
+
+ /* VMIPI_1.8V */
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.8v is off. so ON\n",
+ __func__);
+ ret = regulator_enable(regulator);
+ CAM_CHECK_ERR(ret, "enable vmipi_1.8v");
+ }
+ regulator_put(regulator);
+ }
+ printk(KERN_DEBUG "%s: out\n", __func__);
+
+ return 0;
+
+error_out:
+ printk(KERN_ERR "%s: ERROR: failed to check mipi-power\n", __func__);
+ return 0;
+}
+
+#if defined(CONFIG_MACH_Q1_BD)
+static bool is_torch;
+#endif
+
+static int m9mo_flash_power(int enable)
+{
+ struct regulator *flash = regulator_get(NULL, "led_flash");
+ struct regulator *movie = regulator_get(NULL, "led_movie");
+
+ if (enable) {
+
+#if defined(CONFIG_MACH_Q1_BD)
+ if (regulator_is_enabled(movie)) {
+ printk(KERN_DEBUG "%s: m9mo_torch set~~~~", __func__);
+ is_torch = true;
+ goto torch_exit;
+ }
+ is_torch = false;
+#endif
+ regulator_set_current_limit(flash, 490000, 530000);
+ regulator_enable(flash);
+ regulator_set_current_limit(movie, 90000, 110000);
+ regulator_enable(movie);
+ } else {
+
+#if defined(CONFIG_MACH_Q1_BD)
+ if (is_torch)
+ goto torch_exit;
+#endif
+
+ if (regulator_is_enabled(flash))
+ regulator_disable(flash);
+ if (regulator_is_enabled(movie))
+ regulator_disable(movie);
+ }
+torch_exit:
+ regulator_put(flash);
+ regulator_put(movie);
+
+ return 0;
+}
+
+static int m9mo_power(int enable)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s %s\n", __func__, enable ? "on" : "down");
+ if (enable) {
+ ret = m9mo_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = m9mo_power_down();
+
+ ret = s3c_csis_power(enable);
+/* m9mo_flash_power(enable);*/
+
+error_out:
+ return ret;
+}
+
+static int m9mo_config_isp_irq(void)
+{
+ s3c_gpio_cfgpin(GPIO_ISP_INT, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_ISP_INT, S3C_GPIO_PULL_NONE);
+ return 0;
+}
+
+static struct m9mo_platform_data m9mo_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .config_isp_irq = m9mo_config_isp_irq,
+ .irq = IRQ_EINT(13),
+};
+
+static struct i2c_board_info m9mo_i2c_info = {
+ I2C_BOARD_INFO("M9MO", 0x1F),
+ .platform_data = &m9mo_plat,
+};
+
+static struct s3c_platform_camera m9mo = {
+ .id = CAMERA_CSI_C,
+ .clk_name = "sclk_cam0",
+ .get_i2c_busnum = m9mo_get_i2c_busnum,
+ .cam_power = m9mo_power, /*smdkv310_mipi_cam0_reset, */
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT */
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &m9mo_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 4,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif /* #ifdef CONFIG_VIDEO_M9MO */
+
+#ifdef CONFIG_VIDEO_S5K5BAFX
+static int s5k5bafx_get_i2c_busnum(void)
+{
+ return 12;
+}
+
+static int s5k5bafx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ /* printk("%s: in\n", __func__); */
+
+ ret = gpio_request(GPIO_ISP_RESET, "ISP_RESET");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(ISP_RESET)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_15V, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_VT_CAM_15V)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ if (system_rev >= 9) {
+#endif
+ s3c_gpio_setpull(VT_CAM_SDA_18V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(VT_CAM_SCL_18V, S3C_GPIO_PULL_NONE);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ }
+#endif
+
+ /* ISP_RESET low */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ udelay(100);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable isp_core");
+ udelay(10);
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output io_en");
+ udelay(300); /* don't change me */
+
+ /* VT_CORE_1.5V */
+ ret = gpio_direction_output(GPIO_VT_CAM_15V, 1);
+ CAM_CHECK_ERR_RET(ret, "output vt_15v");
+ udelay(100);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp");
+ udelay(10);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_1.8v");
+ udelay(10);
+
+ /* CAM_VGA_nSTBY */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "output VGA_nSTBY");
+ udelay(50);
+
+ /* Mclk */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ udelay(100);
+
+ /* CAM_VGA_nRST */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "output VGA_nRST");
+ mdelay(2);
+
+ gpio_free(GPIO_ISP_RESET);
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_VT_CAM_15V);
+ gpio_free(GPIO_CAM_VGA_nSTBY);
+ gpio_free(GPIO_CAM_VGA_nRST);
+
+ return 0;
+}
+
+static int s5k5bafx_power_off(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ /* printk("n%s: in\n", __func__); */
+
+ ret = gpio_request(GPIO_CAM_VGA_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VGA_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_VT_CAM_15V, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_VT_CAM_15V)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPE2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+
+ /* CAM_VGA_nRST */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nRST, 0);
+ CAM_CHECK_ERR(ret, "output VGA_nRST");
+ udelay(100);
+
+ /* Mclk */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_VGA_nSTBY */
+ ret = gpio_direction_output(GPIO_CAM_VGA_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "output VGA_nSTBY");
+ udelay(20);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_1.8v");
+ udelay(10);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp");
+ udelay(10);
+
+ /* VT_CORE_1.5V */
+ ret = gpio_direction_output(GPIO_VT_CAM_15V, 0);
+ CAM_CHECK_ERR(ret, "output vt_1.5v");
+ udelay(10);
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 0);
+ CAM_CHECK_ERR(ret, "output io_en");
+ udelay(10);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable isp_core");
+
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ if (system_rev >= 9) {
+#endif
+ gpio_direction_input(VT_CAM_SDA_18V);
+ s3c_gpio_setpull(VT_CAM_SDA_18V, S3C_GPIO_PULL_DOWN);
+ gpio_direction_input(VT_CAM_SCL_18V);
+ s3c_gpio_setpull(VT_CAM_SCL_18V, S3C_GPIO_PULL_DOWN);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ }
+#endif
+
+#if defined(CONFIG_MACH_Q1_BD)
+ mdelay(350);
+#endif
+
+ gpio_free(GPIO_CAM_VGA_nRST);
+ gpio_free(GPIO_CAM_VGA_nSTBY);
+ gpio_free(GPIO_VT_CAM_15V);
+ gpio_free(GPIO_CAM_IO_EN);
+
+ return 0;
+}
+
+static int s5k5bafx_power(int onoff)
+{
+ int ret = 0;
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ u32 cfg = 0;
+#endif
+ printk(KERN_INFO "%s(): %s\n", __func__, onoff ? "on" : "down");
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ cfg = readl(S5P_VA_GPIO2 + 0x002c);
+#endif
+
+ if (onoff) {
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ writel(cfg | 0x0080, S5P_VA_GPIO2 + 0x002c);
+#endif
+
+ ret = s5k5bafx_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else {
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ writel(cfg & 0xff3f, S5P_VA_GPIO2 + 0x002c);
+#endif
+ ret = s5k5bafx_power_off();
+ /* s3c_i2c0_force_stop(); *//* DSLIM. Should be implemented */
+ }
+
+ ret = s3c_csis_power(onoff);
+
+error_out:
+ return ret;
+}
+
+static struct s5k5bafx_platform_data s5k5bafx_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+};
+
+static struct i2c_board_info s5k5bafx_i2c_info = {
+ I2C_BOARD_INFO("S5K5BAFX", 0x5A >> 1),
+ .platform_data = &s5k5bafx_plat,
+};
+
+static struct s3c_platform_camera s5k5bafx = {
+ .id = CAMERA_CSI_D,
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ .get_i2c_busnum = s5k5bafx_get_i2c_busnum,
+ .info = &s5k5bafx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_name = "sclk_cam0",
+ .clk_rate = 24000000,
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = s5k5bafx_power,
+};
+#endif
+
+#ifdef WRITEBACK_ENABLED
+static int get_i2c_busnum_writeback(void)
+{
+ return 0;
+}
+
+static struct i2c_board_info writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .get_i2c_busnum = get_i2c_busnum_writeback,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 800,
+ .width = 480,
+ .height = 800,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 480,
+ .height = 800,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+void cam_cfg_gpio(struct platform_device *pdev)
+{
+ int ret = 0;
+ printk(KERN_INFO "\n\n\n%s: pdev->id=%d\n", __func__, pdev->id);
+
+ if (pdev->id != 0)
+ return;
+}
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+#ifdef CONFIG_ITU_A
+ .default_cam = CAMERA_PAR_A,
+#endif
+#ifdef CONFIG_ITU_B
+ .default_cam = CAMERA_PAR_B,
+#endif
+#ifdef CONFIG_CSI_C
+ .default_cam = CAMERA_CSI_C,
+#endif
+#ifdef CONFIG_CSI_D
+ .default_cam = CAMERA_CSI_D,
+#endif
+ .camera = {
+#ifdef CONFIG_VIDEO_M9MO
+ &m9mo,
+#endif
+#ifdef CONFIG_VIDEO_S5K5BAFX
+ &s5k5bafx,
+#endif
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+ },
+ .hw_ver = 0x51,
+ .cfg_gpio = cam_cfg_gpio,
+};
+#endif /* CONFIG_VIDEO_FIMC */
+
+static DEFINE_MUTEX(notify_lock);
+
+#define DEFINE_MMC_CARD_NOTIFIER(num) \
+static void (*hsmmc##num##_notify_func)(struct platform_device *, int state); \
+static int ext_cd_init_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func); \
+ hsmmc##num##_notify_func = notify_func; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+} \
+static int ext_cd_cleanup_hsmmc##num(void (*notify_func)( \
+ struct platform_device *, int state)) \
+{ \
+ mutex_lock(&notify_lock); \
+ WARN_ON(hsmmc##num##_notify_func != notify_func); \
+ hsmmc##num##_notify_func = NULL; \
+ mutex_unlock(&notify_lock); \
+ return 0; \
+}
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ DEFINE_MMC_CARD_NOTIFIER(3)
+#endif
+
+/*
+ * call this when you need sd stack to recognize insertion or removal of card
+ * that can't be told by SDHCI regs
+ */
+
+void mmc_force_presence_change(struct platform_device *pdev)
+{
+ void (*notify_func)(struct platform_device *, int state) = NULL;
+ mutex_lock(&notify_lock);
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ printk(KERN_INFO "---------test logs pdev : %p s3c_device_hsmmc3 %p\n",
+ pdev, &s3c_device_hsmmc3);
+ if (pdev == &s3c_device_hsmmc3) {
+ notify_func = hsmmc3_notify_func;
+ printk(KERN_INFO "---------test logs notify_func : %p\n",
+ notify_func);
+ }
+#endif
+
+ if (notify_func)
+ notify_func(pdev, 1);
+ else
+ pr_warn("%s: called for device with no notifier\n", __func__);
+ mutex_unlock(&notify_lock);
+}
+EXPORT_SYMBOL_GPL(mmc_force_presence_change);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+static struct s3c_sdhci_platdata exynos4_hsmmc0_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA,
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC2
+static struct s3c_sdhci_platdata exynos4_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = EXYNOS4_GPX3(4),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .vmmc_name = "vtf_2.8v",
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static struct s3c_sdhci_platdata exynos4_hsmmc3_pdata __initdata = {
+/* For Wi-Fi */
+#if 0
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+#else
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .pm_flags = S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME,
+ .ext_cd_init = ext_cd_init_hsmmc3,
+ .ext_cd_cleanup = ext_cd_cleanup_hsmmc3,
+#endif
+};
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static struct s3c_mshci_platdata exynos4_mshc_pdata __initdata = {
+ .cd_type = S3C_MSHCI_CD_PERMANENT,
+#if defined(CONFIG_EXYNOS4_MSHC_8BIT) && \
+ defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50 | MMC_CAP_CMD23,
+#elif defined(CONFIG_EXYNOS4_MSHC_8BIT)
+ .max_width = 8,
+ .host_caps = MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+#elif defined(CONFIG_EXYNOS4_MSHC_DDR)
+ .host_caps = MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_CMD23,
+#endif
+ .int_power_gpio = GPIO_XMMC0_CDn,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+static struct fimg2d_platdata fimg2d_data __initdata = {
+ .hw_ver = 30,
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 267 * 1000000, /* 266 Mhz */
+};
+#endif
+
+#ifdef CONFIG_FB_S3C
+#if defined(CONFIG_LCD_AMS369FG06)
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int err = 0;
+
+ err = gpio_request(EXYNOS4_GPX0(6), "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_free(EXYNOS4_GPX0(6));
+
+ return 1;
+}
+
+static struct lcd_platform_data ams369fg06_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 100, /* 100ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = (void *)&ams369fg06_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s5p_device_fimd0.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win2 = {
+ .win_mode = {
+ .left_margin = 9,
+ .right_margin = 9,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .virtual_x = 480,
+ .virtual_y = 1600,
+ .width = 48,
+ .height = 80,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#elif defined(CONFIG_LCD_WA101S)
+static void lcd_wa101s_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_wa101s_data = {
+ .set_power = lcd_wa101s_set_power,
+};
+
+static struct platform_device smdkc210_lcd_wa101s = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_wa101s_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1366,
+ .yres = 768,
+ },
+ .virtual_x = 1366,
+ .virtual_y = 768 * 2,
+ .width = 223,
+ .height = 125,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+#ifndef CONFIG_LCD_WA101S /* temporarily disables window1 */
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 80,
+ .right_margin = 48,
+ .upper_margin = 14,
+ .lower_margin = 3,
+ .hsync_len = 32,
+ .vsync_len = 5,
+ .xres = 1366,
+ .yres = 768,
+ },
+ .virtual_x = 1366,
+ .virtual_y = 768 * 2,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+#elif defined(CONFIG_LCD_LTE480WV)
+static void lcd_lte480wv_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 1);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ /* fire nRESET on power up */
+ gpio_request(EXYNOS4_GPX0(6), "GPX0");
+
+ gpio_direction_output(EXYNOS4_GPX0(6), 1);
+ mdelay(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ mdelay(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(EXYNOS4_GPD0(1), "GPD0");
+ gpio_direction_output(EXYNOS4_GPD0(1), 0);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc210_lcd_lte480wv_data = {
+ .set_power = lcd_lte480wv_set_power,
+};
+
+static struct platform_device smdkc210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s5p_device_fimd0.dev,
+ .dev.platform_data = &smdkc210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_pd_win smdkc210_fb_win1 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .virtual_x = 800,
+ .virtual_y = 960,
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+#endif
+
+static struct s3c_fb_platdata smdkc210_lcd0_pdata __initdata = {
+#if defined(CONFIG_LCD_AMS369FG06) || defined(CONFIG_LCD_WA101S) || \
+ defined(CONFIG_LCD_LTE480WV)
+ .win[0] = &smdkc210_fb_win0,
+#ifndef CONFIG_LCD_WA101S /* temporarily disables window1 */
+ .win[1] = &smdkc210_fb_win1,
+#endif
+#endif
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+#if defined(CONFIG_LCD_AMS369FG06)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN |
+ VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_WA101S)
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#elif defined(CONFIG_LCD_LTE480WV)
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+#endif
+ .setup_gpio = exynos4_fimd0_gpio_setup_24bpp,
+};
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+static struct s3c64xx_spi_csinfo spi0_csi[] = {
+ [0] = {
+ .line = EXYNOS4_GPB(1),
+ .set_level = gpio_set_value,
+ .fb_delay = 0x0,
+ },
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {
+ .modalias = "tdmbspi",
+ .platform_data = NULL,
+ .max_speed_hz = 5000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ },
+#elif defined(CONFIG_ISDBT_FC8100)
+ {
+ .modalias = "isdbtspi",
+ .platform_data = NULL,
+ .max_speed_hz = 400000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = (SPI_MODE_0|SPI_CS_HIGH),
+ .controller_data = &spi0_csi[0],
+ },
+
+#else
+ {
+ .modalias = "spidev",
+ .platform_data = NULL,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .controller_data = &spi0_csi[0],
+ }
+#endif
+};
+#endif
+
+#ifdef CONFIG_FB_S5P
+unsigned int lcdtype;
+static int __init lcdtype_setup(char *str)
+{
+ get_option(&str, &lcdtype);
+ return 1;
+}
+__setup("lcdtype=", lcdtype_setup);
+
+#ifdef CONFIG_FB_S5P_LD9040
+unsigned int ld9040_lcdtype;
+static int __init ld9040_lcdtype_setup(char *str)
+{
+ get_option(&str, &ld9040_lcdtype);
+ return 1;
+}
+
+__setup("ld9040.get_lcdtype=0x", ld9040_lcdtype_setup);
+
+static int lcd_cfg_gpio(void)
+{
+ int i, f3_end = 4;
+
+ for (i = 0; i < 8; i++) {
+ /* set GPF0,1,2[0:7] for RGB Interface and Data line (32bit) */
+ s3c_gpio_cfgpin(EXYNOS4_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF0(i), S3C_GPIO_PULL_NONE);
+
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < f3_end; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+#ifdef MAX_DRVSTR
+ /* drive strength to max */
+ writel(0xffffffff, S5P_VA_GPIO + 0x18c);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1ac);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xffffff, S5P_VA_GPIO + 0x1ec);
+#else
+ /* drive strength to 2X */
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x18c);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1ac);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xaaaaaa, S5P_VA_GPIO + 0x1ec);
+#endif
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+#else
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(3), S3C_GPIO_PULL_NONE);
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY0(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4210_GPE2(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4210_GPE2(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(1), S3C_GPIO_PULL_NONE);
+#endif
+
+ return 0;
+}
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ struct regulator *regulator;
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return 0;
+ }
+
+ if (enable) {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+ }
+
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ reset_gpio = EXYNOS4_GPY4(5);
+#else
+ reset_gpio = EXYNOS4_GPX1(3);
+#endif
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_request(reset_gpio, "MLCD_RST");
+
+ gpio_direction_output(reset_gpio, 1);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 1);
+
+ gpio_free(reset_gpio);
+
+ return 1;
+}
+
+static int lcd_gpio_cfg_earlysuspend(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ reset_gpio = EXYNOS4_GPY4(5);
+#else
+ reset_gpio = EXYNOS4_GPX1(3);
+#endif
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+
+ gpio_free(reset_gpio);
+
+ return 0;
+}
+
+static int lcd_gpio_cfg_lateresume(struct lcd_device *ld)
+{
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+#else
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(3), S3C_GPIO_PULL_NONE);
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY0(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY0(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4210_GPE2(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4210_GPE2(3), S3C_GPIO_PULL_NONE);
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(1), S3C_GPIO_PULL_NONE);
+#endif
+
+ return 0;
+}
+
+static struct s3cfb_lcd ld9040_info = {
+ .width = 480,
+ .height = 800,
+ .p_width = 56,
+ .p_height = 93,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 16,
+ .h_bp = 14,
+ .h_sw = 2,
+ .v_fp = 10,
+ .v_fpe = 1,
+ .v_bp = 4,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+static struct lcd_platform_data ld9040_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .gpio_cfg_earlysuspend = lcd_gpio_cfg_earlysuspend,
+ .gpio_cfg_lateresume = lcd_gpio_cfg_lateresume,
+ /* it indicates whether lcd panel is enabled from u-boot. */
+ .lcd_enabled = 1,
+ .reset_delay = 20, /* 10ms */
+ .power_on_delay = 20, /* 20ms */
+ .power_off_delay = 200, /* 120ms */
+ .pdata = &u1_panel_data,
+};
+
+#define LCD_BUS_NUM 3
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define DISPLAY_CS EXYNOS4_GPY4(3)
+#else
+#define DISPLAY_CS EXYNOS4_GPY0(3)
+#endif
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+#if !defined(CONFIG_MACH_U1_KOR_LGT)
+#define DISPLAY_CLK EXYNOS4_GPY3(1)
+#define DISPLAY_SI EXYNOS4_GPY3(3)
+#else
+#define DISPLAY_CLK EXYNOS4210_GPE2(3)
+#define DISPLAY_SI EXYNOS4_GPX1(1)
+#endif
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device ld9040_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+ .lcd = &ld9040_info,
+};
+
+/* reading with 3-WIRE SPI with GPIO */
+static inline void setcs(u8 is_on)
+{
+ gpio_set_value(DISPLAY_CS, is_on);
+}
+
+static inline void setsck(u8 is_on)
+{
+ gpio_set_value(DISPLAY_CLK, is_on);
+}
+
+static inline void setmosi(u8 is_on)
+{
+ gpio_set_value(DISPLAY_SI, is_on);
+}
+
+static inline unsigned int getmiso(void)
+{
+ return !!gpio_get_value(DISPLAY_SI);
+}
+
+static inline void setmosi2miso(u8 is_on)
+{
+ if (is_on)
+ s3c_gpio_cfgpin(DISPLAY_SI, S3C_GPIO_INPUT);
+ else
+ s3c_gpio_cfgpin(DISPLAY_SI, S3C_GPIO_OUTPUT);
+}
+
+struct spi_ops ops = {
+ .setcs = setcs,
+ .setsck = setsck,
+ .setmosi = setmosi,
+ .setmosi2miso = setmosi2miso,
+ .getmiso = getmiso,
+};
+
+static void __init ld9040_fb_init(void)
+{
+ struct ld9040_panel_data *pdata;
+
+ strcpy(spi_board_info[0].modalias, "ld9040");
+ spi_board_info[0].platform_data = (void *)&ld9040_platform_data;
+
+ lcdtype = max(ld9040_lcdtype, lcdtype);
+
+ if (lcdtype == LCDTYPE_SM2_A2)
+ ld9040_platform_data.pdata = &u1_panel_data_a2;
+ else if (lcdtype == LCDTYPE_M2)
+ ld9040_platform_data.pdata = &u1_panel_data_m2;
+
+ pdata = ld9040_platform_data.pdata;
+ pdata->ops = &ops;
+
+ printk(KERN_INFO "%s :: lcdtype=%d\n", __func__, lcdtype);
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ if (!ld9040_platform_data.lcd_enabled)
+ lcd_cfg_gpio();
+ s3cfb_set_platdata(&fb_platform_data);
+}
+#endif
+
+#ifdef CONFIG_FB_S5P_NT35560
+static int lcd_cfg_gpio(void)
+{
+ int i, f3_end = 4;
+
+ for (i = 0; i < 8; i++) {
+ /* set GPF0,1,2[0:7] for RGB Interface and Data line (32bit) */
+ s3c_gpio_cfgpin(EXYNOS4_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF0(i), S3C_GPIO_PULL_NONE);
+
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < f3_end; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+#ifdef MAX_DRVSTR
+ /* drive strength to max */
+ writel(0xffffffff, S5P_VA_GPIO + 0x18c);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1ac);
+ writel(0xffffffff, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xffffff, S5P_VA_GPIO + 0x1ec);
+#else
+ /* drive strength to 2X */
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x18c);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1ac);
+ writel(0xaaaaaaaa, S5P_VA_GPIO + 0x1cc);
+ writel(readl(S5P_VA_GPIO + 0x1ec) | 0xaaaaaa, S5P_VA_GPIO + 0x1ec);
+#endif
+
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ struct regulator *regulator;
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return 0;
+ }
+
+ if (enable) {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "vlcd_1.8v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_1.8v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+ }
+
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+ reset_gpio = EXYNOS4_GPY4(5);
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_request(reset_gpio, "MLCD_RST");
+
+ gpio_direction_output(reset_gpio, 1);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 1);
+
+ gpio_free(reset_gpio);
+
+ return 1;
+}
+
+static int lcd_gpio_cfg_earlysuspend(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+ reset_gpio = EXYNOS4_GPY4(5);
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ mdelay(5);
+ gpio_direction_output(reset_gpio, 0);
+
+ gpio_free(reset_gpio);
+
+ return 0;
+}
+
+static int lcd_gpio_cfg_lateresume(struct lcd_device *ld)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static struct s3cfb_lcd nt35560_info = {
+ .width = 480,
+ .height = 800,
+ .p_width = 52,
+ .p_height = 86,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 10,
+ .h_bp = 10,
+ .h_sw = 10,
+ .v_fp = 9,
+ .v_fpe = 1,
+ .v_bp = 4,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+static struct lcd_platform_data nt35560_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .gpio_cfg_earlysuspend = lcd_gpio_cfg_earlysuspend,
+ .gpio_cfg_lateresume = lcd_gpio_cfg_lateresume,
+ /* it indicates whether lcd panel is enabled from u-boot. */
+ .lcd_enabled = 1,
+ .reset_delay = 10, /* 10ms */
+ .power_on_delay = 10, /* 10ms */
+ .power_off_delay = 150, /* 150ms */
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPY4(3)
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+#define DISPLAY_CLK EXYNOS4_GPY3(1)
+#define DISPLAY_SI EXYNOS4_GPY3(3)
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device nt35560_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+ .lcd = &nt35560_info,
+};
+
+static void __init nt35560_fb_init(void)
+{
+ struct ld9040_panel_data *pdata;
+
+ strcpy(spi_board_info[0].modalias, "nt35560");
+ spi_board_info[0].platform_data = (void *)&nt35560_platform_data;
+
+ pdata = nt35560_platform_data.pdata;
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ if (!nt35560_platform_data.lcd_enabled)
+ lcd_cfg_gpio();
+ s3cfb_set_platdata(&fb_platform_data);
+}
+#endif
+
+#ifdef CONFIG_FB_S5P_AMS369FG06
+static struct s3c_platform_fb ams369fg06_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "ams369fg06",
+ .platform_data = NULL,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data ams369fg06_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &ams369fg06_spi_gpio_data,
+ },
+};
+#endif
+
+#ifdef CONFIG_FB_S5P_MDNIE
+static struct platform_device mdnie_device = {
+ .name = "mdnie",
+ .id = -1,
+ .dev = {
+ .parent = &exynos4_device_pd[PD_LCD0].dev,
+ },
+};
+#endif
+
+#endif
+
+static struct platform_device u1_regulator_consumer = {
+ .name = "u1-regulator-consumer",
+ .id = -1,
+};
+
+#ifdef CONFIG_REGULATOR_MAX8997
+static struct regulator_consumer_supply ldo1_supply[] = {
+ REGULATOR_SUPPLY("vadc_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("vusb_1.1v", "usb_otg"),
+ REGULATOR_SUPPLY("vmipi_1.1v", "m9mo"),
+ REGULATOR_SUPPLY("vmipi_1.1v", NULL),
+};
+
+static struct regulator_consumer_supply ldo4_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vhsic", NULL),
+};
+
+static struct regulator_consumer_supply ldo7_supply[] = {
+ REGULATOR_SUPPLY("cam_isp", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vusb_3.3v", NULL),
+};
+
+#if defined(CONFIG_S5PV310_HI_ARMCLK_THAN_1_2GHZ)
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vpll_1.2v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vpll_1.1v", NULL),
+};
+#endif
+
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("top_3.3v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+#endif
+
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("vlcd_1.8v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.0v", NULL),
+};
+
+#ifdef CONFIG_MACH_Q1_BD
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vlcd_2.2v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+#endif
+
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("ois_1.5v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vled", NULL),
+};
+#endif
+
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("cis_1.8v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_io", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("cis_2.8v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("touch_led", NULL),
+};
+#endif
+
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vddq_m1m2", NULL),
+};
+
+static struct regulator_consumer_supply buck1_supply[] = {
+ REGULATOR_SUPPLY("vdd_arm", NULL),
+};
+
+static struct regulator_consumer_supply buck2_supply[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+};
+
+static struct regulator_consumer_supply buck3_supply[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+};
+
+static struct regulator_consumer_supply buck4_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_core", NULL),
+};
+
+static struct regulator_consumer_supply buck7_supply[] = {
+ REGULATOR_SUPPLY("vcc_sub", NULL),
+};
+
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+static struct regulator_consumer_supply led_flash_supply[] = {
+ REGULATOR_SUPPLY("led_flash", NULL),
+};
+
+static struct regulator_consumer_supply led_movie_supply[] = {
+ REGULATOR_SUPPLY("led_movie", NULL),
+};
+
+#if defined(CONFIG_MACH_Q1_BD)
+static struct regulator_consumer_supply led_torch_supply[] = {
+ REGULATOR_SUPPLY("led_torch", NULL),
+};
+#endif /* CONFIG_MACH_Q1_BD */
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = \
+ (_disabled == -1 ? 0 : _disabled),\
+ .enabled = \
+ (_disabled == -1 ? 0 : !(_disabled)),\
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo1, "VADC_3.3V_C210", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo3, "VUSB_1.1V", 1100000, 1100000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo4, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+REGULATOR_INIT(ldo5, "VHSIC_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo5, "VHSIC_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo7, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VUSB_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_S5PV310_HI_ARMCLK_THAN_1_2GHZ)
+REGULATOR_INIT(ldo10, "VPLL_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo10, "VPLL_1.1V", 1100000, 1100000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+REGULATOR_INIT(ldo11, "TOP_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo11, "TOUCH_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+REGULATOR_INIT(ldo12, "VLCD_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo12, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo13, "VCC_3.0V_LCD", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_Q1_BD)
+REGULATOR_INIT(ldo14, "VCC_2.2V_LCD", 2200000, 2200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#elif defined(CONFIG_MACH_U1CAMERA_BD)
+REGULATOR_INIT(ldo14, "MOT_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo14, "VCC_2.8V_MOTOR", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+REGULATOR_INIT(ldo15, "OIS_1.5V", 1500000, 1500000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo15, "LED_A_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, -1);
+#endif
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+REGULATOR_INIT(ldo16, "CIS_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo16, "CAM_SENSOR_IO_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo17, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+REGULATOR_INIT(ldo18, "CIS_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo18, "TOUCH_LED_3.3V", 3000000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, 1);
+#endif
+REGULATOR_INIT(ldo21, "VDDQ_M1M2_1.2V", 1200000, 1200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+
+
+static struct regulator_init_data buck1_init_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 650000,
+ .max_uV = 2225000,
+ .always_on = 1,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck1_supply[0],
+};
+
+static struct regulator_init_data buck2_init_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 650000,
+ .max_uV = 2225000,
+ .always_on = 1,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck2_supply[0],
+};
+
+static struct regulator_init_data buck3_init_data = {
+ .constraints = {
+ .name = "G3D_1.1V",
+ .min_uV = 900000,
+ .max_uV = 1200000,
+ .always_on = 0,
+ .boot_on = 0,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck3_supply[0],
+};
+
+static struct regulator_init_data buck4_init_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck4_supply[0],
+};
+
+static struct regulator_init_data buck5_init_data = {
+ .constraints = {
+ .name = "VMEM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .uV = 1200000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data buck7_init_data = {
+ .constraints = {
+ .name = "VCC_SUB_2.0V",
+ .min_uV = 2000000,
+ .max_uV = 2000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck7_supply[0],
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct regulator_init_data led_flash_init_data = {
+ .constraints = {
+ .name = "FLASH_CUR",
+ .min_uA = 23440,
+ .max_uA = 750080,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
+#if !defined(CONFIG_MACH_Q1_BD)
+ .state_mem = {
+ .disabled = 1,
+ },
+#endif
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &led_flash_supply[0],
+};
+
+static struct regulator_init_data led_movie_init_data = {
+ .constraints = {
+ .name = "MOVIE_CUR",
+ .min_uA = 15625,
+ .max_uA = 250000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
+#if !defined(CONFIG_MACH_Q1_BD)
+ .state_mem = {
+ .disabled = 1,
+ },
+#endif
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &led_movie_supply[0],
+};
+
+#if defined(CONFIG_MACH_Q1_BD)
+static struct regulator_init_data led_torch_init_data = {
+ .constraints = {
+ .name = "FLASH_TORCH",
+ .min_uA = 15625,
+ .max_uA = 250000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &led_torch_supply[0],
+};
+#endif /* CONFIG_MACH_Q1_BD */
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_LDO1, &ldo1_init_data, NULL, },
+ { MAX8997_LDO3, &ldo3_init_data, NULL, },
+ { MAX8997_LDO4, &ldo4_init_data, NULL, },
+ { MAX8997_LDO5, &ldo5_init_data, NULL, },
+ { MAX8997_LDO7, &ldo7_init_data, NULL, },
+ { MAX8997_LDO8, &ldo8_init_data, NULL, },
+ { MAX8997_LDO10, &ldo10_init_data, NULL, },
+ { MAX8997_LDO11, &ldo11_init_data, NULL, },
+ { MAX8997_LDO12, &ldo12_init_data, NULL, },
+ { MAX8997_LDO13, &ldo13_init_data, NULL, },
+ { MAX8997_LDO14, &ldo14_init_data, NULL, },
+ { MAX8997_LDO15, &ldo15_init_data, NULL, },
+ { MAX8997_LDO16, &ldo16_init_data, NULL, },
+ { MAX8997_LDO17, &ldo17_init_data, NULL, },
+ { MAX8997_LDO18, &ldo18_init_data, NULL, },
+ { MAX8997_LDO21, &ldo21_init_data, NULL, },
+ { MAX8997_BUCK1, &buck1_init_data, NULL, },
+ { MAX8997_BUCK2, &buck2_init_data, NULL, },
+ { MAX8997_BUCK3, &buck3_init_data, NULL, },
+ { MAX8997_BUCK4, &buck4_init_data, NULL, },
+ { MAX8997_BUCK5, &buck5_init_data, NULL, },
+ { MAX8997_BUCK7, &buck7_init_data, NULL, },
+ { MAX8997_ESAFEOUT1, &safeout1_init_data, NULL, },
+ { MAX8997_ESAFEOUT2, &safeout2_init_data, NULL, },
+ { MAX8997_FLASH_CUR, &led_flash_init_data, NULL, },
+ { MAX8997_MOVIE_CUR, &led_movie_init_data, NULL, },
+#if defined CONFIG_MACH_Q1_BD
+ { MAX8997_FLASH_TORCH, &led_torch_init_data, NULL, },
+#endif /* CONFIG_MACH_Q1_BD */
+};
+
+static struct max8997_power_data max8997_power = {
+ .batt_detect = 1,
+};
+
+#if defined(CONFIG_MACH_Q1_BD)
+static void motor_init_hw(void)
+{
+ if (gpio_request(GPIO_MOTOR_EN, "MOTOR_EN") < 0)
+ pr_err("[VIB] Failed to request GPIO_MOTOR_EN\n");
+}
+
+static void motor_en(bool enable)
+{
+ gpio_direction_output(GPIO_MOTOR_EN, enable);
+}
+#endif
+
+#ifdef CONFIG_VIBETONZ
+#ifdef CONFIG_TARGET_LOCALE_NTT
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 43696,
+ .period = 44138,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#elif defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_TARGET_LOCALE_NA)
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 44196,
+ .period = 44643,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#elif defined(CONFIG_MACH_Q1_BD)
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 37641,
+ .period = 38022,
+ .init_hw = motor_init_hw,
+ .motor_en = motor_en,
+ .pwm_id = 1,
+};
+#else
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 37641,
+ .period = 38022,
+ .init_hw = NULL,
+ .motor_en = NULL,
+ .pwm_id = 1,
+};
+#endif
+#endif
+
+#ifdef CONFIG_MACH_U1_KOR_LGT
+static int max8997_muic_set_safeout(int path)
+{
+ static int safeout2_enabled;
+ struct regulator *regulator;
+
+ pr_info("%s: path = %d\n", __func__, path);
+
+ if (path == CP_USB_MODE) {
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!safeout2_enabled) {
+ pr_info("%s: enable safeout2\n", __func__);
+ regulator_enable(regulator);
+ safeout2_enabled = 1;
+ } else
+ pr_info("%s: safeout2 is already enabled\n",
+ __func__);
+ regulator_put(regulator);
+ } else {
+ /* AP_USB_MODE || AUDIO_MODE */
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (safeout2_enabled) {
+ pr_info("%s: disable safeout2\n", __func__);
+ regulator_disable(regulator);
+ safeout2_enabled = 0;
+ } else
+ pr_info("%s: safeout2 is already disabled\n",
+ __func__);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+#else
+static int max8997_muic_set_safeout(int path)
+{
+ struct regulator *regulator;
+
+ if (path == CP_USB_MODE) {
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ /* AP_USB_MODE || AUDIO_MODE */
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+#endif
+
+static struct charging_status_callbacks {
+ void (*tsp_set_charging_cable) (int type);
+} charging_cbs;
+
+bool is_cable_attached;
+static int connected_cable_type = CABLE_TYPE_NONE;
+
+static int max8997_muic_charger_cb(int cable_type)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ connected_cable_type = cable_type;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ switch (cable_type) {
+ case CABLE_TYPE_NONE:
+ case CABLE_TYPE_OTG:
+ case CABLE_TYPE_JIG_UART_OFF:
+ case CABLE_TYPE_MHL:
+ value.intval = POWER_SUPPLY_TYPE_BATTERY;
+ is_cable_attached = false;
+ break;
+ case CABLE_TYPE_USB:
+ case CABLE_TYPE_JIG_USB_OFF:
+ case CABLE_TYPE_JIG_USB_ON:
+ value.intval = POWER_SUPPLY_TYPE_USB;
+ is_cable_attached = true;
+ break;
+ case CABLE_TYPE_MHL_VB:
+ value.intval = POWER_SUPPLY_TYPE_MISC;
+ is_cable_attached = true;
+ break;
+ case CABLE_TYPE_TA:
+ case CABLE_TYPE_CARDOCK:
+ case CABLE_TYPE_DESKDOCK:
+ case CABLE_TYPE_JIG_UART_OFF_VB:
+ value.intval = POWER_SUPPLY_TYPE_MAINS;
+ is_cable_attached = true;
+ break;
+ default:
+ pr_err("%s: invalid type:%d\n", __func__, cable_type);
+ return -EINVAL;
+ }
+
+ if (charging_cbs.tsp_set_charging_cable)
+ charging_cbs.tsp_set_charging_cable(value.intval);
+
+ return psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value);
+}
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+static void usb_otg_accessory_power(int enable)
+{
+#ifdef CONFIG_SMB328_CHARGER /* Q1_EUR_OPEN */
+ u8 on = (u8)!!enable;
+ struct power_supply *psy_sub =
+ power_supply_get_by_name("smb328-charger");
+ union power_supply_propval value;
+ int ret;
+
+ if (!psy_sub) {
+ pr_info("%s: fail to get charger ps\n", __func__);
+ return;
+ }
+
+ value.intval = on;
+ ret = psy_sub->set_property(psy_sub,
+ POWER_SUPPLY_PROP_CHARGE_TYPE, /* only for OTG */
+ &value);
+ if (ret) {
+ pr_info("%s: fail to set OTG (%d)\n",
+ __func__, ret);
+ return;
+ }
+ pr_info("%s: otg power = %d\n", __func__, on);
+#else
+ u8 on = (u8)!!enable;
+
+ gpio_request(GPIO_USB_OTG_EN, "USB_OTG_EN");
+ gpio_direction_output(GPIO_USB_OTG_EN, on);
+ gpio_free(GPIO_USB_OTG_EN);
+ pr_info("%s: otg accessory power = %d\n", __func__, on);
+#endif
+}
+
+static struct host_notifier_platform_data host_notifier_pdata = {
+ .ndev.name = "usb_otg",
+ .booster = usb_otg_accessory_power,
+};
+
+struct platform_device host_notifier_device = {
+ .name = "host_notifier",
+ .dev.platform_data = &host_notifier_pdata,
+};
+
+#include "u1-otg.c"
+static void max8997_muic_usb_cb(u8 usb_mode)
+{
+ struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget);
+ int ret = 0;
+
+ pr_info("otg %s: usb mode=%d\n", __func__, usb_mode);
+
+#if 0
+ u32 lpcharging = __raw_readl(S5P_INFORM2);
+ if (lpcharging == 1) {
+ struct regulator *regulator;
+ pr_info("%s: lpcharging: disable USB\n", __func__);
+
+ ret = c210_change_usb_mode(udc, USB_CABLE_DETACHED);
+ if (ret < 0)
+ pr_warn("%s: fail to change mode!!!\n", __func__);
+
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator)) {
+ pr_err("%s: fail to get regulator\n", __func__);
+ return;
+ }
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ return;
+ }
+#endif
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ if (u1_switch_get_usb_lock_state()) {
+ pr_info("%s: usb locked by mdm\n", __func__);
+ return;
+ }
+#endif
+
+ if (udc) {
+ if (usb_mode == USB_OTGHOST_ATTACHED) {
+ usb_otg_accessory_power(1);
+ max8997_muic_charger_cb(CABLE_TYPE_OTG);
+ }
+
+ ret = c210_change_usb_mode(udc, usb_mode);
+ if (ret < 0)
+ pr_err("%s: fail to change mode!!!\n", __func__);
+
+ if (usb_mode == USB_OTGHOST_DETACHED)
+ usb_otg_accessory_power(0);
+ } else
+ pr_info("otg error s3c_udc is null.\n");
+}
+#endif
+
+static void max8997_muic_mhl_cb(int attached)
+{
+ pr_info("%s(%d)\n", __func__, attached);
+
+ if (attached == MAX8997_MUIC_ATTACHED) {
+#ifdef CONFIG_SAMSUNG_MHL
+ sii9234_mhl_detection_sched();
+#endif
+ }
+}
+
+static bool max8997_muic_is_mhl_attached(void)
+{
+ int val;
+
+ gpio_request(GPIO_MHL_SEL, "MHL_SEL");
+ val = gpio_get_value(GPIO_MHL_SEL);
+ gpio_free(GPIO_MHL_SEL);
+
+ return !!val;
+}
+
+static struct switch_dev switch_dock = {
+ .name = "dock",
+};
+
+static void max8997_muic_deskdock_cb(bool attached)
+{
+ if (attached)
+ switch_set_state(&switch_dock, 1);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+static void max8997_muic_cardock_cb(bool attached)
+{
+ if (attached)
+ switch_set_state(&switch_dock, 2);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+static void max8997_muic_init_cb(void)
+{
+ int ret;
+
+ /* for CarDock, DeskDock */
+ ret = switch_dev_register(&switch_dock);
+ if (ret < 0)
+ pr_err("Failed to register dock switch. %d\n", ret);
+}
+
+static void max8997_muic_jig_uart_cb(int path)
+{
+ int val;
+
+ val = path == UART_PATH_AP ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
+ gpio_set_value(GPIO_UART_SEL, val);
+ pr_info("%s: val:%d\n", __func__, val);
+}
+
+static int max8997_muic_host_notify_cb(int enable)
+{
+ struct host_notify_dev *ndev = &host_notifier_pdata.ndev;
+
+ if (ndev) {
+ ndev->booster = enable ? NOTIFY_POWER_ON : NOTIFY_POWER_OFF;
+ pr_info("%s: mode %d, enable %d\n", __func__,
+ ndev->mode, enable);
+ return ndev->mode;
+ } else
+ pr_info("%s: host_notify_dev is null, enable %d\n",
+ __func__, enable);
+
+ return -1;
+}
+
+static struct max8997_muic_data max8997_muic = {
+ .usb_cb = max8997_muic_usb_cb,
+ .charger_cb = max8997_muic_charger_cb,
+ .mhl_cb = max8997_muic_mhl_cb,
+ .is_mhl_attached = max8997_muic_is_mhl_attached,
+ .set_safeout = max8997_muic_set_safeout,
+ .init_cb = max8997_muic_init_cb,
+ .deskdock_cb = max8997_muic_deskdock_cb,
+ .cardock_cb = max8997_muic_cardock_cb,
+ .jig_uart_cb = max8997_muic_jig_uart_cb,
+ .host_notify_cb = max8997_muic_host_notify_cb,
+};
+
+static struct max8997_buck1_dvs_funcs *buck1_dvs_funcs;
+
+void max8997_set_arm_voltage_table(int *voltage_table, int arr_size)
+{
+ pr_info("%s\n", __func__);
+ if (buck1_dvs_funcs && buck1_dvs_funcs->set_buck1_dvs_table)
+ buck1_dvs_funcs->set_buck1_dvs_table(buck1_dvs_funcs,
+ voltage_table, arr_size);
+}
+
+static void max8997_register_buck1dvs_funcs(struct max8997_buck1_dvs_funcs *ptr)
+{
+ buck1_dvs_funcs = ptr;
+}
+
+
+static struct max8997_platform_data exynos4_max8997_info = {
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = &max8997_regulators[0],
+ .irq_base = IRQ_BOARD_START,
+ .wakeup = 1,
+ .buck1_gpiodvs = false,
+ .buck1_max_vol = 1350000,
+ .buck2_max_vol = 1150000,
+ .buck5_max_vol = 1200000,
+ .buck_set1 = GPIO_BUCK1_EN_A,
+ .buck_set2 = GPIO_BUCK1_EN_B,
+ .buck_set3 = GPIO_BUCK2_EN,
+ .buck_ramp_en = true,
+ .buck_ramp_delay = 10, /* 10.00mV /us (default) */
+ .flash_cntl_val = 0x5F, /* Flash safety timer duration: 800msec,
+ Maximum timer mode */
+ .power = &max8997_power,
+#ifdef CONFIG_VIBETONZ
+ .motor = &max8997_motor,
+#endif
+ .muic = &max8997_muic,
+ .register_buck1_dvs_funcs = max8997_register_buck1dvs_funcs,
+};
+#endif /* CONFIG_REGULATOR_MAX8997 */
+
+/* Bluetooth */
+#ifdef CONFIG_BT_BCM4330
+static struct platform_device bcm4330_bluetooth_device = {
+ .name = "bcm4330_bluetooth",
+ .id = -1,
+};
+#endif /* CONFIG_BT_BCM4330 */
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+#define SYSTEM_REV_SND 0x05
+#else
+#define SYSTEM_REV_SND 0x09
+#endif
+
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+void sec_set_main_mic_bias(bool on)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+ gpio_set_value(GPIO_MIC_BIAS_EN, on);
+#endif
+}
+
+int sec_set_ldo1_constraints(int disabled)
+{
+ struct regulator *regulator;
+
+ if (!disabled) {
+ regulator = regulator_get(NULL, "vadc_3.3v");
+ if (IS_ERR(regulator))
+ return -1;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vadc_3.3v");
+ if (IS_ERR(regulator))
+ return -1;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+static struct mc1n2_platform_data mc1n2_pdata = {
+ .set_main_mic_bias = sec_set_main_mic_bias,
+ .set_adc_power_constraints = sec_set_ldo1_constraints,
+};
+
+static void u1_sound_init(void)
+{
+#ifdef CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS
+ int err;
+
+ err = gpio_request(GPIO_MIC_BIAS_EN, "GPE1");
+ if (err) {
+ pr_err(KERN_ERR "MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_MIC_BIAS_EN);
+
+ err = gpio_request(GPIO_EAR_MIC_BIAS_EN, "GPE2");
+ if (err) {
+ pr_err(KERN_ERR "EAR_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_EAR_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_EAR_MIC_BIAS_EN);
+
+#endif
+}
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+static void tdmb_set_config_poweron(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_RST_N, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_RST_N, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_SFN(GPIO_TDMB_INT_AF));
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+}
+static void tdmb_set_config_poweroff(void)
+{
+ s3c_gpio_cfgpin(GPIO_TDMB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_RST_N, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_RST_N, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TDMB_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TDMB_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TDMB_INT, GPIO_LEVEL_LOW);
+}
+
+static void tdmb_gpio_on(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_on\n");
+
+ tdmb_set_config_poweron();
+
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_HIGH);
+ usleep_range(10000, 10000);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+ usleep_range(2000, 2000);
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_HIGH);
+ usleep_range(10000, 10000);
+}
+
+static void tdmb_gpio_off(void)
+{
+ printk(KERN_DEBUG "tdmb_gpio_off\n");
+
+ tdmb_set_config_poweroff();
+
+ gpio_set_value(GPIO_TDMB_RST_N, GPIO_LEVEL_LOW);
+ usleep_range(1000, 1000);
+ gpio_set_value(GPIO_TDMB_EN, GPIO_LEVEL_LOW);
+
+}
+
+static struct tdmb_platform_data tdmb_pdata = {
+ .gpio_on = tdmb_gpio_on,
+ .gpio_off = tdmb_gpio_off,
+};
+
+static struct platform_device tdmb_device = {
+ .name = "tdmb",
+ .id = -1,
+ .dev = {
+ .platform_data = &tdmb_pdata,
+ },
+};
+
+static int __init tdmb_dev_init(void)
+{
+ tdmb_set_config_poweroff();
+ s5p_register_gpio_interrupt(GPIO_TDMB_INT);
+ tdmb_pdata.irq = GPIO_TDMB_IRQ;
+ platform_device_register(&tdmb_device);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_U1
+static int c1_charger_topoff_cb(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ value.intval = POWER_SUPPLY_STATUS_FULL;
+ return psy->set_property(psy, POWER_SUPPLY_PROP_STATUS, &value);
+}
+#endif
+
+#if defined(CONFIG_MACH_Q1_CHN) && \
+ (defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER))
+static int c1_charger_ovp_cb(bool is_ovp)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ if (is_ovp)
+ value.intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ else
+ value.intval = POWER_SUPPLY_HEALTH_GOOD;
+
+ return psy->set_property(psy, POWER_SUPPLY_PROP_VOLTAGE_MAX, &value);
+}
+#endif
+
+#ifdef CONFIG_LEDS_MAX8997
+struct led_max8997_platform_data led_max8997_platform_data = {
+ .name = "leds-sec",
+ .brightness = 0,
+};
+
+struct platform_device sec_device_leds_max8997 = {
+ .name = "leds-max8997",
+ .id = -1,
+ .dev = { .platform_data = &led_max8997_platform_data},
+};
+#endif /* CONFIG_LEDS_MAX8997 */
+
+#ifdef CONFIG_CHARGER_MAX8922_U1
+static int max8922_cfg_gpio(void)
+{
+ if (system_rev < HWREV_FOR_BATTERY)
+ return -ENODEV;
+
+ s3c_gpio_cfgpin(GPIO_CHG_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_CHG_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CHG_EN, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_CHG_ING_N, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CHG_ING_N, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_TA_nCONNECTED, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCONNECTED, S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static struct max8922_platform_data max8922_pdata = {
+#ifdef CONFIG_BATTERY_SEC_U1
+ .topoff_cb = c1_charger_topoff_cb,
+#endif
+ .cfg_gpio = max8922_cfg_gpio,
+ .gpio_chg_en = GPIO_CHG_EN,
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+ .gpio_ta_nconnected = GPIO_TA_nCONNECTED,
+};
+
+static struct platform_device max8922_device_charger = {
+ .name = "max8922-charger",
+ .id = -1,
+ .dev.platform_data = &max8922_pdata,
+};
+#endif /* CONFIG_CHARGER_MAX8922_U1 */
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
+#ifdef CONFIG_BATTERY_SEC_U1
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+/* temperature table for ADC 6 */
+static struct sec_bat_adc_table_data temper_table[] = {
+ { 264, 500 },
+ { 275, 490 },
+ { 286, 480 },
+ { 293, 480 },
+ { 299, 470 },
+ { 306, 460 },
+ { 324, 450 },
+ { 341, 450 },
+ { 354, 440 },
+ { 368, 430 },
+ { 381, 420 },
+ { 396, 420 },
+ { 411, 410 },
+ { 427, 400 },
+ { 442, 390 },
+ { 457, 390 },
+ { 472, 380 },
+ { 487, 370 },
+ { 503, 370 },
+ { 518, 360 },
+ { 533, 350 },
+ { 554, 340 },
+ { 574, 330 },
+ { 595, 330 },
+ { 615, 320 },
+ { 636, 310 },
+ { 656, 310 },
+ { 677, 300 },
+ { 697, 290 },
+ { 718, 280 },
+ { 738, 270 },
+ { 761, 270 },
+ { 784, 260 },
+ { 806, 250 },
+ { 829, 240 },
+ { 852, 230 },
+ { 875, 220 },
+ { 898, 210 },
+ { 920, 200 },
+ { 943, 190 },
+ { 966, 180 },
+ { 990, 170 },
+ { 1013, 160 },
+ { 1037, 150 },
+ { 1060, 140 },
+ { 1084, 130 },
+ { 1108, 120 },
+ { 1131, 110 },
+ { 1155, 100 },
+ { 1178, 90 },
+ { 1202, 80 },
+ { 1226, 70 },
+ { 1251, 60 },
+ { 1275, 50 },
+ { 1299, 40 },
+ { 1324, 30 },
+ { 1348, 20 },
+ { 1372, 10 },
+ { 1396, 0 },
+ { 1421, -10 },
+ { 1445, -20 },
+ { 1468, -30 },
+ { 1491, -40 },
+ { 1513, -50 },
+ { 1536, -60 },
+ { 1559, -70 },
+ { 1577, -80 },
+ { 1596, -90 },
+ { 1614, -100 },
+ { 1619, -110 },
+ { 1632, -120 },
+ { 1658, -130 },
+ { 1667, -140 },
+};
+#elif defined(CONFIG_TARGET_LOCALE_NTT)
+/* temperature table for ADC 6 */
+static struct sec_bat_adc_table_data temper_table[] = {
+ { 273, 670 },
+ { 289, 660 },
+ { 304, 650 },
+ { 314, 640 },
+ { 325, 630 },
+ { 337, 620 },
+ { 347, 610 },
+ { 361, 600 },
+ { 376, 590 },
+ { 391, 580 },
+ { 406, 570 },
+ { 417, 560 },
+ { 431, 550 },
+ { 447, 540 },
+ { 474, 530 },
+ { 491, 520 },
+ { 499, 510 },
+ { 511, 500 },
+ { 519, 490 },
+ { 547, 480 },
+ { 568, 470 },
+ { 585, 460 },
+ { 597, 450 },
+ { 614, 440 },
+ { 629, 430 },
+ { 647, 420 },
+ { 672, 410 },
+ { 690, 400 },
+ { 720, 390 },
+ { 735, 380 },
+ { 755, 370 },
+ { 775, 360 },
+ { 795, 350 },
+ { 818, 340 },
+ { 841, 330 },
+ { 864, 320 },
+ { 887, 310 },
+ { 909, 300 },
+ { 932, 290 },
+ { 954, 280 },
+ { 976, 270 },
+ { 999, 260 },
+ { 1021, 250 },
+ { 1051, 240 },
+ { 1077, 230 },
+ { 1103, 220 },
+ { 1129, 210 },
+ { 1155, 200 },
+ { 1177, 190 },
+ { 1199, 180 },
+ { 1220, 170 },
+ { 1242, 160 },
+ { 1263, 150 },
+ { 1284, 140 },
+ { 1306, 130 },
+ { 1326, 120 },
+ { 1349, 110 },
+ { 1369, 100 },
+ { 1390, 90 },
+ { 1411, 80 },
+ { 1433, 70 },
+ { 1454, 60 },
+ { 1474, 50 },
+ { 1486, 40 },
+ { 1499, 30 },
+ { 1512, 20 },
+ { 1531, 10 },
+ { 1548, 0 },
+ { 1570, -10 },
+ { 1597, -20 },
+ { 1624, -30 },
+ { 1633, -40 },
+ { 1643, -50 },
+ { 1652, -60 },
+ { 1663, -70 },
+};
+#else
+/* temperature table for ADC 6 */
+static struct sec_bat_adc_table_data temper_table[] = {
+ { 165, 800 },
+ { 171, 790 },
+ { 177, 780 },
+ { 183, 770 },
+ { 189, 760 },
+ { 196, 750 },
+ { 202, 740 },
+ { 208, 730 },
+ { 214, 720 },
+ { 220, 710 },
+ { 227, 700 },
+ { 237, 690 },
+ { 247, 680 },
+ { 258, 670 },
+ { 269, 660 },
+ { 281, 650 },
+ { 296, 640 },
+ { 311, 630 },
+ { 326, 620 },
+ { 341, 610 },
+ { 356, 600 },
+ { 370, 590 },
+ { 384, 580 },
+ { 398, 570 },
+ { 412, 560 },
+ { 427, 550 },
+ { 443, 540 },
+ { 457, 530 },
+ { 471, 520 },
+ { 485, 510 },
+ { 498, 500 },
+ { 507, 490 },
+ { 516, 480 },
+ { 525, 470 },
+ { 535, 460 },
+ { 544, 450 },
+ { 553, 440 },
+ { 562, 430 },
+ { 579, 420 },
+ { 596, 410 },
+ { 613, 400 },
+ { 630, 390 },
+ { 648, 380 },
+ { 665, 370 },
+ { 684, 360 },
+ { 702, 350 },
+ { 726, 340 },
+ { 750, 330 },
+ { 774, 320 },
+ { 798, 310 },
+ { 821, 300 },
+ { 844, 290 },
+ { 867, 280 },
+ { 891, 270 },
+ { 914, 260 },
+ { 937, 250 },
+ { 960, 240 },
+ { 983, 230 },
+ { 1007, 220 },
+ { 1030, 210 },
+ { 1054, 200 },
+ { 1083, 190 },
+ { 1113, 180 },
+ { 1143, 170 },
+ { 1173, 160 },
+ { 1202, 150 },
+ { 1232, 140 },
+ { 1262, 130 },
+ { 1291, 120 },
+ { 1321, 110 },
+ { 1351, 100 },
+ { 1357, 90 },
+ { 1363, 80 },
+ { 1369, 70 },
+ { 1375, 60 },
+ { 1382, 50 },
+ { 1402, 40 },
+ { 1422, 30 },
+ { 1442, 20 },
+ { 1462, 10 },
+ { 1482, 0 },
+ { 1519, -10 },
+ { 1528, -20 },
+ { 1546, -30 },
+ { 1563, -40 },
+ { 1587, -50 },
+ { 1601, -60 },
+ { 1614, -70 },
+ { 1625, -80 },
+ { 1641, -90 },
+ { 1663, -100 },
+ { 1678, -110 },
+ { 1693, -120 },
+ { 1705, -130 },
+ { 1720, -140 },
+ { 1736, -150 },
+ { 1751, -160 },
+ { 1767, -170 },
+ { 1782, -180 },
+ { 1798, -190 },
+ { 1815, -200 },
+};
+#endif
+#ifdef CONFIG_TARGET_LOCALE_NTT
+/* temperature table for ADC 7 */
+static struct sec_bat_adc_table_data temper_table_ADC7[] = {
+ { 300, 670 },
+ { 310, 660 },
+ { 324, 650 },
+ { 330, 640 },
+ { 340, 630 },
+ { 353, 620 },
+ { 368, 610 },
+ { 394, 600 },
+ { 394, 590 },
+ { 401, 580 },
+ { 418, 570 },
+ { 431, 560 },
+ { 445, 550 },
+ { 460, 540 },
+ { 478, 530 },
+ { 496, 520 },
+ { 507, 510 },
+ { 513, 500 },
+ { 531, 490 },
+ { 553, 480 },
+ { 571, 470 },
+ { 586, 460 },
+ { 604, 450 },
+ { 614, 440 },
+ { 640, 430 },
+ { 659, 420 },
+ { 669, 410 },
+ { 707, 400 },
+ { 722, 390 },
+ { 740, 380 },
+ { 769, 370 },
+ { 783, 360 },
+ { 816, 350 },
+ { 818, 340 },
+ { 845, 330 },
+ { 859, 320 },
+ { 889, 310 },
+ { 929, 300 },
+ { 942, 290 },
+ { 955, 280 },
+ { 972, 270 },
+ { 996, 260 },
+ { 1040, 250 },
+ { 1049, 240 },
+ { 1073, 230 },
+ { 1096, 220 },
+ { 1114, 210 },
+ { 1159, 200 },
+ { 1165, 190 },
+ { 1206, 180 },
+ { 1214, 170 },
+ { 1227, 160 },
+ { 1256, 150 },
+ { 1275, 140 },
+ { 1301, 130 },
+ { 1308, 120 },
+ { 1357, 110 },
+ { 1388, 100 },
+ { 1396, 90 },
+ { 1430, 80 },
+ { 1448, 70 },
+ { 1468, 60 },
+ { 1499, 50 },
+ { 1506, 40 },
+ { 1522, 30 },
+ { 1535, 20 },
+ { 1561, 10 },
+ { 1567, 0 },
+ { 1595, -10 },
+ { 1620, -20 },
+ { 1637, -30 },
+ { 1640, -40 },
+ { 1668, -50 },
+ { 1669, -60 },
+ { 1688, -70 },
+};
+#else
+/* temperature table for ADC 7 */
+static struct sec_bat_adc_table_data temper_table_ADC7[] = {
+ { 193, 800 },
+ { 200, 790 },
+ { 207, 780 },
+ { 215, 770 },
+ { 223, 760 },
+ { 230, 750 },
+ { 238, 740 },
+ { 245, 730 },
+ { 252, 720 },
+ { 259, 710 },
+ { 266, 700 },
+ { 277, 690 },
+ { 288, 680 },
+ { 300, 670 },
+ { 311, 660 },
+ { 326, 650 },
+ { 340, 640 },
+ { 354, 630 },
+ { 368, 620 },
+ { 382, 610 },
+ { 397, 600 },
+ { 410, 590 },
+ { 423, 580 },
+ { 436, 570 },
+ { 449, 560 },
+ { 462, 550 },
+ { 475, 540 },
+ { 488, 530 },
+ { 491, 520 },
+ { 503, 510 },
+ { 535, 500 },
+ { 548, 490 },
+ { 562, 480 },
+ { 576, 470 },
+ { 590, 460 },
+ { 603, 450 },
+ { 616, 440 },
+ { 630, 430 },
+ { 646, 420 },
+ { 663, 410 },
+ { 679, 400 },
+ { 696, 390 },
+ { 712, 380 },
+ { 728, 370 },
+ { 745, 360 },
+ { 762, 350 },
+ { 784, 340 },
+ { 806, 330 },
+ { 828, 320 },
+ { 850, 310 },
+ { 872, 300 },
+ { 895, 290 },
+ { 919, 280 },
+ { 942, 270 },
+ { 966, 260 },
+ { 989, 250 },
+ { 1013, 240 },
+ { 1036, 230 },
+ { 1060, 220 },
+ { 1083, 210 },
+ { 1107, 200 },
+ { 1133, 190 },
+ { 1159, 180 },
+ { 1186, 170 },
+ { 1212, 160 },
+ { 1238, 150 },
+ { 1265, 140 },
+ { 1291, 130 },
+ { 1316, 120 },
+ { 1343, 110 },
+ { 1370, 100 },
+ { 1381, 90 },
+ { 1393, 80 },
+ { 1404, 70 },
+ { 1416, 60 },
+ { 1427, 50 },
+ { 1453, 40 },
+ { 1479, 30 },
+ { 1505, 20 },
+ { 1531, 10 },
+ { 1557, 0 },
+ { 1565, -10 },
+ { 1577, -20 },
+ { 1601, -30 },
+ { 1620, -40 },
+ { 1633, -50 },
+ { 1642, -60 },
+ { 1656, -70 },
+ { 1667, -80 },
+ { 1674, -90 },
+ { 1689, -100 },
+ { 1704, -110 },
+ { 1719, -120 },
+ { 1734, -130 },
+ { 1749, -140 },
+ { 1763, -150 },
+ { 1778, -160 },
+ { 1793, -170 },
+ { 1818, -180 },
+ { 1823, -190 },
+ { 1838, -200 },
+};
+#endif
+
+#define ADC_CH_TEMPERATURE_PMIC 6
+#define ADC_CH_TEMPERATURE_LCD 7
+
+static unsigned int sec_bat_get_lpcharging_state(void)
+{
+ u32 val = __raw_readl(S5P_INFORM2);
+ struct power_supply *psy = power_supply_get_by_name("max8997-charger");
+ union power_supply_propval value;
+
+ BUG_ON(!psy);
+
+ if (val == 1) {
+ psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &value);
+ pr_info("%s: charging status: %d\n", __func__, value.intval);
+ if (value.intval == POWER_SUPPLY_STATUS_DISCHARGING)
+ pr_warn("%s: DISCHARGING\n", __func__);
+ }
+
+ pr_info("%s: LP charging:%d\n", __func__, val);
+ return val;
+}
+
+static void sec_bat_initial_check(void)
+{
+ pr_info("%s: connected_cable_type:%d\n",
+ __func__, connected_cable_type);
+ if (connected_cable_type != CABLE_TYPE_NONE)
+ max8997_muic_charger_cb(connected_cable_type);
+}
+
+static struct sec_bat_platform_data sec_bat_pdata = {
+ .fuel_gauge_name = "fuelgauge",
+ .charger_name = "max8997-charger",
+#ifdef CONFIG_CHARGER_MAX8922_U1
+ .sub_charger_name = "max8922-charger",
+#elif defined(CONFIG_MAX8903_CHARGER)
+ .sub_charger_name = "max8903-charger",
+#endif
+ /* TODO: should provide temperature table */
+ .adc_arr_size = ARRAY_SIZE(temper_table),
+ .adc_table = temper_table,
+ .adc_channel = ADC_CH_TEMPERATURE_PMIC,
+ .adc_sub_arr_size = ARRAY_SIZE(temper_table_ADC7),
+ .adc_sub_table = temper_table_ADC7,
+ .adc_sub_channel = ADC_CH_TEMPERATURE_LCD,
+ .get_lpcharging_state = sec_bat_get_lpcharging_state,
+#if defined(CONFIG_MACH_Q1_BD)
+ .initial_check = sec_bat_initial_check,
+#else
+ .initial_check = NULL,
+#endif
+};
+
+static struct platform_device sec_device_battery = {
+ .name = "sec-battery",
+ .id = -1,
+ .dev.platform_data = &sec_bat_pdata,
+};
+#endif /* CONFIG_BATTERY_SEC_U1 */
+
+#ifdef CONFIG_SMB136_CHARGER_Q1
+static void smb136_set_charger_name(void)
+{
+ sec_bat_pdata.sub_charger_name = "smb136-charger";
+}
+
+static struct smb136_platform_data smb136_pdata = {
+ .topoff_cb = c1_charger_topoff_cb,
+#if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
+ .ovp_cb = c1_charger_ovp_cb,
+#endif
+ .set_charger_name = smb136_set_charger_name,
+ .gpio_chg_en = GPIO_CHG_EN,
+ .gpio_otg_en = GPIO_OTG_EN,
+#if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+#endif
+ .gpio_ta_nconnected = 0, /*GPIO_TA_nCONNECTED,*/
+};
+#endif /* CONFIG_SMB136_CHARGER_Q1 */
+
+#ifdef CONFIG_SMB328_CHARGER
+static void smb328_set_charger_name(void)
+{
+ sec_bat_pdata.sub_charger_name = "smb328-charger";
+}
+
+static struct smb328_platform_data smb328_pdata = {
+ .topoff_cb = c1_charger_topoff_cb,
+#if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB328_CHARGER)
+ .ovp_cb = c1_charger_ovp_cb,
+#endif
+ .set_charger_name = smb328_set_charger_name,
+ .gpio_chg_ing = GPIO_CHG_ING_N,
+ .gpio_ta_nconnected = 0, /*GPIO_TA_nCONNECTED,*/
+};
+#endif /* CONFIG_SMB328_CHARGER */
+
+#if defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER)
+static struct i2c_gpio_platform_data gpio_i2c_data19 = {
+ .sda_pin = GPIO_CHG_SDA,
+ .scl_pin = GPIO_CHG_SCL,
+};
+
+static struct platform_device s3c_device_i2c19 = {
+ .name = "i2c-gpio",
+ .id = 19,
+ .dev.platform_data = &gpio_i2c_data19,
+};
+
+static struct i2c_board_info i2c_devs19_emul[] = {
+#ifdef CONFIG_SMB136_CHARGER_Q1
+ {
+ I2C_BOARD_INFO("smb136-charger", SMB136_SLAVE_ADDR>>1),
+ .platform_data = &smb136_pdata,
+ },
+#endif
+#ifdef CONFIG_SMB328_CHARGER
+ {
+ I2C_BOARD_INFO("smb328-charger", SMB328_SLAVE_ADDR>>1),
+ .platform_data = &smb328_pdata,
+ },
+#endif
+};
+#endif
+
+#if defined(CONFIG_SEC_THERMISTOR)
+/* temperature table for ADC CH 6 */
+static struct sec_therm_adc_table adc_ch6_table[] = {
+ /* ADC, Temperature */
+ { 173, 800 },
+ { 180, 790 },
+ { 188, 780 },
+ { 196, 770 },
+ { 204, 760 },
+ { 212, 750 },
+ { 220, 740 },
+ { 228, 730 },
+ { 236, 720 },
+ { 244, 710 },
+ { 252, 700 },
+ { 259, 690 },
+ { 266, 680 },
+ { 273, 670 },
+ { 289, 660 },
+ { 304, 650 },
+ { 314, 640 },
+ { 325, 630 },
+ { 337, 620 },
+ { 347, 610 },
+ { 361, 600 },
+ { 376, 590 },
+ { 391, 580 },
+ { 406, 570 },
+ { 417, 560 },
+ { 431, 550 },
+ { 447, 540 },
+ { 474, 530 },
+ { 491, 520 },
+ { 499, 510 },
+ { 511, 500 },
+ { 519, 490 },
+ { 547, 480 },
+ { 568, 470 },
+ { 585, 460 },
+ { 597, 450 },
+ { 614, 440 },
+ { 629, 430 },
+ { 647, 420 },
+ { 672, 410 },
+ { 690, 400 },
+ { 720, 390 },
+ { 735, 380 },
+ { 755, 370 },
+ { 775, 360 },
+ { 795, 350 },
+ { 818, 340 },
+ { 841, 330 },
+ { 864, 320 },
+ { 887, 310 },
+ { 909, 300 },
+ { 932, 290 },
+ { 954, 280 },
+ { 976, 270 },
+ { 999, 260 },
+ { 1021, 250 },
+ { 1051, 240 },
+ { 1077, 230 },
+ { 1103, 220 },
+ { 1129, 210 },
+ { 1155, 200 },
+ { 1177, 190 },
+ { 1199, 180 },
+ { 1220, 170 },
+ { 1242, 160 },
+ { 1263, 150 },
+ { 1284, 140 },
+ { 1306, 130 },
+ { 1326, 120 },
+ { 1349, 110 },
+ { 1369, 100 },
+ { 1390, 90 },
+ { 1411, 80 },
+ { 1433, 70 },
+ { 1454, 60 },
+ { 1474, 50 },
+ { 1486, 40 },
+ { 1499, 30 },
+ { 1512, 20 },
+ { 1531, 10 },
+ { 1548, 0 },
+ { 1570, -10 },
+ { 1597, -20 },
+ { 1624, -30 },
+ { 1633, -40 },
+ { 1643, -50 },
+ { 1652, -60 },
+ { 1663, -70 },
+ { 1687, -80 },
+ { 1711, -90 },
+ { 1735, -100 },
+ { 1746, -110 },
+ { 1757, -120 },
+ { 1768, -130 },
+ { 1779, -140 },
+ { 1790, -150 },
+ { 1801, -160 },
+ { 1812, -170 },
+ { 1823, -180 },
+ { 1834, -190 },
+ { 1845, -200 },
+};
+
+static struct sec_therm_platform_data sec_therm_pdata = {
+ .adc_channel = 6,
+ .adc_arr_size = ARRAY_SIZE(adc_ch6_table),
+ .adc_table = adc_ch6_table,
+ .polling_interval = 30 * 1000, /* msecs */
+};
+
+static struct platform_device sec_device_thermistor = {
+ .name = "sec-thermistor",
+ .id = -1,
+ .dev.platform_data = &sec_therm_pdata,
+};
+#endif /* CONFIG_SEC_THERMISTOR */
+
+
+struct gpio_keys_button u1_buttons[] = {
+#if defined(CONFIG_MACH_U1CAMERA_BD)
+ {
+ .code = KEY_POWER,
+ .gpio = GPIO_nPOWER,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ },
+ {
+ .code = KEY_RESERVED,
+ .gpio = GPIO_RSERVED_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_PLAY,
+ .gpio = GPIO_PLAY_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_RECORD,
+ .gpio = GPIO_RECORD_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_MENU,
+ .gpio = GPIO_MENU_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_HOME,
+ .gpio = GPIO_HOME_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_BACK,
+ .gpio = GPIO_BACK_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_CAMERA_FOCUS,
+ .gpio = GPIO_S1_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ /*KEY_CAMERA_SHUTTER*/
+ .code = 0x220,
+ .gpio = GPIO_S2_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_CAMERA_ZOOMIN,
+ .gpio = GPIO_TELE_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_CAMERA_ZOOMOUT,
+ .gpio = GPIO_WIDE_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+#else
+ {
+ .code = KEY_VOLUMEUP,
+ .gpio = GPIO_VOL_UP,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ }, /* vol up */
+ {
+ .code = KEY_VOLUMEDOWN,
+ .gpio = GPIO_VOL_DOWN,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ }, /* vol down */
+ {
+ .code = KEY_POWER,
+ .gpio = GPIO_nPOWER,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ .isr_hook = sec_debug_check_crash_key,
+ }, /* power key */
+ {
+ .code = KEY_HOME,
+ .gpio = GPIO_OK_KEY,
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ }, /* ok key */
+#endif
+};
+
+struct gpio_keys_platform_data u1_keypad_platform_data = {
+ u1_buttons,
+ ARRAY_SIZE(u1_buttons),
+};
+
+struct platform_device u1_keypad = {
+ .name = "gpio-keys",
+ .dev.platform_data = &u1_keypad_platform_data,
+};
+
+#ifdef CONFIG_SEC_DEV_JACK
+static void sec_set_jack_micbias(bool on)
+{
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, on);
+}
+
+static struct sec_jack_zone sec_jack_zones[] = {
+ {
+ /* adc == 0, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 0,
+ .delay_ms = 15,
+ .check_count = 20,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 0 < adc <= 1200, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 1200,
+ .delay_ms = 10,
+ .check_count = 80,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 950 < adc <= 2600, unstable zone, default to 4pole if it
+ * stays in this range for 800ms (10ms delays, 80 samples)
+ */
+ .adc_high = 2600,
+ .delay_ms = 10,
+ .check_count = 10,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* 2600 < adc <= 3400, 3 pole zone, default to 3pole if it
+ * stays in this range for 100ms (10ms delays, 10 samples)
+ */
+ .adc_high = 3800,
+ .delay_ms = 10,
+ .check_count = 5,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* adc > 3400, unstable zone, default to 3pole if it stays
+ * in this range for two seconds (10ms delays, 200 samples)
+ */
+ .adc_high = 0x7fffffff,
+ .delay_ms = 10,
+ .check_count = 200,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+};
+
+/* To support 3-buttons earjack */
+static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = {
+ {
+ /* 0 <= adc <=170, stable zone */
+ .code = KEY_MEDIA,
+ .adc_low = 0,
+ .adc_high = 170,
+ },
+ {
+ /* 171 <= adc <= 370, stable zone */
+ .code = KEY_VOLUMEUP,
+ .adc_low = 171,
+ .adc_high = 370,
+ },
+ {
+ /* 371 <= adc <= 850, stable zone */
+ .code = KEY_VOLUMEDOWN,
+ .adc_low = 371,
+ .adc_high = 850,
+ },
+};
+
+static struct sec_jack_platform_data sec_jack_data = {
+ .set_micbias_state = sec_set_jack_micbias,
+ .zones = sec_jack_zones,
+ .num_zones = ARRAY_SIZE(sec_jack_zones),
+ .buttons_zones = sec_jack_buttons_zones,
+ .num_buttons_zones = ARRAY_SIZE(sec_jack_buttons_zones),
+ .det_gpio = GPIO_DET_35,
+ .send_end_gpio = GPIO_EAR_SEND_END,
+};
+
+static struct platform_device sec_device_jack = {
+ .name = "sec_jack",
+ .id = 1, /* will be used also for gpio_event id */
+ .dev.platform_data = &sec_jack_data,
+};
+#endif
+
+void tsp_register_callback(void *function)
+{
+ charging_cbs.tsp_set_charging_cable = function;
+}
+
+void tsp_read_ta_status(void *ta_status)
+{
+ *(bool *)ta_status = is_cable_attached;
+}
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC
+static void mxt224_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+}
+
+static void mxt224_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+}
+
+static u8 t7_config[] = {GEN_POWERCONFIG_T7,
+ 64, 255, 50
+};
+static u8 t8_config[] = {GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, 9, 27
+};
+static u8 t9_config[] = {TOUCH_MULTITOUCHSCREEN_T9,
+ 143, 0, 0, 18, 11, 0, 16, 32, 2, 0,
+ 0, 3, 1, 46, 10, 5, 40, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 18
+};
+static u8 t15_config[] = {TOUCH_KEYARRAY_T15,
+ 131, 16, 11, 2, 1, 0, 0, 45, 4, 0,
+ 0
+};
+static u8 t18_config[] = {SPT_COMCONFIG_T18,
+ 0, 0
+};
+static u8 t19_config[] = {SPT_GPIOPWM_T19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+static u8 t20_config[] = {PROCI_GRIPFACESUPPRESSION_T20,
+ 19, 0, 0, 5, 5, 0, 0, 30, 20, 4, 15,
+ 10
+};
+static u8 t22_config[] = {PROCG_NOISESUPPRESSION_T22,
+ 5, 0, 0, 0, 0, 0, 0, 3, 27, 0,
+ 0, 29, 34, 39, 49, 58, 3
+};
+static u8 t23_config[] = {TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+};
+static u8 t24_config[] = {PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+static u8 t25_config[] = {SPT_SELFTEST_T25,
+ 0, 0
+};
+static u8 t27_config[] = {PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ 0, 0, 0, 0, 0, 0, 0
+};
+static u8 t28_config[] = {SPT_CTECONFIG_T28,
+ 1, 0, 2, 16, 63, 60
+};
+static u8 end_config[] = {RESERVED_T255};
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t15_config,
+ t18_config,
+ t19_config,
+ t20_config,
+ t22_config,
+ t23_config,
+ t24_config,
+ t25_config,
+ t27_config,
+ t28_config,
+ end_config,
+};
+
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = 10,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config = mxt224_config,
+ .min_x = 0,
+ .max_x = 479,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+};
+
+
+#endif
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1
+static void mxt224_power_on(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+ /* printk("mxt224_power_on is finished\n"); */
+}
+
+static void mxt224_power_off(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+ /* printk("mxt224_power_off is finished\n"); */
+}
+
+/*
+ Configuration for MXT224
+*/
+#define MXT224_THRESHOLD_BATT 40
+#define MXT224_THRESHOLD_BATT_INIT 55
+#define MXT224_THRESHOLD_CHRG 70
+#define MXT224_NOISE_THRESHOLD_BATT 30
+#define MXT224_NOISE_THRESHOLD_CHRG 40
+#define MXT224_MOVFILTER_BATT 47
+#define MXT224_MOVFILTER_CHRG 47
+#define MXT224_ATCHCALST 4
+#define MXT224_ATCHCALTHR 35
+
+static u8 t7_config[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config[] = { GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, MXT224_ATCHCALST, MXT224_ATCHCALTHR
+}; /*byte 3: 0 */
+
+static u8 t9_config[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, MXT224_THRESHOLD_BATT, 2, 1,
+ 0,
+ 15, /* MOVHYSTI */
+ 1, MXT224_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 143, 55, 143, 90, 18
+};
+
+static u8 t18_config[] = { SPT_COMCONFIG_T18,
+ 0, 1
+};
+
+static u8 t20_config[] = { PROCI_GRIPFACESUPPRESSION_T20,
+ 7, 0, 0, 0, 0, 0, 0, 30, 20, 4, 15, 10
+};
+
+static u8 t22_config[] = { PROCG_NOISESUPPRESSION_T22,
+ 143, 0, 0, 0, 0, 0, 0, 3, MXT224_NOISE_THRESHOLD_BATT, 0,
+ 0, 29, 34, 39, 49, 58, 3
+};
+
+static u8 t28_config[] = { SPT_CTECONFIG_T28,
+ 0, 0, 3, 16, 19, 60
+};
+static u8 end_config[] = { RESERVED_T255 };
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t18_config,
+ t20_config,
+ t22_config,
+ t28_config,
+ end_config,
+};
+
+/*
+ Configuration for MXT224-E
+*/
+#define MXT224E_THRESHOLD_BATT 50
+#define MXT224E_THRESHOLD_CHRG 40
+#define MXT224E_CALCFG_BATT 0x42
+#define MXT224E_CALCFG_CHRG 0x52
+#define MXT224E_ATCHFRCCALTHR_NORMAL 40
+#define MXT224E_ATCHFRCCALRATIO_NORMAL 55
+#define MXT224E_GHRGTIME_BATT 27
+#define MXT224E_GHRGTIME_CHRG 22
+#define MXT224E_ATCHCALST 4
+#define MXT224E_ATCHCALTHR 35
+#define MXT224E_BLEN_BATT 32
+#define MXT224E_BLEN_CHRG 16
+#define MXT224E_MOVFILTER_BATT 46
+#define MXT224E_MOVFILTER_CHRG 46
+#define MXT224E_ACTVSYNCSPERX_NORMAL 32
+#define MXT224E_NEXTTCHDI_NORMAL 0
+
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 25
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 8, 8, 8, 180
+};
+
+/* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 1,
+ 10, 3, 1, 11, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 188, 52, 124, 21, 188, 52, 124, 21, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 32, 120, 100, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, 35, 0, 0, 1, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 4, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 5, 0, 38, 0, 5,
+ 0, 0, 0, 0, 0, 0, 32, 50, 2, 3, 1, 11, 10, 5, 40, 10, 10,
+ 10, 10, 143, 40, 143, 80, 18, 15, 2
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 5, 0, 38, 0, 20,
+ 0, 0, 0, 0, 0, 0, 16, 70, 2, 5, 2, 46, 10, 5, 40, 10, 0,
+ 10, 10, 143, 40, 143, 80, 18, 15, 2
+};
+
+#else
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT224E_GHRGTIME_BATT, 0, 5, 1, 0, 0,
+ MXT224E_ATCHCALST, MXT224E_ATCHCALTHR,
+ MXT224E_ATCHFRCCALTHR_NORMAL,
+ MXT224E_ATCHFRCCALRATIO_NORMAL
+};
+
+/* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 0
+};
+
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+#endif
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 15, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, MXT224E_NEXTTCHDI_NORMAL
+};
+#endif
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 13, 19, 44, 0, 0, 0
+};
+#else
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 14, 23, 44, 0, 0, 0
+};
+#endif
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, MXT224E_ACTVSYNCSPERX_NORMAL, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x52, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 10, 5, 0, 19, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 47,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x40, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#else
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 15,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 2
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, 50, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+#endif /*CONFIG_MACH_U1_NA_USCC_REV05 */
+#else
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_CHRG, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 9, 5, 0, 15, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, MXT224E_THRESHOLD_CHRG, 2,
+ 15, /* MOVHYSTI */
+ 1, 47,
+ MXT224_MAX_MT_FINGERS, 5, 40, 235, 235, 10, 10, 160, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_BATT, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 48, 4, 48,
+ 10, 0, 10, 5, 0, 20, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD_BATT, 2,
+ 15,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 10, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#endif /*CONFIG_TARGET_LOCALE_NA */
+#endif /*CONFIG_TARGET_LOCALE_NAATT */
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt224e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t23_config_e,
+ t25_config_e,
+ t38_config_e,
+ t40_config_e,
+ t42_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ end_config_e,
+};
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = MXT224_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config = mxt224_config,
+ .config_e = mxt224e_config,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .min_x = 0,
+ .max_x = 479,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .atchcalst = MXT224_ATCHCALST,
+ .atchcalsthr = MXT224_ATCHCALTHR,
+ .tchthr_batt = MXT224_THRESHOLD_BATT,
+ .tchthr_batt_init = MXT224_THRESHOLD_BATT_INIT,
+ .tchthr_charging = MXT224_THRESHOLD_CHRG,
+ .noisethr_batt = MXT224_NOISE_THRESHOLD_BATT,
+ .noisethr_charging = MXT224_NOISE_THRESHOLD_CHRG,
+ .movfilter_batt = MXT224_MOVFILTER_BATT,
+ .movfilter_charging = MXT224_MOVFILTER_CHRG,
+ .atchcalst_e = MXT224E_ATCHCALST,
+ .atchcalsthr_e = MXT224E_ATCHCALTHR,
+ .tchthr_batt_e = MXT224E_THRESHOLD_BATT,
+ .tchthr_charging_e = MXT224E_THRESHOLD_CHRG,
+ .calcfg_batt_e = MXT224E_CALCFG_BATT,
+ .calcfg_charging_e = MXT224E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT224E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT224E_ATCHFRCCALRATIO_NORMAL,
+ .chrgtime_batt_e = MXT224E_GHRGTIME_BATT,
+ .chrgtime_charging_e = MXT224E_GHRGTIME_CHRG,
+ .blen_batt_e = MXT224E_BLEN_BATT,
+ .blen_charging_e = MXT224E_BLEN_CHRG,
+ .movfilter_batt_e = MXT224E_MOVFILTER_BATT,
+ .movfilter_charging_e = MXT224E_MOVFILTER_CHRG,
+ .actvsyncsperx_e = MXT224E_ACTVSYNCSPERX_NORMAL,
+ .nexttchdi_e = MXT224E_NEXTTCHDI_NORMAL,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+
+#endif /*CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1 */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT540E)
+static void mxt540e_power_on(void)
+{
+ gpio_request(GPIO_TSP_SDA, "TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "TSP_SCL");
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA, S3C_GPIO_SFN(3));
+ s3c_gpio_cfgpin(GPIO_TSP_SCL, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA, S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(GPIO_TSP_SCL, S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_TSP_LDO_ON, GPIO_LEVEL_HIGH);
+ msleep(MXT540E_HW_RESET_TIME);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+
+ gpio_free(GPIO_TSP_SDA);
+ gpio_free(GPIO_TSP_SCL);
+}
+
+static void mxt540e_power_off(void)
+{
+ gpio_request(GPIO_TSP_SDA, "TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "TSP_SCL");
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA, S3C_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA, S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(GPIO_TSP_SCL, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_TSP_SDA, GPIO_LEVEL_LOW);
+ gpio_direction_output(GPIO_TSP_SCL, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+ gpio_direction_output(GPIO_TSP_INT, GPIO_LEVEL_LOW);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_TSP_LDO_ON, GPIO_LEVEL_LOW);
+
+ gpio_free(GPIO_TSP_SDA);
+ gpio_free(GPIO_TSP_SCL);
+}
+
+static void mxt540e_power_on_oled(void)
+{
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+
+ mxt540e_power_on();
+
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+
+ gpio_free(GPIO_OLED_DET);
+
+ printk(KERN_INFO "[TSP] %s\n", __func__);
+}
+
+static void mxt540e_power_off_oled(void)
+{
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+
+ mxt540e_power_off();
+
+ gpio_free(GPIO_OLED_DET);
+
+ printk(KERN_INFO "[TSP] %s\n", __func__);
+}
+
+/*
+ Configuration for MXT540E
+*/
+#define MXT540E_MAX_MT_FINGERS 10
+#define MXT540E_CHRGTIME_BATT 48
+#define MXT540E_CHRGTIME_CHRG 48
+#define MXT540E_THRESHOLD_BATT 50
+#define MXT540E_THRESHOLD_CHRG 40
+#define MXT540E_ACTVSYNCSPERX_BATT 24
+#define MXT540E_ACTVSYNCSPERX_CHRG 28
+#define MXT540E_CALCFG_BATT 98
+#define MXT540E_CALCFG_CHRG 114
+#define MXT540E_ATCHFRCCALTHR_WAKEUP 8
+#define MXT540E_ATCHFRCCALRATIO_WAKEUP 180
+#define MXT540E_ATCHFRCCALTHR_NORMAL 40
+#define MXT540E_ATCHFRCCALRATIO_NORMAL 55
+
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 50
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT540E_CHRGTIME_BATT, 0, 5, 1, 0, 0, 4, 20,
+ MXT540E_ATCHFRCCALTHR_WAKEUP, MXT540E_ATCHFRCCALRATIO_WAKEUP
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 16, 26, 0, 192, MXT540E_THRESHOLD_BATT, 2, 6,
+ 10, 10, 10, 80, MXT540E_MAX_MT_FINGERS, 20, 40, 20, 31, 3,
+ 255, 4, 3, 3, 2, 2, 136, 60, 136, 40,
+ 18, 15, 0, 0, 0
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t19_config_e[] = { SPT_GPIOPWM_T19,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t24_config_e[] = { PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t27_config_e[] = { PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t43_config_e[] = { SPT_DIGITIZER_T43,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 0, 16, MXT540E_ACTVSYNCSPERX_BATT, 0, 0, 1, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT540E_CALCFG_BATT, 0, 0, 0, 0, 0, 1, 2,
+ 0, 0, 0, 6, 6, 0, 0, 28, 4, 64,
+ 10, 0, 20, 6, 0, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 192, MXT540E_THRESHOLD_BATT, 2, 10, 10, 47,
+ MXT540E_MAX_MT_FINGERS, 5, 20, 253, 0, 7, 7, 160, 55, 136,
+ 0, 18, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT540E_CALCFG_CHRG, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 36, 4, 64,
+ 10, 0, 10, 6, 0, 20, 0, 0, 0, 0,
+ 0, 0, 0, 0, 112, MXT540E_THRESHOLD_CHRG, 2, 10, 5, 47,
+ MXT540E_MAX_MT_FINGERS, 5, 20, 253, 0, 7, 7, 160, 55, 136,
+ 0, 18, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+static u8 t52_config_e[] = { TOUCH_PROXKEY_T52,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t55_config_e[] = {ADAPTIVE_T55,
+ 0, 0, 0, 0, 0, 0
+};
+
+static u8 t57_config_e[] = {SPT_GENERICDATA_T57,
+ 243, 25, 1
+};
+
+static u8 t61_config_e[] = {SPT_TIMER_T61,
+ 0, 0, 0, 0, 0
+};
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt540e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t19_config_e,
+ t24_config_e,
+ t25_config_e,
+ t27_config_e,
+ t40_config_e,
+ t42_config_e,
+ t43_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ t52_config_e,
+ t55_config_e,
+ t57_config_e,
+ t61_config_e,
+ end_config_e,
+};
+
+struct mxt540e_platform_data mxt540e_data = {
+ .max_finger_touches = MXT540E_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config_e = mxt540e_config,
+ .min_x = 0,
+ .max_x = 799,
+ .min_y = 0,
+ .max_y = 1279,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .chrgtime_batt = MXT540E_CHRGTIME_BATT,
+ .chrgtime_charging = MXT540E_CHRGTIME_CHRG,
+ .tchthr_batt = MXT540E_THRESHOLD_BATT,
+ .tchthr_charging = MXT540E_THRESHOLD_CHRG,
+ .actvsyncsperx_batt = MXT540E_ACTVSYNCSPERX_BATT,
+ .actvsyncsperx_charging = MXT540E_ACTVSYNCSPERX_CHRG,
+ .calcfg_batt_e = MXT540E_CALCFG_BATT,
+ .calcfg_charging_e = MXT540E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT540E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT540E_ATCHFRCCALRATIO_NORMAL,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .power_on = mxt540e_power_on,
+ .power_off = mxt540e_power_off,
+ .power_on_with_oleddet = mxt540e_power_on_oled,
+ .power_off_with_oleddet = mxt540e_power_off_oled,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p6_wacom_init_hw(void);
+static int p6_wacom_exit_hw(void);
+static int p6_wacom_suspend_hw(void);
+static int p6_wacom_resume_hw(void);
+static int p6_wacom_early_suspend_hw(void);
+static int p6_wacom_late_resume_hw(void);
+static int p6_wacom_reset_hw(void);
+static void p6_wacom_register_callbacks(struct wacom_g5_callbacks *cb);
+
+static struct wacom_g5_platform_data p6_wacom_platform_data = {
+ .x_invert = 1,
+ .y_invert = 0,
+ .xy_switch = 1,
+ .min_x = 0,
+ .max_x = WACOM_POSX_MAX,
+ .min_y = 0,
+ .max_y = WACOM_POSY_MAX,
+ .min_pressure = 0,
+ .max_pressure = WACOM_PRESSURE_MAX,
+ .init_platform_hw = p6_wacom_init_hw,
+/* .exit_platform_hw =, */
+ .suspend_platform_hw = p6_wacom_suspend_hw,
+ .resume_platform_hw = p6_wacom_resume_hw,
+ .early_suspend_platform_hw = p6_wacom_early_suspend_hw,
+ .late_resume_platform_hw = p6_wacom_late_resume_hw,
+ .reset_platform_hw = p6_wacom_reset_hw,
+ .register_cb = p6_wacom_register_callbacks,
+};
+
+#endif
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p6_wacom_suspend_hw(void)
+{
+ return p6_wacom_early_suspend_hw();
+}
+
+static int p6_wacom_resume_hw(void)
+{
+ return p6_wacom_late_resume_hw();
+}
+
+static int p6_wacom_early_suspend_hw(void)
+{
+ gpio_set_value(GPIO_PEN_RESET, 0);
+ return 0;
+}
+
+static int p6_wacom_late_resume_hw(void)
+{
+ gpio_set_value(GPIO_PEN_RESET, 1);
+ return 0;
+}
+
+static int p6_wacom_reset_hw(void)
+{
+ gpio_set_value(GPIO_PEN_RESET, 0);
+ msleep(200);
+ gpio_set_value(GPIO_PEN_RESET, 1);
+ return 0;
+}
+
+static void p6_wacom_register_callbacks(struct wacom_g5_callbacks *cb)
+{
+ wacom_callbacks = cb;
+};
+
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+#ifdef CONFIG_I2C_S3C2410
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ {I2C_BOARD_INFO("24c128", 0x50),}, /* Samsung S524AD0XD1 */
+ {I2C_BOARD_INFO("24c128", 0x52),}, /* Samsung S524AD0XD1 */
+};
+
+#ifdef CONFIG_S3C_DEV_I2C1
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ {
+ I2C_BOARD_INFO("k3g", 0x69),
+ .irq = IRQ_EINT(1),
+ },
+ {
+ I2C_BOARD_INFO("k3dh", 0x19),
+ },
+#ifdef CONFIG_MACH_Q1_BD
+ {
+ I2C_BOARD_INFO("bmp180", 0x77),
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C2
+/* I2C2 */
+static struct i2c_board_info i2c_devs2[] __initdata = {
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C3
+/* I2C3 */
+static struct i2c_board_info i2c_devs3[] __initdata = {
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data,
+ },
+#endif
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT540E
+ {
+ I2C_BOARD_INFO(MXT540E_DEV_NAME, 0x4c),
+ .platform_data = &mxt540e_data,
+ },
+#endif
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C4
+/* I2C4 */
+static struct i2c_board_info i2c_devs4[] __initdata = {
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C5
+/* I2C5 */
+static struct i2c_board_info i2c_devs5[] __initdata = {
+#ifdef CONFIG_MFD_MAX8998
+ {
+ I2C_BOARD_INFO("lp3974", 0x66),
+ .platform_data = &s5pv310_max8998_info,
+ },
+#endif
+#ifdef CONFIG_MFD_MAX8997
+ {
+ I2C_BOARD_INFO("max8997", (0xcc >> 1)),
+ .platform_data = &exynos4_max8997_info,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C6
+/* I2C6 */
+static struct i2c_board_info i2c_devs6[] __initdata = {
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+ {
+ I2C_BOARD_INFO("mc1n2", 0x3a), /* MC1N2 */
+ .platform_data = &mc1n2_pdata,
+ },
+#endif
+#ifdef CONFIG_EPEN_WACOM_G5SP
+ {
+ I2C_BOARD_INFO("wacom_g5sp_i2c", 0x56),
+ .platform_data = &p6_wacom_platform_data,
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C7
+static struct akm8975_platform_data akm8975_pdata = {
+ .gpio_data_ready_int = GPIO_MSENSE_INT,
+};
+
+/* I2C7 */
+static struct i2c_board_info i2c_devs7[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8975", 0x0C),
+ .platform_data = &akm8975_pdata,
+ },
+#ifdef CONFIG_VIDEO_TVOUT
+ {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+ },
+#endif
+};
+#endif
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data8 = {
+ .sda_pin = GPIO_3_TOUCH_SDA,
+ .scl_pin = GPIO_3_TOUCH_SCL,
+};
+
+struct platform_device s3c_device_i2c8 = {
+ .name = "i2c-gpio",
+ .id = 8,
+ .dev.platform_data = &gpio_i2c_data8,
+};
+
+/* I2C8 */
+static struct i2c_board_info i2c_devs8_emul[] = {
+ {
+ I2C_BOARD_INFO("sec_touchkey", 0x20),
+ },
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C9_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data9 = {
+ .sda_pin = GPIO_FUEL_SDA,
+ .scl_pin = GPIO_FUEL_SCL,
+};
+
+struct platform_device s3c_device_i2c9 = {
+ .name = "i2c-gpio",
+ .id = 9,
+ .dev.platform_data = &gpio_i2c_data9,
+};
+
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_U1
+
+struct max17042_reg_data max17042_init_data[] = {
+ { MAX17042_REG_CGAIN, 0x00, 0x00 },
+ { MAX17042_REG_MISCCFG, 0x03, 0x00 },
+ { MAX17042_REG_LEARNCFG, 0x07, 0x00 },
+ /* RCOMP: 0x0050 2011.02.29 from MAXIM */
+ { MAX17042_REG_RCOMP, 0x50, 0x00 },
+};
+
+struct max17042_reg_data max17042_alert_init_data[] = {
+#ifdef CONFIG_MACH_Q1_BD
+ /* SALRT Threshold setting to 1% wake lock */
+ { MAX17042_REG_SALRT_TH, 0x01, 0xFF },
+#elif defined(CONFIG_TARGET_LOCALE_KOR)
+ /* SALRT Threshold setting to 1% wake lock */
+ { MAX17042_REG_SALRT_TH, 0x01, 0xFF },
+#else
+ /* SALRT Threshold setting to 2% => 1% wake lock */
+ { MAX17042_REG_SALRT_TH, 0x02, 0xFF },
+#endif
+ /* VALRT Threshold setting (disable) */
+ { MAX17042_REG_VALRT_TH, 0x00, 0xFF },
+ /* TALRT Threshold setting (disable) */
+ { MAX17042_REG_TALRT_TH, 0x80, 0x7F },
+};
+
+bool max17042_is_low_batt(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!(psy->get_property(psy, POWER_SUPPLY_PROP_CAPACITY, &value)))
+ if (value.intval > SEC_BATTERY_SOC_3_6)
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL(max17042_is_low_batt);
+
+static int max17042_low_batt_cb(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s: fail to get battery ps\n", __func__);
+ return -ENODEV;
+ }
+
+ value.intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
+ return psy->set_property(psy, POWER_SUPPLY_PROP_CAPACITY_LEVEL, &value);
+}
+
+#ifdef RECAL_SOC_FOR_MAXIM
+static bool max17042_need_soc_recal(void)
+{
+ pr_info("%s: HW(0x%x)\n", __func__, system_rev);
+
+ if (system_rev >= NO_NEED_RECAL_SOC_HW_REV)
+ return false;
+ else
+ return true;
+}
+#endif
+
+static struct max17042_platform_data s5pv310_max17042_info = {
+ .low_batt_cb = max17042_low_batt_cb,
+ .init = max17042_init_data,
+ .init_size = sizeof(max17042_init_data),
+ .alert_init = max17042_alert_init_data,
+ .alert_init_size = sizeof(max17042_alert_init_data),
+ .alert_gpio = GPIO_FUEL_ALERT,
+ .alert_irq = 0,
+ .enable_current_sense = false,
+ .enable_gauging_temperature = true,
+#ifdef RECAL_SOC_FOR_MAXIM
+ .need_soc_recal = max17042_need_soc_recal,
+#endif
+};
+#endif /* CONFIG_BATTERY_MAX17042_U1 */
+
+/* I2C9 */
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+#ifdef CONFIG_BATTERY_MAX17042_FUELGAUGE_U1
+ {
+ I2C_BOARD_INFO("max17042", 0x36),
+ .platform_data = &s5pv310_max17042_info,
+ .irq = IRQ_EINT(19),
+ },
+#endif
+#ifdef CONFIG_BATTERY_MAX17040
+ {
+ I2C_BOARD_INFO("max17040", 0x36),
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C10_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data10 __initdata = {
+ .sda_pin = GPIO_USB_SDA,
+ .scl_pin = GPIO_USB_SCL,
+};
+
+struct platform_device s3c_device_i2c10 = {
+ .name = "i2c-gpio",
+ .id = 10,
+ .dev.platform_data = &gpio_i2c_data10,
+};
+
+/* I2C10 */
+static struct fsa9480_platform_data fsa9480_info = {
+};
+
+static struct i2c_board_info i2c_devs10_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("fsa9480", 0x25),
+ .platform_data = &fsa9480_info,
+ },
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C11_EMUL
+static struct i2c_gpio_platform_data gpio_i2c_data11 = {
+ .sda_pin = GPIO_PS_ALS_SDA,
+ .scl_pin = GPIO_PS_ALS_SCL,
+};
+
+struct platform_device s3c_device_i2c11 = {
+ .name = "i2c-gpio",
+ .id = 11,
+ .dev.platform_data = &gpio_i2c_data11,
+};
+
+/* I2C11 */
+#ifdef CONFIG_SENSORS_CM3663
+static int cm3663_ldo(bool on)
+{
+ struct regulator *regulator;
+
+ if (on) {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+static struct cm3663_platform_data cm3663_pdata = {
+ .proximity_power = cm3663_ldo,
+};
+#ifdef CONFIG_SENSORS_PAS2M110
+static struct pas2m110_platform_data pas2m110_pdata = {
+ .proximity_power = cm3663_ldo,
+};
+#endif
+#endif
+#ifdef CONFIG_SENSORS_GP2A_ANALOG
+static int gp2a_power(bool on)
+{
+ struct regulator *regulator;
+
+ if (on) {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vled");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+static struct gp2a_platform_data gp2a_pdata = {
+ .p_out = GPIO_PS_ALS_INT,
+ .power = gp2a_power,
+};
+#endif
+
+static struct i2c_board_info i2c_devs11_emul[] __initdata = {
+#ifdef CONFIG_MACH_U1_BD
+ {
+ I2C_BOARD_INFO("cm3663", 0x20),
+ .irq = GPIO_PS_ALS_INT,
+ .platform_data = &cm3663_pdata,
+ },
+#ifdef CONFIG_SENSORS_PAS2M110
+ {
+ I2C_BOARD_INFO("pas2m110", (0x88>>1)),
+ .irq = GPIO_PS_ALS_INT,
+ .platform_data = &pas2m110_pdata,
+ },
+#endif
+#endif
+#ifdef CONFIG_MACH_Q1_BD
+ {
+ I2C_BOARD_INFO("gp2a", (0x88 >> 1)),
+ .platform_data = &gp2a_pdata,
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C14_EMUL
+static struct i2c_gpio_platform_data i2c14_platdata = {
+ .sda_pin = GPIO_NFC_SDA,
+ .scl_pin = GPIO_NFC_SCL,
+ .udelay = 2,
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c14 = {
+ .name = "i2c-gpio",
+ .id = 14,
+ .dev.platform_data = &i2c14_platdata,
+};
+
+static struct pn544_i2c_platform_data pn544_pdata = {
+ .irq_gpio = GPIO_NFC_IRQ,
+ .ven_gpio = GPIO_NFC_EN,
+ .firm_gpio = GPIO_NFC_FIRM,
+};
+
+static struct i2c_board_info i2c_devs14[] __initdata = {
+ {
+ I2C_BOARD_INFO("pn544", 0x2b),
+ .irq = IRQ_EINT(15),
+ .platform_data = &pn544_pdata,
+ },
+};
+
+static unsigned int nfc_gpio_table[][4] = {
+ {GPIO_NFC_IRQ, S3C_GPIO_INPUT, GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+ {GPIO_NFC_EN, S3C_GPIO_OUTPUT, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_NFC_FIRM, S3C_GPIO_OUTPUT, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+/* {GPIO_NFC_SCL, S3C_GPIO_INPUT, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, */
+/* {GPIO_NFC_SDA, S3C_GPIO_INPUT, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, */
+};
+
+void nfc_setup_gpio(void)
+{
+ /* s3c_config_gpio_alive_table(ARRAY_SIZE(nfc_gpio_table),
+ nfc_gpio_table); */
+ int array_size = ARRAY_SIZE(nfc_gpio_table);
+ u32 i, gpio;
+ for (i = 0; i < array_size; i++) {
+ gpio = nfc_gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(nfc_gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, nfc_gpio_table[i][3]);
+ if (nfc_gpio_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(gpio, nfc_gpio_table[i][2]);
+ }
+
+ /* s3c_gpio_cfgpin(GPIO_NFC_IRQ, EINT_MODE); */
+ /* s3c_gpio_setpull(GPIO_NFC_IRQ, S3C_GPIO_PULL_DOWN); */
+}
+#endif
+
+#if defined(CONFIG_VIDEO_S5K5BAFX)
+static struct i2c_gpio_platform_data i2c12_platdata = {
+ .sda_pin = VT_CAM_SDA_18V,
+ .scl_pin = VT_CAM_SCL_18V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c12 = {
+ .name = "i2c-gpio",
+ .id = 12,
+ .dev.platform_data = &i2c12_platdata,
+};
+
+/* I2C12 */
+static struct i2c_board_info i2c_devs12_emul[] __initdata = {
+ /* need to work here */
+};
+#endif
+
+#ifdef CONFIG_FM_SI4709_MODULE
+static struct i2c_gpio_platform_data i2c16_platdata = {
+ .sda_pin = GPIO_FM_SDA_28V,
+ .scl_pin = GPIO_FM_SCL_28V,
+ .udelay = 2, /* 250KHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c16 = {
+ .name = "i2c-gpio",
+ .id = 16,
+ .dev.platform_data = &i2c16_platdata,
+};
+
+static struct i2c_board_info i2c_devs16[] __initdata = {
+ {
+ I2C_BOARD_INFO("Si4709", (0x20 >> 1)),
+ },
+};
+#endif
+
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cal_x_max = 480,
+ .cal_y_max = 800,
+ .cal_param = {
+ 33, -9156, 34720100, 14819, 57, -4234968, 65536,
+ },
+};
+#endif
+
+#ifdef CONFIG_ISDBT_FC8100
+static struct i2c_board_info i2c_devs17[] __initdata = {
+ {
+ I2C_BOARD_INFO("isdbti2c", 0x77),
+ },
+};
+
+static struct i2c_gpio_platform_data i2c17_platdata = {
+ .sda_pin = GPIO_ISDBT_SDA_28V,
+ .scl_pin = GPIO_ISDBT_SCL_28V,
+ .udelay = 3, /* kHz */
+ .sda_is_open_drain = 0,
+ .scl_is_open_drain = 0,
+ .scl_is_output_only = 0,
+};
+
+static struct platform_device s3c_device_i2c17 = {
+ .name = "i2c-gpio",
+ .id = 17,
+ .dev.platform_data = &i2c17_platdata,
+};
+#endif
+
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#ifdef CONFIG_FB_S5P_S6E8AA0
+/* for Geminus based on MIPI-DSI interface */
+static struct s3cfb_lcd s6e8aa0 = {
+ .name = "s6e8aa0",
+ .width = 800,
+ .height = 1280,
+ .p_width = 64,
+ .p_height = 106,
+ .bpp = 24,
+
+ .freq = 57,
+
+ /* minumun value is 0 except for wr_act time. */
+ .cpu_timing = {
+ .cs_setup = 0,
+ .wr_setup = 0,
+ .wr_act = 1,
+ .wr_hold = 0,
+ },
+
+ .timing = {
+ .h_fp = 10,
+ .h_bp = 10,
+ .h_sw = 10,
+ .v_fp = 13,
+ .v_fpe = 1,
+ .v_bp = 1,
+ .v_bpe = 1,
+ .v_sw = 2,
+ .cmd_allow_len = 11, /*v_fp=stable_vfp + cmd_allow_len */
+ .stable_vfp = 2,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+#endif
+static struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+#ifdef CONFIG_FB_S5P_S6E8AA0
+ .lcd = &s6e8aa0
+#endif
+};
+
+#ifdef CONFIG_FB_S5P_S6E8AA0
+static int reset_lcd(void)
+{
+ int err;
+
+ /* Set GPY4[5] OUTPUT HIGH */
+ err = gpio_request(EXYNOS4_GPY4(5), "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY4(5) for "
+ "lcd reset control\n");
+ return -EPERM;
+ }
+
+ gpio_direction_output(EXYNOS4_GPY4(5), 1);
+ msleep(5);
+ gpio_set_value(EXYNOS4_GPY4(5), 0);
+ msleep(5);
+ gpio_set_value(EXYNOS4_GPY4(5), 1);
+ msleep(5);
+
+ gpio_free(EXYNOS4_GPY4(5));
+
+ return 0;
+}
+#endif
+static void lcd_cfg_gpio(void)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_EN */
+ s3c_gpio_cfgpin(GPIO_LCD_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_LCD_EN, S3C_GPIO_PULL_NONE);
+
+ return;
+}
+
+static int lcd_power_on(void *ld, int enable)
+{
+ struct regulator *regulator;
+ int err;
+
+ printk(KERN_INFO "%s : enable=%d\n", __func__, enable);
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(EXYNOS4_GPY4(5), "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY4[5] for "
+ "MLCD_RST control\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(GPIO_LCD_EN, "LCD_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY3[1] for "
+ "LCD_EN control\n");
+ return -EPERM;
+ }
+
+ if (enable) {
+#ifdef CONFIG_MACH_Q1_BD
+ if (system_rev < 8) {
+ regulator = regulator_get(NULL, "vlcd_2.2v");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+#endif
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+#ifdef CONFIG_MACH_Q1_BD
+ if (system_rev < 8) {
+ regulator = regulator_get(NULL, "vlcd_2.2v");
+ if (IS_ERR(regulator))
+ return 0;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ } else
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+#endif
+
+ gpio_set_value(EXYNOS4_GPY4(5), 0);
+ }
+
+ /* Release GPIO */
+ gpio_free(EXYNOS4_GPY4(5));
+ gpio_free(GPIO_LCD_EN);
+
+ return 0;
+}
+
+static void __init mipi_fb_init(void)
+{
+ struct s5p_platform_dsim *dsim_pd = NULL;
+ struct mipi_ddi_platform_data *mipi_ddi_pd = NULL;
+ struct dsim_lcd_config *dsim_lcd_info = NULL;
+
+ /* set platform data */
+
+ /* gpio pad configuration for rgb and spi interface. */
+ lcd_cfg_gpio();
+
+ /*
+ * register lcd panel data.
+ */
+ printk(KERN_INFO "%s :: fb_platform_data.hw_ver = 0x%x\n",
+ __func__, fb_platform_data.hw_ver);
+
+ fb_platform_data.mipi_is_enabled = 1;
+ fb_platform_data.interface_mode = FIMD_CPU_INTERFACE;
+
+ dsim_pd = (struct s5p_platform_dsim *)
+ s5p_device_dsim.dev.platform_data;
+
+ dsim_pd->platform_rev = 1;
+
+ dsim_lcd_info = dsim_pd->dsim_lcd_info;
+
+#ifdef CONFIG_FB_S5P_S6E8AA0
+ dsim_lcd_info->lcd_panel_info = (void *)&s6e8aa0;
+
+ /* 483Mbps for Q1 */
+ dsim_pd->dsim_info->p = 4;
+ dsim_pd->dsim_info->m = 161;
+ dsim_pd->dsim_info->s = 1;
+#endif
+
+ mipi_ddi_pd = (struct mipi_ddi_platform_data *)
+ dsim_lcd_info->mipi_ddi_pd;
+ mipi_ddi_pd->lcd_reset = reset_lcd;
+ mipi_ddi_pd->lcd_power_on = lcd_power_on;
+
+ platform_device_register(&s5p_device_dsim);
+
+ s3cfb_set_platdata(&fb_platform_data);
+
+ printk(KERN_INFO
+ "platform data of %s lcd panel has been registered.\n",
+ dsim_pd->lcd_panel_name);
+}
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 0,
+ .start = 0,
+ .size = 0
+};
+
+static struct android_pmem_platform_data pmem_gpu1_pdata = {
+ .name = "pmem_gpu1",
+ .no_allocator = 1,
+ .cached = 0,
+ .start = 0,
+ .size = 0,
+};
+
+static struct platform_device pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = {
+ .platform_data = &pmem_pdata},
+};
+
+static struct platform_device pmem_gpu1_device = {
+ .name = "android_pmem",
+ .id = 1,
+ .dev = {
+ .platform_data = &pmem_gpu1_pdata},
+};
+
+static void __init android_pmem_set_platdata(void)
+{
+#if defined(CONFIG_S5P_MEM_CMA)
+ pmem_pdata.size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K;
+ pmem_gpu1_pdata.size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K;
+#else
+ pmem_pdata.start = (u32) s5p_get_media_memory_bank(S5P_MDEV_PMEM, 0);
+ pmem_pdata.size = (u32) s5p_get_media_memsize_bank(S5P_MDEV_PMEM, 0);
+ pmem_gpu1_pdata.start =
+ (u32) s5p_get_media_memory_bank(S5P_MDEV_PMEM_GPU1, 0);
+ pmem_gpu1_pdata.size =
+ (u32) s5p_get_media_memsize_bank(S5P_MDEV_PMEM_GPU1, 0);
+#endif
+}
+#endif
+
+/* USB EHCI */
+#ifdef CONFIG_USB_EHCI_S5P
+static struct s5p_ehci_platdata smdkc210_ehci_pdata;
+
+static void __init smdkc210_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &smdkc210_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+static struct s5p_ohci_platdata smdkc210_ohci_pdata;
+
+static void __init smdkc210_ohci_init(void)
+{
+ struct s5p_ohci_platdata *pdata = &smdkc210_ohci_pdata;
+
+ s5p_ohci_set_platdata(pdata);
+}
+#endif
+
+/* USB GADGET */
+#ifdef CONFIG_USB_GADGET
+static struct s5p_usbgadget_platdata smdkc210_usbgadget_pdata;
+
+#include <linux/usb/android_composite.h>
+static void __init smdkc210_usbgadget_init(void)
+{
+ struct s5p_usbgadget_platdata *pdata = &smdkc210_usbgadget_pdata;
+
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ struct android_usb_platform_data *android_pdata =
+ s3c_device_android_usb.dev.platform_data;
+ if (android_pdata) {
+ unsigned int newluns = 2;
+ printk(KERN_DEBUG "usb: %s: default luns=%d, new luns=%d\n",
+ __func__, android_pdata->nluns, newluns);
+ android_pdata->nluns = newluns;
+ } else {
+ printk(KERN_DEBUG "usb: %s android_pdata is not available\n",
+ __func__);
+ }
+#endif
+
+ s5p_usbgadget_set_platdata(pdata);
+
+ pdata = s3c_device_usbgadget.dev.platform_data;
+ if (pdata) {
+ /* Enables HS Transmitter pre-emphasis [20] */
+ pdata->phy_tune_mask = 0;
+ pdata->phy_tune_mask |= (0x1 << 20);
+ pdata->phy_tune |= (0x1 << 20);
+
+#if defined(CONFIG_MACH_U1_KOR_SKT) || defined(CONFIG_MACH_U1_KOR_KT)
+ /* Squelch Threshold Tune [13:11] (101 : -10%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x5 << 11);
+
+ /* HS DC Voltage Level Adjustment [3:0] (1011 : +16%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xb;
+#elif defined(CONFIG_MACH_U1_KOR_LGT)
+ /* Squelch Threshold Tune [13:11] (100 : -5%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x4 << 11);
+
+ /* HS DC Voltage Level Adjustment [3:0] (1100 : +18%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xc;
+#else
+ /* Squelch Threshold Tune [13:11] (101 : -10%) */
+ pdata->phy_tune_mask |= (0x7 << 11);
+ pdata->phy_tune |= (0x5 << 11);
+ /* HS DC Voltage Level Adjustment [3:0] (1011 : +16%) */
+ pdata->phy_tune_mask |= 0xf;
+ pdata->phy_tune |= 0xb;
+#endif
+
+ printk(KERN_DEBUG "usb: %s tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+ }
+}
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+/* BUSFREQ to control memory/bus*/
+static struct device_domain busfreq;
+
+static struct platform_device exynos4_busfreq = {
+ .id = -1,
+ .name = "exynos-busfreq",
+};
+#endif
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+static struct platform_device watchdog_reset_device = {
+ .name = "watchdog-reset",
+ .id = -1,
+};
+#endif
+
+static struct platform_device *smdkc210_devices[] __initdata = {
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ &watchdog_reset_device,
+#endif
+ &exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_G3D],
+ &exynos4_device_pd[PD_LCD0],
+ &exynos4_device_pd[PD_LCD1],
+ &exynos4_device_pd[PD_CAM],
+ &exynos4_device_pd[PD_TV],
+ &exynos4_device_pd[PD_GPS],
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+#ifdef CONFIG_FB_S5P
+ &s3c_device_fb,
+#endif
+
+#ifdef CONFIG_I2C_S3C2410
+ &s3c_device_i2c0,
+#if defined(CONFIG_S3C_DEV_I2C1)
+ &s3c_device_i2c1,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C2)
+ &s3c_device_i2c2,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C3)
+ &s3c_device_i2c3,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C4)
+ &s3c_device_i2c4,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C5)
+ &s3c_device_i2c5,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C6)
+ &s3c_device_i2c6,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C7)
+ &s3c_device_i2c7,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C8_EMUL)
+ &s3c_device_i2c8,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C9_EMUL)
+ &s3c_device_i2c9,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C10_EMUL)
+ &s3c_device_i2c10,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C11_EMUL)
+ &s3c_device_i2c11,
+#endif
+#if defined(CONFIG_S3C_DEV_I2C14_EMUL)
+ &s3c_device_i2c14,
+#endif
+#if defined(CONFIG_VIDEO_S5K5BAFX)
+ &s3c_device_i2c12,
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ &s3c_device_i2c15,
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+ &s3c_device_i2c16,
+#endif
+#ifdef CONFIG_ISDBT_FC8100
+ &s3c_device_i2c17, /* ISDBT */
+#endif
+#if defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER)
+ &s3c_device_i2c19, /* SMB136, SMB328 */
+#endif
+#endif
+
+ /* consumer driver should resume after resuming i2c drivers */
+ &u1_regulator_consumer,
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ &s3c_device_mshci,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ &s3c_device_hsmmc0,
+#endif
+
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ &s3c_device_hsmmc1,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ &s3c_device_hsmmc2,
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ &s3c_device_hsmmc3,
+#endif
+#ifdef CONFIG_S3C_ADC
+ &s3c_device_adc,
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ &s3c_device_ts,
+#elif CONFIG_S3C_DEV_ADC1
+ &s3c_device_ts1,
+#endif
+#endif
+ &u1_keypad,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+#ifdef CONFIG_SND_SAMSUNG_AC97
+ &exynos_device_ac97,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_I2S
+ &exynos_device_i2s0,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_PCM
+ &exynos_device_pcm0,
+#endif
+#if defined(CONFIG_SND_SAMSUNG_RP) || defined(CONFIG_SND_SAMSUNG_ALP)
+ &exynos_device_srp,
+#endif
+#ifdef CONFIG_SND_SAMSUNG_SPDIF
+ &exynos_device_spdif,
+#endif
+#ifdef CONFIG_BATTERY_SEC_U1
+ &sec_device_battery,
+#endif
+#ifdef CONFIG_LEDS_MAX8997
+ &sec_device_leds_max8997,
+#endif
+#ifdef CONFIG_CHARGER_MAX8922_U1
+ &max8922_device_charger,
+#endif
+#ifdef CONFIG_S5P_SYSTEM_MMU
+ &SYSMMU_PLATDEV(fimc0),
+ &SYSMMU_PLATDEV(fimc1),
+ &SYSMMU_PLATDEV(fimc2),
+ &SYSMMU_PLATDEV(fimc3),
+ &SYSMMU_PLATDEV(2d),
+ &SYSMMU_PLATDEV(tv),
+ &SYSMMU_PLATDEV(mfc_l),
+ &SYSMMU_PLATDEV(mfc_r),
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ &exynos_device_ion,
+#endif
+
+ &samsung_asoc_dma,
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+ &samsung_asoc_idma,
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ &exynos_device_spi0,
+#endif
+
+/* mainline fimd */
+#ifdef CONFIG_FB_S3C
+ &s5p_device_fimd0,
+#if defined(CONFIG_LCD_AMS369FG06)
+ &s3c_device_spi_gpio,
+#elif defined(CONFIG_LCD_WA101S)
+ &smdkc210_lcd_wa101s,
+#elif defined(CONFIG_LCD_LTE480WV)
+ &smdkc210_lcd_lte480wv,
+#endif
+#endif
+/* legacy fimd */
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ &s3c_device_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ &ld9040_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_NT35560
+ &nt35560_spi_gpio,
+#endif
+#ifdef CONFIG_FB_S5P_MDNIE
+ &mdnie_device,
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ &s5p_device_tvout,
+ &s5p_device_cec,
+ &s5p_device_hpd,
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+ &pmem_device,
+ &pmem_gpu1_device,
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ &s3c_device_fimc0,
+ &s3c_device_fimc1,
+ &s3c_device_fimc2,
+ &s3c_device_fimc3,
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ &s3c_device_csis0,
+ &s3c_device_csis1,
+#endif
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ &s5p_device_mfc,
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ &s5p_device_fimg2d,
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ &s5p_device_jpeg,
+#endif
+#if defined CONFIG_USB_EHCI_S5P && !defined CONFIG_LINK_DEVICE_HSIC
+ &s5p_device_ehci,
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ &s5p_device_ohci,
+#endif
+#ifdef CONFIG_USB_GADGET
+ &s3c_device_usbgadget,
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ &s3c_device_rndis,
+#endif
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+ &s3c_device_android_usb,
+ &s3c_device_usb_mass_storage,
+#endif
+#ifdef CONFIG_HAVE_PWM
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &s3c_device_timer[2],
+ &s3c_device_timer[3],
+#endif
+#ifdef CONFIG_VIDEO_TSI
+ &s3c_device_tsi,
+#endif
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ &s5p_device_tmu,
+#endif
+#ifdef CONFIG_BT_BCM4330
+ &bcm4330_bluetooth_device,
+#endif
+#ifdef CONFIG_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
+#ifdef CONFIG_BUSFREQ_OPP
+ &exynos4_busfreq,
+#endif
+#ifdef CONFIG_SEC_DEV_JACK
+ &sec_device_jack,
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ &host_notifier_device,
+#endif
+ &s3c_device_usb_otghcd,
+};
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+/* below temperature base on the celcius degree */
+struct s5p_platform_tmu u1_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 61,
+ .start_1st_throttle = 64,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110,
+ .start_emergency = 120,
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000, /* 800MHz in KHz order */
+ .limit_2nd_throttle = 200000, /* 200MHz in KHz order */
+ },
+};
+#endif
+
+#if defined CONFIG_USB_EHCI_S5P && defined CONFIG_LINK_DEVICE_HSIC
+static int __init s5p_ehci_device_initcall(void)
+{
+ return platform_device_register(&s5p_device_ehci);
+}
+late_initcall(s5p_ehci_device_initcall);
+#endif
+
+#if defined(CONFIG_VIDEO_TVOUT)
+static struct s5p_platform_hpd hdmi_hpd_data __initdata = {
+
+};
+
+static struct s5p_platform_cec hdmi_cec_data __initdata = {
+
+};
+#endif
+
+#if defined(CONFIG_S5P_MEM_CMA)
+static void __init exynos4_cma_region_reserve(struct cma_region *regions_normal,
+ struct cma_region *regions_secure)
+{
+ struct cma_region *reg;
+ size_t size_secure = 0, align_secure = 0;
+ phys_addr_t paddr = 0;
+
+ for (reg = regions_normal; reg->size != 0; reg++) {
+ if (WARN_ON(cma_early_region_register(reg)))
+ continue;
+
+ if ((reg->alignment & (reg->alignment - 1)) || reg->reserved)
+ continue;
+
+ if (reg->start) {
+ if (!memblock_is_region_reserved(reg->start, reg->size)
+ && memblock_reserve(reg->start, reg->size) >= 0)
+ reg->reserved = 1;
+ } else {
+ paddr = __memblock_alloc_base(reg->size, reg->alignment,
+ MEMBLOCK_ALLOC_ACCESSIBLE);
+ if (paddr) {
+ reg->start = paddr;
+ reg->reserved = 1;
+ }
+ }
+ }
+
+ if (regions_secure && regions_secure->size) {
+ for (reg = regions_secure; reg->size != 0; reg++)
+ size_secure += reg->size;
+
+ reg--;
+
+ align_secure = reg->alignment;
+ BUG_ON(align_secure & (align_secure - 1));
+
+ paddr -= size_secure;
+ paddr &= ~(align_secure - 1);
+
+ if (!memblock_reserve(paddr, size_secure)) {
+ do {
+ reg->start = paddr;
+ reg->reserved = 1;
+ paddr += reg->size;
+
+ if (WARN_ON(cma_early_region_register(reg)))
+ memblock_free(reg->start, reg->size);
+ } while (reg-- != regions_secure);
+ }
+ }
+}
+
+static void __init exynos4_reserve_mem(void)
+{
+ static struct cma_region regions[] = {
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM
+ {
+ .name = "pmem",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1
+ {
+ .name = "pmem_gpu1",
+ .size = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .name = "fimd",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .name = "fimc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .name = "fimc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .name = "fimc2",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3
+ {
+ .name = "fimc3",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .name = "mfc1",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .name = "mfc0",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC
+ {
+ .name = "mfc",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC * SZ_1K,
+ {
+ .alignment = 1 << 17,
+ },
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .name = "jpeg",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .name = "srp",
+ .size = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .name = "fimg2d",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .start = 0,
+ },
+#endif
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT
+ {
+ .name = "tvout",
+ .size = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT * SZ_1K,
+ .start = 0,
+ },
+#endif
+ {
+ .size = 0,
+ },
+ };
+
+ static const char map[] __initconst =
+ "android_pmem.0=pmem;android_pmem.1=pmem_gpu1;"
+ "s3cfb.0=fimd;exynos4-fb.0=fimd;"
+ "s3c-fimc.0=fimc0;s3c-fimc.1=fimc1;s3c-fimc.2=fimc2;"
+ "exynos4210-fimc.0=fimc0;exynos4210-fimc.1=fimc1;exynos4210-fimc.2=fimc2;exynos4210-fimc3=fimc3;"
+#ifdef CONFIG_VIDEO_MFC5X
+ "s3c-mfc/A=mfc0,mfc-secure;"
+ "s3c-mfc/B=mfc1,mfc-normal;"
+ "s3c-mfc/AB=mfc;"
+#endif
+ "samsung-rp=srp;"
+ "s5p-jpeg=jpeg;"
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+ "exynos4-fimc-is=fimc_is;"
+#endif
+ "s5p-fimg2d=fimg2d;"
+ "s5p-tvout=tvout";
+
+ cma_set_defaults(regions, map);
+ exynos4_cma_region_reserve(regions, NULL);
+
+}
+#endif
+
+static void __init exynos_sysmmu_init(void)
+{
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc0, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc1, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc2, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimc3, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(jpeg, &exynos4_device_pd[PD_CAM].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(fimd0, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(2d, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(rot, &exynos4_device_pd[PD_LCD0].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(tv, &exynos4_device_pd[PD_TV].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_l, &exynos4_device_pd[PD_MFC].dev);
+ ASSIGN_SYSMMU_POWERDOMAIN(mfc_r, &exynos4_device_pd[PD_MFC].dev);
+#if defined CONFIG_VIDEO_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s3c_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s3c_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s3c_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s3c_device_fimc3.dev);
+#elif defined CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev);
+#endif
+#ifdef CONFIG_VIDEO_JPEG
+ sysmmu_set_owner(&SYSMMU_PLATDEV(jpeg).dev, &s5p_device_jpeg.dev);
+#endif
+#ifdef CONFIG_FB_S3C
+ sysmmu_set_owner(&SYSMMU_PLATDEV(fimd0).dev, &s5p_device_fimd0.dev);
+#endif
+#ifdef CONFIG_VIDEO_FIMG2D
+ sysmmu_set_owner(&SYSMMU_PLATDEV(2d).dev, &s5p_device_fimg2d.dev);
+#endif
+#ifdef CONFIG_VIDEO_TVOUT
+ sysmmu_set_owner(&SYSMMU_PLATDEV(tv).dev, &s5p_device_tvout.dev);
+#endif
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc.dev);
+ sysmmu_set_owner(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc.dev);
+#endif
+}
+
+static void __init smdkc210_map_io(void)
+{
+ clk_xusbxti.rate = 24000000;
+
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
+
+#if defined(CONFIG_S5P_MEM_CMA)
+ exynos4_reserve_mem();
+#else
+ s5p_reserve_mem(S5P_RANGE_MFC);
+#endif
+
+ /* as soon as INFORM3 is visible, sec_debug is ready to run */
+ sec_debug_init();
+}
+
+static void __init universal_tsp_init(void)
+{
+ int gpio;
+
+ /* TSP_LDO_ON: XMDMADDR_11 */
+ gpio = GPIO_TSP_LDO_ON;
+ gpio_request(gpio, "TSP_LDO_ON");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+
+ /* TSP_INT: XMDMADDR_7 */
+ gpio = GPIO_TSP_INT;
+ gpio_request(gpio, "TSP_INT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+
+ printk(KERN_INFO "%s touch : %d\n", __func__, i2c_devs3[0].irq);
+#ifdef CONFIG_MACH_Q1_BD
+ gpio_request(GPIO_TSP_SDA, "TSP_SDA");
+ gpio_request(GPIO_TSP_SCL, "TSP_SCL");
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+#endif
+}
+
+#ifdef CONFIG_EPEN_WACOM_G5SP
+static int p6_wacom_init_hw(void)
+{
+ int gpio;
+ int ret;
+
+ gpio = GPIO_PEN_RESET;
+ ret = gpio_request(gpio, "PEN_RESET");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ gpio_direction_output(gpio, 1);
+
+ gpio = GPIO_PEN_SLP;
+ ret = gpio_request(gpio, "PEN_SLP");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_direction_output(gpio, 0);
+
+ gpio = GPIO_PEN_PDCT;
+ ret = gpio_request(gpio, "PEN_PDCT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0x0));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_direction_input(gpio);
+
+ gpio = GPIO_PEN_IRQ;
+ ret = gpio_request(gpio, "PEN_IRQ");
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_register_gpio_interrupt(gpio);
+ gpio_direction_input(gpio);
+
+ i2c_devs6[1].irq = gpio_to_irq(gpio);
+ irq_set_irq_type(i2c_devs6[1].irq, IRQ_TYPE_EDGE_RISING);
+
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+
+ return 0;
+}
+
+static int __init p6_wacom_init(void)
+{
+ p6_wacom_init_hw();
+ printk(KERN_INFO "[E-PEN] : wacom IC initialized.\n");
+ return 0;
+}
+#endif
+
+static void __init smdkc210_machine_init(void)
+{
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ struct clk *sclk = NULL;
+ struct clk *prnt = NULL;
+ struct device *spi0_dev = &exynos_device_spi0.dev;
+#endif
+ /* initialise the gpios */
+ u1_config_gpio_table();
+ exynos4_sleep_gpio_table_set = u1_config_sleep_gpio_table;
+
+#ifdef CONFIG_I2C_S3C2410
+ s3c_i2c0_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+
+#ifdef CONFIG_S3C_DEV_I2C1
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C2
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(2, i2c_devs2, ARRAY_SIZE(i2c_devs2));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C3
+ universal_tsp_init();
+ s3c_i2c3_set_platdata(NULL);
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C4
+ s3c_i2c4_set_platdata(NULL);
+ i2c_register_board_info(4, i2c_devs4, ARRAY_SIZE(i2c_devs4));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C5
+ s3c_i2c5_set_platdata(NULL);
+ s3c_gpio_cfgpin(GPIO_PMIC_IRQ, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_PMIC_IRQ, S3C_GPIO_PULL_NONE);
+ i2c_devs5[0].irq = gpio_to_irq(GPIO_PMIC_IRQ);
+ i2c_register_board_info(5, i2c_devs5, ARRAY_SIZE(i2c_devs5));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C6
+#ifdef CONFIG_EPEN_WACOM_G5SP
+ p6_wacom_init();
+#endif
+ s3c_i2c6_set_platdata(NULL);
+ i2c_register_board_info(6, i2c_devs6, ARRAY_SIZE(i2c_devs6));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C7
+ s3c_i2c7_set_platdata(NULL);
+ i2c_register_board_info(7, i2c_devs7, ARRAY_SIZE(i2c_devs7));
+#endif
+#ifdef CONFIG_SAMSUNG_MHL
+ printk(KERN_INFO "%s() register sii9234 driver\n", __func__);
+
+ i2c_register_board_info(15, tuna_i2c15_boardinfo,
+ ARRAY_SIZE(tuna_i2c15_boardinfo));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C8_EMUL
+ i2c_register_board_info(8, i2c_devs8_emul, ARRAY_SIZE(i2c_devs8_emul));
+ gpio_request(GPIO_3_TOUCH_INT, "sec_touchkey");
+ s5p_register_gpio_interrupt(GPIO_3_TOUCH_INT);
+
+#endif
+#ifdef CONFIG_S3C_DEV_I2C9_EMUL
+ i2c_register_board_info(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C10_EMUL
+ i2c_register_board_info(10, i2c_devs10_emul,
+ ARRAY_SIZE(i2c_devs10_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C11_EMUL
+ s3c_gpio_setpull(GPIO_PS_ALS_INT, S3C_GPIO_PULL_NONE);
+ i2c_register_board_info(11, i2c_devs11_emul,
+ ARRAY_SIZE(i2c_devs11_emul));
+#endif
+#ifdef CONFIG_S3C_DEV_I2C14_EMUL
+ nfc_setup_gpio();
+ i2c_register_board_info(14, i2c_devs14, ARRAY_SIZE(i2c_devs14));
+#endif
+#if defined(CONFIG_VIDEO_S5K5BAFX)
+ i2c_register_board_info(12, i2c_devs12_emul,
+ ARRAY_SIZE(i2c_devs12_emul));
+#endif
+#ifdef CONFIG_FM_SI4709_MODULE
+ i2c_register_board_info(16, i2c_devs16, ARRAY_SIZE(i2c_devs16));
+#endif
+#ifdef CONFIG_ISDBT_FC8100
+ i2c_register_board_info(17, i2c_devs17, ARRAY_SIZE(i2c_devs17));
+#endif
+
+#if defined(CONFIG_SMB136_CHARGER_Q1) || defined(CONFIG_SMB328_CHARGER)
+ i2c_register_board_info(19, i2c_devs19_emul,
+ ARRAY_SIZE(i2c_devs19_emul));
+#endif
+#endif
+
+ /* 400 kHz for initialization of MMC Card */
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS3) & 0xfffffff0)
+ | 0x9, EXYNOS4_CLKDIV_FSYS3);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS2) & 0xfff0fff0)
+ | 0x80008, EXYNOS4_CLKDIV_FSYS2);
+ __raw_writel((__raw_readl(EXYNOS4_CLKDIV_FSYS1) & 0xfff0fff0)
+ | 0x90009, EXYNOS4_CLKDIV_FSYS1);
+
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_sdhci0_set_platdata(&exynos4_hsmmc0_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_sdhci1_set_platdata(&exynos4_hsmmc1_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_sdhci2_set_platdata(&exynos4_hsmmc2_pdata);
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_sdhci3_set_platdata(&exynos4_hsmmc3_pdata);
+#endif
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_set_platdata(&exynos4_mshc_pdata);
+#endif
+
+#ifdef CONFIG_FB_S3C
+#ifdef CONFIG_LCD_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+ s5p_fimd0_set_platdata(&smdkc210_lcd0_pdata);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_AMS369FG06
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ s3cfb_set_platdata(&ams369fg06_data);
+#else
+ s3cfb_set_platdata(NULL);
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fb.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_JPEG
+ s5p_device_jpeg.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#if defined(CONFIG_VIDEO_TVOUT)
+ s5p_hdmi_hpd_set_platdata(&hdmi_hpd_data);
+ s5p_hdmi_cec_set_platdata(&hdmi_cec_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_tvout.dev.parent = &exynos4_device_pd[PD_TV].dev;
+#endif
+#endif
+#ifdef CONFIG_TOUCHSCREEN_S3C2410
+#ifdef CONFIG_S3C_DEV_ADC
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+#endif
+#ifdef CONFIG_S3C_DEV_ADC1
+ s3c24xx_ts1_set_platdata(&s3c_ts_platform);
+#endif
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+ android_pmem_set_platdata();
+#endif
+#ifdef CONFIG_VIDEO_FIMC
+ /* fimc */
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(NULL);
+ s3c_fimc2_set_platdata(&fimc_plat);
+ s3c_fimc3_set_platdata(NULL);
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#endif
+#endif
+
+#ifdef CONFIG_EXYNOS_DEV_PD
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_ION_EXYNOS
+ exynos_ion_set_platdata();
+#endif
+
+#ifdef CONFIG_EXYNOS4_SETUP_THERMAL
+ s5p_tmu_set_platdata(&u1_tmu_data);
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X) || defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+#endif
+#endif
+
+#if defined(CONFIG_VIDEO_MFC5X)
+ exynos4_mfc_setup_clock(&s5p_device_mfc.dev, 200 * MHZ);
+#endif
+#if defined(CONFIG_VIDEO_SAMSUNG_S5P_MFC)
+ dev_set_name(&s5p_device_mfc.dev, "s3c-mfc");
+ clk_add_alias("mfc", "s5p-mfc", "mfc", &s5p_device_mfc.dev);
+ s5p_mfc_setname(&s5p_device_mfc, "s5p-mfc");
+#endif
+
+#ifdef CONFIG_VIDEO_FIMG2D
+ s5p_fimg2d_set_platdata(&fimg2d_data);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimg2d.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
+#endif
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ smdkc210_ehci_init();
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ smdkc210_ohci_init();
+#endif
+#ifdef CONFIG_USB_GADGET
+ smdkc210_usbgadget_init();
+#endif
+#ifdef CONFIG_FB_S5P_LD9040
+ ld9040_fb_init();
+#endif
+#ifdef CONFIG_FB_S5P_NT35560
+ nt35560_fb_init();
+#endif
+#if defined(CONFIG_FB_S5P_MIPI_DSIM)
+ mipi_fb_init();
+#endif
+
+#ifdef CONFIG_SND_SOC_U1_MC1N2
+ u1_sound_init();
+#endif
+
+ brcm_wlan_init();
+
+ exynos_sysmmu_init();
+
+ platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
+
+#ifdef CONFIG_SEC_THERMISTOR
+ platform_device_register(&sec_device_thermistor);
+#endif
+
+#ifdef CONFIG_FB_S3C
+ exynos4_fimd0_setup_clock(&s5p_device_fimd0.dev, "mout_mpll",
+ 800 * MHZ);
+#endif
+
+#ifdef CONFIG_S3C64XX_DEV_SPI
+ sclk = clk_get(spi0_dev, "dout_spi0");
+ if (IS_ERR(sclk))
+ dev_err(spi0_dev, "failed to get sclk for SPI-0\n");
+ prnt = clk_get(spi0_dev, "mout_mpll");
+ if (IS_ERR(prnt))
+ dev_err(spi0_dev, "failed to get prnt\n");
+ clk_set_parent(sclk, prnt);
+
+ clk_put(sclk);
+ clk_put(prnt);
+
+ if (!gpio_request(EXYNOS4_GPB(1), "SPI_CS0")) {
+ gpio_direction_output(EXYNOS4_GPB(1), 1);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(1), S3C_GPIO_SFN(1));
+ s3c_gpio_setpull(EXYNOS4_GPB(1), S3C_GPIO_PULL_UP);
+ exynos_spi_set_info(0, EXYNOS_SPI_SRCCLK_SCLK,
+ ARRAY_SIZE(spi0_csi));
+ }
+ spi_register_board_info(spi0_board_info, ARRAY_SIZE(spi0_board_info));
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ dev_add(&busfreq, &exynos4_busfreq.dev);
+#endif
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ tdmb_dev_init();
+#endif
+
+}
+
+static void __init exynos_init_reserve(void)
+{
+ sec_debug_magic_init();
+}
+
+#ifdef CONFIG_MACH_U1_KOR_SKT
+#define MODEL_NAME "SHW-M250S"
+#elif defined(CONFIG_MACH_U1_KOR_KT)
+#define MODEL_NAME "SHW-M250K"
+#elif defined(CONFIG_MACH_U1_KOR_LGT)
+#define MODEL_NAME "SHW-M250L"
+#else
+#define MODEL_NAME "SMDK4210"
+#endif
+
+MACHINE_START(SMDKC210, MODEL_NAME)
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = smdkc210_map_io,
+ .init_machine = smdkc210_machine_init,
+ .timer = &exynos4_timer,
+ .init_early = &exynos_init_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 97d329f..a458483 100644
--- a/arch/arm/mach-exynos4/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/mach-universal_c210.c
+/* linux/arch/arm/mach-exynos/mach-universal_c210.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
@@ -613,7 +613,6 @@ static struct platform_device *universal_devices[] __initdata = {
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
&s3c_device_i2c5,
-
/* Universal Devices */
&universal_gpio_keys,
&s5p_device_onenand,
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos/mct.c
index 14ac10b..dececa1 100644
--- a/arch/arm/mach-exynos4/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/mct.c
+/* linux/arch/arm/mach-exynos/mct.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -20,19 +20,32 @@
#include <linux/delay.h>
#include <linux/percpu.h>
+#include <plat/cpu.h>
+
#include <mach/map.h>
#include <mach/regs-mct.h>
+
#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+
+#define TICK_BASE_CNT 1
+
+enum {
+ MCT_INT_PPI,
+ MCT_INT_SPI
+};
static unsigned long clk_cnt_per_tick;
static unsigned long clk_rate;
+static unsigned int mct_int_type;
struct mct_clock_event_device {
struct clock_event_device *evt;
void __iomem *base;
+ char name[10];
};
-struct mct_clock_event_device mct_tick[2];
+struct mct_clock_event_device mct_tick[NR_CPUS];
static void exynos4_mct_write(unsigned int value, void *addr)
{
@@ -42,60 +55,67 @@ static void exynos4_mct_write(unsigned int value, void *addr)
__raw_writel(value, addr);
- switch ((u32) addr) {
- case (u32) EXYNOS4_MCT_G_TCON:
- stat_addr = EXYNOS4_MCT_G_WSTAT;
- mask = 1 << 16; /* G_TCON write status */
- break;
- case (u32) EXYNOS4_MCT_G_COMP0_L:
- stat_addr = EXYNOS4_MCT_G_WSTAT;
- mask = 1 << 0; /* G_COMP0_L write status */
- break;
- case (u32) EXYNOS4_MCT_G_COMP0_U:
- stat_addr = EXYNOS4_MCT_G_WSTAT;
- mask = 1 << 1; /* G_COMP0_U write status */
- break;
- case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
- stat_addr = EXYNOS4_MCT_G_WSTAT;
- mask = 1 << 2; /* G_COMP0_ADD_INCR write status */
- break;
- case (u32) EXYNOS4_MCT_G_CNT_L:
- stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
- mask = 1 << 0; /* G_CNT_L write status */
- break;
- case (u32) EXYNOS4_MCT_G_CNT_U:
- stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
- mask = 1 << 1; /* G_CNT_U write status */
- break;
- case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCON_OFFSET):
- stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
- mask = 1 << 3; /* L0_TCON write status */
- break;
- case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCON_OFFSET):
- stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
- mask = 1 << 3; /* L1_TCON write status */
- break;
- case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCNTB_OFFSET):
- stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
- mask = 1 << 0; /* L0_TCNTB write status */
- break;
- case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCNTB_OFFSET):
- stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
- mask = 1 << 0; /* L1_TCNTB write status */
- break;
- case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_ICNTB_OFFSET):
- stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
- mask = 1 << 1; /* L0_ICNTB write status */
- break;
- case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_ICNTB_OFFSET):
- stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
- mask = 1 << 1; /* L1_ICNTB write status */
- break;
- default:
- return;
+ if (likely(addr >= EXYNOS4_MCT_L_BASE(0))) {
+ u32 base = (u32) addr & EXYNOS4_MCT_L_MASK;
+ switch ((u32) addr & ~EXYNOS4_MCT_L_MASK) {
+ case (u32) MCT_L_TCON_OFFSET:
+ stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
+ mask = 1 << 3; /* L_TCON write status */
+ break;
+ case (u32) MCT_L_ICNTB_OFFSET:
+ stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
+ mask = 1 << 1; /* L_ICNTB write status */
+ break;
+ case (u32) MCT_L_TCNTB_OFFSET:
+ stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
+ mask = 1 << 0; /* L_TCNTB write status */
+ break;
+ default:
+ return;
+ }
+ } else {
+ switch ((u32) addr) {
+ case (u32) EXYNOS4_MCT_G_TCON:
+ stat_addr = EXYNOS4_MCT_G_WSTAT;
+ mask = 1 << 16; /* G_TCON write status */
+ break;
+ case (u32) EXYNOS4_MCT_G_COMP0_L:
+ stat_addr = EXYNOS4_MCT_G_WSTAT;
+ mask = 1 << 0; /* G_COMP0_L write status */
+ break;
+ case (u32) EXYNOS4_MCT_G_COMP0_U:
+ stat_addr = EXYNOS4_MCT_G_WSTAT;
+ mask = 1 << 1; /* G_COMP0_U write status */
+ break;
+ case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
+ stat_addr = EXYNOS4_MCT_G_WSTAT;
+ mask = 1 << 2; /* G_COMP0_ADD_INCR write status */
+ break;
+ case (u32) EXYNOS4_MCT_G_CNT_L:
+ stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+ mask = 1 << 0; /* G_CNT_L write status */
+ break;
+ case (u32) EXYNOS4_MCT_G_CNT_U:
+ stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+ mask = 1 << 1; /* G_CNT_U write status */
+ break;
+ default:
+ return;
+ }
}
- /* Wait maximum 1 ms until written values are applied */
+ /* Wait until written values are applied */
+ for (i = 0; i < 0x1000; i++)
+ if (__raw_readl(stat_addr) & mask) {
+ __raw_writel(mask, stat_addr);
+ return;
+ }
+
+ /* Workaround: Try again if fail */
+ __raw_writel(value, addr);
+
+ printk(KERN_ERR "[%s]value=%d addr=0x%X\n", __func__, value, (u32)addr);
+
for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
if (__raw_readl(stat_addr) & mask) {
__raw_writel(mask, stat_addr);
@@ -118,7 +138,7 @@ static void exynos4_mct_frc_start(u32 hi, u32 lo)
exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
}
-static cycle_t exynos4_frc_read(struct clocksource *cs)
+static cycle_t notrace exynos4_frc_read(struct clocksource *cs)
{
unsigned int lo, hi;
u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
@@ -132,12 +152,27 @@ static cycle_t exynos4_frc_read(struct clocksource *cs)
return ((cycle_t)hi << 32) | lo;
}
+cycle_t suspended_frc_count;
+
+static void exynos4_frc_suspend(struct clocksource *cs)
+{
+ suspended_frc_count = cs->read(cs);
+}
+
+static void exynos4_frc_resume(struct clocksource *cs)
+{
+ exynos4_mct_frc_start(suspended_frc_count >> 32, suspended_frc_count);
+}
+
struct clocksource mct_frc = {
.name = "mct-frc",
.rating = 400,
.read = exynos4_frc_read,
.mask = CLOCKSOURCE_MASK(64),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
+ CLOCK_SOURCE_SCHED_CLOCK,
+ .suspend = exynos4_frc_suspend,
+ .resume = exynos4_frc_resume,
};
static void __init exynos4_clocksource_init(void)
@@ -236,9 +271,9 @@ static struct irqaction mct_comp_event_irq = {
static void exynos4_clockevent_init(void)
{
- clk_cnt_per_tick = clk_rate / 2 / HZ;
+ clk_cnt_per_tick = clk_rate / HZ;
- clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
+ clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
mct_comp_device.max_delta_ns =
clockevent_delta2ns(0xffffffff, &mct_comp_device);
mct_comp_device.min_delta_ns =
@@ -290,7 +325,8 @@ static int exynos4_tick_set_next_event(unsigned long cycles,
{
struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
- exynos4_mct_tick_start(cycles, mevt);
+ if (cpu_online(smp_processor_id()))
+ exynos4_mct_tick_start(cycles, mevt);
return 0;
}
@@ -304,20 +340,23 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
- exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
+ exynos4_mct_tick_start(clk_cnt_per_tick / (TICK_BASE_CNT + 1)
+ , mevt);
break;
case CLOCK_EVT_MODE_ONESHOT:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+
case CLOCK_EVT_MODE_RESUME:
+ exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
break;
}
}
-static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
+static inline int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
{
- struct mct_clock_event_device *mevt = dev_id;
struct clock_event_device *evt = mevt->evt;
/*
@@ -328,8 +367,26 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
exynos4_mct_tick_stop(mevt);
- /* Clear the MCT tick interrupt */
- exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+ /*
+ * Clear the MCT tick interrupt.
+ * Because of the limitation of MCT hardware,
+ * it should be cleared twice.
+ */
+ if (__raw_readl(mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
+ exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+ exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
+{
+ struct mct_clock_event_device *mevt = dev_id;
+ struct clock_event_device *evt = mevt->evt;
+
+ exynos4_mct_tick_clear(mevt);
evt->event_handler(evt);
@@ -354,21 +411,17 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
mct_tick[cpu].evt = evt;
- if (cpu == 0) {
- mct_tick[cpu].base = EXYNOS4_MCT_L0_BASE;
- evt->name = "mct_tick0";
- } else {
- mct_tick[cpu].base = EXYNOS4_MCT_L1_BASE;
- evt->name = "mct_tick1";
- }
+ mct_tick[cpu].base = EXYNOS4_MCT_L_BASE(cpu);
+ sprintf(mct_tick[cpu].name, "mct_tick%d", cpu);
+ evt->name = mct_tick[cpu].name;
evt->cpumask = cpumask_of(cpu);
evt->set_next_event = exynos4_tick_set_next_event;
evt->set_mode = exynos4_tick_set_mode;
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
evt->rating = 450;
- clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
+ clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
evt->max_delta_ns =
clockevent_delta2ns(0x7fffffff, evt);
evt->min_delta_ns =
@@ -376,27 +429,36 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
clockevents_register_device(evt);
- exynos4_mct_write(0x1, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET);
+ exynos4_mct_write(TICK_BASE_CNT, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET);
- if (cpu == 0) {
- mct_tick0_event_irq.dev_id = &mct_tick[cpu];
- setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+ if (mct_int_type == MCT_INT_SPI) {
+ if (cpu == 0) {
+ mct_tick0_event_irq.dev_id = &mct_tick[cpu];
+ setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+ } else {
+ mct_tick1_event_irq.dev_id = &mct_tick[cpu];
+ setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
+ irq_set_affinity(IRQ_MCT_L1, cpumask_of(1));
+ }
} else {
- mct_tick1_event_irq.dev_id = &mct_tick[cpu];
- irq_set_affinity(IRQ_MCT1, cpumask_of(1));
- setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
+ gic_enable_ppi(IRQ_PPI_MCT_L);
}
}
/* Setup the local clock events for a CPU */
-void __cpuinit local_timer_setup(struct clock_event_device *evt)
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
exynos4_mct_tick_init(evt);
+
+ return 0;
}
int local_timer_ack(void)
{
- return 0;
+ unsigned int cpu = smp_processor_id();
+ struct mct_clock_event_device *mevt = &mct_tick[cpu];
+
+ return exynos4_mct_tick_clear(mevt);
}
#endif /* CONFIG_LOCAL_TIMERS */
@@ -411,6 +473,12 @@ static void __init exynos4_timer_resources(void)
static void __init exynos4_timer_init(void)
{
+ if (soc_is_exynos4210() ||
+ (soc_is_exynos5250() && samsung_rev() >= EXYNOS5250_REV_1_0))
+ mct_int_type = MCT_INT_SPI;
+ else
+ mct_int_type = MCT_INT_PPI;
+
exynos4_timer_resources();
exynos4_clocksource_init();
exynos4_clockevent_init();
diff --git a/arch/arm/mach-exynos/mdm2.c b/arch/arm/mach-exynos/mdm2.c
new file mode 100644
index 0000000..249b7cf
--- /dev/null
+++ b/arch/arm/mach-exynos/mdm2.c
@@ -0,0 +1,253 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/debugfs.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include <linux/mfd/pmic8058.h>
+#endif
+#include <asm/mach-types.h>
+#include <asm/uaccess.h>
+#include <mach/mdm2.h>
+#include <mach/restart.h>
+#include <mach/subsystem_notif.h>
+#include <mach/subsystem_restart.h>
+#include <linux/msm_charm.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include "msm_watchdog.h"
+#include "devices.h"
+#include "clock.h"
+#endif
+#include "mdm_private.h"
+#include <linux/wakelock.h>
+
+#define MDM_MODEM_TIMEOUT 6000
+#define MDM_HOLD_TIME 4000
+#define MDM_MODEM_DELTA 100
+
+static int mdm_debug_on;
+static int power_on_count;
+static int hsic_peripheral_status = 1;
+static DEFINE_MUTEX(hsic_status_lock);
+
+static void mdm_peripheral_connect(struct mdm_modem_drv *mdm_drv)
+{
+ pr_err("%s\n", __func__);
+ mutex_lock(&hsic_status_lock);
+ if (hsic_peripheral_status)
+ goto out;
+ if (mdm_drv->pdata->peripheral_platform_device)
+ platform_device_add(mdm_drv->pdata->peripheral_platform_device);
+ hsic_peripheral_status = 1;
+out:
+ mutex_unlock(&hsic_status_lock);
+ pr_err("%s : ap2mdm_status = %d\n", __func__,
+ gpio_get_value(mdm_drv->ap2mdm_status_gpio));
+}
+
+static void mdm_peripheral_disconnect(struct mdm_modem_drv *mdm_drv)
+{
+ pr_err("%s\n", __func__);
+ mutex_lock(&hsic_status_lock);
+ if (!hsic_peripheral_status)
+ goto out;
+ if (mdm_drv->pdata->peripheral_platform_device)
+ platform_device_del(mdm_drv->pdata->peripheral_platform_device);
+ hsic_peripheral_status = 0;
+out:
+ mutex_unlock(&hsic_status_lock);
+ pr_err("%s : ap2mdm_status = %d\n", __func__,
+ gpio_get_value(mdm_drv->ap2mdm_status_gpio));
+}
+
+static void power_on_mdm(struct mdm_modem_drv *mdm_drv)
+{
+ power_on_count++;
+
+ pr_err("%s: power count %d\n", __func__, power_on_count);
+ /* this gpio will be used to indicate apq readiness,
+ * de-assert it now so that it can asserted later
+ */
+ gpio_direction_output(mdm_drv->ap2mdm_wakeup_gpio, 0);
+
+ /* The second attempt to power-on the mdm is the first attempt
+ * from user space, but we're already powered on. Ignore this.
+ * Subsequent attempts are from SSR or if something failed, in
+ * which case we must always reset the modem.
+ */
+ if (power_on_count == 2)
+ return;
+
+ mdm_peripheral_disconnect(mdm_drv);
+
+ /* Pull RESET gpio low and wait for it to settle. */
+ pr_info("Pulling RESET gpio low\n");
+ gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);
+ usleep_range(5000, 10000);
+
+ /* Deassert RESET first and wait for ir to settle. */
+ pr_info("%s: Pulling RESET gpio high\n", __func__);
+ gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 1);
+ msleep(20);
+
+ /* Pull PWR gpio high and wait for it to settle, but only
+ * the first time the mdm is powered up.
+ * Some targets do not use ap2mdm_kpdpwr_n_gpio.
+ */
+ if (power_on_count == 1) {
+ if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0) {
+ pr_debug("%s: Powering on mdm modem\n", __func__);
+ gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 1);
+ usleep_range(1000, 1000);
+ }
+ }
+
+#ifdef CONFIG_ARCH_EXYNOS
+ gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
+#endif
+ mdm_peripheral_connect(mdm_drv);
+
+ msleep(200);
+}
+
+static void power_down_mdm(struct mdm_modem_drv *mdm_drv)
+{
+ int i;
+
+ pr_err("%s\n", __func__);
+ for (i = MDM_MODEM_TIMEOUT; i > 0; i -= MDM_MODEM_DELTA) {
+ /* pet_watchdog(); */
+ msleep(MDM_MODEM_DELTA);
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ break;
+ }
+ if (i <= 0) {
+ pr_err("%s: MDM2AP_STATUS never went low.\n",
+ __func__);
+ gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);
+
+ for (i = MDM_HOLD_TIME; i > 0; i -= MDM_MODEM_DELTA) {
+ /* pet_watchdog(); */
+ msleep(MDM_MODEM_DELTA);
+ }
+ }
+ if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0)
+ gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
+ mdm_peripheral_disconnect(mdm_drv);
+}
+
+#ifdef CONFIG_ARCH_EXYNOS
+static void normal_boot_done(struct mdm_modem_drv *mdm_drv)
+{
+ pr_err("%s\n", __func__);
+ mdm_peripheral_disconnect(mdm_drv);
+}
+#endif
+
+static void debug_state_changed(int value)
+{
+ mdm_debug_on = value;
+}
+
+static void mdm_status_changed(struct mdm_modem_drv *mdm_drv, int value)
+{
+ pr_debug("%s: value:%d\n", __func__, value);
+
+ pr_err("%s: ap2mdm_status = %d\n", __func__,
+ gpio_get_value(mdm_drv->ap2mdm_status_gpio));
+ if (value) {
+ mdm_peripheral_disconnect(mdm_drv);
+ mdm_peripheral_connect(mdm_drv);
+ gpio_direction_output(mdm_drv->ap2mdm_wakeup_gpio, 1);
+ }
+}
+
+static struct mdm_ops mdm_cb = {
+ .power_on_mdm_cb = power_on_mdm,
+ .power_down_mdm_cb = power_down_mdm,
+ .debug_state_changed_cb = debug_state_changed,
+ .status_cb = mdm_status_changed,
+#ifdef CONFIG_ARCH_EXYNOS
+ .normal_boot_done_cb = normal_boot_done,
+#endif
+};
+
+/* temprary wakelock, remove when L3 state implemented */
+#ifdef CONFIG_ARCH_EXYNOS
+static struct wake_lock mdm_wake;
+#endif
+
+static int __init mdm_modem_probe(struct platform_device *pdev)
+{
+ pr_err("%s\n", __func__);
+/* temprary wakelock, remove when L3 state implemented */
+#ifdef CONFIG_ARCH_EXYNOS
+ wake_lock_init(&mdm_wake, WAKE_LOCK_SUSPEND, "mdm_wake");
+ wake_lock(&mdm_wake);
+#endif
+ return mdm_common_create(pdev, &mdm_cb);
+}
+
+static int __devexit mdm_modem_remove(struct platform_device *pdev)
+{
+ return mdm_common_modem_remove(pdev);
+}
+
+static void mdm_modem_shutdown(struct platform_device *pdev)
+{
+ mdm_common_modem_shutdown(pdev);
+}
+
+static struct platform_driver mdm_modem_driver = {
+ .remove = mdm_modem_remove,
+ .shutdown = mdm_modem_shutdown,
+ .driver = {
+ .name = "mdm2_modem",
+ .owner = THIS_MODULE
+ },
+};
+
+static int __init mdm_modem_init(void)
+{
+ return platform_driver_probe(&mdm_modem_driver, mdm_modem_probe);
+}
+
+static void __exit mdm_modem_exit(void)
+{
+ platform_driver_unregister(&mdm_modem_driver);
+}
+
+late_initcall(mdm_modem_init);
+/* module_init(mdm_modem_init); */
+module_exit(mdm_modem_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("mdm modem driver");
+MODULE_VERSION("2.0");
+MODULE_ALIAS("mdm_modem");
diff --git a/arch/arm/mach-exynos/mdm_common.c b/arch/arm/mach-exynos/mdm_common.c
new file mode 100644
index 0000000..30b5f75
--- /dev/null
+++ b/arch/arm/mach-exynos/mdm_common.c
@@ -0,0 +1,567 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/debugfs.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include <linux/mfd/pmic8058.h>
+#endif
+#include <asm/mach-types.h>
+#include <asm/uaccess.h>
+#include <mach/mdm2.h>
+#include <mach/restart.h>
+#include <mach/subsystem_notif.h>
+#include <mach/subsystem_restart.h>
+#include <linux/msm_charm.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include "msm_watchdog.h"
+#endif
+#include "mdm_private.h"
+
+#ifdef CONFIG_ARCH_EXYNOS
+#include <linux/interrupt.h>
+#include <plat/gpio-cfg.h>
+#endif
+
+#define MDM_MODEM_TIMEOUT 6000
+#define MDM_MODEM_DELTA 100
+#define MDM_BOOT_TIMEOUT 60000L
+#define MDM_RDUMP_TIMEOUT 60000L
+
+static int mdm_debug_on;
+static struct workqueue_struct *mdm_queue;
+
+#define EXTERNAL_MODEM "external_modem"
+
+static struct mdm_modem_drv *mdm_drv;
+
+DECLARE_COMPLETION(mdm_needs_reload);
+DECLARE_COMPLETION(mdm_boot);
+DECLARE_COMPLETION(mdm_ram_dumps);
+
+static int first_boot = 1;
+
+long mdm_modem_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ int status, ret = 0;
+
+ if (_IOC_TYPE(cmd) != CHARM_CODE) {
+ pr_err("%s: invalid ioctl code\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: Entering ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
+ switch (cmd) {
+ case WAKE_CHARM:
+ pr_info("%s: Powering on mdm\n", __func__);
+ mdm_drv->ops->power_on_mdm_cb(mdm_drv);
+ break;
+ case CHECK_FOR_BOOT:
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ put_user(1, (unsigned long __user *) arg);
+ else
+ put_user(0, (unsigned long __user *) arg);
+ break;
+ case NORMAL_BOOT_DONE:
+ pr_info("%s: check if mdm is booted up\n", __func__);
+ get_user(status, (unsigned long __user *) arg);
+ if (status) {
+ pr_debug("%s: normal boot failed\n", __func__);
+ mdm_drv->mdm_boot_status = -EIO;
+ } else {
+ pr_info("%s: normal boot done\n", __func__);
+ mdm_drv->mdm_boot_status = 0;
+ }
+ mdm_drv->mdm_ready = 1;
+
+ if (mdm_drv->ops->normal_boot_done_cb != NULL)
+ mdm_drv->ops->normal_boot_done_cb(mdm_drv);
+
+ if (!first_boot)
+ complete(&mdm_boot);
+ else
+ first_boot = 0;
+ break;
+ case RAM_DUMP_DONE:
+ pr_info("%s: mdm done collecting RAM dumps\n", __func__);
+ get_user(status, (unsigned long __user *) arg);
+ if (status)
+ mdm_drv->mdm_ram_dump_status = -EIO;
+ else {
+ pr_info("%s: ramdump collection completed\n", __func__);
+ mdm_drv->mdm_ram_dump_status = 0;
+ }
+ complete(&mdm_ram_dumps);
+ break;
+ case WAIT_FOR_RESTART:
+ pr_info("%s: wait for mdm to need images reloaded\n",
+ __func__);
+ ret = wait_for_completion_interruptible(&mdm_needs_reload);
+ if (!ret)
+ put_user(mdm_drv->boot_type,
+ (unsigned long __user *) arg);
+ INIT_COMPLETION(mdm_needs_reload);
+ break;
+ default:
+ pr_err("%s: invalid ioctl cmd = %d\n", __func__, _IOC_NR(cmd));
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static void mdm_fatal_fn(struct work_struct *work)
+{
+ pr_info("%s: Reseting the mdm due to an errfatal\n", __func__);
+ subsystem_restart(EXTERNAL_MODEM);
+}
+
+static DECLARE_WORK(mdm_fatal_work, mdm_fatal_fn);
+
+static void mdm_status_fn(struct work_struct *work)
+{
+ int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
+
+ if (!mdm_drv->mdm_ready)
+ return;
+
+ mdm_drv->ops->status_cb(mdm_drv, value);
+
+ pr_err("%s: status:%d\n", __func__, value);
+
+ if ((value == 0)) {
+ pr_info("%s: unexpected reset external modem\n", __func__);
+ subsystem_restart(EXTERNAL_MODEM);
+ } else if (value == 1) {
+ pr_info("%s: status = 1: mdm is now ready\n", __func__);
+ }
+}
+
+static DECLARE_WORK(mdm_status_work, mdm_status_fn);
+
+static void mdm_disable_irqs(void)
+{
+ disable_irq_nosync(mdm_drv->mdm_errfatal_irq);
+ disable_irq_nosync(mdm_drv->mdm_status_irq);
+
+}
+
+static irqreturn_t mdm_errfatal(int irq, void *dev_id)
+{
+ pr_debug("%s: mdm got errfatal interrupt\n", __func__);
+ if (mdm_drv->mdm_ready &&
+ (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1)) {
+ pr_debug("%s: scheduling work now\n", __func__);
+ queue_work(mdm_queue, &mdm_fatal_work);
+ }
+ return IRQ_HANDLED;
+}
+
+static int mdm_modem_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static const struct file_operations mdm_modem_fops = {
+ .owner = THIS_MODULE,
+ .open = mdm_modem_open,
+ .unlocked_ioctl = mdm_modem_ioctl,
+};
+
+
+static struct miscdevice mdm_modem_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "mdm",
+ .fops = &mdm_modem_fops
+};
+
+static int mdm_panic_prep(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ int i;
+
+ pr_debug("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
+ __func__);
+ mdm_disable_irqs();
+ gpio_set_value(mdm_drv->ap2mdm_errfatal_gpio, 1);
+
+ for (i = MDM_MODEM_TIMEOUT; i > 0; i -= MDM_MODEM_DELTA) {
+ /* pet_watchdog(); */
+ mdelay(MDM_MODEM_DELTA);
+ if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+ break;
+ }
+ if (i <= 0)
+ pr_err("%s: MDM2AP_STATUS never went low\n", __func__);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block mdm_panic_blk = {
+ .notifier_call = mdm_panic_prep,
+};
+
+static irqreturn_t mdm_status_change(int irq, void *dev_id)
+{
+ int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio);
+ pr_err("%s: mdm sent status change interrupt : %d\n", __func__, value);
+
+ queue_work(mdm_queue, &mdm_status_work);
+
+ return IRQ_HANDLED;
+}
+
+static int mdm_subsys_shutdown(const struct subsys_data *crashed_subsys)
+{
+ pr_info("%s\n", __func__);
+ mdm_drv->mdm_ready = 0;
+ gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
+ if (mdm_drv->pdata->ramdump_delay_ms > 0) {
+ /* Wait for the external modem to complete
+ * its preparation for ramdumps.
+ */
+ msleep(mdm_drv->pdata->ramdump_delay_ms);
+ }
+ mdm_drv->ops->power_down_mdm_cb(mdm_drv);
+ return 0;
+}
+
+static int mdm_subsys_powerup(const struct subsys_data *crashed_subsys)
+{
+ pr_info("%s\n", __func__);
+ gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
+ gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
+ mdm_drv->ops->power_on_mdm_cb(mdm_drv);
+ mdm_drv->boot_type = CHARM_NORMAL_BOOT;
+ complete(&mdm_needs_reload);
+ if (!wait_for_completion_timeout(&mdm_boot,
+ msecs_to_jiffies(MDM_BOOT_TIMEOUT))) {
+ mdm_drv->mdm_boot_status = -ETIMEDOUT;
+ pr_info("%s: mdm modem restart timed out.\n", __func__);
+ } else
+ pr_info("%s: mdm modem has been restarted\n", __func__);
+ INIT_COMPLETION(mdm_boot);
+ return mdm_drv->mdm_boot_status;
+}
+
+static int mdm_subsys_ramdumps(int want_dumps,
+ const struct subsys_data *crashed_subsys)
+{
+ pr_info("%s\n", __func__);
+ mdm_drv->mdm_ram_dump_status = 0;
+ if (want_dumps) {
+ mdm_drv->boot_type = CHARM_RAM_DUMPS;
+ complete(&mdm_needs_reload);
+ if (!wait_for_completion_timeout(&mdm_ram_dumps,
+ msecs_to_jiffies(MDM_RDUMP_TIMEOUT))) {
+ mdm_drv->mdm_ram_dump_status = -ETIMEDOUT;
+ pr_info("%s: mdm modem ramdumps timed out.\n",
+ __func__);
+ } else
+ pr_info("%s: mdm modem ramdumps completed.\n",
+ __func__);
+ INIT_COMPLETION(mdm_ram_dumps);
+ gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 1);
+ mdm_drv->ops->power_down_mdm_cb(mdm_drv);
+ }
+ return mdm_drv->mdm_ram_dump_status;
+}
+
+static struct subsys_data mdm_subsystem = {
+ .shutdown = mdm_subsys_shutdown,
+ .ramdump = mdm_subsys_ramdumps,
+ .powerup = mdm_subsys_powerup,
+ .name = EXTERNAL_MODEM,
+};
+
+static int mdm_debug_on_set(void *data, u64 val)
+{
+ mdm_debug_on = val;
+ if (mdm_drv->ops->debug_state_changed_cb)
+ mdm_drv->ops->debug_state_changed_cb(mdm_debug_on);
+ return 0;
+}
+
+static int mdm_debug_on_get(void *data, u64 *val)
+{
+ *val = mdm_debug_on;
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(mdm_debug_on_fops,
+ mdm_debug_on_get,
+ mdm_debug_on_set, "%llu\n");
+
+static int mdm_debugfs_init(void)
+{
+ struct dentry *dent;
+
+ dent = debugfs_create_dir("mdm_dbg", 0);
+ if (IS_ERR(dent))
+ return PTR_ERR(dent);
+
+ debugfs_create_file("debug_on", 0644, dent, NULL,
+ &mdm_debug_on_fops);
+ return 0;
+}
+
+static void mdm_modem_initialize_data(struct platform_device *pdev,
+ struct mdm_ops *mdm_ops)
+{
+ struct resource *pres;
+
+ /* MDM2AP_ERRFATAL */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "MDM2AP_ERRFATAL");
+ if (pres)
+ mdm_drv->mdm2ap_errfatal_gpio = pres->start;
+
+ /* AP2MDM_ERRFATAL */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "AP2MDM_ERRFATAL");
+ if (pres)
+ mdm_drv->ap2mdm_errfatal_gpio = pres->start;
+
+ /* MDM2AP_STATUS */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "MDM2AP_STATUS");
+ if (pres)
+ mdm_drv->mdm2ap_status_gpio = pres->start;
+
+ /* AP2MDM_STATUS */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "AP2MDM_STATUS");
+ if (pres)
+ mdm_drv->ap2mdm_status_gpio = pres->start;
+
+ /* MDM2AP_WAKEUP */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "MDM2AP_WAKEUP");
+ if (pres)
+ mdm_drv->mdm2ap_wakeup_gpio = pres->start;
+
+ /* AP2MDM_WAKEUP */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "AP2MDM_WAKEUP");
+ if (pres)
+ mdm_drv->ap2mdm_wakeup_gpio = pres->start;
+
+ /* AP2MDM_PMIC_RESET_N */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "AP2MDM_PMIC_RESET_N");
+ if (pres)
+ mdm_drv->ap2mdm_pmic_reset_n_gpio = pres->start;
+
+ /* AP2MDM_KPDPWR_N */
+ pres = platform_get_resource_byname(pdev, IORESOURCE_IO,
+ "AP2MDM_KPDPWR_N");
+ if (pres)
+ mdm_drv->ap2mdm_kpdpwr_n_gpio = pres->start;
+
+ mdm_drv->boot_type = CHARM_NORMAL_BOOT;
+
+ mdm_drv->ops = mdm_ops;
+ mdm_drv->pdata = pdev->dev.platform_data;
+}
+
+int mdm_common_create(struct platform_device *pdev,
+ struct mdm_ops *p_mdm_cb)
+{
+ int ret = -1, irq;
+ pr_err("%s\n", __func__);
+
+ mdm_drv = kzalloc(sizeof(struct mdm_modem_drv), GFP_KERNEL);
+ if (mdm_drv == NULL) {
+ pr_err("%s: kzalloc fail.\n", __func__);
+ goto alloc_err;
+ }
+
+ mdm_modem_initialize_data(pdev, p_mdm_cb);
+ if (mdm_drv->ops->debug_state_changed_cb)
+ mdm_drv->ops->debug_state_changed_cb(mdm_debug_on);
+
+ gpio_request(mdm_drv->ap2mdm_status_gpio, "AP2MDM_STATUS");
+ gpio_request(mdm_drv->ap2mdm_errfatal_gpio, "AP2MDM_ERRFATAL");
+ gpio_request(mdm_drv->ap2mdm_kpdpwr_n_gpio, "AP2MDM_KPDPWR_N");
+ gpio_request(mdm_drv->ap2mdm_pmic_reset_n_gpio, "AP2MDM_PMIC_RESET_N");
+ gpio_request(mdm_drv->mdm2ap_status_gpio, "MDM2AP_STATUS");
+ gpio_request(mdm_drv->mdm2ap_errfatal_gpio, "MDM2AP_ERRFATAL");
+
+ if (mdm_drv->ap2mdm_wakeup_gpio > 0)
+ gpio_request(mdm_drv->ap2mdm_wakeup_gpio, "AP2MDM_WAKEUP");
+
+#ifdef CONFIG_ARCH_EXYNOS
+ gpio_set_value(mdm_drv->ap2mdm_status_gpio, 1);
+ s3c_gpio_cfgpin(mdm_drv->ap2mdm_status_gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(mdm_drv->ap2mdm_status_gpio, S3C_GPIO_PULL_UP);
+#endif
+ gpio_direction_output(mdm_drv->ap2mdm_status_gpio, 1);
+ pr_err("%s> : right after ap2mdm_status = %d\n", __func__,
+ gpio_get_value(mdm_drv->ap2mdm_status_gpio));
+
+#ifdef CONFIG_ARCH_EXYNOS
+ gpio_set_value(mdm_drv->ap2mdm_errfatal_gpio, 0);
+ s3c_gpio_cfgpin(mdm_drv->ap2mdm_errfatal_gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(mdm_drv->ap2mdm_errfatal_gpio, S3C_GPIO_PULL_DOWN);
+#endif
+ gpio_direction_output(mdm_drv->ap2mdm_errfatal_gpio, 0);
+ pr_err("%s>> : right after ap2mdm_status = %d\n", __func__,
+ gpio_get_value(mdm_drv->ap2mdm_status_gpio));
+
+ if (mdm_drv->ap2mdm_wakeup_gpio > 0)
+ gpio_direction_output(mdm_drv->ap2mdm_wakeup_gpio, 0);
+
+ gpio_direction_input(mdm_drv->mdm2ap_status_gpio);
+ gpio_direction_input(mdm_drv->mdm2ap_errfatal_gpio);
+
+ mdm_queue = create_singlethread_workqueue("mdm_queue");
+ if (!mdm_queue) {
+ pr_err("%s: could not create workqueue. All mdm "
+ "functionality will be disabled\n",
+ __func__);
+ ret = -ENOMEM;
+ goto fatal_err;
+ }
+
+ atomic_notifier_chain_register(&panic_notifier_list, &mdm_panic_blk);
+ mdm_debugfs_init();
+
+ /* Register subsystem handlers */
+ ssr_register_subsystem(&mdm_subsystem);
+
+ /* ERR_FATAL irq. */
+#ifdef CONFIG_ARCH_EXYNOS
+ irq = gpio_to_irq(mdm_drv->mdm2ap_errfatal_gpio);
+#else
+ irq = MSM_GPIO_TO_INT(mdm_drv->mdm2ap_errfatal_gpio);
+#endif
+ if (irq < 0) {
+ pr_err("%s: could not get MDM2AP_ERRFATAL IRQ resource. "
+ "error=%d No IRQ will be generated on errfatal.",
+ __func__, irq);
+ goto errfatal_err;
+ }
+ ret = request_irq(irq, mdm_errfatal,
+ IRQF_TRIGGER_RISING , "mdm errfatal", NULL);
+
+ if (ret < 0) {
+ pr_err("%s: MDM2AP_ERRFATAL IRQ#%d request failed with error=%d"
+ ". No IRQ will be generated on errfatal.",
+ __func__, irq, ret);
+ goto errfatal_err;
+ }
+ mdm_drv->mdm_errfatal_irq = irq;
+
+errfatal_err:
+
+ /* status irq */
+#ifdef CONFIG_ARCH_EXYNOS
+ ret = s5p_register_gpio_interrupt(mdm_drv->mdm2ap_status_gpio);
+ if (ret)
+ pr_err("%s: register MDM2AP_STATUS ret = %d\n", __func__, ret);
+ irq = gpio_to_irq(mdm_drv->mdm2ap_status_gpio);
+#else
+ irq = MSM_GPIO_TO_INT(mdm_drv->mdm2ap_status_gpio);
+#endif
+ if (irq < 0) {
+ pr_err("%s: could not get MDM2AP_STATUS IRQ resource. "
+ "error=%d No IRQ will be generated on status change.",
+ __func__, irq);
+ goto status_err;
+ }
+
+ ret = request_threaded_irq(irq, NULL, mdm_status_change,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED,
+ "mdm status", mdm_drv);
+
+ if (ret < 0) {
+ pr_err("%s: MDM2AP_STATUS IRQ#%d request failed with error=%d"
+ ". No IRQ will be generated on status change.",
+ __func__, irq, ret);
+ goto status_err;
+ }
+ mdm_drv->mdm_status_irq = irq;
+
+status_err:
+ /* Perform early powerup of the external modem in order to
+ * allow tabla devices to be found.
+ */
+ mdm_drv->ops->power_on_mdm_cb(mdm_drv);
+ pr_err("%s : ap2mdm_status = %d\n", __func__,
+ gpio_get_value(mdm_drv->ap2mdm_status_gpio));
+
+ pr_info("%s: Registering mdm modem\n", __func__);
+ return misc_register(&mdm_modem_misc);
+
+fatal_err:
+ gpio_free(mdm_drv->ap2mdm_status_gpio);
+ gpio_free(mdm_drv->ap2mdm_errfatal_gpio);
+ gpio_free(mdm_drv->ap2mdm_kpdpwr_n_gpio);
+ gpio_free(mdm_drv->ap2mdm_pmic_reset_n_gpio);
+ gpio_free(mdm_drv->mdm2ap_status_gpio);
+ gpio_free(mdm_drv->mdm2ap_errfatal_gpio);
+
+ if (mdm_drv->ap2mdm_wakeup_gpio > 0)
+ gpio_free(mdm_drv->ap2mdm_wakeup_gpio);
+
+ kfree(mdm_drv);
+ ret = -ENODEV;
+
+alloc_err:
+ return ret;
+}
+
+int mdm_common_modem_remove(struct platform_device *pdev)
+{
+ int ret;
+
+ gpio_free(mdm_drv->ap2mdm_status_gpio);
+ gpio_free(mdm_drv->ap2mdm_errfatal_gpio);
+ gpio_free(mdm_drv->ap2mdm_kpdpwr_n_gpio);
+ gpio_free(mdm_drv->ap2mdm_pmic_reset_n_gpio);
+ gpio_free(mdm_drv->mdm2ap_status_gpio);
+ gpio_free(mdm_drv->mdm2ap_errfatal_gpio);
+
+ if (mdm_drv->ap2mdm_wakeup_gpio > 0)
+ gpio_free(mdm_drv->ap2mdm_wakeup_gpio);
+
+ kfree(mdm_drv);
+
+ ret = misc_deregister(&mdm_modem_misc);
+ return ret;
+}
+
+void mdm_common_modem_shutdown(struct platform_device *pdev)
+{
+ mdm_disable_irqs();
+
+ mdm_drv->ops->power_down_mdm_cb(mdm_drv);
+}
+
diff --git a/arch/arm/mach-exynos/mdm_device.c b/arch/arm/mach-exynos/mdm_device.c
new file mode 100644
index 0000000..22be1d5
--- /dev/null
+++ b/arch/arm/mach-exynos/mdm_device.c
@@ -0,0 +1,64 @@
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <mach/gpio-exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/ehci.h>
+#include <linux/msm_charm.h>
+#include <mach/mdm2.h>
+#include "mdm_private.h"
+
+static struct resource mdm_resources[] = {
+ {
+ .start = MDM2AP_ERRFATAL,
+ .end = MDM2AP_ERRFATAL,
+ .name = "MDM2AP_ERRFATAL",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = AP2MDM_ERRFATAL,
+ .end = AP2MDM_ERRFATAL,
+ .name = "AP2MDM_ERRFATAL",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = MDM2AP_STATUS,
+ .end = MDM2AP_STATUS,
+ .name = "MDM2AP_STATUS",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = AP2MDM_STATUS,
+ .end = AP2MDM_STATUS,
+ .name = "AP2MDM_STATUS",
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = AP2MDM_PMIC_RESET_N,
+ .end = AP2MDM_PMIC_RESET_N,
+ .name = "AP2MDM_PMIC_RESET_N",
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct mdm_platform_data mdm_platform_data = {
+ .mdm_version = "3.0",
+ .ramdump_delay_ms = 2000,
+ .peripheral_platform_device = &s5p_device_ehci,
+};
+
+struct platform_device mdm_device = {
+ .name = "mdm2_modem",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mdm_resources),
+ .resource = mdm_resources,
+};
+
+static int __init init_mdm_modem(void)
+{
+ pr_err("%s !!! !!\n", __func__);
+ mdm_device.dev.platform_data = &mdm_platform_data;
+ return platform_device_register(&mdm_device);
+}
+module_init(init_mdm_modem);
diff --git a/arch/arm/mach-exynos/mdm_private.h b/arch/arm/mach-exynos/mdm_private.h
new file mode 100644
index 0000000..206bd8b
--- /dev/null
+++ b/arch/arm/mach-exynos/mdm_private.h
@@ -0,0 +1,56 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_MDM_PRIVATE_H
+#define _ARCH_ARM_MACH_MSM_MDM_PRIVATE_H
+
+struct mdm_modem_drv;
+
+struct mdm_ops {
+ void (*power_on_mdm_cb)(struct mdm_modem_drv *mdm_drv);
+ void (*normal_boot_done_cb)(struct mdm_modem_drv *mdm_drv);
+ void (*power_down_mdm_cb)(struct mdm_modem_drv *mdm_drv);
+ void (*debug_state_changed_cb)(int value);
+ void (*status_cb)(struct mdm_modem_drv *mdm_drv, int value);
+};
+
+/* Private mdm2 data structure */
+struct mdm_modem_drv {
+ unsigned mdm2ap_errfatal_gpio;
+ unsigned ap2mdm_errfatal_gpio;
+ unsigned mdm2ap_status_gpio;
+ unsigned ap2mdm_status_gpio;
+ unsigned mdm2ap_wakeup_gpio;
+ unsigned ap2mdm_wakeup_gpio;
+ unsigned ap2mdm_pmic_reset_n_gpio;
+ unsigned ap2mdm_kpdpwr_n_gpio;
+
+ int mdm_errfatal_irq;
+ int mdm_status_irq;
+ int mdm_ready;
+ int mdm_boot_status;
+ int mdm_ram_dump_status;
+ enum charm_boot_type boot_type;
+ int mdm_debug_on;
+
+ struct mdm_ops *ops;
+ struct mdm_platform_data *pdata;
+};
+
+int mdm_common_create(struct platform_device *pdev,
+ struct mdm_ops *mdm_cb);
+int mdm_common_modem_remove(struct platform_device *pdev);
+void mdm_common_modem_shutdown(struct platform_device *pdev);
+void mdm_common_set_debug_state(int value);
+
+#endif
+
diff --git a/arch/arm/mach-exynos/midas-camera.c b/arch/arm/mach-exynos/midas-camera.c
new file mode 100644
index 0000000..587a9be
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-camera.c
@@ -0,0 +1,3450 @@
+/*
+ * camera class init
+ */
+
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-device.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/regulator/machine.h>
+#include <linux/init.h>
+
+#include <plat/devs.h>
+#include <plat/csis.h>
+#include <plat/pd.h>
+#include <plat/gpio-cfg.h>
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+#include <plat/fimc-core.h>
+#include <media/s5p_fimc.h>
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+#include <media/exynos_flite.h>
+#endif
+
+#if defined(CONFIG_VIDEO_S5C73M3) || defined(CONFIG_VIDEO_SLP_S5C73M3)
+#include <media/s5c73m3_platform.h>
+#endif
+
+#if defined(CONFIG_VIDEO_M5MO)
+#include <mach/regs-gpio.h>
+#include <media/m5mo_platform.h>
+#endif
+
+#if defined(CONFIG_VIDEO_M9MO)
+#include <mach/regs-gpio.h>
+#include <media/m9mo_platform.h>
+#endif
+
+#if defined(CONFIG_VIDEO_ISX012)
+#include <media/isx012_platform.h>
+#endif
+#if defined(CONFIG_VIDEO_S5K5CCGX_COMMON)
+#include <media/s5k5ccgx_platform.h>
+#endif
+
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+#include <mach/secmem.h>
+#endif
+
+#ifdef CONFIG_VIDEO_SR200PC20M
+#include <media/sr200pc20m_platform.h>
+#endif
+
+#ifdef CONFIG_VIDEO_SR200PC20
+#include <media/sr200pc20_platform.h>
+#endif
+
+struct class *camera_class;
+
+static int __init camera_class_init(void)
+{
+ camera_class = class_create(THIS_MODULE, "camera");
+ if (IS_ERR(camera_class)) {
+ pr_err("Failed to create class(camera)!\n");
+ return PTR_ERR(camera_class);
+ }
+
+ return 0;
+}
+
+subsys_initcall(camera_class_init);
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+#define FRONT_CAM_MCLK_DEVIDED_REVISION 0x06
+#define USE_8M_CAM_SENSOR_CORE_REVISION 0x09
+#elif defined(CONFIG_MACH_C1_KOR_LGT)
+#define FRONT_CAM_MCLK_DEVIDED_REVISION 0x04
+#define USE_8M_CAM_SENSOR_CORE_REVISION 0x07
+#elif defined(CONFIG_MACH_C1_USA_ATT)
+#define FRONT_CAM_MCLK_DEVIDED_REVISION 0x05
+#elif defined(CONFIG_MACH_C1VZW)
+#define FRONT_CAM_MCLK_DEVIDED_REVISION 0x0A
+#else
+#define FRONT_CAM_MCLK_DEVIDED_REVISION 0x08
+#endif
+
+#if defined(CONFIG_VIDEO_FIMC)
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+ */
+
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR "\nfail to %s: err = %d\n", msg, x); \
+ }
+#define CAM_CHECK_ERR_GOTO(x, out, fmt, ...) \
+ if (unlikely((x) < 0)) { \
+ printk(KERN_ERR fmt, ##__VA_ARGS__); \
+ goto out; \
+ }
+
+int s3c_csis_power(int enable)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ /* mipi_1.1v ,mipi_1.8v are always powered-on.
+ * If they are off, we then power them on.
+ */
+ if (enable) {
+ /* VMIPI_1.0V */
+ regulator = regulator_get(NULL, "vmipi_1.0v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ /* VMIPI_1.8V */
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ printk(KERN_WARNING "%s: vmipi_1.0v and vmipi_1.8v were ON\n",
+ __func__);
+ } else {
+ /* VMIPI_1.8V */
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.8v is on. so OFF\n",
+ __func__);
+ ret = regulator_disable(regulator);
+ }
+ regulator_put(regulator);
+
+ /* VMIPI_1.0V */
+ regulator = regulator_get(NULL, "vmipi_1.0v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (regulator_is_enabled(regulator)) {
+ printk(KERN_WARNING "%s: vmipi_1.1v is on. so OFF\n",
+ __func__);
+ ret = regulator_disable(regulator);
+ }
+ regulator_put(regulator);
+
+ printk(KERN_WARNING "%s: vmipi_1.0v and vmipi_1.8v were OFF\n",
+ __func__);
+ }
+
+ return 0;
+
+error_out:
+ printk(KERN_ERR "%s: ERROR: failed to check mipi-power\n", __func__);
+ return 0;
+}
+
+#ifdef CONFIG_WRITEBACK_ENABLED
+#define WRITEBACK_ENABLED
+#endif
+#ifdef WRITEBACK_ENABLED
+static int get_i2c_busnum_writeback(void)
+{
+ return 0;
+}
+
+static struct i2c_board_info writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .get_i2c_busnum = get_i2c_busnum_writeback,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 1280,
+ .width = 720,
+ .height = 1280,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 720,
+ .height = 1280,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_IS
+#ifdef CONFIG_VIDEO_S5K6A3
+#ifdef CONFIG_MACH_P4NOTE
+/* For P4Note PegasusQ */
+static int s5k6a3_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_VT_CAM_nRST, "GPJ1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "request GPIO_VT_CAM_nRST\n");
+ return ret;
+ }
+
+ /* VT_CAM_2.8V */
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_a2.8v");
+ udelay(100);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_NONE);
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ udelay(1);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(1000);
+
+ /* VT_CAM_nRST */
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "GPIO_VT_CAM_nRST");
+ udelay(600);
+
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "GPIO_VT_CAM_nRST");
+ udelay(600);
+
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "GPIO_VT_CAM_nRST");
+
+ gpio_free(GPIO_VT_CAM_nRST);
+
+ return ret;
+}
+
+static int s5k6a3_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_VT_CAM_nRST, "GPJ1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "request GPIO_VT_CAM_nRST\n");
+ return ret;
+ }
+
+ /* VT_CAM_nRST */
+ ret = gpio_direction_output(GPIO_VT_CAM_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "GPIO_VT_CAM_nRST");
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+
+
+ /* VT_CAM_2.8V */
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_a2.8v");
+ udelay(100);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ udelay(1);
+
+ gpio_free(GPIO_VT_CAM_nRST);
+
+ return ret;
+}
+#else /* !CONFIG_MACH_P4NOTE */
+static int s5k6a3_gpio_request(void)
+{
+ int ret = 0;
+
+ /* SENSOR_A2.8V */
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+
+ if (system_rev <= FRONT_CAM_MCLK_DEVIDED_REVISION)
+ ret = gpio_request(GPIO_CAM_MCLK, "GPJ1");
+ else
+ ret = gpio_request(GPIO_VTCAM_MCLK, "GPM2");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_VTCAM_MCLK)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPM1");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_CAM_VT_nRST)\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int s5k6a3_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ s5k6a3_gpio_request();
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_IO_EN");
+ /* delay is needed : external LDO control is slower than MCLK control*/
+ udelay(100);
+
+ /* MCLK */
+ if (system_rev <= FRONT_CAM_MCLK_DEVIDED_REVISION) {
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(GPIO_CAM_MCLK, S5P_GPIO_DRVSTR_LV2);
+ } else {
+ ret = s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(GPIO_VTCAM_MCLK, S5P_GPIO_DRVSTR_LV2);
+ }
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_cam_1.8v");
+ udelay(1000);
+
+ /* VT_RESET */
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_VT_nRST");
+ udelay(600);
+
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_VT_nRST");
+ udelay(600);
+
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_VT_nRST");
+
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_CAM_VT_nRST);
+ if (system_rev <= FRONT_CAM_MCLK_DEVIDED_REVISION)
+ gpio_free(GPIO_CAM_MCLK);
+ else
+ gpio_free(GPIO_VTCAM_MCLK);
+
+ return ret;
+}
+
+static int s5k6a3_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ s5k6a3_gpio_request();
+
+ /* VT_RESET */
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_VT_nRST");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_cam_1.8v");
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_IO_EN");
+ /* delay is needed : external LDO control is slower than MCLK control*/
+ udelay(500);
+
+ /* MCLK */
+ if (system_rev <= FRONT_CAM_MCLK_DEVIDED_REVISION) {
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+
+ } else {
+ ret = s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_DOWN);
+ }
+ CAM_CHECK_ERR(ret, "cfg mclk");
+
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_CAM_VT_nRST);
+
+ if (system_rev <= FRONT_CAM_MCLK_DEVIDED_REVISION)
+ gpio_free(GPIO_CAM_MCLK);
+ else
+ gpio_free(GPIO_VTCAM_MCLK);
+
+ return ret;
+}
+#endif /* CONFIG_MACH_P4NOTE */
+
+static int s5k6a3_power(int enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = s5k6a3_power_on();
+ if (unlikely(ret)) {
+ printk(KERN_ERR "%s: power-on fail\n", __func__);
+ goto error_out;
+ }
+ } else
+ ret = s5k6a3_power_down();
+
+ ret = s3c_csis_power(enable);
+
+error_out:
+ return ret;
+}
+
+static const char *s5k6a3_get_clk_name(void)
+{
+#ifdef CONFIG_MACH_P4NOTE
+ return "sclk_cam1";
+#else
+ if (system_rev <= FRONT_CAM_MCLK_DEVIDED_REVISION)
+ return "sclk_cam0";
+ else
+ return "sclk_cam1";
+#endif
+}
+
+static struct s3c_platform_camera s5k6a3 = {
+ .id = CAMERA_CSI_D,
+ .get_clk_name = s5k6a3_get_clk_name,
+ .cam_power = s5k6a3_power,
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 1,
+ .mipi_settle = 18,
+ .mipi_align = 24,
+
+ .initialized = 0,
+ .flite_id = FLITE_IDX_B,
+ .use_isp = true,
+ .sensor_index = 102,
+};
+
+#ifdef CONFIG_S5K6A3_CSI_D
+static struct s3c_platform_camera s5k6a3_fd = {
+ .id = CAMERA_CSI_D,
+ .get_clk_name = s5k6a3_get_clk_name,
+ .cam_power = s5k6a3_power,
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_RAW10,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .line_length = 1920,
+ .width = 1920,
+ .height = 1080,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 1920,
+ .height = 1080,
+ },
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .mipi_lanes = 1,
+ .mipi_settle = 18,
+ .mipi_align = 24,
+
+ .initialized = 0,
+ .flite_id = FLITE_IDX_B,
+ .use_isp = true,
+ .sensor_index = 200,
+};
+#endif
+#endif
+#endif
+
+#if defined(CONFIG_VIDEO_S5C73M3) || defined(CONFIG_VIDEO_SLP_S5C73M3)
+static int vddCore = 1150000;
+static bool isVddCoreSet;
+static void s5c73m3_set_vdd_core(int level)
+{
+ vddCore = level;
+ isVddCoreSet = true;
+ printk(KERN_ERR "%s : %d\n", __func__, vddCore);
+}
+
+static void s5c73m3_check_vdd_core(void)
+{
+ struct file *fp;
+ mm_segment_t old_fs;
+ u8 *buf = NULL;
+ int err = 0;
+ int nread = 0;
+ int voltage = 0;
+ int count = 0;
+
+ if (!isVddCoreSet) {
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ fp = filp_open("/data/ISP_CV", O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ printk(KERN_ERR "failed open file. :: %ld\n",
+ PTR_ERR(fp));
+ set_fs(old_fs);
+ return;
+ }
+
+ buf = vmalloc(10);
+ if (!buf) {
+ printk(KERN_ERR "failed to allocate memory\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ nread = vfs_read(fp, (char __user *)buf, 10, &fp->f_pos);
+ if (nread != 10) {
+ printk(KERN_ERR "failed to read file, %d Bytes\n",
+ nread);
+ err = -EIO;
+ goto out;
+ }
+
+ while (buf[count] != '\0' &&
+ buf[count] >= '0' && buf[count] <= '9') {
+ voltage = voltage * 10 + buf[count] - '0';
+ ++count;
+ }
+
+ if (voltage == 1000000 || voltage == 1050000 ||
+ voltage == 1100000 || voltage == 1150000) {
+ printk(KERN_ERR "@@@@ Voltage = %d", voltage);
+ vddCore = voltage;
+ /*isVddCoreSet = true;*/
+ }
+out:
+ if (buf != NULL)
+ vfree(buf);
+
+ if (fp != NULL)
+ filp_close(fp, current->files);
+
+ set_fs(old_fs);
+ }
+}
+static bool s5c73m3_is_vdd_core_set(void)
+{
+ return isVddCoreSet;
+}
+
+static int s5c73m3_is_isp_reset(void)
+{
+ int ret = 0;
+
+ ret = gpio_request(GPIO_ISP_RESET, "GPF1");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_RESET");
+ udelay(10); /* 200 cycle */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_RESET");
+ udelay(10); /* 200 cycle */
+
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int s5c73m3_gpio_request(void)
+{
+ int ret = 0;
+
+ ret = gpio_request(GPIO_ISP_STANDBY, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_STANDBY)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_ISP_RESET, "GPF1");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+
+ /* SENSOR_A2.8V */
+ ret = gpio_request(GPIO_CAM_IO_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_CAM_IO_EN)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_CAM_AF_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_AF_EN)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_ISP_CORE_EN)\n");
+ return ret;
+ }
+
+#if defined(CONFIG_MACH_C1) && defined(CONFIG_TARGET_LOCALE_KOR)
+ if (system_rev >= USE_8M_CAM_SENSOR_CORE_REVISION) {
+ ret = gpio_request(GPIO_CAM_SENSOR_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(GPIO_CAM_SENSOR_CORE_EN)\n");
+ return ret;
+ }
+ }
+#endif
+
+ return ret;
+}
+
+static void s5c73m3_gpio_free(void)
+{
+ gpio_free(GPIO_ISP_STANDBY);
+ gpio_free(GPIO_ISP_RESET);
+ gpio_free(GPIO_CAM_IO_EN);
+ gpio_free(GPIO_CAM_AF_EN);
+ gpio_free(GPIO_ISP_CORE_EN);
+
+#if defined(CONFIG_MACH_C1) && defined(CONFIG_TARGET_LOCALE_KOR)
+ if (system_rev >= USE_8M_CAM_SENSOR_CORE_REVISION)
+ gpio_free(GPIO_CAM_SENSOR_CORE_EN);
+#endif
+}
+
+static int s5c73m3_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+#ifndef CONFIG_VIDEO_SLP_S5C73M3
+ s5c73m3_check_vdd_core();
+#endif
+ printk(KERN_DEBUG "s5c73m3 vddCore : %d\n", vddCore);
+
+ s5c73m3_gpio_request();
+
+ /* CAM_ISP_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_CORE_EN");
+
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ regulator_set_voltage(regulator, vddCore, vddCore);
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core_1.2v");
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output IO_EN");
+
+ /* CAM_SENSOR_CORE_1.2V */
+#if defined(CONFIG_MACH_C1) && defined(CONFIG_TARGET_LOCALE_KOR)
+ if (system_rev >= USE_8M_CAM_SENSOR_CORE_REVISION) {
+ ret = gpio_direction_output(GPIO_CAM_SENSOR_CORE_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output CAM_SENSOR_CORE_EN");
+ mdelay(5);
+ } else {
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_core_1.2v");
+ /* delay is needed : pmu control is slower than gpio control*/
+ mdelay(5);
+ }
+#else
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_core_1.2v");
+ /* delay is needed : pmu control is slower than gpio control*/
+ mdelay(5);
+#endif
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(GPIO_CAM_MCLK, S5P_GPIO_DRVSTR_LV3);
+
+ /* CAM_AF_2.8V */
+ ret = gpio_direction_output(GPIO_CAM_AF_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_AF_EN");
+ udelay(2000);
+
+ /* CAM_ISP_SENSOR_1.8V */
+ regulator = regulator_get(NULL, "cam_isp_sensor_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_sensor_1.8v");
+
+ /* CAM_ISP_MIPI_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_mipi_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_mipi_1.2v");
+ /* delay is needed : pmu control is slower than gpio control*/
+ mdelay(5);
+
+ /* ISP_STANDBY */
+ ret = gpio_direction_output(GPIO_ISP_STANDBY, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_STANDBY");
+ udelay(100); /* 2000 cycle */
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_RESET");
+ udelay(10); /* 200 cycle */
+
+ s5c73m3_gpio_free();
+
+ return ret;
+}
+
+static int s5c73m3_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ s5c73m3_gpio_request();
+
+ /* ISP_STANDBY */
+ ret = gpio_direction_output(GPIO_ISP_STANDBY, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_STANDBY");
+ udelay(2); /* 40 cycle */
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_RESET");
+
+ /* CAM_AF_2.8V */
+ ret = gpio_direction_output(GPIO_CAM_AF_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_AF_EN");
+
+ /* CAM_ISP_MIPI_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_mipi_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp_mipi_1.2v");
+ udelay(10); /* 200 cycle */
+
+ /* CAM_ISP_SENSOR_1.8V */
+ regulator = regulator_get(NULL, "cam_isp_sensor_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp_sensor_1.8v");
+
+ /* CAM_SENSOR_CORE_1.2V */
+#if defined(CONFIG_MACH_C1) && defined(CONFIG_TARGET_LOCALE_KOR)
+ if (system_rev >= USE_8M_CAM_SENSOR_CORE_REVISION) {
+ ret = gpio_direction_output(GPIO_CAM_SENSOR_CORE_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "output CAM_SENSOR_CORE_EN");
+ udelay(500);
+ } else {
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_core_1.2v");
+ /* delay is needed : hw request*/
+ udelay(500);
+ }
+#else
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_core_1.2v");
+ /* delay is needed : hw request*/
+ udelay(500);
+#endif
+
+ /* CAM_SENSOR_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_IO_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_IO_EN");
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp_core_1.2v");
+
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 0);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_CAM_ISP_CORE_EN");
+ /* delay is needed : hw request*/
+ mdelay(30);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+
+ s5c73m3_gpio_free();
+
+ return ret;
+}
+
+static int s5c73m3_power(int enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = s5c73m3_power_on();
+
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = s5c73m3_power_down();
+
+ ret = s3c_csis_power(enable);
+
+error_out:
+ return ret;
+}
+
+static int s5c73m3_get_i2c_busnum(void)
+{
+#if 0
+ if (system_rev == 0x03) /*M0, M1 REV00*/
+ return 18;
+ else
+#endif
+ return 0;
+}
+
+static const char *s5c73m3_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct s5c73m3_platform_data s5c73m3_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .set_vdd_core = s5c73m3_set_vdd_core,
+ .is_vdd_core_set = s5c73m3_is_vdd_core_set,
+ .is_isp_reset = s5c73m3_is_isp_reset,
+};
+
+static struct i2c_board_info s5c73m3_i2c_info = {
+ I2C_BOARD_INFO("S5C73M3", 0x78 >> 1),
+ .platform_data = &s5c73m3_plat,
+};
+
+static struct s3c_platform_camera s5c73m3 = {
+ .id = CAMERA_CSI_C,
+ .get_clk_name = s5c73m3_get_clk_name,
+ .get_i2c_busnum = s5c73m3_get_i2c_busnum,
+ .cam_power = s5c73m3_power,
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .info = &s5c73m3_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 4,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 1,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif
+
+#ifdef CONFIG_VIDEO_M5MO
+static int m5mo_get_i2c_busnum(void)
+{
+#ifdef CONFIG_VIDEO_M5MO_USE_SWI2C
+ return 25;
+#else
+ return 0;
+#endif
+}
+
+static int m5mo_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_CAM_VT_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_RESET, "GPY3");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+ /* CAM_VT_nSTBY low */
+ ret = gpio_direction_output(GPIO_CAM_VT_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "output VT_nSTBY");
+
+ /* CAM_VT_nRST low */
+ gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "output VT_nRST");
+ udelay(10);
+
+ /* CAM_ISP_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_CORE_EN");
+
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core_1.2v");
+ udelay(10);
+ /* CAM_SENSOR_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_sensor_core_1.2v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_core_1.2v");
+ udelay(10);
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_sensor_a2.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_a2.8v");
+ /* it takes about 100us at least during level transition.*/
+ udelay(160); /* 130us -> 160us */
+ /* VT_CAM_DVDD_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_dvdd_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_cam_dvdd_1.8v");
+ udelay(10);
+
+ /* CAM_AF_2.8V */
+ regulator = regulator_get(NULL, "cam_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "output cam_af_2.8v");
+ mdelay(7);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err vt_cam_1.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_cam_1.8v");
+ udelay(20);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp_1.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_isp_1.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_1.8v");
+ udelay(120); /* at least */
+
+ /* CAM_ISP_SEN_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_isp_sensor_1.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_isp_sensor_1.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_sensor_1.8v");
+ udelay(30);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ udelay(70);
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ mdelay(4);
+
+ gpio_free(GPIO_CAM_VT_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_ISP_CORE_EN);
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int m5mo_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_CAM_VT_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_RESET, "GPY3");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+
+ /* s3c_i2c0_force_stop(); */
+
+ mdelay(3);
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR(ret, "output reset");
+ mdelay(2);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_AF_2.8V */
+ regulator = regulator_get(NULL, "cam_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_af_2.8v");
+
+ /* CAM_ISP_SEN_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_isp_sensor_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable, cam_isp_sensor_1.8v");
+ udelay(10);
+
+ /* CAM_ISP_1.8V */
+ regulator = regulator_get(NULL, "cam_isp_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp_1.8v");
+ udelay(500); /* 100us -> 500us */
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_cam_1.8v");
+ udelay(250); /* 10us -> 250us */
+
+ /* VT_CAM_DVDD_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_dvdd_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_cam_dvdd_1.8v");
+ udelay(300); /*10 -> 300 us */
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_a2.8v");
+ udelay(800);
+
+ /* CAM_SENSOR_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_core_1.2v");
+ udelay(5);
+
+ /* CAM_ISP_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 0);
+ CAM_CHECK_ERR(ret, "output ISP_CORE");
+
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_isp_core_1.2v");
+
+ gpio_free(GPIO_CAM_VT_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_ISP_CORE_EN);
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int m5mo_flash_power(int enable)
+{
+/* TODO */
+ return 0;
+}
+
+static int m5mo_power(int enable)
+{
+ int ret = 0;
+
+ printk(KERN_ERR "%s %s\n", __func__, enable ? "on" : "down");
+ if (enable) {
+ ret = m5mo_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = m5mo_power_down();
+
+ ret = s3c_csis_power(enable);
+ m5mo_flash_power(enable);
+
+error_out:
+ return ret;
+}
+
+static int m5mo_config_isp_irq(void)
+{
+ s3c_gpio_cfgpin(GPIO_ISP_INT, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_ISP_INT, S3C_GPIO_PULL_NONE);
+ return 0;
+}
+
+static const char *m5mo_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct m5mo_platform_data m5mo_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .config_isp_irq = m5mo_config_isp_irq,
+ .irq = IRQ_EINT(24),
+};
+
+static struct i2c_board_info m5mo_i2c_info = {
+ I2C_BOARD_INFO("M5MO", 0x1F),
+ .platform_data = &m5mo_plat,
+};
+
+static struct s3c_platform_camera m5mo = {
+ .id = CAMERA_CSI_C,
+ .get_clk_name = m5mo_get_clk_name,
+ .get_i2c_busnum = m5mo_get_i2c_busnum,
+ .cam_power = m5mo_power, /*smdkv310_mipi_cam0_reset,*/
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+
+ .info = &m5mo_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif /* #ifdef CONFIG_VIDEO_M5MO */
+
+#ifdef CONFIG_VIDEO_M9MO
+static int m9mo_get_i2c_busnum(void)
+{
+ return 0;
+}
+
+static int m9mo_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_CORE_EN)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_ISP_RESET, "GPF1");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+ /* CAM_ISP_CORE_EN */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_CORE_EN");
+
+ /* CAM_ISP_1.2V (ISP 1.2V) => BUCK 9*/
+ regulator = regulator_get(NULL, "cam_isp_1.2v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_isp_1.2v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_1.2v");
+
+ /* CAM_SENSOR_CORE_1.2V (CIS 1.2V) => LDO17*/
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_sensor_core_1.2v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_core_1.2v");
+
+ /* CAM_ISP_1.8V (ISP 1.8V) => LDO23*/
+ regulator = regulator_get(NULL, "cam_isp_1.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_isp_1.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_1.8v");
+
+ /* CAM_SENSOR_1.8V (CIS 1.8V) => LDO19*/
+ regulator = regulator_get(NULL, "cam_sensor_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_1.8v");
+
+ /* CAM_SENSOR_2.8V (CIS 2.8V) => LDO25*/
+ regulator = regulator_get(NULL, "cam_sensor_2.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_sensor_2.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_2.8v");
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ udelay(70);
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "output reset");
+ mdelay(4);
+
+ gpio_free(GPIO_ISP_CORE_EN);
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int m9mo_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s: in\n", __func__);
+
+ if (system_rev > 0) {
+ ret = gpio_request(GPIO_MOT_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_MOT_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_SAMBAZ_RESET, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_SAMBAZ_RESET)\n");
+ return ret;
+ }
+ }
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_CORE_EN)\n");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_ISP_RESET, "GPF1");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+ /* s3c_i2c0_force_stop(); */
+
+ mdelay(3);
+
+ /*MOT_3.3*/
+ regulator = regulator_get(NULL, "mot_3.3v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "mot_3.3v");
+
+ /*OIS_1.5*/
+ regulator = regulator_get(NULL, "ois_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable ois_1.5v");
+ msleep(10);
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR(ret, "output reset");
+ mdelay(2);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_SENSOR_2.8V (CIS 2.8V) => LDO25*/
+ regulator = regulator_get(NULL, "cam_sensor_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_2.8v");
+
+ /* CAM_SENSOR_1.8V (CIS 1.8V) => LDO19*/
+ regulator = regulator_get(NULL, "cam_sensor_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_1.8v");
+
+ /* CAM_ISP_1.8V (ISP 1.8V) => LDO23*/
+ regulator = regulator_get(NULL, "cam_isp_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_isp_1.8v");
+
+ /* CAM_SENSOR_CORE_1.2V (CIS 1.2V) => LDO17*/
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_core_1.2v");
+
+ /* CAM_ISP_1.2V (ISP 1.2V) => BUCK 9*/
+ regulator = regulator_get(NULL, "cam_isp_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable, cam_isp_1.2v");
+
+ /* CAM_ISP_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 0);
+ CAM_CHECK_ERR(ret, "output ISP_CORE");
+
+ if (system_rev > 0) {
+ ret = gpio_direction_output(GPIO_SAMBAZ_RESET, 0);
+ CAM_CHECK_ERR(ret, "output GPIO_SAMBAZ_RESET");
+ mdelay(100);
+
+ ret = gpio_direction_output(GPIO_MOT_EN, 0);
+ CAM_CHECK_ERR(ret, "output GPIO_MOT_EN");
+ mdelay(2);
+
+ gpio_free(GPIO_MOT_EN);
+ gpio_free(GPIO_SAMBAZ_RESET);
+ }
+ gpio_free(GPIO_ISP_CORE_EN);
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int m9mo_flash_power(int enable)
+{
+/* TODO */
+ return 0;
+}
+
+static int m9mo_power(int enable)
+{
+ int ret = 0;
+
+ printk(KERN_ERR "%s %s\n", __func__, enable ? "on" : "down");
+ if (enable) {
+ ret = m9mo_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = m9mo_power_down();
+
+ ret = s3c_csis_power(enable);
+ m9mo_flash_power(enable);
+
+error_out:
+ return ret;
+}
+
+static int m9mo_config_isp_irq(void)
+{
+printk(KERN_ERR "m9mo_config_isp_irq~~~~~~~~~~\n");
+ s3c_gpio_cfgpin(GPIO_ISP_INT, S3C_GPIO_SFN(0xF));
+ s3c_gpio_setpull(GPIO_ISP_INT, S3C_GPIO_PULL_NONE);
+ return 0;
+}
+
+static int m9mo_config_sambaz(int enable)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ if (enable) {
+ if (system_rev > 0) {
+ ret = gpio_request(GPIO_MOT_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_CORE_EN)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_SAMBAZ_RESET, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_MOT_EN, 1);
+ CAM_CHECK_ERR(ret, "output reset");
+ msleep(100);
+ }
+
+ regulator = regulator_get(NULL, "mot_3.3v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "mot_3.3v");
+ mdelay(100);
+
+ regulator = regulator_get(NULL, "ois_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "ois_1.5v");
+ mdelay(10);
+
+ if (system_rev > 0) {
+ ret = gpio_direction_output(GPIO_SAMBAZ_RESET, 1);
+ CAM_CHECK_ERR(ret, "output reset");
+ msleep(100);
+
+ gpio_free(GPIO_MOT_EN);
+ gpio_free(GPIO_SAMBAZ_RESET);
+ }
+
+ } else {
+ regulator = regulator_get(NULL, "mot_3.3v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "mot_3.3v");
+
+ regulator = regulator_get(NULL, "ois_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable ois_1.5v");
+ }
+ return ret;
+}
+
+static const char *m9mo_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct m9mo_platform_data m9mo_plat = {
+ .default_width = 640, /* 1920 */
+ .default_height = 480, /* 1080 */
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .config_isp_irq = m9mo_config_isp_irq,
+ .config_sambaz = m9mo_config_sambaz,
+ .irq = IRQ_EINT(2),
+};
+
+static struct i2c_board_info m9mo_i2c_info = {
+ I2C_BOARD_INFO("M9MO", 0x1F),
+ .platform_data = &m9mo_plat,
+};
+
+static struct s3c_platform_camera m9mo = {
+ .id = CAMERA_CSI_C,
+ .get_clk_name = m9mo_get_clk_name,
+ .get_i2c_busnum = m9mo_get_i2c_busnum,
+ .cam_power = m9mo_power, /*smdkv310_mipi_cam0_reset,*/
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+
+ .info = &m9mo_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 1920,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 4,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif /* #ifdef CONFIG_VIDEO_M9MO */
+
+#ifdef CONFIG_VIDEO_ISX012
+static int isx012_get_i2c_busnum(void)
+{
+ return 0;
+}
+
+static void isx012_flashtimer_handler(unsigned long data)
+{
+ int ret = -ENODEV;
+ atomic_t *flash_status = (atomic_t *)data;
+
+ pr_info("********** flashtimer_handler **********\n");
+
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN, 0);
+ atomic_set(flash_status, ISX012_FLASH_OFF);
+ if (unlikely(ret))
+ pr_err("flash_timer: ERROR, failed to oneshot flash off\n");
+
+}
+
+static atomic_t flash_status = ATOMIC_INIT(ISX012_FLASH_OFF);
+static int isx012_flash_en(u32 mode, u32 onoff)
+{
+ static int flash_mode = ISX012_FLASH_MODE_NORMAL;
+ static DEFINE_MUTEX(flash_lock);
+ static DEFINE_TIMER(flash_timer, isx012_flashtimer_handler,
+ 0, (unsigned long)&flash_status);
+ int ret = 0;
+
+ printk(KERN_DEBUG "flash_en: mode=%d, on=%d\n", mode, onoff);
+
+ if (unlikely((u32)mode >= ISX012_FLASH_MODE_MAX)) {
+ pr_err("flash_en: ERROR, invalid flash mode(%d)\n", mode);
+ return -EINVAL;
+ }
+
+ /* We could not use spin lock because of gpio kernel API.*/
+ mutex_lock(&flash_lock);
+ if (atomic_read(&flash_status) == onoff) {
+ mutex_unlock(&flash_lock);
+ pr_warn("flash_en: WARNING, already flash %s\n",
+ onoff ? "On" : "Off");
+ return 0;
+ }
+
+ switch (onoff) {
+ case ISX012_FLASH_ON:
+ if (mode == ISX012_FLASH_MODE_MOVIE)
+ ret = gpio_direction_output(GPIO_CAM_MOVIE_EN, 1);
+ else {
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN, 1);
+ flash_timer.expires = get_jiffies_64() + HZ / 2;
+ add_timer(&flash_timer);
+ }
+ CAM_CHECK_ERR_GOTO(ret, out,
+ "flash_en: ERROR, fail to turn flash on (mode:%d)\n",
+ mode);
+ flash_mode = mode;
+ break;
+
+ case ISX012_FLASH_OFF:
+ if (unlikely(flash_mode != mode)) {
+ pr_err("flash_en: ERROR, unmatched flash mode(%d, %d)\n",
+ flash_mode, mode);
+ WARN_ON(1);
+ goto out;
+ }
+
+ if (mode == ISX012_FLASH_MODE_MOVIE)
+ ret = gpio_direction_output(GPIO_CAM_MOVIE_EN, 0);
+ else {
+ if (del_timer_sync(&flash_timer)) {
+ pr_info("flash_en: terminate flash timer...\n");
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN,
+ 0);
+ }
+ }
+ CAM_CHECK_ERR_GOTO(ret, out,
+ "flash_en: ERROR, flash off (mode:%d)\n", mode);
+ break;
+
+ default:
+ pr_err("flash_en: ERROR, invalid flash cmd(%d)\n", onoff);
+ goto out;
+ break;
+ }
+
+ atomic_set(&flash_status, onoff);
+
+out:
+ mutex_unlock(&flash_lock);
+ return 0;
+}
+
+static int isx012_is_flash_on(void)
+{
+ return atomic_read(&flash_status);
+}
+
+/* Power up/down func for P4C, P2. */
+static int isx012_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "[ISX012] power on\n");
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_5M_nSTBY, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 5M_nSTBY\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_5M_nRST, "GPL1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 5M_nRST\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_EN2, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request CAM_EN2\n");
+ return ret;
+ }
+#endif
+
+ /* 5MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core_1.2v");
+ udelay(10);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ udelay(10);
+
+ /* CAM_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_EN2, 1);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+ udelay(200);
+
+ /* CAM_MCLK */
+ /*s5p_gpio_set_drvstr(GPIO_CAM_MCLK, S5P_GPIO_DRVSTR_LV2);*/
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ udelay(10);
+
+ /* 3M_nRST */
+ ret = gpio_direction_output(GPIO_5M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+ udelay(10);
+
+ /* 5MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3mp_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_af_2.8v");
+ usleep_range(6000, 6500);
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_5M_nSTBY);
+ gpio_free(GPIO_5M_nRST);
+ gpio_free(GPIO_CAM_EN2);
+#endif
+
+ return ret;
+}
+
+static int isx012_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "[ISX012] power down\n");
+
+ ret = gpio_request(GPIO_5M_nSTBY, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 3M_nSTBY\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_5M_nRST, "GPL1");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request 3M_nRST\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_EN2, "GPJ0");
+ if (unlikely(ret)) {
+ printk(KERN_ERR "error: request CAM_EN2\n");
+ return ret;
+ }
+
+ /* 5MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3mp_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_af_2.8v");
+ udelay(10);
+
+ /* 5M_nSTBY */
+ ret = gpio_direction_output(GPIO_5M_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "5M_nSTBY");
+ udelay(10);
+
+ /* 5M_nRST */
+ ret = gpio_direction_output(GPIO_5M_nRST, 0);
+ CAM_CHECK_ERR(ret, "5M_nRST");
+ udelay(50);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(10);
+
+ /* CAM_A2.8V */
+ ret = gpio_direction_output(GPIO_CAM_EN2, 0);
+ CAM_CHECK_ERR_RET(ret, "CAM_A2.8V");
+ udelay(10);
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ udelay(10);
+
+ /* 5MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core_1.2v");
+
+ gpio_free(GPIO_5M_nSTBY);
+ gpio_free(GPIO_5M_nRST);
+ gpio_free(GPIO_CAM_EN2);
+
+ return ret;
+}
+
+static int isx012_power(int enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = isx012_power_on();
+ } else
+ ret = isx012_power_down();
+
+ if (unlikely(ret)) {
+ pr_err("%s: power-on/down failed\n", __func__);
+ return ret;
+ }
+
+ ret = s3c_csis_power(enable);
+ if (unlikely(ret)) {
+ pr_err("%s: csis power-on failed\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int isx012_enable_standby(bool enable)
+{
+ int err;
+
+ pr_info("%s: %s\n", __func__, enable ? "on" : "off");
+
+ err = gpio_request(GPIO_5M_nSTBY, "GPJ0");
+ if (unlikely(err)) {
+ printk(KERN_ERR "error: request 5M_nSTBY\n");
+ return err;
+ }
+
+ /* GPIO_5M_nSTBY */
+ err = gpio_direction_output(GPIO_5M_nSTBY, enable ?
+ GPIO_LEVEL_LOW : GPIO_LEVEL_HIGH);
+ CAM_CHECK_ERR_RET(err, "GPIO_5M_nSTBY");
+
+ gpio_free(GPIO_5M_nSTBY);
+ return 0;
+}
+
+static int px_cam_cfg_init(void)
+{
+ int ret = -ENODEV;
+
+ pr_info("cam_cfg_init\n");
+
+ ret = gpio_request(GPIO_CAM_MOVIE_EN, "GPM3");
+ if (unlikely(ret)) {
+ pr_err("cam_cfg_init: fail to get gpio(MOVIE_EN), "
+ "err=%d\n", ret);
+ goto out;
+ }
+
+ ret = gpio_request(GPIO_CAM_FLASH_EN, "GPM3");
+ if (unlikely(ret)) {
+ pr_err("cam_cfg_init: fail to get gpio(FLASH_EN), "
+ "err=%d\n", ret);
+ goto out_free;
+ }
+
+ return 0;
+
+out_free:
+ gpio_free(GPIO_CAM_MOVIE_EN);
+out:
+ return ret;
+}
+
+static const char *isx012_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct isx012_platform_data isx012_plat = {
+ .default_width = 1024,
+ .default_height = 768,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .streamoff_delay = ISX012_STREAMOFF_DELAY,
+ .flash_en = isx012_flash_en,
+ .is_flash_on = isx012_is_flash_on,
+ .stby_on = isx012_enable_standby,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+#define REAR_CAM_PLAT (isx012_plat)
+
+static struct i2c_board_info isx012_i2c_info = {
+ I2C_BOARD_INFO("ISX012", 0x7A>>1),
+ .platform_data = &isx012_plat,
+};
+
+static struct s3c_platform_camera isx012 = {
+ .id = CAMERA_CSI_C,
+ .get_clk_name = isx012_get_clk_name,
+ .get_i2c_busnum = isx012_get_i2c_busnum,
+ .cam_power = isx012_power, /*smdkv310_mipi_cam0_reset,*/
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &isx012_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 2,
+ .mipi_settle = 12,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+
+static ssize_t isx012_camtype_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const char cam_type[] = "SONY_ISX012";
+ pr_info("%s\n", __func__);
+ return sprintf(buf, "%s\n", cam_type);
+}
+static DEVICE_ATTR(rear_camtype, S_IRUGO, isx012_camtype_show, NULL);
+
+static ssize_t isx012_camfw_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char type[] = "ISX012";
+ return sprintf(buf, "%s %s\n", type, type);
+
+}
+static DEVICE_ATTR(rear_camfw, S_IRUGO, isx012_camfw_show, NULL);
+
+static ssize_t flash_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", isx012_is_flash_on() ? "on" : "off");
+}
+
+static ssize_t flash_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+
+ isx012_flash_en(ISX012_FLASH_MODE_MOVIE, (*buf == '0') ?
+ ISX012_FLASH_OFF : ISX012_FLASH_ON);
+
+ return count;
+}
+static DEVICE_ATTR(rear_flash, 0664, flash_show, flash_store);
+
+int isx012_create_file(struct class *cls)
+{
+ struct device *dev_rear = NULL;
+ int ret = -ENODEV;
+
+ dev_rear = device_create(cls, NULL, 0, NULL, "rear");
+ if (IS_ERR(dev_rear)) {
+ pr_err("cam_init: failed to create device(rearcam_dev)\n");
+ return -ENODEV;
+ }
+
+ ret = device_create_file(dev_rear, &dev_attr_rear_camtype);
+ if (unlikely(ret < 0))
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_rear_camtype.attr.name);
+
+ ret = device_create_file(dev_rear, &dev_attr_rear_camfw);
+ if (unlikely(ret < 0))
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_rear_camtype.attr.name);
+
+ ret = device_create_file(dev_rear, &dev_attr_rear_flash);
+ if (unlikely(ret < 0))
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_rear_flash.attr.name);
+
+ return 0;
+}
+#endif /* CONFIG_VIDEO_ISX012*/
+
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+static int s5k5ccgx_get_i2c_busnum(void)
+{
+ return 0;
+}
+
+/* Power up/down func for P4C, P2. */
+static int s5k5ccgx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in P4C,P2\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+#endif
+
+ /* 2M_nSTBY low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* 2M_nRST low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core_1.2v");
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+
+ /* CAM_A2.8V, LDO13 */
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_a2.8v");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(20);
+
+ /* 2M_nSTBY High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(3);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ msleep(5); /* >=5ms */
+
+ /* 2M_nSTBY Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(10); /* >=10ms */
+
+ /* 2M_nRST High */
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ msleep(5);
+
+ /* 2M_nSTBY High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(2);
+
+ /* 3M_nSTBY */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nSTBY");
+ udelay(16);
+
+ /* 3M_nRST */
+ ret = gpio_direction_output(GPIO_3M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+ /* udelay(10); */
+
+ /* 3MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3mp_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_af_2.8v");
+ msleep(10);
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+
+ return ret;
+}
+
+static int s5k5ccgx_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in P4C,P2\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+#endif
+ /* 3MP_AF_2.8V */
+ regulator = regulator_get(NULL, "3mp_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_af_2.8v");
+
+ /* 3M_nRST Low*/
+ ret = gpio_direction_output(GPIO_3M_nRST, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(50);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(5);
+
+ /* 3M_nSTBY */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 0);
+ CAM_CHECK_ERR(ret, "3M_nSTBY");
+ udelay(1);
+
+ /* 2M_nRST Low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* 2M_nSTBY Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+
+ /* CAM_A2.8V */
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_a2.8v");
+ /* udelay(50); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ /*udelay(50); */
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "3mp_core_1.2v");
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+ return ret;
+}
+
+static int s5k5ccgx_power(int enable)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s %s\n", __func__, enable ? "on" : "down");
+ if (enable) {
+#ifdef USE_CAM_GPIO_CFG
+ if (cfg_gpio_err) {
+ printk(KERN_ERR "%s: ERROR: gpio configuration",
+ __func__);
+ return cfg_gpio_err;
+ }
+#endif
+ ret = s5k5ccgx_power_on();
+ } else
+ ret = s5k5ccgx_power_down();
+
+ s3c_csis_power(enable);
+
+ return ret;
+}
+
+static void s5k5ccgx_flashtimer_handler(unsigned long data)
+{
+#if 0 /* dslim */
+ int ret = -ENODEV;
+ atomic_t *flash_status = (atomic_t *)data;
+
+ pr_info("********** flashtimer_handler **********\n");
+
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN, 0);
+ atomic_set(flash_status, S5K5CCGX_FLASH_OFF);
+ if (unlikely(ret))
+ pr_err("flash_timer: ERROR, failed to oneshot flash off\n");
+#endif
+}
+
+static atomic_t flash_status = ATOMIC_INIT(S5K5CCGX_FLASH_OFF);
+static int s5k5ccgx_flash_en(u32 mode, u32 onoff)
+{
+#if 0 /* dslim */
+
+ static int flash_mode = S5K5CCGX_FLASH_MODE_NORMAL;
+ static DEFINE_MUTEX(flash_lock);
+ static DEFINE_TIMER(flash_timer, s5k5ccgx_flashtimer_handler,
+ 0, (unsigned long)&flash_status);
+ int ret = 0;
+
+ printk(KERN_DEBUG "flash_en: mode=%d, on=%d\n", mode, onoff);
+
+ if (unlikely((u32)mode >= S5K5CCGX_FLASH_MODE_MAX)) {
+ pr_err("flash_en: ERROR, invalid flash mode(%d)\n", mode);
+ return -EINVAL;
+ }
+
+ /* We could not use spin lock because of gpio kernel API.*/
+ mutex_lock(&flash_lock);
+ if (atomic_read(&flash_status) == onoff) {
+ mutex_unlock(&flash_lock);
+ pr_warn("flash_en: WARNING, already flash %s\n",
+ onoff ? "On" : "Off");
+ return 0;
+ }
+
+ switch (onoff) {
+ case S5K5CCGX_FLASH_ON:
+ if (mode == S5K5CCGX_FLASH_MODE_MOVIE)
+ ret = gpio_direction_output(GPIO_CAM_MOVIE_EN, 1);
+ else {
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN, 1);
+ flash_timer.expires = get_jiffies_64() + HZ / 2;
+ add_timer(&flash_timer);
+ }
+ CAM_CHECK_ERR_GOTO(ret, out,
+ "flash_en: ERROR, fail to turn flash on (mode:%d)\n",
+ mode);
+ flash_mode = mode;
+ break;
+
+ case S5K5CCGX_FLASH_OFF:
+ if (unlikely(flash_mode != mode)) {
+ pr_err("flash_en: ERROR, unmatched flash mode(%d, %d)\n",
+ flash_mode, mode);
+ WARN_ON(1);
+ goto out;
+ }
+
+ if (mode == S5K5CCGX_FLASH_MODE_MOVIE)
+ ret = gpio_direction_output(GPIO_CAM_MOVIE_EN, 0);
+ else {
+ if (del_timer_sync(&flash_timer)) {
+ pr_info("flash_en: terminate flash timer...\n");
+ ret = gpio_direction_output(GPIO_CAM_FLASH_EN,
+ 0);
+ }
+ }
+ CAM_CHECK_ERR_GOTO(ret, out,
+ "flash_en: ERROR, flash off (mode:%d)\n", mode);
+ break;
+
+ default:
+ pr_err("flash_en: ERROR, invalid flash cmd(%d)\n", onoff);
+ goto out;
+ break;
+ }
+
+ atomic_set(&flash_status, onoff);
+
+out:
+ mutex_unlock(&flash_lock);
+#endif
+ return 0;
+}
+
+static int s5k5ccgx_is_flash_on(void)
+{
+ return atomic_read(&flash_status);
+}
+
+static int px_cam_cfg_init(void)
+{
+ int ret = -ENODEV;
+
+ /* pr_info("%s\n", __func__); */
+#if 0 /* dslim */
+ ret = gpio_request(GPIO_CAM_MOVIE_EN, "GPL0");
+ if (unlikely(ret)) {
+ pr_err("cam_cfg_init: fail to get gpio(MOVIE_EN), "
+ "err=%d\n", ret);
+ goto out;
+ }
+
+ ret = gpio_request(GPIO_CAM_FLASH_EN, "GPL0");
+ if (unlikely(ret)) {
+ pr_err("cam_cfg_init: fail to get gpio(FLASH_EN), "
+ "err=%d\n", ret);
+ goto out_free;
+ }
+
+ return 0;
+
+out_free:
+ gpio_free(GPIO_CAM_MOVIE_EN);
+out:
+ return ret;
+#else
+ return 0;
+#endif
+}
+
+static const char *s5k5ccgx_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct s5k5ccgx_platform_data s5k5ccgx_plat = {
+ .default_width = 1024,
+ .default_height = 768,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .streamoff_delay = S5K5CCGX_STREAMOFF_DELAY,
+ .flash_en = s5k5ccgx_flash_en,
+ .is_flash_on = s5k5ccgx_is_flash_on,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+#define REAR_CAM_PLAT (s5k5ccgx_plat)
+
+static struct i2c_board_info s5k5ccgx_i2c_info = {
+ I2C_BOARD_INFO("S5K5CCGX", 0x78>>1),
+ .platform_data = &s5k5ccgx_plat,
+};
+
+static struct s3c_platform_camera s5k5ccgx = {
+ .id = CAMERA_CSI_C,
+ .get_clk_name = s5k5ccgx_get_clk_name,
+ .get_i2c_busnum = s5k5ccgx_get_i2c_busnum,
+ .cam_power = s5k5ccgx_power, /*smdkv310_mipi_cam0_reset,*/
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT, /*MIPI_CSI_YCBCR422_8BIT*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .info = &s5k5ccgx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti", /* "mout_mpll" */
+ .clk_rate = 24000000, /* 48000000 */
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+};
+#endif /* #ifdef CONFIG_VIDEO_S5K5CCGX_COMMON */
+
+
+#ifdef CONFIG_VIDEO_SR200PC20M
+static int sr200pc20m_get_i2c_busnum(void)
+{
+ return 13;
+}
+
+static int sr200pc20m_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ ret = gpio_request(GPIO_CAM_VT_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_RESET, "GPY3");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+
+ /* CAM_VT_nSTBY low */
+ ret = gpio_direction_output(GPIO_CAM_VT_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "output VT_nSTBY");
+
+ /* CAM_VT_nRST low */
+ gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "output VT_nRST");
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR(ret, "output reset");
+
+ /* CAM_ISP_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 1);
+ CAM_CHECK_ERR_RET(ret, "output GPIO_ISP_CORE_EN");
+
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core_1.2v");
+ /* No delay */
+
+ /* CAM_SENSOR_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_sensor_core_1.2v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_core_1.2v");
+ udelay(10);
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err cam_sensor_a2.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_a2.8v");
+ /* it takes about 100us at least during level transition.*/
+ udelay(160); /* 130us -> 160us */
+
+ /* VT_CAM_DVDD_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_dvdd_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_cam_dvdd_1.8v");
+ udelay(10);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator)) {
+ CAM_CHECK_ERR_RET(ret, "output Err vt_cam_1.8v");
+ return -ENODEV;
+ }
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_cam_1.8v");
+ udelay(20);
+
+ /* CAM_VT_nSTBY high */
+ ret = gpio_direction_output(GPIO_CAM_VT_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "output VT_nSTBY");
+ mdelay(2);
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ mdelay(30);
+
+ /* CAM_VT_nRST high */
+ gpio_direction_output(GPIO_CAM_VT_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "output VT_nRST");
+
+ gpio_free(GPIO_CAM_VT_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_ISP_CORE_EN);
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int sr200pc20m_power_off(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in\n", __func__);
+
+ ret = gpio_request(GPIO_CAM_VT_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_CAM_VGA_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_CORE_EN, "GPM0");
+ if (ret) {
+ printk(KERN_ERR "fail to request gpio(CAM_SENSOR_CORE)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_ISP_RESET, "GPY3");
+ if (ret) {
+ printk(KERN_ERR "faile to request gpio(GPIO_ISP_RESET)\n");
+ return ret;
+ }
+
+ /* ISP_RESET */
+ ret = gpio_direction_output(GPIO_ISP_RESET, 0);
+ CAM_CHECK_ERR(ret, "output reset");
+
+ /* CAM_VT_nRST low */
+ gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "output VT_nRST");
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(20);
+
+ /* CAM_VT_nSTBY low */
+ ret = gpio_direction_output(GPIO_CAM_VT_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "output VT_nSTBY");
+ mdelay(2);
+
+ /* CAM_SENSOR_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_sensor_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_core_1.2v");
+ udelay(5);
+
+ /* CAM_ISP_CORE_1.2V */
+ ret = gpio_direction_output(GPIO_ISP_CORE_EN, 0);
+ CAM_CHECK_ERR(ret, "output ISP_CORE");
+
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_isp_core_1.2v");
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable cam_sensor_a2.8v");
+ udelay(800);
+
+ /* VT_CAM_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_cam_1.8v");
+ udelay(250); /* 10us -> 250us */
+
+ /* VT_CAM_DVDD_1.8V */
+ regulator = regulator_get(NULL, "vt_cam_dvdd_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "disable vt_cam_dvdd_1.8v");
+ udelay(300); /*10 -> 300 us */
+
+ gpio_free(GPIO_CAM_VT_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_ISP_CORE_EN);
+ gpio_free(GPIO_ISP_RESET);
+
+ return ret;
+}
+
+static int sr200pc20m_power(int onoff)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s(): %s\n", __func__, onoff ? "on" : "down");
+
+ if (onoff) {
+ ret = sr200pc20m_power_on();
+ if (unlikely(ret))
+ goto error_out;
+ } else {
+ ret = sr200pc20m_power_off();
+ }
+
+ ret = s3c_csis_power(onoff);
+
+error_out:
+ return ret;
+}
+
+static const char *sr200pc20m_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct sr200pc20m_platform_data sr200pc20m_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .streamoff_delay = 0,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+
+static struct i2c_board_info sr200pc20m_i2c_info = {
+ I2C_BOARD_INFO("SR200PC20M", 0x40 >> 1),
+ .platform_data = &sr200pc20m_plat,
+};
+
+static struct s3c_platform_camera sr200pc20m = {
+ .id = CAMERA_CSI_D,
+ .get_clk_name = sr200pc20m_get_clk_name,
+ .type = CAM_TYPE_MIPI,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .get_i2c_busnum = sr200pc20m_get_i2c_busnum,
+ .info = &sr200pc20m_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ .mipi_lanes = 1,
+ .mipi_settle = 6,
+ .mipi_align = 32,
+
+ .inv_pclk = 0,
+ .inv_vsync = 0,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = sr200pc20m_power,
+};
+#endif /* CONFIG_VIDEO_SR200PC20M */
+
+#ifdef CONFIG_VIDEO_SR200PC20
+static int sr200pc20_get_i2c_busnum(void)
+{
+#ifdef CONFIG_MACH_P4
+ pr_info("%s: system_rev=%d\n", __func__);
+ if (system_rev >= 2)
+ return 0;
+ else
+#endif
+ return 13;
+}
+
+static int sr200pc20_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_3M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(3M_nRST)\n");
+ return ret;
+ }
+#endif
+
+ /* 3M_nSTBY low */
+ ret = gpio_direction_output(GPIO_3M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "3M_nSTBY");
+
+ /* 3M_nRST low */
+ ret = gpio_direction_output(GPIO_3M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "3M_nRST");
+
+ /* 2M_nSTBY low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+
+ /* 2M_nRST low */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "3mp_core_1.2v");
+ /* udelay(5); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_io_1.8v");
+ /*udelay(5); */
+
+ /* CAM_A2.8V */
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "cam_a2.8v");
+ /* udelay(5); */
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "vt_core_1.8v");
+ udelay(20);
+
+ /* ENB High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(3); /* 30 -> 3 */
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+ msleep(5); /* >= 5ms */
+
+ /* ENB Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(10); /* >= 10ms */
+
+ /* 2M_nRST High*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ /*msleep(7);*/ /* >= 7ms */
+
+#if 0
+ /* ENB High */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(12); /* >= 10ms */
+
+ /* ENB Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ msleep(12); /* >= 10ms */
+
+ /* 2M_nRST Low*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(10); /* >= 16 cycle */
+
+ /* 2M_nRST High */
+ ret = gpio_direction_output(GPIO_2M_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+#endif
+ udelay(10); /* >= 16 cycle */
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+ gpio_free(GPIO_3M_nSTBY);
+ gpio_free(GPIO_3M_nRST);
+#endif
+ return 0;
+}
+
+static int sr200pc20_power_off(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s in\n", __func__);
+
+#ifndef USE_CAM_GPIO_CFG
+ ret = gpio_request(GPIO_2M_nSTBY, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nSTBY)\n");
+ return ret;
+ }
+ ret = gpio_request(GPIO_2M_nRST, "GPL2");
+ if (ret) {
+ printk(KERN_ERR "Error: fail to request gpio(2M_nRST)\n");
+ return ret;
+ }
+#endif
+
+#if 0
+ /* 2M_nRST */
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(100);
+
+ /* 2M_nSTBY */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ udelay(100);
+#endif
+ /* Sleep command */
+ mdelay(1);
+
+ /* 2M_nRST Low*/
+ ret = gpio_direction_output(GPIO_2M_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_nRST");
+ udelay(3);
+
+ /* CAM_MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+ udelay(10);
+
+ /* ENB High*/
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "2M_nSTBY");
+ mdelay(5);
+
+ /* ENB Low */
+ ret = gpio_direction_output(GPIO_2M_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "2M_spnSTBY");
+ /* udelay(1); */
+
+ /* VT_CORE_1.8V */
+ regulator = regulator_get(NULL, "vt_core_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "vt_core_1.8v");
+ /* udelay(10); */
+
+ /* CAM_A2.8V */
+ regulator = regulator_get(NULL, "cam_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_a2.8v");
+ /* udelay(10); */
+
+ /* CAM_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR(ret, "cam_io_1.8v");
+ /*udelay(10); */
+
+ /* 3MP_CORE_1.2V */
+ regulator = regulator_get(NULL, "3mp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+#ifndef USE_CAM_GPIO_CFG
+ gpio_free(GPIO_2M_nSTBY);
+ gpio_free(GPIO_2M_nRST);
+#endif
+ return 0;
+}
+
+static int sr200pc20_power(int onoff)
+{
+ int ret = 0;
+
+ printk(KERN_DEBUG "%s(): %s\n", __func__, onoff ? "on" : "down");
+
+ if (onoff) {
+#ifdef USE_CAM_GPIO_CFG
+ if (cfg_gpio_err) {
+ printk(KERN_ERR "%s: ERROR: gpio configuration",
+ __func__);
+ return cfg_gpio_err;
+ }
+#endif
+ ret = sr200pc20_power_on();
+ } else {
+ ret = sr200pc20_power_off();
+ /* s3c_i2c0_force_stop();*/ /* DSLIM. Should be implemented */
+ }
+
+ return ret;
+}
+
+static const char *sr200pc20_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct sr200pc20_platform_data sr200pc20_plat = {
+ .default_width = 800,
+ .default_height = 600,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .is_mipi = 0,
+ .streamoff_delay = 0,
+ .dbg_level = CAMDBG_LEVEL_DEFAULT,
+};
+#define FRONT_CAM_PLAT (sr200pc20_plat)
+
+static struct i2c_board_info sr200pc20_i2c_info = {
+ I2C_BOARD_INFO("SR200PC20", 0x40 >> 1),
+ .platform_data = &sr200pc20_plat,
+};
+
+static struct s3c_platform_camera sr200pc20 = {
+ .id = CAMERA_PAR_A,
+ .get_clk_name = sr200pc20_get_clk_name,
+ .type = CAM_TYPE_ITU,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_YCBYCR,
+ .get_i2c_busnum = sr200pc20_get_i2c_busnum,
+ .info = &sr200pc20_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 800,
+ .width = 800,
+ .height = 600,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 800,
+ .height = 600,
+ },
+
+ /* Polarity */
+#if 1 /*def CONFIG_VIDEO_SR200PC20_P4W */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+#else
+ .inv_pclk = 1,
+ .inv_vsync = 0,
+#endif
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = sr200pc20_power,
+};
+#endif /* CONFIG_VIDEO_SR200PC20 */
+
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+ .default_cam = CAMERA_CSI_D,
+ .camera = {
+#if defined(CONFIG_VIDEO_S5C73M3) || defined(CONFIG_VIDEO_SLP_S5C73M3)
+ &s5c73m3,
+#endif
+#ifdef CONFIG_VIDEO_ISX012
+ &isx012,
+#endif
+#ifdef CONFIG_VIDEO_S5K6A3
+ &s5k6a3,
+#endif
+#if defined(CONFIG_VIDEO_S5K6A3) && defined(CONFIG_S5K6A3_CSI_D)
+ &s5k6a3_fd,
+#endif
+#if defined(CONFIG_VIDEO_M5MO)
+ &m5mo,
+#endif
+#if defined(CONFIG_VIDEO_M9MO)
+ &m9mo,
+#endif
+#if defined(CONFIG_VIDEO_SR200PC20M)
+ &sr200pc20m,
+#endif
+#ifdef CONFIG_VIDEO_S5K5CCGX_COMMON
+ &s5k5ccgx,
+#endif
+#ifdef CONFIG_VIDEO_SR200PC20
+ &sr200pc20,
+#endif
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+ },
+ .hw_ver = 0x51,
+};
+
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+static void __set_flite_camera_config(struct exynos_platform_flite *data,
+ u32 active_index, u32 max_cam)
+{
+ data->active_cam_index = active_index;
+ data->num_clients = max_cam;
+}
+
+static void __init smdk4x12_set_camera_flite_platdata(void)
+{
+ int flite0_cam_index = 0;
+ int flite1_cam_index = 0;
+#ifdef CONFIG_VIDEO_S5K6A3
+ exynos_flite1_default_data.cam[flite1_cam_index++] = &s5k6a3;
+#endif
+#ifdef CONFIG_VIDEO_SR200PC20M
+ exynos_flite1_default_data.cam[flite1_cam_index++] = &sr200pc20m;
+#endif
+ __set_flite_camera_config(&exynos_flite0_default_data, 0, flite0_cam_index);
+ __set_flite_camera_config(&exynos_flite1_default_data, 0, flite1_cam_index);
+}
+#endif /* CONFIG_VIDEO_EXYNOS_FIMC_LITE */
+#endif /* CONFIG_VIDEO_FIMC */
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+static struct i2c_board_info __initdata test_info = {
+ I2C_BOARD_INFO("testinfo", 0x0),
+};
+
+static struct s5p_fimc_isp_info isp_info[] = {
+ {
+ .board_info = &test_info,
+ .bus_type = FIMC_LCD_WB,
+ .i2c_bus_num = 0,
+ .mux_id = 0, /* A-Port : 0, B-Port : 1 */
+ .flags = FIMC_CLK_INV_VSYNC,
+ },
+};
+
+static void __init midas_subdev_config(void)
+{
+ s3c_fimc0_default_data.isp_info[0] = &isp_info[0];
+ s3c_fimc0_default_data.isp_info[0]->use_cam = true;
+ s3c_fimc0_default_data.isp_info[1] = &isp_info[1];
+ s3c_fimc0_default_data.isp_info[1]->use_cam = false;
+ s3c_fimc0_default_data.isp_info[2] = &isp_info[1];
+ s3c_fimc0_default_data.isp_info[2]->use_cam = false;
+ s3c_fimc0_default_data.isp_info[3] = &isp_info[1];
+ s3c_fimc0_default_data.isp_info[3]->use_cam = false;
+}
+#endif /* CONFIG_VIDEO_SAMSUNG_S5P_FIMC */
+
+void __init midas_camera_init(void)
+{
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(&fimc_plat);
+ s3c_fimc2_set_platdata(NULL);
+#ifdef CONFIG_DRM_EXYNOS_FIMD_WB
+ s3c_fimc3_set_platdata(&fimc_plat);
+#else
+ s3c_fimc3_set_platdata(NULL);
+#endif
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#ifdef CONFIG_EXYNOS_CONTENT_PATH_PROTECTION
+ secmem.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#ifdef CONFIG_VIDEO_EXYNOS_FIMC_LITE
+ smdk4x12_set_camera_flite_platdata();
+ s3c_set_platdata(&exynos_flite0_default_data,
+ sizeof(exynos_flite0_default_data), &exynos_device_flite0);
+ s3c_set_platdata(&exynos_flite1_default_data,
+ sizeof(exynos_flite1_default_data), &exynos_device_flite1);
+#endif
+#endif /* CONFIG_VIDEO_FIMC */
+
+#ifdef CONFIG_VIDEO_SAMSUNG_S5P_FIMC
+ midas_subdev_config();
+
+ dev_set_name(&s5p_device_fimc0.dev, "s3c-fimc.0");
+ dev_set_name(&s5p_device_fimc1.dev, "s3c-fimc.1");
+ dev_set_name(&s5p_device_fimc2.dev, "s3c-fimc.2");
+ dev_set_name(&s5p_device_fimc3.dev, "s3c-fimc.3");
+
+ clk_add_alias("fimc", "exynos4210-fimc.0", "fimc",
+ &s5p_device_fimc0.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.1", "fimc",
+ &s5p_device_fimc1.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.2", "fimc",
+ &s5p_device_fimc2.dev);
+ clk_add_alias("fimc", "exynos4210-fimc.3", "fimc",
+ &s5p_device_fimc3.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.0", "sclk_fimc",
+ &s5p_device_fimc0.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.1", "sclk_fimc",
+ &s5p_device_fimc1.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.2", "sclk_fimc",
+ &s5p_device_fimc2.dev);
+ clk_add_alias("sclk_fimc", "exynos4210-fimc.3", "sclk_fimc",
+ &s5p_device_fimc3.dev);
+
+ s3c_fimc_setname(0, "exynos4210-fimc");
+ s3c_fimc_setname(1, "exynos4210-fimc");
+ s3c_fimc_setname(2, "exynos4210-fimc");
+ s3c_fimc_setname(3, "exynos4210-fimc");
+
+ s3c_set_platdata(&s3c_fimc0_default_data,
+ sizeof(s3c_fimc0_default_data), &s5p_device_fimc0);
+ s3c_set_platdata(&s3c_fimc1_default_data,
+ sizeof(s3c_fimc1_default_data), &s5p_device_fimc1);
+ s3c_set_platdata(&s3c_fimc2_default_data,
+ sizeof(s3c_fimc2_default_data), &s5p_device_fimc2);
+ s3c_set_platdata(&s3c_fimc3_default_data,
+ sizeof(s3c_fimc3_default_data), &s5p_device_fimc3);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif /* CONFIG_VIDEO_S5P_FIMC */
+
+#if defined(CONFIG_MACH_P4NOTE) && defined(CONFIG_VIDEO_ISX012)
+ px_cam_cfg_init();
+#endif
+}
diff --git a/arch/arm/mach-exynos/midas-extcon.c b/arch/arm/mach-exynos/midas-extcon.c
new file mode 100644
index 0000000..f65bf04
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-extcon.c
@@ -0,0 +1,90 @@
+/*
+ * midas-extcon.c - EXTCON (External Connector)
+ *
+ * Copyright (C) 2012 Samsung Electrnoics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/err.h>
+#include <linux/extcon.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/host_notify.h>
+#include <linux/power_supply.h>
+#include <linux/regulator/machine.h>
+
+#include <plat/devs.h>
+#include <plat/udc-hs.h>
+
+#ifdef CONFIG_JACK_MON
+#include <linux/jack.h>
+#endif
+
+#define EXTCON_DEV_NAME "max77693-muic"
+
+static struct extcon_dev *midas_extcon;
+static struct notifier_block extcon_nb;
+static struct work_struct extcon_notifier_work;
+static unsigned long prev_value;
+
+static void midas_extcon_notifier_work(struct work_struct *work)
+{
+ /* TODO */
+}
+
+static int midas_extcon_notifier(struct notifier_block *self,
+ unsigned long event, void *ptr)
+{
+ /* Store the previous cable state of extcon device */
+ prev_value = event;
+
+ schedule_work(&extcon_notifier_work);
+
+ return NOTIFY_DONE;
+}
+
+static int __init midas_extcon_init(void)
+{
+ int ret;
+
+ midas_extcon = extcon_get_extcon_dev(EXTCON_DEV_NAME);
+ if (!midas_extcon) {
+ printk(KERN_ERR "Failed to get extcon device of %s\n",
+ EXTCON_DEV_NAME);
+ ret = -EINVAL;
+ goto err_extcon;
+ }
+
+ INIT_WORK(&extcon_notifier_work, midas_extcon_notifier_work);
+ extcon_nb.notifier_call = midas_extcon_notifier;
+ ret = extcon_register_notifier(midas_extcon, &extcon_nb);
+ if (ret < 0) {
+ pr_err("Failed to register extcon device for mms_ts\n");
+ ret = -EINVAL;
+ goto err_extcon;
+ }
+
+ /* TODO */
+
+ return 0;
+
+err_extcon:
+ midas_extcon = NULL;
+ return ret;
+}
+late_initcall(midas_extcon_init);
diff --git a/arch/arm/mach-exynos/midas-gpio.c b/arch/arm/mach-exynos/midas-gpio.c
new file mode 100644
index 0000000..cb69a05
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-gpio.c
@@ -0,0 +1,2873 @@
+/*
+ * linux/arch/arm/mach-exynos/midas-gpio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - GPIO setting in set board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio-midas.h>
+#include <plat/cpu.h>
+#include <mach/pmu.h>
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+#if !defined(CONFIG_MIDAS_COMMON)
+/* this is sample code for midas board */
+static struct gpio_init_data midas_init_gpios[] = {
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SDA_1.8V */
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SCL_1.8V */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M3)
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SDA_1.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SCL_1.8V */
+#endif
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* EAR_DET */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_INT */
+ {EXYNOS4_GPX0(7), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS4_GPX1(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_IRQ */
+
+ {EXYNOS4_GPX2(0), S3C_GPIO_SFN(2), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_UP */
+ {EXYNOS4_GPX2(1), S3C_GPIO_SFN(2), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_DOWN */
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* FUEL_ALERT */
+
+#ifdef CONFIG_BATTERY_WPC_CHARGER
+ {EXYNOS4_GPX2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* V_BUS_INT */
+#endif
+ {EXYNOS4_GPX2(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_HOST_WAKEUP */
+ {EXYNOS4_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKEUP */
+
+#ifdef CONFIG_BATTERY_WPC_CHARGER
+ {EXYNOS4_GPX3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WPC_INT */
+#endif
+ {EXYNOS4_GPX3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_WAKE */
+
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV4}, /* WLAN_EN */
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+};
+
+/* this table only for midas board */
+static unsigned int exynos4_sleep_gpio_table_common[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#elif defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_M0_KOR_SKT) || defined(CONFIG_MACH_M0_KOR_KT)
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3)
+ /* GPF1(6) M0, C1 PDA_ACTIVE, let cp know AP sleep status*/
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, /*UART_SEL*/
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+#if defined(CONFIG_MACH_M0_KOR_SKT) || defined(CONFIG_MACH_M0_KOR_KT)
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M3)
+ /* GLP2(4) CMC_CPU_RESET, hold high */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* NC */
+#else
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_MACH_M0_CMCC)
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+#if defined(CONFIG_MACH_M0) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS)
+ /* GPX3(2) M0 CP_PMU_RESET, hold high */
+ {EXYNOS4_GPX3(2), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+#endif
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ /* GPY4(2) S2Plus PDA_ACTIVE, let cp know AP sleep status*/
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#endif
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* PMIC_DVS1(Q) / NC(D) */
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* PMIC_DVS2(Q) / NC(D) */
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* PMIC_DVS3(Q) / NC(D) */
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ /* BUCK2_SEL(Q) / NC(D) */
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* BUCK3_SEL(Q) / NC(D) */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* BUCK4_SEL(Q) / NC(D) */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static unsigned int exynos4210_sleep_gpio_table[][3] = {
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static unsigned int exynos4212_sleep_gpio_table[][3] = {
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS)
+ /* GPM3(3) M0, CP_RESET_REQ hold high */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* MICBAS_EN */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* SUB_MICBIAS_EN */
+#else
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int exynos4212_sleep_gpio_table_c2c[][3] = {
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+};
+#endif
+
+#ifdef CONFIG_MIDAS_COMMON
+/*
+ * M0 GPIO Init Table
+ */
+static struct gpio_init_data m0_init_gpios[] = {
+#if !defined(CONFIG_MACH_M0_CMCC)
+ {EXYNOS4_GPA1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPA1(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SDA_1.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SCL_1.8V */
+#endif
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SCL_1.8V */
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* DET_3.5 */
+#endif
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_INT */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPX0(7), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS4_GPX1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX1(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_IRQ */
+
+ {EXYNOS4_GPX2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+#if defined(CONFIG_MACH_M0_CMCC)
+ {EXYNOS4_GPX2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+#endif
+ {EXYNOS4_GPX2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* V_BUS_INT */
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* FUEL_ALERT */
+ {EXYNOS4_GPX2(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_HOST_WAKEUP */
+ {EXYNOS4_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKEUP */
+ {EXYNOS4_GPX2(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* nPower */
+
+ {EXYNOS4_GPX3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WPC_INT */
+ {EXYNOS4_GPX3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_WAKE */
+#if defined(CONFIG_MACH_M0)
+ {EXYNOS4_GPX3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CP_PMU_RST */
+#endif
+#if defined(CONFIG_SEC_MODEM_M0_TD)
+ {EXYNOS4_GPX3(5), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+#else
+ {EXYNOS4_GPX3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+#endif
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV4}, /* WLAN_EN */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPK3(0), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CLK */
+#endif
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPK3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PMIC_DVS1 */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPY0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV3}, /* CAM_MCLK */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV3}, /* VTCAM_MCLK */
+};
+
+/*
+ * M0 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_CLK(NC) */
+#endif
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_SYNC(NC) */
+#endif
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#elif defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_IN(NC) */
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_OUT(NC) */
+#endif
+#if defined(CONFIG_SEC_MODEM_M0_TD)
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* FM_RST */
+
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ /* CMC221 Active States */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, /* NC */
+#else
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ)
+ /* GPF1(6) M0, C1 PDA_ACTIVE, let cp know AP sleep status*/
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* S_LED_I2C_SCL */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* S_LED_I2C_SDA */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK2_SEL */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK3_SEL */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK4_SEL */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(3) */
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(7) */
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* HDMI_EN */
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ /* GLP2(4) CMC_CPU_RESET, hold high */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* NC */
+#else
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_MACH_M0_CMCC)
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_CSN */
+#else
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* VIA_DPRAM_CSN */
+#else
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_REN */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_WEN */
+#else
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_LBN */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_UBN */
+#else
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN},/*USB_SEL*/
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1) ||\
+ defined(CONFIG_MACH_C1VZW) || defined(CONFIG_MACH_C1ATT) ||\
+ defined(CONFIG_MACH_S2PLUS) || defined(CONFIG_MACH_SLP_PQ)
+ /* GPIO_PS_ALS_EN */
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TORCH_EN */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TORCH_SET */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS1 */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS2 */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS3 */
+#if (defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ)) \
+ && !defined(CONFIG_MACH_M0_CMCC)
+ /* GPM3(3) M0, CP_RESET_REQ hold high */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* m0_sleep_gpio_table */
+
+/*
+ * M0 Rev0.4 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev04[][3] = {
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+/*
+ * M0 Rev0.5 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev05[][3] = {
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CAM_SW_EN */
+};
+
+/*
+ * M0 Rev0.6 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev06[][3] = {
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* RADIO_EN */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* 3_MICBIAS_EN */
+};
+
+/*
+ * M0 Rev0.8 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev08[][3] = {
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AP_DUMP_INT */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VTCAM_MCLK */
+};
+
+/*
+ * M0 Rev0.9 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev09[][3] = {
+#if defined(CONFIG_SEC_MODEM_M0_TD)
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+/*
+ * M0 Rev1.0 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev10[][3] = {
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 2_TOUCH_SCL_1.8V */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 2_TOUCH_SDA_1.8V */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 2_TOUCH_INT */
+};
+
+/*
+ * M0 Rev1.1 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table_rev11[][3] = {
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+/*
+ * C1 GPIO Sleep Table
+ * Based on C1 Rev0.4(0x6) / C1VZW Rev0.3(0xB)
+ */
+static unsigned int c1_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AP_VIA_TXD_1.8V */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AP_VIA_RXD_1.8V */
+#else
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* LCD_2.2V_EN */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(AP_CP_WAKEUP_1.8V) */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* EARMICBIAS_EN */
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* 2MIC_WAKE */
+#else
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_IN(NC) */
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_OUT(NC) */
+#endif
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* CP_RST_INDICATE_1.8V */
+#else
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* 2MIC_SDA_1.8V */
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* 2MIC_SCL_1.8V */
+#else
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* OLED_ID */
+#else
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_CMC_INT */
+#else
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_CP_INT */
+#endif
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CP_RST_1.8V */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* 2MIC_RST */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* S_LED_I2C_SCL */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* S_LED_I2C_SDA */
+#else
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK2_SEL */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK3_SEL */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK4_SEL */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(3) */
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(7) */
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* USB_HUB_RST */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TOUCH_SCL */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TOUCH_SDA */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*FM_PW*/
+#else
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* HDMI_EN */
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BT_EN */
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* USB_HUB_SCL */
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* USB_HUB_SDA */
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* CMC221_CPU_RST */
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CMC_PMIC_PWRON */
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_CSN */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* VIA_DPRAM_CSN */
+#else
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_REN */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_WEN */
+
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_LBN */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_UBN */
+#else
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},/*FM_BP*/
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},/*FM_RST*/
+#else
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(0) */
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(1) */
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(2) */
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(3) */
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(4) */
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(5) */
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(6) */
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(7) */
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(8) */
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(9) */
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(10) */
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(11) */
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(12) */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(13) */
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#else
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AUTO_DFS */
+#endif
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* WLAN_EN */
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TOUCH_INT */
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CODEC_LDO_EN */
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PS_ALS_EN */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* LTE_VIA_UART_SEL */
+#else
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CAM_SW_EN */
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TORCH_EN */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TORCH_SET */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CP_BOOT_SEL_1.8V */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CP_PMIC_ON */
+#else
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* VIA_PS_HOLD_OFF */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* VIA_USB_OFF */
+#else
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS1 */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS2 */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS3 */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(ISP_TXD) */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CMC_SPI_CLK_REQ */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(ISP_RXD) */
+
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},/*FM_SCL*/
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},/*FM_SDA*/
+#else
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_CLK_1.8V */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_CS_1.8V */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_DO_1.8V */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_DI_1.8V */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* c1_sleep_gpio_table */
+
+/*
+ * C1 Rev0.5(0x7)
+ */
+static unsigned int c1_sleep_gpio_table_rev05[][3] = {
+#if defined(CONFIG_MACH_C1)
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TOUCH_SCL */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TOUCH_SDA */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TOUCH_INT */
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* LED_VDD_EN */
+#endif
+};
+
+/*
+ * C1VZW Rev0.4(0xC)
+ */
+static unsigned int c1vzw_sleep_gpio_table_rev04[][3] = {
+#if defined(CONFIG_MACH_C1VZW)
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+};
+#endif
+
+struct m0_sleep_table {
+ unsigned int (*ptr)[3];
+ int size;
+};
+
+#define GPIO_TABLE(_ptr) \
+ {.ptr = _ptr, \
+ .size = ARRAY_SIZE(_ptr)} \
+
+ #define GPIO_TABLE_NULL \
+ {.ptr = NULL, \
+ .size = 0} \
+
+static struct m0_sleep_table m0_sleep_table[] = {
+ GPIO_TABLE(m0_sleep_gpio_table), /* Rev0.0(0x0) - SLP */
+ GPIO_TABLE_NULL, /* Rev0.0(0x1) - Android */
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE(m0_sleep_gpio_table_rev04), /* Rev0.4(0x5) */
+ GPIO_TABLE(m0_sleep_gpio_table_rev05), /* Rev0.5(0x6) */
+ GPIO_TABLE(m0_sleep_gpio_table_rev06), /* Rev0.6(0x7) */
+ GPIO_TABLE_NULL,
+ GPIO_TABLE(m0_sleep_gpio_table_rev08), /* Rev0.8(0x9) */
+ GPIO_TABLE(m0_sleep_gpio_table_rev09), /* Rev0.9(0xA) */
+ GPIO_TABLE(m0_sleep_gpio_table_rev10), /* Rev1.0(0xB) */
+ GPIO_TABLE(m0_sleep_gpio_table_rev11), /* Rev1.1(0xC) */
+};
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+static struct m0_sleep_table c1_sleep_table[] = {
+ GPIO_TABLE(c1_sleep_gpio_table), /* Rev0.0(0x0) */
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE(c1_sleep_gpio_table_rev05), /* C1 Rev0.5(0x7) */
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE(c1vzw_sleep_gpio_table_rev04), /* C1VZW Rev0.4(0xC) */
+};
+#endif
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+/*
+ * C1-KOR GPIO Sleep Table
+ */
+static unsigned int c1kor_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* BT_UART_RXD */
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* BT_UART_TXD */
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* BT_UART_CTS */
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* BT_UART_RTS */
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* GPS_UART_RXD */
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* GPS_UART_TXD */
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* GPS_UART_CTS */
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* GPS_UART_RTS */
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_RXD */
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_TXD */
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TSP_SDA_1.8V */
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TSP_SCL_1.8V */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AP_VIA_TXD_1.8V */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AP_VIA_RXD_1.8V */
+#else
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* CODEC_SDA_1.8V */
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* CODEC_SCL_1.8V */
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MHL_DSCL_1.8V,NFC_SCL_1.8V */
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MHL_DSDA_1.8V,NFC_SDA_1.8V */
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_SPI_SCLK */
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* CAM_SPI_SSN */
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_SPI_MISO */
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_SPI_MOSI */
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TDMB_PWR_EN */
+#else
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* LCD_2.2V_EN */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TDMB_PWR_EN */
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#else
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_CP_WAKEUP_1.8V */
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* EARMICBIAS_EN */
+#endif
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TDMB_INT */
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* CP_RST_INDICATE_1.8V */
+#else
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TDMB_SPI_CLK */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TDMB_SPI_CS */
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TDMB_SPI_DI */
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TDMB_SPI_DO */
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VIBTONE_PWM */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* AP_PMIC_SDA_1.8V */
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* AP_PMIC_SCL_1.8V */
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 8M_CAM_SDA_1.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 8M_CAM_SCL_1.8V */
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* RGB_SDA_1.8V_AP */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* RGB_SCL_1.8V_AP */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* GYRO_INT */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MHL_SDA_1.8V */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* BARO_INT */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MHL_SCL_1.8V */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* OTG_EN */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* OLED_ID */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, /* ACTIVE_STATE_HSIC */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_ID */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_RESET */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* FUEL_SCL_1.8V */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* FUEL_SDA_1.8V */
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* PDA_ACTIVE */
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* MICBIAS_EN */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* SUB_MICBIAS_EN */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MLCD_RST */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_CMC_INT */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* UART_SEL */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CP_RST_1.8V */
+#else
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* S_LED_I2C_SCL */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* S_LED_I2C_SDA */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* OLED_DET */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK2_SEL */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK3_SEL */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BUCK4_SEL */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MHL_RST */
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MHL_INT */
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(3) */
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(7) */
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* T_FLASH_CLK */
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* T_FLASH_CMD */
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(0) */
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(1) */
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(2) */
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(3) */
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_CLK */
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(3) */
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* USB_HUB_RST */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* GPIO_FM34_PWDN */
+#else
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* HDMI_EN */
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* BT_EN */
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* USB_HUB_SCL */
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* USB_HUB_SDA */
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* GYRO_DE */
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* GPS_nRST */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* GPS_EN */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* CMC221_CPU_RST */
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CMC_PMIC_PWRON */
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NFC_EN */
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NFC_FIRMWARE */
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_CSN */
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* VIA_DPRAM_CSN */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_REN */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_WEN */
+#else
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_CSN */
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_REN */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_WEN */
+#endif
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_LBN */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* DPRAM_UBN */
+#else
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* GPIO_FM34_BYPASS */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* GPIO_FM34_RESET */
+#else
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* BSENSE_SDA_1.8V */
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* BSENSE_SCL_1.8V */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MSENSE_SDA_1.8V */
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(0) */
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(1) */
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(2) */
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(3) */
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(4) */
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(5) */
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(6) */
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(7) */
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(8) */
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(9) */
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(10) */
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(11) */
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(12) */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* DPRAM_A(13) */
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(0) */
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(1) */
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(2) */
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(3) */
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(4) */
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(5) */
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(6) */
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(7) */
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(8) */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(9) */
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(10) */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(11) */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(12) */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(13) */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(14) */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* DPRAM_D(15) */
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MM_I2S_CLK */
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* AUTO_DFS */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MM_I2S_SYNC */
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MM_I2S_DI */
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MM_I2S_DO */
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* WLAN_EN */
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* USB_SEL */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CMC_USB_DETECT(Cur NC) */
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CODEC_LDO_EN */
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PS_ALS_EN */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* LTE_VIA_UART_SEL */
+#else
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MSENSE_INT */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TORCH_EN */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TORCH_SET */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_MCLK */
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MHL_WAKE_UP */
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_STANDBY */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_IO_EN */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_ISP_CORE_EN */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_AF_EN */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CP_BOOT_SEL_1.8V */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CP_ON */
+#else
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* VIA_PS_HOLD_OFF */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* VIA_USB_OFF */
+#else
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV0 */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV1 */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV2 */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV3 */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_VT_nRST */
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* IF_PMIC_SDA_1.8V */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* IF_PMIC_SCL_1.8V */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TSP_nINT */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* SUSPEND_REQUEST_HSIC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS1 */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS2 */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS3 */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(SKT,KT),ISP_TXD(LGT) */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CMC_SPI_CLK_REQ */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(SKT,KT),ISP_RXD(LGT) */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* 1K PU */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* 1K PU */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_CLK_1.8V */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_CS_1.8V */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_DI_1.8V */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CMC_DO_1.8V */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+}; /* clkor_sleep_gpio_table */
+
+/*
+ * c1kor Rev0.5 GPIO Sleep Table
+ */
+static unsigned int c1kor_sleep_gpio_table_rev05[][3] = {
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* EARMICBIAS_EN -> NC */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC -> VP_RST_N*/
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC -> VP_BP_N */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC -> VP_PWDN_N */
+#endif
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* UART_SEL -> NC(LG AUTO_DFS) */
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* USB_SEL -> NC */
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC -> CAM_SW_EN */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CP_BOOT_SEL_1.8V -> Open */
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC -> VP_SCL */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC -> VP_SDA */
+#else
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 1K PU (NC)*/
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 1K PU (NC)*/
+#endif
+};
+
+static unsigned int c1kor_sleep_gpio_table_rev06[][3] = {
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VP_RST_N -> TOUCH_SCL_1.8V */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VP_BP_N -> TOUCH_SDA_1.8V*/
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC -> KEY_LED_EN */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC -> VP_BP_N */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC -> VP_RST_N */
+#endif
+};
+
+static unsigned int c1kor_sleep_gpio_table_rev07[][3] = {
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC -> AUTO_DFS */
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VIA_USB_OFF -> NC */
+#endif
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* CAM_MCLK_VGA */
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AUTO_DFS -> NC */
+};
+
+static unsigned int c1kor_sleep_gpio_table_rev08[][3] = {
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC -> CAM_SENSOR_CORE_EN */
+#endif
+};
+
+static unsigned int c1kor_sleep_gpio_table_rev09[][3] = {
+#if !defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC -> LED_VDD_EN */
+#endif
+};
+
+static unsigned int c1kor_sleep_gpio_table_rev12[][3] = {
+#if !defined(CONFIG_MACH_C1_KOR_LGT)
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC -> CAM_SENSOR_CORE_EN */
+#endif
+};
+
+struct c1kor_sleep_table {
+ unsigned int (*ptr)[3];
+ int size;
+};
+
+#define GPIO_TABLE(_ptr) \
+ {.ptr = _ptr, \
+ .size = ARRAY_SIZE(_ptr)} \
+
+ #define GPIO_TABLE_NULL \
+ {.ptr = NULL, \
+ .size = 0} \
+
+static struct c1kor_sleep_table c1kor_sleep_table[] = {
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE(c1kor_sleep_gpio_table),/* Rev0.0(0x2) */
+ GPIO_TABLE_NULL,
+ GPIO_TABLE_NULL,
+ GPIO_TABLE(c1kor_sleep_gpio_table_rev05), /* Rev0.1(0x5) */
+ GPIO_TABLE(c1kor_sleep_gpio_table_rev06), /* KT Rev0.0(0x6), LGT Rev0.5(0x6) */
+ GPIO_TABLE(c1kor_sleep_gpio_table_rev07), /* Rev0.2(0x7), LGT Rev0.6(0x7) */
+ GPIO_TABLE(c1kor_sleep_gpio_table_rev08), /* kT Rev0.1(0x8), LGT Rev0.7(0x8) */
+ GPIO_TABLE(c1kor_sleep_gpio_table_rev09), /* Rev0.4(0x9) */
+ GPIO_TABLE_NULL, /* KT Rev0.3(0xA) */
+ GPIO_TABLE_NULL, /* Rev0.5(0xB) */
+ GPIO_TABLE(c1kor_sleep_gpio_table_rev12), /* Rev0.6(0xC) */
+ GPIO_TABLE_NULL, /* KT Rev0.4(0xD) */
+};
+#endif /* C1_KOR */
+#endif /* CONFIG_MIDAS_COMMON */
+
+#if defined(CONFIG_MACH_S2PLUS)
+/*
+ * S2Plus GPIO Sleep Table
+ */
+static unsigned int s2plus_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* FM_RST */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(3) */
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(7) */
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ /* GPM3(3) M0, CP_RESET_REQ hold high */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* S2Plus_sleep_gpio_table */
+#endif
+
+/*
+ * M0CTC GPIO Sleep Table
+ */
+static unsigned int m0ctc_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* FM_RST */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*L_I2C_SCL*/
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /*L_I2C_SDA*/
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*BUCK2_SEL*/
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*BUCK3_SEL*/
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*BUCK4_SEL*/
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_CLK*/
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_CMD*/
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*eMMC_EN*/
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(0)*/
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(1)*/
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(2)*/
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(3)*/
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(4)*/
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(5)*/
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(6)*/
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*NAND_D(7)*/
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* HDMI_EN */
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},/*TCH_EN*/
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},/*TCH_SET*/
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*PMIC_DVS1*/
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*PMIC_DVS2*/
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /*PMIC_DVS3*/
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},/*VTC_SCL*/
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},/*VTC_SDA*/
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* m0ctc_sleep_gpio_table */
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+#ifdef CONFIG_MIDAS_COMMON
+void m0_config_sleep_gpio_table(void)
+{
+ int i;
+ int index = min(ARRAY_SIZE(m0_sleep_table), system_rev + 1);
+
+ for (i = 0; i < index; i++) {
+ if (m0_sleep_table[i].ptr == NULL)
+ continue;
+
+ config_sleep_gpio_table(m0_sleep_table[i].size,
+ m0_sleep_table[i].ptr);
+ }
+}
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+void c1_config_sleep_gpio_table(void)
+{
+ int i;
+ int index = min(ARRAY_SIZE(c1_sleep_table), system_rev + 1);
+
+ for (i = 0; i < index; i++) {
+ if (c1_sleep_table[i].ptr == NULL)
+ continue;
+
+ config_sleep_gpio_table(c1_sleep_table[i].size,
+ c1_sleep_table[i].ptr);
+ }
+}
+#endif
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+void c1kor_config_sleep_gpio_table(void)
+{
+ int i;
+ int index = min(ARRAY_SIZE(c1kor_sleep_table), system_rev + 1);
+
+ for (i = 0; i < index; i++) {
+ if (c1kor_sleep_table[i].ptr == NULL)
+ continue;
+
+ config_sleep_gpio_table(c1kor_sleep_table[i].size,
+ c1kor_sleep_table[i].ptr);
+ }
+}
+#endif
+#endif
+
+/* To save power consumption, gpio pin set before enterling sleep */
+void midas_config_sleep_gpio_table(void)
+{
+#ifdef CONFIG_MIDAS_COMMON
+#if defined(CONFIG_MACH_S2PLUS)
+ config_sleep_gpio_table(ARRAY_SIZE(s2plus_sleep_gpio_table),
+ s2plus_sleep_gpio_table);
+#elif defined(CONFIG_MACH_C1CTC) || defined(CONFIG_MACH_M0_CTC) || \
+ defined(CONFIG_MACH_M0_GRANDECTC)
+ config_sleep_gpio_table(ARRAY_SIZE(m0ctc_sleep_gpio_table),
+ m0ctc_sleep_gpio_table);
+#elif defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ c1kor_config_sleep_gpio_table();
+#elif defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ c1_config_sleep_gpio_table();
+#else
+ m0_config_sleep_gpio_table();
+#endif
+#else
+ config_sleep_gpio_table(ARRAY_SIZE(exynos4_sleep_gpio_table_common),
+ exynos4_sleep_gpio_table_common);
+
+ if (!soc_is_exynos4210()) {
+ if (exynos4_is_c2c_use()) {
+ config_sleep_gpio_table(ARRAY_SIZE(exynos4212_sleep_gpio_table_c2c),
+ exynos4212_sleep_gpio_table_c2c);
+ } else {
+ config_sleep_gpio_table(ARRAY_SIZE(exynos4212_sleep_gpio_table),
+ exynos4212_sleep_gpio_table);
+ }
+ } else {
+ config_sleep_gpio_table(ARRAY_SIZE(exynos4210_sleep_gpio_table),
+ exynos4210_sleep_gpio_table);
+ }
+#endif
+}
+
+/* Intialize gpio set in midas board */
+void midas_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+#ifdef CONFIG_MIDAS_COMMON
+ for (i = 0; i < ARRAY_SIZE(m0_init_gpios); i++) {
+ gpio = m0_init_gpios[i].num;
+ if (gpio <= EXYNOS4212_GPV4(1)) {
+ s3c_gpio_cfgpin(gpio, m0_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, m0_init_gpios[i].pud);
+
+ if (m0_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, m0_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, m0_init_gpios[i].drv);
+ }
+ }
+#else
+ for (i = 0; i < ARRAY_SIZE(midas_init_gpios); i++) {
+ gpio = midas_init_gpios[i].num;
+ if (!soc_is_exynos4210()) {
+ if (gpio <= EXYNOS4212_GPV4(1)) {
+ s3c_gpio_cfgpin(gpio, midas_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, midas_init_gpios[i].pud);
+
+ if (midas_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, midas_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, midas_init_gpios[i].drv);
+ }
+ } else {
+ if (gpio <= EXYNOS4210_GPJ1(4)) {
+ s3c_gpio_cfgpin(gpio, midas_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, midas_init_gpios[i].pud);
+
+ if (midas_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, midas_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, midas_init_gpios[i].drv);
+ }
+ }
+ }
+#endif
+}
diff --git a/arch/arm/mach-exynos/midas-gps.c b/arch/arm/mach-exynos/midas-gps.c
new file mode 100644
index 0000000..ebfc1bd
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-gps.c
@@ -0,0 +1,50 @@
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+//#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+extern struct class *sec_class;
+static struct device *gps_dev;
+
+static int __init midas_gps_init(void)
+{
+ BUG_ON(!sec_class);
+ gps_dev = device_create(sec_class, NULL, 0, NULL, "gps");
+ BUG_ON(!gps_dev);
+
+ s3c_gpio_cfgpin(GPIO_GPS_RXD, S3C_GPIO_SFN(GPIO_GPS_RXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_RXD, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_TXD, S3C_GPIO_SFN(GPIO_GPS_TXD_AF));
+ s3c_gpio_setpull(GPIO_GPS_TXD, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_CTS, S3C_GPIO_SFN(GPIO_GPS_CTS_AF));
+ s3c_gpio_setpull(GPIO_GPS_CTS, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_RTS, S3C_GPIO_SFN(GPIO_GPS_RTS_AF));
+ s3c_gpio_setpull(GPIO_GPS_RTS, S3C_GPIO_PULL_NONE);
+
+ if (gpio_request(GPIO_GPS_nRST, "GPS_nRST"))
+ WARN(1, "fail to request gpio (GPS_nRST)\n");
+
+ s3c_gpio_setpull(GPIO_GPS_nRST, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_GPS_nRST, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_nRST, 1);
+
+ if (gpio_request(GPIO_GPS_PWR_EN, "GPS_PWR_EN"))
+ WARN(1, "fail to request gpio (GPS_PWR_EN)\n");
+
+ s3c_gpio_setpull(GPIO_GPS_PWR_EN, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_direction_output(GPIO_GPS_PWR_EN, 0);
+
+ gpio_export(GPIO_GPS_nRST, 1);
+ gpio_export(GPIO_GPS_PWR_EN, 1);
+
+ gpio_export_link(gps_dev, "GPS_nRST", GPIO_GPS_nRST);
+ gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN);
+
+ return 0;
+}
+
+device_initcall(midas_gps_init);
diff --git a/arch/arm/mach-exynos/midas-lcd.c b/arch/arm/mach-exynos/midas-lcd.c
new file mode 100644
index 0000000..549a742
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-lcd.c
@@ -0,0 +1,810 @@
+/*
+ * midas-lcd.c - lcd driver of MIDAS Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/lcd.h>
+
+#include <plat/devs.h>
+#include <plat/fb-s5p.h>
+#include <plat/gpio-cfg.h>
+#include <plat/pd.h>
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#ifdef CONFIG_FB_S5P_LD9040
+#include <linux/ld9040.h>
+#endif
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#include <mach/mipi_ddi.h>
+#include <mach/dsim.h>
+#endif
+#include <../../../drivers/video/samsung/s3cfb.h>
+
+#ifdef CONFIG_FB_S5P_MDNIE
+#include <linux/mdnie.h>
+#endif
+
+struct s3c_platform_fb fb_platform_data;
+unsigned int lcdtype;
+static int __init lcdtype_setup(char *str)
+{
+ get_option(&str, &lcdtype);
+ return 1;
+}
+__setup("lcdtype=", lcdtype_setup);
+
+
+#ifdef CONFIG_FB_S5P
+#ifdef CONFIG_FB_S5P_LD9040
+static int lcd_cfg_gpio(void)
+{
+ int i, f3_end = 4;
+
+ for (i = 0; i < 8; i++) {
+ /* set GPF0,1,2[0:7] for RGB Interface and Data line (32bit) */
+ s3c_gpio_cfgpin(EXYNOS4_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF0(i), S3C_GPIO_PULL_NONE);
+ }
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < f3_end; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ struct regulator *regulator;
+
+ if (ld == NULL) {
+ printk(KERN_ERR "lcd device object is NULL.\n");
+ return 0;
+ }
+
+ if (enable) {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+ if (IS_ERR(regulator))
+ return 0;
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_3.0v");
+
+ if (IS_ERR(regulator))
+ return 0;
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+ }
+
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+ reset_gpio = EXYNOS4_GPY4(5);
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_request(reset_gpio, "MLCD_RST");
+
+ mdelay(10);
+ gpio_direction_output(reset_gpio, 0);
+ mdelay(10);
+ gpio_direction_output(reset_gpio, 1);
+
+ gpio_free(reset_gpio);
+
+ return 1;
+}
+
+static int lcd_gpio_cfg_earlysuspend(struct lcd_device *ld)
+{
+ int reset_gpio = -1;
+ int err;
+
+ reset_gpio = EXYNOS4_GPY4(5);
+
+ err = gpio_request(reset_gpio, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request MLCD_RST for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ mdelay(10);
+ gpio_direction_output(reset_gpio, 0);
+
+ gpio_free(reset_gpio);
+
+ return 0;
+}
+
+static int lcd_gpio_cfg_lateresume(struct lcd_device *ld)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(5), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(5), S3C_GPIO_PULL_NONE);
+
+ /* LCD_nCS */
+ s3c_gpio_cfgpin(EXYNOS4_GPY4(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY4(3), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SCLK */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(1), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(1), S3C_GPIO_PULL_NONE);
+
+ /* LCD_SDI */
+ s3c_gpio_cfgpin(EXYNOS4_GPY3(3), S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(EXYNOS4_GPY3(3), S3C_GPIO_PULL_NONE);
+
+ return 0;
+}
+
+static struct s3cfb_lcd ld9040_info = {
+ .width = 480,
+ .height = 800,
+ .p_width = 56,
+ .p_height = 93,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 16,
+ .h_bp = 14,
+ .h_sw = 2,
+ .v_fp = 10,
+ .v_fpe = 1,
+ .v_bp = 4,
+ .v_bpe = 1,
+ .v_sw = 2,
+ },
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 1,
+ },
+};
+
+struct ld9040_panel_data s2plus_panel_data;
+static struct lcd_platform_data ld9040_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .gpio_cfg_earlysuspend = lcd_gpio_cfg_earlysuspend,
+ .gpio_cfg_lateresume = lcd_gpio_cfg_lateresume,
+ /* it indicates whether lcd panel is enabled from u-boot. */
+#if defined(CONFIG_MACH_S2PLUS)
+ .lcd_enabled = 1,
+#else
+ .lcd_enabled = 0,
+#endif
+ .reset_delay = 20, /* 20ms */
+ .power_on_delay = 20, /* 20ms */
+ .power_off_delay = 200, /* 200ms */
+ .sleep_in_delay = 160,
+ .pdata = &s2plus_panel_data,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPY4(3)
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ },
+};
+
+#define DISPLAY_CLK EXYNOS4_GPY3(1)
+#define DISPLAY_SI EXYNOS4_GPY3(3)
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device ld9040_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+/* reading with 3-WIRE SPI with GPIO */
+static inline void setcs(u8 is_on)
+{
+ gpio_set_value(DISPLAY_CS, is_on);
+}
+
+static inline void setsck(u8 is_on)
+{
+ gpio_set_value(DISPLAY_CLK, is_on);
+}
+
+static inline void setmosi(u8 is_on)
+{
+ gpio_set_value(DISPLAY_SI, is_on);
+}
+
+static inline unsigned int getmiso(void)
+{
+ return !!gpio_get_value(DISPLAY_SI);
+}
+
+static inline void setmosi2miso(u8 is_on)
+{
+ if (is_on)
+ s3c_gpio_cfgpin(DISPLAY_SI, S3C_GPIO_INPUT);
+ else
+ s3c_gpio_cfgpin(DISPLAY_SI, S3C_GPIO_OUTPUT);
+}
+
+struct spi_ops ops = {
+ .setcs = setcs,
+ .setsck = setsck,
+ .setmosi = setmosi,
+ .setmosi2miso = setmosi2miso,
+ .getmiso = getmiso,
+};
+
+void __init ld9040_fb_init(void)
+{
+ struct ld9040_panel_data *pdata;
+
+ strcpy(spi_board_info[0].modalias, "ld9040");
+ spi_board_info[0].platform_data = (void *)&ld9040_platform_data;
+
+ pdata = ld9040_platform_data.pdata;
+ pdata->ops = &ops;
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ if (!ld9040_platform_data.lcd_enabled)
+ lcd_cfg_gpio();
+ /*s3cfb_set_platdata(&fb_platform_data);*/
+}
+#endif
+
+#if defined(CONFIG_FB_S5P_S6C1372)
+int s6c1372_panel_gpio_init(void)
+{
+ int i, f3_end = 4;
+
+ for (i = 0; i < 8; i++) {
+ /* set GPF0,1,2[0:7] for RGB Interface and Data line (32bit) */
+ s3c_gpio_cfgpin(EXYNOS4_GPF0(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF0(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF1(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF1(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < 8; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF2(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF2(i), S3C_GPIO_PULL_NONE);
+ }
+
+ for (i = 0; i < f3_end; i++) {
+ s3c_gpio_cfgpin(EXYNOS4_GPF3(i), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPF3(i), S3C_GPIO_PULL_NONE);
+ }
+
+ return 0;
+}
+
+static struct s3cfb_lcd s6c1372 = {
+ .width = 1280,
+ .height = 800,
+ .p_width = 217,
+ .p_height = 135,
+ .bpp = 24,
+
+ .freq = 60,
+ .timing = {
+ .h_fp = 18,
+ .h_bp = 36,
+ .h_sw = 16,
+ .v_fp = 4,
+ .v_fpe = 1,
+ .v_bp = 16,
+ .v_bpe = 1,
+ .v_sw = 3,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 1,
+ .inv_vsync = 1,
+ .inv_vden = 0,
+ },
+};
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ if (enable) {
+ /* LVDS_N_SHDN to high*/
+ mdelay(1);
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_HIGH);
+ msleep(300);
+
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, GPIO_LEVEL_HIGH);
+ mdelay(2);
+ } else {
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, GPIO_LEVEL_LOW);
+ msleep(200);
+
+ /* LVDS_nSHDN low*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_LOW);
+ msleep(40);
+}
+
+ return 0;
+}
+
+static struct lcd_platform_data s6c1372_platform_data = {
+ .power_on = lcd_power_on,
+};
+
+struct platform_device lcd_s6c1372 = {
+ .name = "s6c1372",
+ .id = -1,
+ .dev.platform_data = &s6c1372_platform_data,
+};
+
+#endif
+
+#ifdef CONFIG_FB_S5P_LMS501KF03
+static struct s3c_platform_fb lms501kf03_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "sclk_lcd",
+ .nr_wins = 5,
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+};
+
+#define LCD_BUS_NUM 3
+#define DISPLAY_CS EXYNOS4_GPB(5)
+#define DISPLAY_CLK EXYNOS4_GPB(4)
+#define DISPLAY_SI EXYNOS4_GPB(7)
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "lms501kf03",
+ .platform_data = NULL,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)DISPLAY_CS,
+ }
+};
+
+static struct spi_gpio_platform_data lms501kf03_spi_gpio_data = {
+ .sck = DISPLAY_CLK,
+ .mosi = DISPLAY_SI,
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device s3c_device_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lms501kf03_spi_gpio_data,
+ },
+};
+#endif
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+#ifdef CONFIG_FB_S5P_S6E8AA0
+/* for Geminus based on MIPI-DSI interface */
+static struct s3cfb_lcd s6e8aa0 = {
+ .name = "s6e8aa0",
+ .width = 720,
+ .height = 1280,
+ .p_width = 60, /* 59.76 mm */
+ .p_height = 106, /* 106.24 mm */
+ .bpp = 24,
+
+ .freq = 60,
+
+ /* minumun value is 0 except for wr_act time. */
+ .cpu_timing = {
+ .cs_setup = 0,
+ .wr_setup = 0,
+ .wr_act = 1,
+ .wr_hold = 0,
+ },
+
+ .timing = {
+ .h_fp = 5,
+ .h_bp = 5,
+ .h_sw = 5,
+ .v_fp = 13,
+ .v_fpe = 1,
+ .v_bp = 1,
+ .v_bpe = 1,
+ .v_sw = 2,
+ .cmd_allow_len = 11, /* v_fp=stable_vfp + cmd_allow_len */
+ .stable_vfp = 2,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+#endif
+
+#ifdef CONFIG_FB_S5P_S6E39A0
+static struct s3cfb_lcd s6e39a0 = {
+ .name = "s6e8aa0",
+ .width = 540,
+ .height = 960,
+ .p_width = 58,
+ .p_height = 103,
+ .bpp = 24,
+
+ .freq = 60,
+
+ /* minumun value is 0 except for wr_act time. */
+ .cpu_timing = {
+ .cs_setup = 0,
+ .wr_setup = 0,
+ .wr_act = 1,
+ .wr_hold = 0,
+ },
+
+ .timing = {
+ .h_fp = 0x48,
+ .h_bp = 12,
+ .h_sw = 4,
+ .v_fp = 13,
+ .v_fpe = 1,
+ .v_bp = 1,
+ .v_bpe = 1,
+ .v_sw = 2,
+ .cmd_allow_len = 0x4,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+#endif
+
+#ifdef CONFIG_FB_S5P_S6D6AA1
+/* for Geminus based on MIPI-DSI interface */
+static struct s3cfb_lcd s6d6aa1 = {
+ .name = "s6d6aa1",
+ .width = 720,
+ .height = 1280,
+ .p_width = 63, /* 63.2 mm */
+ .p_height = 114, /* 114.19 mm */
+ .bpp = 24,
+
+ .freq = 60,
+
+ /* minumun value is 0 except for wr_act time. */
+ .cpu_timing = {
+ .cs_setup = 0,
+ .wr_setup = 0,
+ .wr_act = 1,
+ .wr_hold = 0,
+ },
+
+ .timing = {
+ .h_fp = 50,
+ .h_bp = 15,
+ .h_sw = 3,
+ .v_fp = 3,
+ .v_fpe = 1,
+ .v_bp = 2,
+ .v_bpe = 1,
+ .v_sw = 2,
+ .cmd_allow_len = 11, /* v_fp=stable_vfp + cmd_allow_len */
+ .stable_vfp = 2,
+ },
+
+ .polarity = {
+ .rise_vclk = 1,
+ .inv_hsync = 0,
+ .inv_vsync = 0,
+ .inv_vden = 0,
+ },
+};
+#endif
+
+static int reset_lcd(void)
+{
+ int err;
+
+ err = gpio_request(GPIO_MLCD_RST, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY4(5) for "
+ "lcd reset control\n");
+ return -EINVAL;
+ }
+
+ gpio_direction_output(GPIO_MLCD_RST, 1);
+ usleep_range(5000, 5000);
+ gpio_set_value(GPIO_MLCD_RST, 0);
+ usleep_range(5000, 5000);
+ gpio_set_value(GPIO_MLCD_RST, 1);
+ usleep_range(5000, 5000);
+ gpio_free(GPIO_MLCD_RST);
+ return 0;
+}
+
+static void lcd_cfg_gpio(void)
+{
+ /* MLCD_RST */
+ s3c_gpio_cfgpin(GPIO_MLCD_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MLCD_RST, S3C_GPIO_PULL_NONE);
+
+ /* LCD_EN */
+ s3c_gpio_cfgpin(GPIO_LCD_22V_EN_00, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_LCD_22V_EN_00, S3C_GPIO_PULL_NONE);
+
+ return;
+}
+
+static int lcd_power_on(void *ld, int enable)
+{
+ struct regulator *regulator;
+ int err;
+
+ printk(KERN_INFO "%s : enable=%d\n", __func__, enable);
+
+ err = gpio_request(GPIO_MLCD_RST, "MLCD_RST");
+ if (err) {
+ printk(KERN_ERR "failed to request GPY4[5] for "
+ "MLCD_RST control\n");
+ return -EPERM;
+ }
+
+ err = gpio_request(GPIO_LCD_22V_EN_00, "LCD_EN");
+ if (err) {
+ printk(KERN_ERR "failed to request GPM4[4] for "
+ "LCD_2.2V_EN control\n");
+ return -EPERM;
+ }
+
+ if (enable) {
+ gpio_set_value(GPIO_LCD_22V_EN_00, GPIO_LEVEL_HIGH);
+
+ regulator = regulator_get(NULL, "vlcd_3.3v");
+ if (IS_ERR(regulator))
+ goto out;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vlcd_3.3v");
+ if (IS_ERR(regulator))
+ goto out;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ gpio_set_value(GPIO_LCD_22V_EN_00, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_MLCD_RST, 0);
+ }
+
+out:
+/* Release GPIO */
+ gpio_free(GPIO_MLCD_RST);
+ gpio_free(GPIO_LCD_22V_EN_00);
+return 0;
+}
+
+static void s5p_dsim_mipi_power_control(int enable)
+{
+ struct regulator *regulator;
+ int power_en = 0;
+
+ if (power_en == 1) {
+ printk(KERN_INFO "%s : enable=%d\n", __func__, enable);
+
+ if (enable) {
+ regulator = regulator_get(NULL, "vmipi_1.0v");
+ if (IS_ERR(regulator))
+ goto out;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto out;
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto out;
+ if (regulator_is_enabled(regulator))
+ regulator_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "vmipi_1.0v");
+ if (IS_ERR(regulator))
+ goto out;
+ if (regulator_is_enabled(regulator))
+ regulator_disable(regulator);
+ regulator_put(regulator);
+ }
+out:
+ return ;
+ } else {
+ return ;
+ }
+}
+
+void __init mipi_fb_init(void)
+{
+ struct s5p_platform_dsim *dsim_pd = NULL;
+ struct mipi_ddi_platform_data *mipi_ddi_pd = NULL;
+ struct dsim_lcd_config *dsim_lcd_info = NULL;
+
+ /* set platform data */
+
+ /* gpio pad configuration for rgb and spi interface. */
+ lcd_cfg_gpio();
+
+ /*
+ * register lcd panel data.
+ */
+ printk(KERN_INFO "%s :: fb_platform_data.hw_ver = 0x%x\n",
+ __func__, fb_platform_data.hw_ver);
+
+ fb_platform_data.mipi_is_enabled = 1;
+ fb_platform_data.interface_mode = FIMD_CPU_INTERFACE;
+
+ dsim_pd = (struct s5p_platform_dsim *)
+ s5p_device_dsim.dev.platform_data;
+
+ dsim_pd->platform_rev = 1;
+ dsim_pd->mipi_power = s5p_dsim_mipi_power_control;
+
+ dsim_lcd_info = dsim_pd->dsim_lcd_info;
+
+#if defined(CONFIG_FB_S5P_S6E8AA0)
+ dsim_lcd_info->lcd_panel_info = (void *)&s6e8aa0;
+#endif
+#if defined(CONFIG_FB_S5P_S6D6AA1)
+ dsim_lcd_info->lcd_panel_info = (void *)&s6d6aa1;
+#endif
+
+ /* 500Mbps */
+ dsim_pd->dsim_info->p = 3;
+ dsim_pd->dsim_info->m = 125;
+ dsim_pd->dsim_info->s = 1;
+
+ mipi_ddi_pd = (struct mipi_ddi_platform_data *)
+ dsim_lcd_info->mipi_ddi_pd;
+ mipi_ddi_pd->lcd_reset = reset_lcd;
+ mipi_ddi_pd->lcd_power_on = lcd_power_on;
+
+ platform_device_register(&s5p_device_dsim);
+
+ /*s3cfb_set_platdata(&fb_platform_data);*/
+}
+#endif
+#endif
+
+struct s3c_platform_fb fb_platform_data __initdata = {
+ .hw_ver = 0x70,
+ .clk_name = "fimd",
+ .nr_wins = 5,
+#ifdef CONFIG_FB_S5P_DEFAULT_WINDOW
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_HWORD | FB_SWAP_WORD,
+#if defined(CONFIG_FB_S5P_S6E8AA0)
+ .lcd = &s6e8aa0
+#endif
+#if defined(CONFIG_FB_S5P_S6E39A0)
+ .lcd = &s6e39a0
+#endif
+#if defined(CONFIG_FB_S5P_LD9040)
+ .lcd = &ld9040_info
+#endif
+#if defined(CONFIG_FB_S5P_S6C1372)
+ .lcd = &s6c1372
+#endif
+#if defined(CONFIG_FB_S5P_S6D6AA1)
+ .lcd = &s6d6aa1
+#endif
+};
+
+#ifdef CONFIG_FB_S5P_MDNIE
+static struct platform_mdnie_data mdnie_data = {
+ .display_type = -1,
+#if defined(CONFIG_FB_S5P_S6C1372)
+ .lcd_pd = &s6c1372_platform_data,
+#endif
+};
+#endif
+
+struct platform_device mdnie_device = {
+ .name = "mdnie",
+ .id = -1,
+ .dev = {
+ .parent = &exynos4_device_pd[PD_LCD0].dev,
+#ifdef CONFIG_FB_S5P_MDNIE
+ .platform_data = &mdnie_data,
+#endif
+ },
+};
diff --git a/arch/arm/mach-exynos/midas-leds.c b/arch/arm/mach-exynos/midas-leds.c
new file mode 100644
index 0000000..2d6e1e2
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-leds.c
@@ -0,0 +1,54 @@
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/leds-lp5521.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include "midas.h"
+
+#ifdef CONFIG_LEDS_LP5521
+static struct lp5521_led_config lp5521_led_config[] = {
+ {
+ .name = "red",
+ .chan_nr = 0,
+ .led_current = 50,
+ .max_current = 130,
+ }, {
+ .name = "green",
+ .chan_nr = 1,
+ .led_current = 30,
+ .max_current = 130,
+ }, {
+ .name = "blue",
+ .chan_nr = 2,
+ .led_current = 30,
+ .max_current = 130,
+ },
+};
+#define LP5521_CONFIGS (LP5521_PWM_HF | LP5521_PWRSAVE_EN | \
+LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT | \
+LP5521_CLK_INT)
+
+static struct lp5521_platform_data lp5521_pdata = {
+ .led_config = lp5521_led_config,
+ .num_channels = ARRAY_SIZE(lp5521_led_config),
+ .clock_mode = LP5521_CLOCK_INT,
+ .update_config = LP5521_CONFIGS,
+};
+static struct i2c_board_info i2c_devs21_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("lp5521", 0x32),
+ .platform_data = &lp5521_pdata,
+ },
+};
+
+int __init plat_leds_init(void)
+{
+ i2c_add_devices(21, i2c_devs21_emul, ARRAY_SIZE(i2c_devs21_emul));
+ return 0;
+};
+module_init(plat_leds_init);
+#endif
diff --git a/arch/arm/mach-exynos/midas-mhl.c b/arch/arm/mach-exynos/midas-mhl.c
new file mode 100644
index 0000000..5a97b00
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-mhl.c
@@ -0,0 +1,192 @@
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/sii9234.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include "midas.h"
+
+#ifdef CONFIG_SAMSUNG_MHL
+static void sii9234_cfg_gpio(void)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+
+ /* AP_MHL_SDA */
+ s3c_gpio_cfgpin(GPIO_MHL_SDA_1_8V, S3C_GPIO_SFN(0x0));
+ s3c_gpio_setpull(GPIO_MHL_SDA_1_8V, S3C_GPIO_PULL_NONE);
+
+ /* AP_MHL_SCL */
+ s3c_gpio_cfgpin(GPIO_MHL_SCL_1_8V, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_MHL_SCL_1_8V, S3C_GPIO_PULL_NONE);
+
+ /* GPH1(6) XEINT 14 */
+ s3c_gpio_cfgpin(GPIO_MHL_WAKE_UP, S3C_GPIO_INPUT);
+ irq_set_irq_type(MHL_WAKEUP_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_setpull(GPIO_MHL_WAKE_UP, S3C_GPIO_PULL_DOWN);
+
+ gpio_request(GPIO_MHL_INT, "MHL_INT");
+ s5p_register_gpio_interrupt(GPIO_MHL_INT);
+ s3c_gpio_setpull(GPIO_MHL_INT, S3C_GPIO_PULL_DOWN);
+ irq_set_irq_type(MHL_INT_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_cfgpin(GPIO_MHL_INT, GPIO_MHL_INT_AF);
+
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT); /* HDMI_EN */
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+
+#if !defined(CONFIG_MACH_C1_KOR_LGT) && !defined(CONFIG_SAMSUNG_MHL_9290)
+#if !defined(CONFIG_MACH_P4NOTE)
+ s3c_gpio_cfgpin(GPIO_MHL_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_SEL, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_LOW);
+#endif
+#endif
+}
+
+static void sii9234_power_onoff(bool on)
+{
+ printk(KERN_INFO "%s(%d)\n", __func__, on);
+
+ if (on) {
+ /* To avoid floating state of the HPD pin *
+ * in the absence of external pull-up */
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+
+ s3c_gpio_setpull(GPIO_MHL_SCL_1_8V, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_MHL_SCL_1_8V, S3C_GPIO_PULL_NONE);
+
+ /* sii9234_unmaks_interrupt(); // - need to add */
+ /* VCC_SUB_2.0V is always on */
+ } else {
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+
+ /* To avoid floating state of the HPD pin *
+ * in the absence of external pull-up */
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_DOWN);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ }
+}
+
+static void sii9234_reset(void)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+
+
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+}
+
+#ifndef CONFIG_SAMSUNG_USE_11PIN_CONNECTOR
+#ifndef CONFIG_MACH_P4NOTE
+static void mhl_usb_switch_control(bool on)
+{
+ printk(KERN_INFO "%s() [MHL] USB path change : %s\n",
+ __func__, on ? "MHL" : "USB");
+ if (on == 1) {
+ if (gpio_get_value(GPIO_MHL_SEL))
+ printk(KERN_INFO "[MHL] GPIO_MHL_SEL : already 1\n");
+ else
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_HIGH);
+ } else {
+ if (!gpio_get_value(GPIO_MHL_SEL))
+ printk(KERN_INFO "[MHL] GPIO_MHL_SEL : already 0\n");
+ else
+ gpio_set_value(GPIO_MHL_SEL, GPIO_LEVEL_LOW);
+ }
+}
+#endif
+#endif
+
+static struct sii9234_platform_data sii9234_pdata = {
+ .init = sii9234_cfg_gpio,
+#if defined(CONFIG_SAMSUNG_USE_11PIN_CONNECTOR) || \
+ defined(CONFIG_MACH_P4NOTE)
+ .mhl_sel = NULL,
+#else
+ .mhl_sel = mhl_usb_switch_control,
+#endif
+ .hw_onoff = sii9234_power_onoff,
+ .hw_reset = sii9234_reset,
+ .enable_vbus = NULL,
+#if defined(__MHL_NEW_CBUS_MSC_CMD__)
+ .vbus_present = NULL,
+#else
+ .vbus_present = NULL,
+#endif
+
+#ifdef CONFIG_EXTCON
+ .extcon_name = "max77693-muic",
+#endif
+};
+
+static struct i2c_board_info __initdata i2c_devs_sii9234[] = {
+ {
+ I2C_BOARD_INFO("sii9234_mhl_tx", 0x72>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_tpi", 0x7A>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_hdmi_rx", 0x92>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_cbus", 0xC8>>1),
+ .platform_data = &sii9234_pdata,
+ },
+};
+
+static struct i2c_board_info i2c_dev_hdmi_ddc __initdata = {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+};
+
+static int __init midas_mhl_init(void)
+{
+ int ret;
+#define I2C_BUS_ID_MHL 15
+ ret = i2c_add_devices(I2C_BUS_ID_MHL, i2c_devs_sii9234,
+ ARRAY_SIZE(i2c_devs_sii9234));
+
+ if (ret < 0) {
+ printk(KERN_ERR "[MHL] adding i2c fail - nodevice\n");
+ return -ENODEV;
+ }
+#if defined(CONFIG_MACH_S2PLUS) || defined(CONFIG_MACH_P4NOTE)
+ sii9234_pdata.ddc_i2c_num = 5;
+#else
+ sii9234_pdata.ddc_i2c_num = (system_rev == 3 ? 16 : 5);
+#endif
+
+#ifdef CONFIG_MACH_SLP_PQ_LTE
+ sii9234_pdata.ddc_i2c_num = 16;
+#endif
+ ret = i2c_add_devices(sii9234_pdata.ddc_i2c_num, &i2c_dev_hdmi_ddc, 1);
+ if (ret < 0) {
+ printk(KERN_ERR "[MHL] adding ddc fail - nodevice\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+module_init(midas_mhl_init);
+#endif
diff --git a/arch/arm/mach-exynos/midas-nfc.c b/arch/arm/mach-exynos/midas-nfc.c
new file mode 100644
index 0000000..c9c05f5
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-nfc.c
@@ -0,0 +1,78 @@
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/nfc/pn65n.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include "midas.h"
+
+/* GPIO_LEVEL_NONE = 2, GPIO_LEVEL_LOW = 0 */
+static unsigned int nfc_gpio_table[][4] = {
+ {GPIO_NFC_IRQ, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_NFC_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+ {GPIO_NFC_FIRMWARE, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+};
+
+static inline void nfc_setup_gpio(void)
+{
+ int array_size = ARRAY_SIZE(nfc_gpio_table);
+ u32 i, gpio;
+ for (i = 0; i < array_size; i++) {
+ gpio = nfc_gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(nfc_gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, nfc_gpio_table[i][3]);
+ if (nfc_gpio_table[i][2] != 2)
+ gpio_set_value(gpio, nfc_gpio_table[i][2]);
+ }
+}
+
+static struct pn65n_i2c_platform_data pn65n_pdata = {
+ .irq_gpio = GPIO_NFC_IRQ,
+ .ven_gpio = GPIO_NFC_EN,
+ .firm_gpio = GPIO_NFC_FIRMWARE,
+};
+
+static struct i2c_board_info i2c_dev_pn65n __initdata = {
+ I2C_BOARD_INFO("pn65n", 0x2b),
+ .irq = IRQ_EINT(15),
+ .platform_data = &pn65n_pdata,
+};
+
+#ifdef CONFIG_SLP
+/* In SLP Kernel, i2c_bus number is decided at board file. */
+int __init midas_nfc_init(int i2c_bus)
+{
+ nfc_setup_gpio();
+
+ i2c_register_board_info(i2c_bus, &i2c_dev_pn65n, 1);
+
+ return 0;
+}
+#else
+static int __init midas_nfc_init(void)
+{
+ int ret = 0;
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M3) || defined(CONFIG_MACH_M0_CTC)
+#define I2C_BUSNUM_PN65N (system_rev == 3 ? 0 : 5)
+#elif defined(CONFIG_MACH_M0) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS)
+#define I2C_BUSNUM_PN65N (system_rev == 3 ? 12 : 5)
+#else
+#define I2C_BUSNUM_PN65N 12
+#endif
+
+ nfc_setup_gpio();
+
+ ret = i2c_add_devices(I2C_BUSNUM_PN65N, &i2c_dev_pn65n, 1);
+ if (ret < 0) {
+ pr_err("%s, i2c%d adding i2c fail(err=%d)\n",
+ __func__, I2C_BUSNUM_PN65N, ret);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(midas_nfc_init);
+#endif
diff --git a/arch/arm/mach-exynos/midas-power.c b/arch/arm/mach-exynos/midas-power.c
new file mode 100644
index 0000000..78318f2
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-power.c
@@ -0,0 +1,1125 @@
+/*
+ * midas-power.c - Power Management of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Chiwoong Byun <woong.byun@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-midas.h>
+#include <mach/irqs.h>
+
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max77686.h>
+#include <linux/mfd/max77693.h>
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#endif
+
+#ifdef CONFIG_REGULATOR_MAX8997
+/* MOTOR */
+#ifdef CONFIG_VIBETONZ
+static void max8997_motor_init(void)
+{
+ gpio_request(GPIO_VIBTONE_EN, "VIBTONE_EN");
+ s3c_gpio_cfgpin(GPIO_VIBTONE_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_VIBTONE_EN, S3C_GPIO_PULL_NONE);
+}
+
+static void max8997_motor_en(bool en)
+{
+ gpio_direction_output(GPIO_VIBTONE_EN, en);
+}
+
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 44000,
+ .period = 44642,
+ .reg2 = MOTOR_LRA | EXT_PWM | DIVIDER_128,
+ .init_hw = max8997_motor_init,
+ .motor_en = max8997_motor_en,
+ .pwm_id = 1,
+};
+#endif
+
+/* max8997 */
+static struct regulator_consumer_supply ldo1_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim"),
+};
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo6_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo7_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim"),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.3v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vlcd_2.2v", NULL),
+ REGULATOR_SUPPLY("VDD3", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply max8997_buck1 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max8997_buck3 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max8997_buck4 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo1, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo6, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo7, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo11, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo13, "VCC_3.3V_LCD", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo14, "VCC_1.8V_IO", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo15, "VDD_2.2V_LCD", 2200000, 2200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo16, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data max8997_buck1_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 950000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck1,
+};
+
+static struct regulator_init_data max8997_buck2_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 900000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max8997_buck2),
+ .consumer_supplies = max8997_buck2,
+};
+
+static struct regulator_init_data max8997_buck3_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 950000,
+ .max_uV = 1150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck3,
+};
+
+static struct regulator_init_data max8997_buck4_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck4,
+};
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_BUCK1, &max8997_buck1_data, },
+ { MAX8997_BUCK2, &max8997_buck2_data, },
+ { MAX8997_BUCK3, &max8997_buck3_data, },
+ { MAX8997_BUCK4, &max8997_buck4_data, },
+ { MAX8997_LDO1, &ldo1_init_data, },
+ { MAX8997_LDO6, &ldo6_init_data, },
+ { MAX8997_LDO7, &ldo7_init_data, },
+ { MAX8997_LDO8, &ldo8_init_data, },
+ { MAX8997_LDO11, &ldo11_init_data, },
+ { MAX8997_LDO12, &ldo12_init_data, },
+ { MAX8997_LDO13, &ldo13_init_data, },
+ { MAX8997_LDO14, &ldo14_init_data, },
+ { MAX8997_LDO15, &ldo15_init_data, },
+ { MAX8997_LDO16, &ldo16_init_data, },
+ { MAX8997_LDO17, &ldo17_init_data, },
+ { MAX8997_LDO18, &ldo18_init_data, },
+};
+
+struct max8997_platform_data exynos4_max8997_info = {
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = max8997_regulators,
+ .buck1_max_vol = 1100000,
+ .buck2_max_vol = 1100000,
+ .buck5_max_vol = 1100000,
+ .buck_set1 = EXYNOS4212_GPJ1(1),
+ .buck_set2 = EXYNOS4212_GPJ1(2),
+ .buck_set3 = EXYNOS4_GPL0(0),
+#ifdef CONFIG_VIBETONZ
+ .motor = &max8997_motor,
+#endif
+};
+#elif defined(CONFIG_REGULATOR_MAX77686)
+/* max77686 */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo3_supply[] = {};
+#endif
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+ REGULATOR_SUPPLY("touchkey", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
+ REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_mipi_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.95v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_C1)
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vusbhub_osc_1.8v", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb2_1.95v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3) || \
+ defined(CONFIG_MACH_GC1)
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("touch_1.8v", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("vlcd_2.2v", NULL),
+ REGULATOR_SUPPLY("VDD3", "s6e8aa0"),
+};
+#endif
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.3v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+
+static struct regulator_consumer_supply max77686_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynoss4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply max77686_buck9 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+static struct regulator_consumer_supply max77686_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo5, "VCC_1.8V_IO", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo9, "CAM_ISP_MIPI_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo11, "VABB1_1.95V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_C1)
+REGULATOR_INIT(ldo13, "VUSBHUB_OSC_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo14, "VABB2_1.95V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3) || \
+ defined(CONFIG_MACH_GC1)
+REGULATOR_INIT(ldo24, "VDD_1.8V_TSP", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo24, "VDD_2.2V_LCD", 2200000, 2200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo25, "VCC_3.3V_LCD", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "VCC_MOTOR_3.0V", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+#if defined(CONFIG_MACH_SLP_PQ)
+static struct regulator_init_data ldo24_pq11_init_data = {
+ .constraints = {
+ .name = "VDD_1.8V_TSP",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 0,
+ .boot_on = 0,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 0,
+ .disabled = 1,
+ }
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = ldo24_supply,
+};
+#endif
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+#ifdef CONFIG_SLP
+ .max_uV = 1100000,
+#else
+ .max_uV = 1050000,
+#endif
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck1),
+ .consumer_supplies = max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+#ifdef CONFIG_SLP
+ .max_uV = 1150000,
+#else
+ .max_uV = 1100000,
+#endif
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck3),
+ .consumer_supplies = max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+#ifdef CONFIG_SLP
+ .max_uV = 1100000,
+#else
+ .max_uV = 1075000,
+#endif
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck4),
+ .consumer_supplies = max77686_buck4,
+};
+
+static struct regulator_init_data max77686_buck9_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck9,
+};
+
+static struct regulator_init_data max77686_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_enp32khz),
+ .consumer_supplies = max77686_enp32khz,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_BUCK9, &max77686_buck9_data,},
+ {MAX77686_LDO3, &ldo3_init_data,},
+ {MAX77686_LDO5, &ldo5_init_data,},
+ {MAX77686_LDO8, &ldo8_init_data,},
+ {MAX77686_LDO9, &ldo9_init_data,},
+ {MAX77686_LDO10, &ldo10_init_data,},
+ {MAX77686_LDO11, &ldo11_init_data,},
+ {MAX77686_LDO12, &ldo12_init_data,},
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_C1)
+ {MAX77686_LDO13, &ldo13_init_data,},
+#endif
+ {MAX77686_LDO14, &ldo14_init_data,},
+ {MAX77686_LDO17, &ldo17_init_data,},
+ {MAX77686_LDO18, &ldo18_init_data,},
+ {MAX77686_LDO19, &ldo19_init_data,},
+ {MAX77686_LDO21, &ldo21_init_data,},
+ {MAX77686_LDO23, &ldo23_init_data,},
+ {MAX77686_LDO24, &ldo24_init_data,},
+ {MAX77686_LDO25, &ldo25_init_data,},
+ {MAX77686_LDO26, &ldo26_init_data,},
+ {MAX77686_P32KH, &max77686_enp32khz_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO3] = {MAX77686_LDO3, MAX77686_OPMODE_NORMAL},
+ [MAX77686_LDO8] = {MAX77686_LDO8, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO10] = {MAX77686_LDO10, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO12] = {MAX77686_LDO12, MAX77686_OPMODE_STANDBY},
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_C1)
+ [MAX77686_LDO13] = {MAX77686_LDO13, MAX77686_OPMODE_NORMAL},
+#endif
+ [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+struct max77686_platform_data exynos4_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+ .wtsr_smpl = MAX77686_WTSR_ENABLE | MAX77686_SMPL_ENABLE,
+
+ .buck234_gpio_dvs = {
+ /* Use DVS2 register of each bucks to supply stable power
+ * after sudden reset */
+ {GPIO_PMIC_DVS1, 1},
+ {GPIO_PMIC_DVS2, 0},
+ {GPIO_PMIC_DVS3, 0},
+ },
+ .buck234_gpio_selb = {
+ GPIO_BUCK2_SEL,
+ GPIO_BUCK3_SEL,
+ GPIO_BUCK4_SEL,
+ },
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1000000, /* 1.0V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1000000, /* 1.0V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+};
+
+void midas_power_init(void)
+{
+ printk(KERN_INFO "%s\n", __func__);
+}
+#endif /* CONFIG_REGULATOR_MAX77686 */
+
+void midas_power_set_muic_pdata(void *pdata, int gpio)
+{
+ gpio_request(gpio, "AP_PMIC_IRQ");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+#ifdef CONFIG_REGULATOR_MAX8997
+ exynos4_max8997_info.muic = pdata;
+#endif
+}
+
+void midas_power_gpio_init(void)
+{
+#ifdef CONFIG_REGULATOR_MAX8997
+ int gpio;
+
+ gpio = EXYNOS4212_GPJ1(1);
+ gpio_request(gpio, "BUCK_SET1");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = EXYNOS4212_GPJ1(2);
+ gpio_request(gpio, "BUCK_SET2");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = EXYNOS4_GPL0(0);
+ gpio_request(gpio, "BUCK_SET3");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+#endif
+}
+
+#ifdef CONFIG_MFD_MAX77693
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+static struct regulator_consumer_supply charger_supply[] = {
+ REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
+ REGULATOR_SUPPLY("vinchg1", NULL),
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 0,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct regulator_init_data charger_init_data = {
+ .constraints = {
+ .name = "CHARGER",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_CURRENT,
+ .boot_on = 1,
+ .min_uA = 60000,
+ .max_uA = 2580000,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(charger_supply),
+ .consumer_supplies = charger_supply,
+};
+
+struct max77693_regulator_data max77693_regulators[] = {
+ {MAX77693_ESAFEOUT1, &safeout1_init_data,},
+ {MAX77693_ESAFEOUT2, &safeout2_init_data,},
+ {MAX77693_CHARGER, &charger_init_data,},
+};
+
+#if defined(CONFIG_MACH_SLP_PQ)
+/* this initcall replace ldo24 from VDD 2.2 to VDD 1.8 for evt1.1 board. */
+static int __init regulator_init_with_rev(void)
+{
+ /* SLP PQ Promixa evt1.1 */
+ if (system_rev != 3) {
+ ldo24_supply[0].supply = "touch_1.8v";
+ ldo24_supply[0].dev_name = NULL;
+
+ memcpy(&ldo24_init_data, &ldo24_pq11_init_data,
+ sizeof(struct regulator_init_data));
+ }
+ return 0;
+}
+
+postcore_initcall(regulator_init_with_rev);
+#endif /* CONFIG_MACH_SLP_PQ */
+#endif /* CONFIG_MFD_MAX77693 */
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+/* S5M8767 Regulator */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_dvdd_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo20_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.0v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+
+static struct regulator_consumer_supply ldo22_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_a2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo27_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo28_supply[] = {
+ REGULATOR_SUPPLY("3_touch_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m8767_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck6 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+static struct regulator_consumer_supply s5m8767_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo9, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VT_CAM_DVDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo13, "VMIPI_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo20, "VCC_3.0V_LCD", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VCC_MOTOR_3.0V", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo22, "CAM_SENSOR_A2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo25, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo27, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo28, "3_TOUCH_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data s5m8767_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck1),
+ .consumer_supplies = s5m8767_buck1,
+};
+
+static struct regulator_init_data s5m8767_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck2,
+};
+
+static struct regulator_init_data s5m8767_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+ .max_uV = 1300000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck3),
+ .consumer_supplies = s5m8767_buck3,
+};
+
+static struct regulator_init_data s5m8767_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1150000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck4),
+ .consumer_supplies = s5m8767_buck4,
+};
+
+static struct regulator_init_data s5m8767_buck6_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck6,
+};
+
+static struct regulator_init_data s5m8767_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_enp32khz),
+ .consumer_supplies = s5m8767_enp32khz,
+};
+
+static struct s5m_regulator_data s5m8767_regulators[] = {
+ {S5M8767_BUCK1, &s5m8767_buck1_data,},
+ {S5M8767_BUCK2, &s5m8767_buck2_data,},
+ {S5M8767_BUCK3, &s5m8767_buck3_data,},
+ {S5M8767_BUCK4, &s5m8767_buck4_data,},
+ {S5M8767_BUCK6, &s5m8767_buck6_data,},
+ {S5M8767_LDO3, &ldo3_init_data,},
+ {S5M8767_LDO8, &ldo8_init_data,},
+ {S5M8767_LDO9, &ldo9_init_data,},
+ {S5M8767_LDO10, &ldo10_init_data,},
+ {S5M8767_LDO13, &ldo13_init_data,},
+ {S5M8767_LDO19, &ldo19_init_data,},
+ {S5M8767_LDO20, &ldo20_init_data,},
+ {S5M8767_LDO21, &ldo21_init_data,},
+ {S5M8767_LDO22, &ldo22_init_data,},
+ {S5M8767_LDO23, &ldo23_init_data,},
+ {S5M8767_LDO24, &ldo24_init_data,},
+ {S5M8767_LDO25, &ldo25_init_data,},
+ {S5M8767_LDO26, &ldo26_init_data,},
+ {S5M8767_LDO27, &ldo27_init_data,},
+ {S5M8767_LDO28, &ldo28_init_data,},
+};
+
+struct s5m_opmode_data s5m8767_opmode_data[S5M8767_REG_MAX] = {
+ [S5M8767_BUCK1] = {S5M8767_BUCK1, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK2] = {S5M8767_BUCK2, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK3] = {S5M8767_BUCK3, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK4] = {S5M8767_BUCK4, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK6] = {S5M8767_BUCK6, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO3] = {S5M8767_LDO3, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO8] = {S5M8767_LDO8, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO9] = {S5M8767_LDO9, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO10] = {S5M8767_LDO10, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO19] = {S5M8767_LDO19, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO20] = {S5M8767_LDO20, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO21] = {S5M8767_LDO21, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO22] = {S5M8767_LDO22, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO23] = {S5M8767_LDO23, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO24] = {S5M8767_LDO24, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO25] = {S5M8767_LDO25, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO26] = {S5M8767_LDO26, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO27] = {S5M8767_LDO27, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO28] = {S5M8767_LDO28, S5M_OPMODE_NORMAL},
+};
+
+struct s5m_platform_data exynos4_s5m8767_info = {
+ .device_type = S5M8767X,
+ .num_regulators = ARRAY_SIZE(s5m8767_regulators),
+ .regulators = s5m8767_regulators,
+ .buck2_ramp_enable = true,
+ .buck3_ramp_enable = true,
+ .buck4_ramp_enable = true,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = s5m8767_opmode_data,
+ .wtsr_smpl = 1,
+
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1100000, /* 1.1V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1100000, /* 1.1V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+
+ .buck_ramp_delay = 10,
+ .buck_default_idx = 3,
+
+ .buck_gpios[0] = GPIO_BUCK2_SEL,
+ .buck_gpios[1] = GPIO_BUCK3_SEL,
+ .buck_gpios[2] = GPIO_BUCK4_SEL,
+};
+
+void midas_power_init(void)
+{
+#ifdef CONFIG_MACH_S2PLUS
+ ldo8_init_data.constraints.always_on = 1;
+ ldo13_init_data.constraints.always_on = 1;
+#else
+ ldo8_init_data.constraints.always_on = 1;
+ ldo10_init_data.constraints.always_on = 1;
+#endif
+}
+
+/* End of S5M8767 */
+#endif
diff --git a/arch/arm/mach-exynos/midas-sensor.c b/arch/arm/mach-exynos/midas-sensor.c
new file mode 100644
index 0000000..6c8385c
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-sensor.c
@@ -0,0 +1,428 @@
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/sensor/sensors_core.h>
+#include <linux/sensor/ak8975.h>
+#include <linux/sensor/k3dh.h>
+#include <linux/sensor/gp2a.h>
+#include <linux/sensor/lsm330dlc_accel.h>
+#include <linux/sensor/lsm330dlc_gyro.h>
+#include <linux/sensor/lps331ap.h>
+#include <linux/sensor/cm36651.h>
+#include <linux/sensor/cm3663.h>
+#include <linux/sensor/bh1721.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include "midas.h"
+
+static int accel_get_position(void);
+
+static struct accel_platform_data accel_pdata = {
+ .accel_get_position = accel_get_position,
+ .axis_adjust = true,
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+#ifdef CONFIG_SENSORS_LSM330DLC
+ {
+ I2C_BOARD_INFO("lsm330dlc_accel", (0x32 >> 1)),
+ .platform_data = &accel_pdata,
+ },
+ {
+ I2C_BOARD_INFO("lsm330dlc_gyro", (0xD6 >> 1)),
+ },
+#elif defined(CONFIG_SENSORS_K3DH)
+ {
+ I2C_BOARD_INFO("k3dh", 0x19),
+ .platform_data = &accel_pdata,
+ },
+#endif
+};
+
+static int accel_get_position(void)
+{
+ int position = 0;
+
+#if defined(CONFIG_MACH_C1VZW) /* C1_SPR */
+ if (system_rev == 1)
+ position = 3; /* top/lower-left */
+ else
+ position = 2; /* top/lower-right */
+#elif defined(CONFIG_MACH_C1CTC)
+ position = 2; /* top/lower-right */
+#elif defined(CONFIG_MACH_M0_CMCC)
+ if (system_rev == 2)
+ position = 0; /* top/upper-left */
+ else
+ position = 2; /* top/lower-right */
+#elif defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT)
+ if (system_rev >= 6)
+ position = 6; /* bottom/lower-right */
+ else
+ position = 3; /* top/lower-left */
+#elif defined(CONFIG_MACH_C1_KOR_LGT)
+ if (system_rev >= 6)
+ position = 2; /* top/lower-right */
+ else if (system_rev == 5)
+ position = 4; /* bottom/upper-left */
+ else
+ position = 3; /* top/lower-left */
+#elif defined(CONFIG_MACH_S2PLUS)
+ position = 3; /* top/lower-left */
+#elif defined(CONFIG_MACH_P4NOTE)
+ position = 4; /* bottom/upper-left */
+#elif defined(CONFIG_MACH_M0)
+ if (system_rev == 3 || system_rev == 0)
+ position = 6; /* bottom/lower-right */
+ else if (system_rev == 1 || system_rev == 2\
+ || system_rev == 4 || system_rev == 5)
+ position = 0; /* top/upper-left */
+ else
+ position = 2; /* top/lower-right */
+#elif defined(CONFIG_MACH_C1)
+ if (system_rev == 3 || system_rev == 0)
+ position = 7; /* bottom/lower-left */
+ else if (system_rev == 2)
+ position = 3; /* top/lower-left */
+ else
+ position = 2; /* top/lower-right */
+#else /* Common */
+ position = 2; /* top/lower-right */
+#endif
+ return position;
+}
+
+#if defined(CONFIG_SENSORS_LSM330DLC) || \
+ defined(CONFIG_SENSORS_K3DH)
+static int accel_gpio_init(void)
+{
+ int ret = gpio_request(GPIO_ACC_INT, "accelerometer_irq");
+
+ pr_info("%s\n", __func__);
+
+ if (ret) {
+ pr_err("%s, Failed to request gpio lsm330dlc_accel_irq(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* Accelerometer sensor interrupt pin initialization */
+ s3c_gpio_cfgpin(GPIO_ACC_INT, S3C_GPIO_INPUT);
+ gpio_set_value(GPIO_ACC_INT, 2);
+ s3c_gpio_setpull(GPIO_ACC_INT, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(GPIO_ACC_INT, S5P_GPIO_DRVSTR_LV1);
+ i2c_devs1[0].irq = gpio_to_irq(GPIO_ACC_INT);
+
+ return ret;
+}
+#endif
+
+#ifdef CONFIG_SENSORS_LSM330DLC
+static int gyro_gpio_init(void)
+{
+ int ret = gpio_request(GPIO_GYRO_INT, "lsm330dlc_gyro_irq");
+
+ pr_info("%s\n", __func__);
+
+ if (ret) {
+ pr_err("%s, Failed to request gpio lsm330dlc_gyro_irq(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_GYRO_DE, "lsm330dlc_gyro_data_enable");
+
+ if (ret) {
+ pr_err("%s, Failed to request gpio lsm330dlc_gyro_data_enable(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* Gyro sensor interrupt pin initialization */
+#if 0
+ s5p_register_gpio_interrupt(GPIO_GYRO_INT);
+ s3c_gpio_cfgpin(GPIO_GYRO_INT, S3C_GPIO_SFN(0xF));
+#else
+ s3c_gpio_cfgpin(GPIO_GYRO_INT, S3C_GPIO_INPUT);
+#endif
+ gpio_set_value(GPIO_GYRO_INT, 2);
+ s3c_gpio_setpull(GPIO_GYRO_INT, S3C_GPIO_PULL_DOWN);
+ s5p_gpio_set_drvstr(GPIO_GYRO_INT, S5P_GPIO_DRVSTR_LV1);
+#if 0
+ i2c_devs1[1].irq = gpio_to_irq(GPIO_GYRO_INT); /* interrupt */
+#else
+ i2c_devs1[1].irq = -1; /* polling */
+#endif
+
+ /* Gyro sensor data enable pin initialization */
+ s3c_gpio_cfgpin(GPIO_GYRO_DE, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_GYRO_DE, 0);
+ s3c_gpio_setpull(GPIO_GYRO_DE, S3C_GPIO_PULL_DOWN);
+ s5p_gpio_set_drvstr(GPIO_GYRO_DE, S5P_GPIO_DRVSTR_LV1);
+
+ return ret;
+}
+#endif
+
+#if defined(CONFIG_SENSORS_GP2A) || defined(CONFIG_SENSORS_CM36651) || \
+ defined(CONFIG_SENSORS_CM3663)
+static int proximity_leda_on(bool onoff)
+{
+ pr_info("%s, onoff = %d\n", __func__, onoff);
+
+ gpio_set_value(GPIO_PS_ALS_EN, onoff);
+
+ return 0;
+}
+
+static int optical_gpio_init(void)
+{
+ int ret = gpio_request(GPIO_PS_ALS_EN, "optical_power_supply_on");
+
+ pr_info("%s\n", __func__);
+
+ if (ret) {
+ pr_err("%s, Failed to request gpio optical power supply(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ /* configuring for gp2a gpio for LEDA power */
+ s3c_gpio_cfgpin(GPIO_PS_ALS_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_PS_ALS_EN, 0);
+ s3c_gpio_setpull(GPIO_PS_ALS_EN, S3C_GPIO_PULL_NONE);
+ return ret;
+}
+#endif
+
+#if defined(CONFIG_SENSORS_CM36651)
+/* Depends window, threshold is needed to be set */
+static u8 cm36651_get_threshold(void)
+{
+ u8 threshold = 17;
+
+ /* Add model config and threshold here. */
+#if defined(CONFIG_MACH_M0)
+ if (system_rev >= 12)
+ threshold = 15;
+#elif defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) ||\
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ if (system_rev >= 6)
+ threshold = 13;
+#elif defined(CONFIG_MACH_C1VZW)
+ if (system_rev >= 11)
+ threshold = 13;
+#elif defined(CONFIG_MACH_C1)
+ if (system_rev >= 7)
+ threshold = 13;
+#endif
+
+ return threshold;
+}
+
+static struct cm36651_platform_data cm36651_pdata = {
+ .cm36651_led_on = proximity_leda_on,
+ .cm36651_get_threshold = cm36651_get_threshold,
+ .irq = GPIO_PS_ALS_INT,
+};
+#endif
+
+#if defined(CONFIG_SENSORS_CM3663)
+static struct cm3663_platform_data cm3663_pdata = {
+ .proximity_power = proximity_leda_on,
+};
+#endif
+
+#if defined(CONFIG_SENSORS_GP2A)
+static struct gp2a_platform_data gp2a_pdata = {
+ .gp2a_led_on = proximity_leda_on,
+ .p_out = GPIO_PS_ALS_INT,
+};
+
+static struct platform_device opt_gp2a = {
+ .name = "gp2a-opt",
+ .id = -1,
+ .dev = {
+ .platform_data = &gp2a_pdata,
+ },
+};
+#endif
+
+static struct i2c_board_info i2c_devs9_emul[] __initdata = {
+#if defined(CONFIG_SENSORS_GP2A)
+ {
+ I2C_BOARD_INFO("gp2a", (0x72 >> 1)),
+ },
+#elif defined(CONFIG_SENSORS_CM36651)
+ {
+ I2C_BOARD_INFO("cm36651", (0x30 >> 1)),
+ .platform_data = &cm36651_pdata,
+ },
+#elif defined(CONFIG_SENSORS_CM3663)
+ {
+ I2C_BOARD_INFO("cm3663", (0x20)),
+ .irq = GPIO_PS_ALS_INT,
+ .platform_data = &cm3663_pdata,
+ },
+#elif defined(CONFIG_SENSORS_BH1721)
+ {
+ I2C_BOARD_INFO("bh1721fvc", 0x23),
+ },
+#endif
+};
+
+#ifdef CONFIG_SENSORS_AK8975C
+static struct akm8975_platform_data akm8975_pdata = {
+ .gpio_data_ready_int = GPIO_MSENSOR_INT,
+};
+
+static struct i2c_board_info i2c_devs10_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak8975", 0x0C),
+ .platform_data = &akm8975_pdata,
+ },
+};
+
+static int ak8975c_gpio_init(void)
+{
+ int ret = gpio_request(GPIO_MSENSOR_INT, "gpio_akm_int");
+
+ pr_info("%s\n", __func__);
+
+ if (ret) {
+ pr_err("%s, Failed to request gpio akm_int.(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ s5p_register_gpio_interrupt(GPIO_MSENSOR_INT);
+ s3c_gpio_setpull(GPIO_MSENSOR_INT, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(GPIO_MSENSOR_INT, S3C_GPIO_SFN(0xF));
+ i2c_devs10_emul[0].irq = gpio_to_irq(GPIO_MSENSOR_INT);
+ return ret;
+}
+#endif
+
+#ifdef CONFIG_SENSORS_LPS331
+static int lps331_gpio_init(void)
+{
+ int ret = gpio_request(GPIO_BARO_INT, "lps331_irq");
+
+ pr_info("%s\n", __func__);
+
+ if (ret) {
+ pr_err("%s, Failed to request gpio lps331_irq(%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ s3c_gpio_cfgpin(GPIO_BARO_INT, S3C_GPIO_INPUT);
+ gpio_set_value(GPIO_BARO_INT, 2);
+ s3c_gpio_setpull(GPIO_BARO_INT, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(GPIO_BARO_INT, S5P_GPIO_DRVSTR_LV1);
+ return ret;
+}
+
+static struct lps331ap_platform_data lps331ap_pdata = {
+ .irq = GPIO_BARO_INT,
+};
+
+static struct i2c_board_info i2c_devs11_emul[] __initdata = {
+ {
+ I2C_BOARD_INFO("lps331ap", 0x5D),
+ .platform_data = &lps331ap_pdata,
+ },
+};
+#endif
+
+static int __init midas_sensor_init(void)
+{
+ int ret = 0;
+
+ /* Gyro & Accelerometer Sensor */
+#if defined(CONFIG_SENSORS_LSM330DLC)
+ ret = accel_gpio_init();
+ if (ret < 0) {
+ pr_err("%s, accel_gpio_init fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+ ret = gyro_gpio_init();
+ if (ret < 0) {
+ pr_err("%s, gyro_gpio_init(err=%d)\n", __func__, ret);
+ return ret;
+ }
+#elif defined(CONFIG_SENSORS_K3DH)
+ ret = accel_gpio_init();
+ if (ret < 0) {
+ pr_err("%s, accel_gpio_init fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+#endif
+ ret = i2c_add_devices(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+ if (ret < 0) {
+ pr_err("%s, i2c1 adding i2c fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+
+ /* Optical Sensor */
+#if defined(CONFIG_SENSORS_GP2A) || defined(CONFIG_SENSORS_CM36651) || \
+ defined(CONFIG_SENSORS_CM3663)
+ ret = optical_gpio_init();
+ if (ret) {
+ pr_err("%s, optical_gpio_init(err=%d)\n", __func__, ret);
+ return ret;
+ }
+ ret = i2c_add_devices(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+ if (ret < 0) {
+ pr_err("%s, i2c9 adding i2c fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+#elif defined(CONFIG_SENSORS_BH1721)
+ ret = i2c_add_devices(9, i2c_devs9_emul, ARRAY_SIZE(i2c_devs9_emul));
+ if (ret < 0) {
+ pr_err("%s, i2c9 adding i2c fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+#endif
+
+#if defined(CONFIG_SENSORS_GP2A)
+ ret = platform_device_register(&opt_gp2a);
+ if (ret < 0) {
+ pr_err("%s, failed to register opt_gp2a(err=%d)\n",
+ __func__, ret);
+ return ret;
+ }
+#endif
+
+ /* Magnetic Sensor */
+#ifdef CONFIG_SENSORS_AK8975C
+ ret = ak8975c_gpio_init();
+ if (ret < 0) {
+ pr_err("%s, ak8975c_gpio_init fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+ ret = i2c_add_devices(10, i2c_devs10_emul, ARRAY_SIZE(i2c_devs10_emul));
+ if (ret < 0) {
+ pr_err("%s, i2c10 adding i2c fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+#endif
+
+ /* Pressure Sensor */
+#ifdef CONFIG_SENSORS_LPS331
+ ret = lps331_gpio_init();
+ if (ret < 0) {
+ pr_err("%s, ak8975c_gpio_init fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+ ret = i2c_add_devices(11, i2c_devs11_emul, ARRAY_SIZE(i2c_devs11_emul));
+ if (ret < 0) {
+ pr_err("%s, i2c1 adding i2c fail(err=%d)\n", __func__, ret);
+ return ret;
+ }
+#endif
+ return ret;
+}
+module_init(midas_sensor_init);
diff --git a/arch/arm/mach-exynos/midas-sound.c b/arch/arm/mach-exynos/midas-sound.c
new file mode 100644
index 0000000..80d2d45
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-sound.c
@@ -0,0 +1,365 @@
+/*
+ * midas-sound.c - Sound Management of MIDAS Project
+ *
+ * Copyright (C) 2012 Samsung Electrnoics
+ * JS Park <aitdark.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/i2c-gpio.h>
+#include <mach/irqs.h>
+#include <mach/pmu.h>
+#include <plat/iic.h>
+
+#include <plat/gpio-cfg.h>
+#ifdef CONFIG_ARCH_EXYNOS5
+#include <mach/gpio-p10.h>
+#else
+#include <mach/gpio-midas.h>
+#endif
+
+#ifdef CONFIG_SND_SOC_WM8994
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/wm8994/gpio.h>
+#endif
+
+#ifdef CONFIG_FM34_WE395
+#include <linux/i2c/fm34_we395.h>
+#endif
+
+#ifdef CONFIG_AUDIENCE_ES305
+#include <linux/i2c/es305.h>
+#endif
+
+static bool midas_snd_mclk_enabled;
+
+#ifdef CONFIG_ARCH_EXYNOS5
+#define I2C_NUM_2MIC 4
+#define I2C_NUM_CODEC 7
+#define SET_PLATDATA_2MIC(i2c_pd) s3c_i2c4_set_platdata(i2c_pd)
+#define SET_PLATDATA_CODEC(i2c_pd) s3c_i2c7_set_platdata(i2c_pd)
+#else /* for CONFIG_ARCH_EXYNOS4 */
+#define I2C_NUM_2MIC 6
+#define I2C_NUM_CODEC 4
+#define SET_PLATDATA_2MIC(i2c_pd) s3c_i2c6_set_platdata(i2c_pd)
+#define SET_PLATDATA_CODEC(i2c_pd) s3c_i2c4_set_platdata(i2c_pd)
+#endif
+
+static DEFINE_SPINLOCK(midas_snd_spinlock);
+
+void midas_snd_set_mclk(bool on, bool forced)
+{
+ static int use_cnt;
+
+ spin_lock(&midas_snd_spinlock);
+
+ midas_snd_mclk_enabled = on;
+
+ if (midas_snd_mclk_enabled) {
+ if (use_cnt++ == 0 || forced) {
+ printk(KERN_INFO "Sound: enabled mclk\n");
+#ifdef CONFIG_ARCH_EXYNOS5
+ exynos5_pmu_xclkout_set(midas_snd_mclk_enabled,
+ XCLKOUT_XXTI);
+#else /* for CONFIG_ARCH_EXYNOS4 */
+ exynos4_pmu_xclkout_set(midas_snd_mclk_enabled,
+ XCLKOUT_XUSBXTI);
+#endif
+ mdelay(10);
+ }
+ } else {
+ if ((--use_cnt <= 0) || forced) {
+ printk(KERN_INFO "Sound: disabled mclk\n");
+#ifdef CONFIG_ARCH_EXYNOS5
+ exynos5_pmu_xclkout_set(midas_snd_mclk_enabled,
+ XCLKOUT_XXTI);
+#else /* for CONFIG_ARCH_EXYNOS4 */
+ exynos4_pmu_xclkout_set(midas_snd_mclk_enabled,
+ XCLKOUT_XUSBXTI);
+#endif
+ use_cnt = 0;
+ }
+ }
+
+ spin_unlock(&midas_snd_spinlock);
+
+ printk(KERN_INFO "Sound: state: %d, use_cnt: %d\n",
+ midas_snd_mclk_enabled, use_cnt);
+}
+
+bool midas_snd_get_mclk(void)
+{
+ return midas_snd_mclk_enabled;
+}
+
+#ifdef CONFIG_SND_SOC_WM8994
+/* vbatt_devices */
+static struct regulator_consumer_supply vbatt_supplies[] = {
+ REGULATOR_SUPPLY("LDO1VDD", NULL),
+ REGULATOR_SUPPLY("SPKVDD1", NULL),
+ REGULATOR_SUPPLY("SPKVDD2", NULL),
+};
+
+static struct regulator_init_data vbatt_initdata = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vbatt_supplies),
+ .consumer_supplies = vbatt_supplies,
+};
+
+static struct fixed_voltage_config vbatt_config = {
+ .init_data = &vbatt_initdata,
+ .microvolts = 5000000,
+ .supply_name = "VBATT",
+ .gpio = -EINVAL,
+};
+
+struct platform_device vbatt_device = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &vbatt_config,
+ },
+};
+
+/* wm1811 ldo1 */
+static struct regulator_consumer_supply wm1811_ldo1_supplies[] = {
+ REGULATOR_SUPPLY("AVDD1", NULL),
+};
+
+static struct regulator_init_data wm1811_ldo1_initdata = {
+ .constraints = {
+ .name = "WM1811 LDO1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm1811_ldo1_supplies),
+ .consumer_supplies = wm1811_ldo1_supplies,
+};
+
+/* wm1811 ldo2 */
+static struct regulator_consumer_supply wm1811_ldo2_supplies[] = {
+ REGULATOR_SUPPLY("DCVDD", NULL),
+};
+
+static struct regulator_init_data wm1811_ldo2_initdata = {
+ .constraints = {
+ .name = "WM1811 LDO2",
+ .always_on = true, /* Actually status changed by LDO1 */
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm1811_ldo2_supplies),
+ .consumer_supplies = wm1811_ldo2_supplies,
+};
+
+static struct wm8994_drc_cfg drc_value[] = {
+ {
+ .name = "voice call DRC",
+ .regs[0] = 0x009B,
+ .regs[1] = 0x0844,
+ .regs[2] = 0x00E8,
+ .regs[3] = 0x0210,
+ .regs[4] = 0x0000,
+ },
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ {
+ .name = "voice call DRC",
+ .regs[0] = 0x008c,
+ .regs[1] = 0x0253,
+ .regs[2] = 0x0028,
+ .regs[3] = 0x028a,
+ .regs[4] = 0x0000,
+ },
+#endif
+};
+
+static struct wm8994_pdata wm1811_pdata = {
+ .gpio_defaults = {
+ [0] = WM8994_GP_FN_IRQ, /* GPIO1 IRQ output, CMOS mode */
+ [7] = WM8994_GPN_DIR | WM8994_GP_FN_PIN_SPECIFIC, /* DACDAT3 */
+ [8] = WM8994_CONFIGURE_GPIO |
+ WM8994_GP_FN_PIN_SPECIFIC, /* ADCDAT3 */
+ [9] = WM8994_CONFIGURE_GPIO |\
+ WM8994_GP_FN_PIN_SPECIFIC, /* LRCLK3 */
+ [10] = WM8994_CONFIGURE_GPIO |\
+ WM8994_GP_FN_PIN_SPECIFIC, /* BCLK3 */
+ },
+
+ .irq_base = IRQ_BOARD_CODEC_START,
+
+ /* The enable is shared but assign it to LDO1 for software */
+ .ldo = {
+ {
+ .enable = GPIO_WM8994_LDO,
+ .init_data = &wm1811_ldo1_initdata,
+ },
+ {
+ .init_data = &wm1811_ldo2_initdata,
+ },
+ },
+ /* Apply DRC Value */
+ .drc_cfgs = drc_value,
+ .num_drc_cfgs = ARRAY_SIZE(drc_value),
+
+ /* Support external capacitors*/
+ .jd_ext_cap = 1,
+
+ /* Regulated mode at highest output voltage */
+ .micbias = {0x2f, 0x27},
+
+ .micd_lvl_sel = 0xFF,
+
+ .ldo_ena_always_driven = true,
+ .ldo_ena_delay = 30000,
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ .lineout2_diff = 0,
+#endif
+#ifdef CONFIG_MACH_C1
+ .lineout1fb = 0,
+#else
+ .lineout1fb = 1,
+#endif
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1_KOR_SKT) || \
+ defined(CONFIG_MACH_C1_KOR_KT) || defined(CONFIG_MACH_C1_KOR_LGT) || \
+ defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_GC1)
+ .lineout2fb = 0,
+#else
+ .lineout2fb = 1,
+#endif
+};
+
+static struct i2c_board_info i2c_wm1811[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm1811", (0x34 >> 1)), /* Audio CODEC */
+ .platform_data = &wm1811_pdata,
+ .irq = IRQ_EINT(30),
+ },
+};
+
+#endif
+
+#ifdef CONFIG_FM34_WE395
+static struct fm34_platform_data fm34_we395_pdata = {
+ .gpio_pwdn = GPIO_FM34_PWDN,
+ .gpio_rst = GPIO_FM34_RESET,
+ .gpio_bp = GPIO_FM34_BYPASS,
+ .set_mclk = midas_snd_set_mclk,
+};
+#ifdef CONFIG_MACH_C1_KOR_LGT
+static struct fm34_platform_data fm34_we395_pdata_rev05 = {
+ .gpio_pwdn = GPIO_FM34_PWDN,
+ .gpio_rst = GPIO_FM34_RESET_05,
+ .gpio_bp = GPIO_FM34_BYPASS_05,
+ .set_mclk = midas_snd_set_mclk,
+};
+#endif
+static struct i2c_board_info i2c_2mic[] __initdata = {
+ {
+ I2C_BOARD_INFO("fm34_we395", (0xC0 >> 1)), /* 2MIC */
+ .platform_data = &fm34_we395_pdata,
+ },
+};
+
+#if defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_C1VZW)
+static struct i2c_gpio_platform_data gpio_i2c_fm34 = {
+ .sda_pin = GPIO_FM34_SDA,
+ .scl_pin = GPIO_FM34_SCL,
+};
+
+struct platform_device s3c_device_fm34 = {
+ .name = "i2c-gpio",
+ .id = I2C_NUM_2MIC,
+ .dev.platform_data = &gpio_i2c_fm34,
+};
+#endif
+#endif
+
+#ifdef CONFIG_AUDIENCE_ES305
+static struct es305_platform_data es305_pdata = {
+ .gpio_wakeup = GPIO_ES305_WAKEUP,
+ .gpio_reset = GPIO_ES305_RESET,
+ .set_mclk = midas_snd_set_mclk,
+};
+
+static struct i2c_board_info i2c_2mic[] __initdata = {
+ {
+ I2C_BOARD_INFO("audience_es305", 0x3E), /* 2MIC */
+ .platform_data = &es305_pdata,
+ },
+};
+#endif
+
+static struct platform_device *midas_sound_devices[] __initdata = {
+#if defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_C1VZW)
+#ifdef CONFIG_FM34_WE395
+ &s3c_device_fm34,
+#endif
+#endif
+};
+
+void __init midas_sound_init(void)
+{
+ printk(KERN_INFO "Sound: start %s\n", __func__);
+
+ platform_add_devices(midas_sound_devices,
+ ARRAY_SIZE(midas_sound_devices));
+
+#ifdef CONFIG_ARCH_EXYNOS5
+#ifndef CONFIG_MACH_P10_LTE_00_BD
+ i2c_wm1811[0].irq = IRQ_EINT(29);
+#endif
+ SET_PLATDATA_CODEC(NULL);
+ i2c_register_board_info(I2C_NUM_CODEC, i2c_wm1811,
+ ARRAY_SIZE(i2c_wm1811));
+#else /* for CONFIG_ARCH_EXYNOS4 */
+#ifdef CONFIG_MACH_P4NOTE
+ i2c_wm1811[0].irq = 0;
+ SET_PLATDATA_CODEC(NULL);
+ i2c_register_board_info(I2C_NUM_CODEC, i2c_wm1811,
+ ARRAY_SIZE(i2c_wm1811));
+
+#else
+ if (system_rev != 3 && system_rev >= 0) {
+ SET_PLATDATA_CODEC(NULL);
+ i2c_register_board_info(I2C_NUM_CODEC, i2c_wm1811,
+ ARRAY_SIZE(i2c_wm1811));
+ }
+#endif
+#endif/* CONFIG_ARCH_EXYNOS5 */
+
+#ifdef CONFIG_FM34_WE395
+ midas_snd_set_mclk(true, false);
+ SET_PLATDATA_2MIC(NULL);
+
+#if defined(CONFIG_MACH_C1_KOR_LGT)
+ if (system_rev > 5)
+ i2c_2mic[0].platform_data = &fm34_we395_pdata_rev05;
+#endif
+
+ i2c_register_board_info(I2C_NUM_2MIC, i2c_2mic, ARRAY_SIZE(i2c_2mic));
+#endif
+
+
+#ifdef CONFIG_AUDIENCE_ES305
+ midas_snd_set_mclk(true, false);
+ SET_PLATDATA_2MIC(NULL);
+ i2c_register_board_info(I2C_NUM_2MIC, i2c_2mic, ARRAY_SIZE(i2c_2mic));
+#endif
+}
diff --git a/arch/arm/mach-exynos/midas-thermistor.c b/arch/arm/mach-exynos/midas-thermistor.c
new file mode 100644
index 0000000..999a56e
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-thermistor.c
@@ -0,0 +1,600 @@
+/*
+ * midas-thermistor.c - thermistor of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * SangYoung Son <hello.son@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <mach/midas-thermistor.h>
+#ifdef CONFIG_SEC_THERMISTOR
+#include <mach/sec_thermistor.h>
+#endif
+
+#ifdef CONFIG_S3C_ADC
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_P4NOTE)
+static struct adc_table_data ap_adc_temper_table_battery[] = {
+ { 204, 800 },
+ { 210, 790 },
+ { 216, 780 },
+ { 223, 770 },
+ { 230, 760 },
+ { 237, 750 },
+ { 244, 740 },
+ { 252, 730 },
+ { 260, 720 },
+ { 268, 710 },
+ { 276, 700 },
+ { 285, 690 },
+ { 294, 680 },
+ { 303, 670 },
+ { 312, 660 },
+ { 322, 650 },
+ { 332, 640 },
+ { 342, 630 },
+ { 353, 620 },
+ { 364, 610 },
+ { 375, 600 },
+ { 387, 590 },
+ { 399, 580 },
+ { 411, 570 },
+ { 423, 560 },
+ { 436, 550 },
+ { 450, 540 },
+ { 463, 530 },
+ { 477, 520 },
+ { 492, 510 },
+ { 507, 500 },
+ { 522, 490 },
+ { 537, 480 },
+ { 553, 470 },
+ { 569, 460 },
+ { 586, 450 },
+ { 603, 440 },
+ { 621, 430 },
+ { 638, 420 },
+ { 657, 410 },
+ { 675, 400 },
+ { 694, 390 },
+ { 713, 380 },
+ { 733, 370 },
+ { 753, 360 },
+ { 773, 350 },
+ { 794, 340 },
+ { 815, 330 },
+ { 836, 320 },
+ { 858, 310 },
+ { 880, 300 },
+ { 902, 290 },
+ { 924, 280 },
+ { 947, 270 },
+ { 969, 260 },
+ { 992, 250 },
+ { 1015, 240 },
+ { 1039, 230 },
+ { 1062, 220 },
+ { 1086, 210 },
+ { 1109, 200 },
+ { 1133, 190 },
+ { 1156, 180 },
+ { 1180, 170 },
+ { 1204, 160 },
+ { 1227, 150 },
+ { 1250, 140 },
+ { 1274, 130 },
+ { 1297, 120 },
+ { 1320, 110 },
+ { 1343, 100 },
+ { 1366, 90 },
+ { 1388, 80 },
+ { 1410, 70 },
+ { 1432, 60 },
+ { 1454, 50 },
+ { 1475, 40 },
+ { 1496, 30 },
+ { 1516, 20 },
+ { 1536, 10 },
+ { 1556, 0 },
+ { 1576, -10 },
+ { 1595, -20 },
+ { 1613, -30 },
+ { 1631, -40 },
+ { 1649, -50 },
+ { 1666, -60 },
+ { 1683, -70 },
+ { 1699, -80 },
+ { 1714, -90 },
+ { 1730, -100 },
+ { 1744, -110 },
+ { 1759, -120 },
+ { 1773, -130 },
+ { 1786, -140 },
+ { 1799, -150 },
+ { 1811, -160 },
+ { 1823, -170 },
+ { 1835, -180 },
+ { 1846, -190 },
+ { 1856, -200 },
+};
+#elif defined(CONFIG_MACH_C1)
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+static struct adc_table_data ap_adc_temper_table_battery[] = {
+ { 178, 800 },
+ { 186, 790 },
+ { 193, 780 },
+ { 198, 770 },
+ { 204, 760 },
+ { 210, 750 },
+ { 220, 740 },
+ { 226, 730 },
+ { 232, 720 },
+ { 247, 710 },
+ { 254, 700 },
+ { 261, 690 },
+ { 270, 680 },
+ { 278, 670 },
+ { 285, 660 },
+ { 292, 650 },
+ { 304, 640 },
+ { 319, 630 },
+ { 325, 620 },
+ { 331, 610 },
+ { 343, 600 },
+ { 354, 590 },
+ { 373, 580 },
+ { 387, 570 },
+ { 392, 560 },
+ { 408, 550 },
+ { 422, 540 },
+ { 433, 530 },
+ { 452, 520 },
+ { 466, 510 },
+ { 479, 500 },
+ { 497, 490 },
+ { 510, 480 },
+ { 529, 470 },
+ { 545, 460 },
+ { 562, 450 },
+ { 578, 440 },
+ { 594, 430 },
+ { 620, 420 },
+ { 632, 410 },
+ { 651, 400 },
+ { 663, 390 },
+ { 681, 380 },
+ { 705, 370 },
+ { 727, 360 },
+ { 736, 350 },
+ { 778, 340 },
+ { 793, 330 },
+ { 820, 320 },
+ { 834, 310 },
+ { 859, 300 },
+ { 872, 290 },
+ { 891, 280 },
+ { 914, 270 },
+ { 939, 260 },
+ { 951, 250 },
+ { 967, 240 },
+ { 999, 230 },
+ { 1031, 220 },
+ { 1049, 210 },
+ { 1073, 200 },
+ { 1097, 190 },
+ { 1128, 180 },
+ { 1140, 170 },
+ { 1171, 160 },
+ { 1188, 150 },
+ { 1198, 140 },
+ { 1223, 130 },
+ { 1236, 120 },
+ { 1274, 110 },
+ { 1290, 100 },
+ { 1312, 90 },
+ { 1321, 80 },
+ { 1353, 70 },
+ { 1363, 60 },
+ { 1404, 50 },
+ { 1413, 40 },
+ { 1444, 30 },
+ { 1461, 20 },
+ { 1470, 10 },
+ { 1516, 0 },
+ { 1522, -10 },
+ { 1533, -20 },
+ { 1540, -30 },
+ { 1558, -40 },
+ { 1581, -50 },
+ { 1595, -60 },
+ { 1607, -70 },
+ { 1614, -80 },
+ { 1627, -90 },
+ { 1655, -100 },
+ { 1664, -110 },
+ { 1670, -120 },
+ { 1676, -130 },
+ { 1692, -140 },
+ { 1713, -150 },
+ { 1734, -160 },
+ { 1746, -170 },
+ { 1789, -180 },
+ { 1805, -190 },
+ { 1824, -200 },
+};
+#else
+static struct adc_table_data ap_adc_temper_table_battery[] = {
+ { 305, 650 },
+ { 566, 430 },
+ { 1494, 0 },
+ { 1571, -50 },
+};
+#endif
+#elif defined(CONFIG_MACH_S2PLUS)
+static struct adc_table_data ap_adc_temper_table_battery[] = {
+ { 305, 650 },
+ { 566, 430 },
+ { 1494, 0 },
+ { 1571, -50 },
+};
+#else /* sample */
+static struct adc_table_data ap_adc_temper_table_battery[] = {
+ { 305, 650 },
+ { 566, 430 },
+ { 1494, 0 },
+ { 1571, -50 },
+};
+#endif
+
+int convert_adc(int adc_data, int channel)
+{
+ int adc_value;
+ int low, mid, high;
+ struct adc_table_data *temper_table = NULL;
+ pr_debug("%s\n", __func__);
+
+ low = mid = high = 0;
+ switch (channel) {
+ case 1:
+ temper_table = ap_adc_temper_table_battery;
+ high = ARRAY_SIZE(ap_adc_temper_table_battery) - 1;
+ break;
+ case 2:
+ temper_table = ap_adc_temper_table_battery;
+ high = ARRAY_SIZE(ap_adc_temper_table_battery) - 1;
+ break;
+ default:
+ pr_info("%s: not exist temper table for ch(%d)\n", __func__,
+ channel);
+ return -EINVAL;
+ break;
+ }
+
+ /* Out of table range */
+ if (adc_data <= temper_table[low].adc) {
+ adc_value = temper_table[low].value;
+ return adc_value;
+ } else if (adc_data >= temper_table[high].adc) {
+ adc_value = temper_table[high].value;
+ return adc_value;
+ }
+
+ while (low <= high) {
+ mid = (low + high) / 2;
+ if (temper_table[mid].adc > adc_data)
+ high = mid - 1;
+ else if (temper_table[mid].adc < adc_data)
+ low = mid + 1;
+ else
+ break;
+ }
+ adc_value = temper_table[mid].value;
+
+ /* high resolution */
+ if (adc_data < temper_table[mid].adc)
+ adc_value = temper_table[mid].value +
+ ((temper_table[mid-1].value - temper_table[mid].value) *
+ (temper_table[mid].adc - adc_data) /
+ (temper_table[mid].adc - temper_table[mid-1].adc));
+ else
+ adc_value = temper_table[mid].value -
+ ((temper_table[mid].value - temper_table[mid+1].value) *
+ (adc_data - temper_table[mid].adc) /
+ (temper_table[mid+1].adc - temper_table[mid].adc));
+
+ pr_debug("%s: adc data(%d), adc value(%d)\n", __func__,
+ adc_data, adc_value);
+ return adc_value;
+
+}
+#endif
+
+#ifdef CONFIG_SEC_THERMISTOR
+static struct sec_therm_adc_table temper_table_ap[] = {
+ {196, 700},
+ {211, 690},
+ {242, 685},
+ {249, 680},
+ {262, 670},
+ {275, 660},
+ {288, 650},
+ {301, 640},
+ {314, 630},
+ {328, 620},
+ {341, 610},
+ {354, 600},
+ {366, 590},
+ {377, 580},
+ {389, 570},
+ {404, 560},
+ {419, 550},
+ {434, 540},
+ {452, 530},
+ {469, 520},
+ {487, 510},
+ {498, 500},
+ {509, 490},
+ {520, 480},
+ {529, 460},
+ {538, 470},
+ {547, 450},
+ {556, 440},
+ {564, 430},
+ {573, 420},
+ {581, 410},
+ {590, 400},
+ {615, 390},
+ {640, 380},
+ {665, 370},
+ {690, 360},
+ {715, 350},
+ {736, 340},
+ {758, 330},
+ {779, 320},
+ {801, 310},
+ {822, 300},
+};
+
+/* when the next level is same as prev, returns -1 */
+static int get_midas_siop_level(int temp)
+{
+ static int prev_temp = 400;
+ static int prev_level = 0;
+ int level = -1;
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ if (temp > prev_temp) {
+ if (temp >= 490)
+ level = 4;
+ else if (temp >= 480)
+ level = 3;
+ else if (temp >= 450)
+ level = 2;
+ else if (temp >= 420)
+ level = 1;
+ else
+ level = 0;
+ } else {
+ if (temp < 400)
+ level = 0;
+ else if (temp < 420)
+ level = 1;
+ else if (temp < 450)
+ level = 2;
+ else if (temp < 480)
+ level = 3;
+ else
+ level = 4;
+
+ if (level > prev_level)
+ level = prev_level;
+ }
+#elif defined(CONFIG_MACH_P4NOTE)
+ if (temp > prev_temp) {
+ if (temp >= 620)
+ level = 4;
+ else if (temp >= 610)
+ level = 3;
+ else if (temp >= 580)
+ level = 2;
+ else if (temp >= 550)
+ level = 1;
+ else
+ level = 0;
+ } else {
+ if (temp < 520)
+ level = 0;
+ else if (temp < 550)
+ level = 1;
+ else if (temp < 580)
+ level = 2;
+ else if (temp < 610)
+ level = 3;
+ else
+ level = 4;
+
+ if (level > prev_level)
+ level = prev_level;
+ }
+#else
+ if (temp > prev_temp) {
+ if (temp >= 540)
+ level = 4;
+ else if (temp >= 530)
+ level = 3;
+ else if (temp >= 480)
+ level = 2;
+ else if (temp >= 440)
+ level = 1;
+ else
+ level = 0;
+ } else {
+ if (temp < 410)
+ level = 0;
+ else if (temp < 440)
+ level = 1;
+ else if (temp < 480)
+ level = 2;
+ else if (temp < 530)
+ level = 3;
+ else
+ level = 4;
+
+ if (level > prev_level)
+ level = prev_level;
+ }
+#endif
+
+ prev_temp = temp;
+ if (prev_level == level)
+ return -1;
+
+ prev_level = level;
+
+ return level;
+}
+
+static struct sec_therm_platform_data sec_therm_pdata = {
+ .adc_channel = 1,
+ .adc_arr_size = ARRAY_SIZE(temper_table_ap),
+ .adc_table = temper_table_ap,
+ .polling_interval = 30 * 1000, /* msecs */
+ .get_siop_level = get_midas_siop_level,
+};
+
+struct platform_device sec_device_thermistor = {
+ .name = "sec-thermistor",
+ .id = -1,
+ .dev.platform_data = &sec_therm_pdata,
+};
+#endif
+
+#ifdef CONFIG_STMPE811_ADC
+/* temperature table for ADC ch7 */
+static struct adc_table_data temper_table_battery[] = {
+ { 1856, -20 },
+ { 1846, -19 },
+ { 1835, -18 },
+ { 1823, -17 },
+ { 1811, -16 },
+ { 1799, -15 },
+ { 1786, -14 },
+ { 1773, -13 },
+ { 1759, -12 },
+ { 1744, -11 },
+ { 1730, -10 },
+ { 1714, -9 },
+ { 1699, -8 },
+ { 1683, -7 },
+ { 1666, -6 },
+ { 1649, -5 },
+ { 1631, -4 },
+ { 1613, -3 },
+ { 1595, -2 },
+ { 1576, -1 },
+ { 1556, 0 },
+ { 1536, 1 },
+ { 1516, 2 },
+ { 1496, 3 },
+ { 1475, 4 },
+ { 1454, 5 },
+ { 1432, 6 },
+ { 1410, 7 },
+ { 1388, 8 },
+ { 1366, 9 },
+ { 1343, 10 },
+ { 1320, 11 },
+ { 1297, 12 },
+ { 1274, 13 },
+ { 1250, 14 },
+ { 1227, 15 },
+ { 1204, 16 },
+ { 1180, 17 },
+ { 1156, 18 },
+ { 1133, 19 },
+ { 1109, 20 },
+ { 1086, 21 },
+ { 1062, 22 },
+ { 1039, 23 },
+ { 1015, 24 },
+ { 992, 25 },
+ { 969, 26 },
+ { 947, 27 },
+ { 924, 28 },
+ { 902, 29 },
+ { 880, 30 },
+ { 858, 31 },
+ { 836, 32 },
+ { 815, 33 },
+ { 794, 34 },
+ { 773, 35 },
+ { 753, 36 },
+ { 733, 37 },
+ { 713, 38 },
+ { 694, 39 },
+ { 675, 40 },
+ { 657, 41 },
+ { 638, 42 },
+ { 621, 43 },
+ { 603, 44 },
+ { 586, 45 },
+ { 569, 46 },
+ { 553, 47 },
+ { 537, 48 },
+ { 522, 49 },
+ { 507, 50 },
+ { 492, 51 },
+ { 477, 52 },
+ { 463, 53 },
+ { 450, 54 },
+ { 436, 55 },
+ { 423, 56 },
+ { 411, 57 },
+ { 399, 58 },
+ { 387, 59 },
+ { 375, 60 },
+ { 364, 61 },
+ { 353, 62 },
+ { 342, 63 },
+ { 332, 64 },
+ { 322, 65 },
+ { 312, 66 },
+ { 303, 67 },
+ { 294, 68 },
+ { 285, 69 },
+ { 276, 70 },
+ { 268, 71 },
+ { 260, 72 },
+ { 252, 73 },
+ { 244, 74 },
+ { 237, 75 },
+ { 230, 76 },
+ { 223, 77 },
+ { 216, 78 },
+ { 210, 79 },
+ { 204, 80 },
+};
+
+struct stmpe811_platform_data stmpe811_pdata = {
+ .adc_table_ch4 = temper_table_battery,
+ .table_size_ch4 = ARRAY_SIZE(temper_table_battery),
+ .adc_table_ch7 = temper_table_battery,
+ .table_size_ch7 = ARRAY_SIZE(temper_table_battery),
+
+ .irq_gpio = GPIO_ADC_INT,
+};
+#endif
+
diff --git a/arch/arm/mach-exynos/midas-tsp.c b/arch/arm/mach-exynos/midas-tsp.c
new file mode 100644
index 0000000..e3361c6
--- /dev/null
+++ b/arch/arm/mach-exynos/midas-tsp.c
@@ -0,0 +1,1095 @@
+/*
+ * linux/arch/arm/mach-exynos/midas-tsp.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1)
+#include <linux/delay.h>
+#include <linux/i2c/mxt224_u1.h>
+#elif defined(CONFIG_TOUCHSCREEN_MELFAS_GC)
+#include <linux/platform_data/mms_ts_gc.h>
+#else
+#include <linux/platform_data/mms_ts.h>
+#endif
+#include <linux/regulator/consumer.h>
+#include <plat/gpio-cfg.h>
+
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+#include <linux/cpufreq.h>
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1)
+/* mxt224 TSP */
+extern bool is_cable_attached;
+
+static struct charging_status_callbacks {
+ void (*tsp_set_charging_cable) (int type);
+} charging_cbs;
+
+void tsp_register_callback(void *function)
+{
+ charging_cbs.tsp_set_charging_cable = function;
+}
+
+void tsp_read_ta_status(void *ta_status)
+{
+ *(bool *) ta_status = is_cable_attached;
+}
+
+static void mxt224_power_on(void)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "touch");
+ if (IS_ERR(regulator))
+ return;
+
+ regulator_enable(regulator);
+ printk(KERN_INFO "[TSP] melfas power on\n");
+
+ regulator_put(regulator);
+
+ mdelay(70);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ mdelay(40);
+ printk(KERN_INFO "mxt224_power_on is finished\n");
+}
+
+EXPORT_SYMBOL(mxt224_power_on);
+
+static void mxt224_power_off(void)
+{
+ struct regulator *regulator;
+
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_DOWN);
+
+ regulator = regulator_get(NULL, "touch");
+ if (IS_ERR(regulator))
+ return;
+
+ regulator_disable(regulator);
+
+ regulator_put(regulator);
+
+ printk(KERN_INFO "mxt224_power_off is finished\n");
+}
+
+EXPORT_SYMBOL(mxt224_power_off);
+
+/*
+ Configuration for MXT224
+*/
+#define MXT224_THRESHOLD_BATT 40
+#define MXT224_THRESHOLD_BATT_INIT 55
+#define MXT224_THRESHOLD_CHRG 70
+#define MXT224_NOISE_THRESHOLD_BATT 30
+#define MXT224_NOISE_THRESHOLD_CHRG 40
+#define MXT224_MOVFILTER_BATT 11
+#define MXT224_MOVFILTER_CHRG 46
+#define MXT224_ATCHCALST 9
+#define MXT224_ATCHCALTHR 30
+
+static u8 t7_config[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config[] = { GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, MXT224_ATCHCALST, MXT224_ATCHCALTHR
+}; /*byte 3: 0 */
+
+static u8 t9_config[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, MXT224_THRESHOLD_BATT, 2, 1,
+ 0,
+ 15, /* MOVHYSTI */
+ 1, MXT224_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 0, 0, 0, 0, 143, 55, 143, 90, 18
+};
+
+static u8 t18_config[] = { SPT_COMCONFIG_T18,
+ 0, 1
+};
+
+static u8 t20_config[] = { PROCI_GRIPFACESUPPRESSION_T20,
+ 7, 0, 0, 0, 0, 0, 0, 30, 20, 4, 15, 10
+};
+
+static u8 t22_config[] = { PROCG_NOISESUPPRESSION_T22,
+ 143, 0, 0, 0, 0, 0, 0, 3, MXT224_NOISE_THRESHOLD_BATT, 0, 0, 29, 34, 39,
+ 49, 58, 3
+};
+
+static u8 t28_config[] = { SPT_CTECONFIG_T28,
+ 0, 0, 3, 16, 19, 60
+};
+static u8 end_config[] = { RESERVED_T255 };
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t18_config,
+ t20_config,
+ t22_config,
+ t28_config,
+ end_config,
+};
+
+/*
+ Configuration for MXT224-E
+*/
+#define MXT224E_THRESHOLD_BATT 50
+#define MXT224E_THRESHOLD_CHRG 40
+#define MXT224E_CALCFG_BATT 0x42
+#define MXT224E_CALCFG_CHRG 0x52
+#define MXT224E_ATCHFRCCALTHR_NORMAL 40
+#define MXT224E_ATCHFRCCALRATIO_NORMAL 55
+#define MXT224E_GHRGTIME_BATT 27
+#define MXT224E_GHRGTIME_CHRG 22
+#define MXT224E_ATCHCALST 4
+#define MXT224E_ATCHCALTHR 35
+#define MXT224E_BLEN_BATT 32
+#define MXT224E_BLEN_CHRG 16
+#define MXT224E_MOVFILTER_BATT 46
+#define MXT224E_MOVFILTER_CHRG 46
+#define MXT224E_ACTVSYNCSPERX_NORMAL 32
+#define MXT224E_NEXTTCHDI_NORMAL 0
+
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 25
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 8, 8, 8, 180
+};
+
+/* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 1,
+ 10, 3, 1, 11, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 188, 52, 124, 21, 188, 52, 124, 21, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 32, 120, 100, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, 35, 0, 0, 1, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 4, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 5, 0, 38, 0, 5,
+ 0, 0, 0, 0, 0, 0, 32, 50, 2, 3, 1, 11, 10, 5, 40, 10, 10,
+ 10, 10, 143, 40, 143, 80, 18, 15, 2
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 0, 0, 100, 4, 64, 10, 0, 20, 5, 0, 38, 0, 20,
+ 0, 0, 0, 0, 0, 0, 16, 70, 2, 5, 2, 46, 10, 5, 40, 10, 0,
+ 10, 10, 143, 40, 143, 80, 18, 15, 2
+};
+
+#elif defined(CONFIG_MACH_U1_NA_SPR_EPIC2_REV00)
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, 255, 15
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 4, 35, 40, 55
+};
+
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, 50, 2, 7,
+ 10, 3, 1, 46, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 32, 120, 100, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, 48, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 4, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0,
+ 0, 0, 0, 0, 32, 50, 2, 3, 1, 46,
+ 10, 5, 40, 10, 10, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 80, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 16, 70, 2, 5, 2, 46,
+ 10, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+#else
+
+static u8 t7_config_e[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config_e[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT224E_GHRGTIME_BATT, 0, 5, 1, 0, 0,
+ MXT224E_ATCHCALST, MXT224E_ATCHCALTHR,
+ MXT224E_ATCHFRCCALTHR_NORMAL,
+ MXT224E_ATCHFRCCALRATIO_NORMAL
+};
+
+/* MXT224E_0V5_CONFIG */
+/* NEXTTCHDI added */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 0
+};
+
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 10, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 2
+};
+#endif
+#else
+static u8 t9_config_e[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, MXT224E_BLEN_BATT, MXT224E_THRESHOLD_BATT, 2, 1,
+ 10,
+ 15, /* MOVHYSTI */
+ 1, MXT224E_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 31, 3,
+ 223, 1, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, MXT224E_NEXTTCHDI_NORMAL
+};
+#endif
+
+static u8 t15_config_e[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t18_config_e[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t23_config_e[] = { TOUCH_PROXIMITY_T23,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_e[] = { SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 13, 19, 44, 0, 0, 0
+};
+#else
+static u8 t38_config_e[] = { SPT_USERDATA_T38,
+ 0, 1, 14, 23, 44, 0, 0, 0
+};
+#endif
+
+static u8 t40_config_e[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_e[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t46_config_e[] = { SPT_CTECONFIG_T46,
+ 0, 3, 16, MXT224E_ACTVSYNCSPERX_NORMAL, 0, 0, 1, 0, 0
+};
+
+static u8 t47_config_e[] = { PROCI_STYLUS_T47,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*MXT224E_0V5_CONFIG */
+#ifdef CONFIG_TARGET_LOCALE_NA
+#ifdef CONFIG_MACH_U1_NA_USCC_REV05
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x52, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 10, 5, 0, 19, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 47,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x40, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#else
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x50, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2, /*blen=0,threshold=50 */
+ 10, /* MOVHYSTI */
+ 1, 15,
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 10, 2
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 1, 4, 0x40, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, 50, 2,
+ 10,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 0, 10, 10, 143, 40, 143,
+ 80, 18, 15, 2
+};
+#endif /*CONFIG_MACH_U1_NA_USCC_REV05 */
+#else
+static u8 t48_config_chrg_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_CHRG, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 9, 5, 0, 15, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, MXT224E_THRESHOLD_CHRG, 2,
+ 15, /* MOVHYSTI */
+ 1, 47,
+ MXT224_MAX_MT_FINGERS, 5, 40, 235, 235, 10, 10, 160, 50, 143,
+ 80, 18, 10, 0
+};
+
+static u8 t48_config_e[] = { PROCG_NOISESUPPRESSION_T48,
+ 3, 132, MXT224E_CALCFG_BATT, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 48, 4, 48,
+ 10, 0, 10, 5, 0, 20, 0, 5, 0, 0, /*byte 27 original value 20 */
+ 0, 0, 0, 0, 32, MXT224E_THRESHOLD_BATT, 2,
+ 15,
+ 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 10, 10, 10, 143, 40, 143,
+ 80, 18, 15, 0
+};
+#endif /*CONFIG_TARGET_LOCALE_NA */
+#endif /*CONFIG_TARGET_LOCALE_NAATT */
+
+static u8 end_config_e[] = { RESERVED_T255 };
+
+static const u8 *mxt224e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t23_config_e,
+ t25_config_e,
+ t38_config_e,
+ t40_config_e,
+ t42_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ end_config_e,
+};
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = MXT224_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config = mxt224_config,
+ .config_e = mxt224e_config,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .min_x = 0,
+ .max_x = 479,
+ .min_y = 0,
+ .max_y = 799,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .atchcalst = MXT224_ATCHCALST,
+ .atchcalsthr = MXT224_ATCHCALTHR,
+ .tchthr_batt = MXT224_THRESHOLD_BATT,
+ .tchthr_batt_init = MXT224_THRESHOLD_BATT_INIT,
+ .tchthr_charging = MXT224_THRESHOLD_CHRG,
+ .noisethr_batt = MXT224_NOISE_THRESHOLD_BATT,
+ .noisethr_charging = MXT224_NOISE_THRESHOLD_CHRG,
+ .movfilter_batt = MXT224_MOVFILTER_BATT,
+ .movfilter_charging = MXT224_MOVFILTER_CHRG,
+ .atchcalst_e = MXT224E_ATCHCALST,
+ .atchcalsthr_e = MXT224E_ATCHCALTHR,
+ .tchthr_batt_e = MXT224E_THRESHOLD_BATT,
+ .tchthr_charging_e = MXT224E_THRESHOLD_CHRG,
+ .calcfg_batt_e = MXT224E_CALCFG_BATT,
+ .calcfg_charging_e = MXT224E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT224E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT224E_ATCHFRCCALRATIO_NORMAL,
+ .chrgtime_batt_e = MXT224E_GHRGTIME_BATT,
+ .chrgtime_charging_e = MXT224E_GHRGTIME_CHRG,
+ .blen_batt_e = MXT224E_BLEN_BATT,
+ .blen_charging_e = MXT224E_BLEN_CHRG,
+ .movfilter_batt_e = MXT224E_MOVFILTER_BATT,
+ .movfilter_charging_e = MXT224E_MOVFILTER_CHRG,
+ .actvsyncsperx_e = MXT224E_ACTVSYNCSPERX_NORMAL,
+ .nexttchdi_e = MXT224E_NEXTTCHDI_NORMAL,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+
+void mxt224_set_touch_i2c(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_UP);
+ gpio_free(GPIO_TSP_SDA_18V);
+ gpio_free(GPIO_TSP_SCL_18V);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ /* s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); */
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+}
+
+void mxt224_set_touch_i2c_to_gpio(void)
+{
+ int ret;
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_UP);
+ ret = gpio_request(GPIO_TSP_SDA_18V, "GPIO_TSP_SDA");
+ if (ret)
+ pr_err("failed to request gpio(GPIO_TSP_SDA)\n");
+ ret = gpio_request(GPIO_TSP_SCL_18V, "GPIO_TSP_SCL");
+ if (ret)
+ pr_err("failed to request gpio(GPIO_TSP_SCL)\n");
+}
+
+/* I2C3 */
+static struct i2c_board_info i2c_devs3[] __initdata = {
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4a),
+ .platform_data = &mxt224_data},
+};
+
+#ifndef CONFIG_MACH_NEWTON_BD
+void midas_tsp_set_platdata(struct mxt224_platform_data *pdata)
+{
+ if (!pdata)
+ pdata = &mxt224_data;
+
+ i2c_devs3[0].platform_data = pdata;
+}
+#endif
+
+void __init midas_tsp_init(void)
+{
+#ifndef CONFIG_MACH_NEWTON_BD
+ int gpio;
+ int ret;
+ printk(KERN_INFO "[TSP] midas_tsp_init() is called\n");
+
+ /* TSP_INT: XEINT_4 */
+ gpio = GPIO_TSP_INT;
+ ret = gpio_request(gpio, "TSP_INT");
+ if (ret)
+ pr_err("failed to request gpio(TSP_INT)\n");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ /* s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); */
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ s5p_register_gpio_interrupt(gpio);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+
+ printk(KERN_INFO "%s touch : %d\n", __func__, i2c_devs3[0].irq);
+#endif
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+}
+
+#elif defined(CONFIG_TOUCHSCREEN_MELFAS_GC)
+
+static bool enabled;
+int melfas_power(int on)
+{
+ struct regulator *regulator_pwr;
+ struct regulator *regulator_vdd;
+ int ret = 0;
+
+ if (enabled == on) {
+ pr_err("melfas-ts : %s same state!", __func__);
+ return 0;
+ }
+
+ regulator_pwr = regulator_get(NULL, "touch");
+ regulator_vdd = regulator_get(NULL, "touch_1.8v");
+
+ if (IS_ERR(regulator_pwr)) {
+ pr_err("melfas-ts : %s regulator_pwr error!", __func__);
+ return PTR_ERR(regulator_pwr);
+ }
+ if (IS_ERR(regulator_vdd)) {
+ pr_err("melfas-ts : %s regulator_vdd error!", __func__);
+ return PTR_ERR(regulator_vdd);
+ }
+
+ if (on) {
+ regulator_enable(regulator_vdd);
+ regulator_enable(regulator_pwr);
+ } else {
+ if (regulator_is_enabled(regulator_pwr))
+ regulator_disable(regulator_pwr);
+ if (regulator_is_enabled(regulator_vdd))
+ regulator_disable(regulator_vdd);
+ }
+
+ if (regulator_is_enabled(regulator_pwr) == !!on &&
+ regulator_is_enabled(regulator_vdd) == !!on) {
+ pr_info("melfas-ts : %s %s", __func__, !!on ? "ON" : "OFF");
+ enabled = on;
+ } else {
+ pr_err("melfas-ts : regulator_is_enabled value error!");
+ ret = -1;
+ }
+
+ regulator_put(regulator_vdd);
+ regulator_put(regulator_pwr);
+
+ return ret;
+}
+
+int melfas_mux_fw_flash(bool to_gpios)
+{
+ pr_info("melfas-ts : %s:to_gpios=%d\n", __func__, to_gpios);
+
+ /* TOUCH_EN is always an output */
+ if (to_gpios) {
+ if (gpio_request(GPIO_TSP_SCL_18V, "GPIO_TSP_SCL"))
+ pr_err("failed to request gpio(GPIO_TSP_SCL)\n");
+ if (gpio_request(GPIO_TSP_SDA_18V, "GPIO_TSP_SDA"))
+ pr_err("failed to request gpio(GPIO_TSP_SDA)\n");
+
+ gpio_direction_output(GPIO_TSP_INT, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+
+ gpio_direction_output(GPIO_TSP_SCL_18V, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ gpio_direction_output(GPIO_TSP_SDA_18V, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ } else {
+ gpio_direction_output(GPIO_TSP_INT, 1);
+ gpio_direction_input(GPIO_TSP_INT);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ /*s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT); */
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ /*S3C_GPIO_PULL_UP */
+
+ gpio_direction_output(GPIO_TSP_SCL_18V, 1);
+ gpio_direction_input(GPIO_TSP_SCL_18V);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ gpio_direction_output(GPIO_TSP_SDA_18V, 1);
+ gpio_direction_input(GPIO_TSP_SDA_18V);
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ gpio_free(GPIO_TSP_SCL_18V);
+ gpio_free(GPIO_TSP_SDA_18V);
+ }
+ return 0;
+}
+
+struct tsp_callbacks *charger_callbacks;
+struct tsp_callbacks {
+ void (*inform_charger)(struct tsp_callbacks *, bool);
+};
+
+void tsp_charger_infom(bool en)
+{
+ if (charger_callbacks && charger_callbacks->inform_charger)
+ charger_callbacks->inform_charger(charger_callbacks, en);
+}
+
+static void melfas_register_callback(void *cb)
+{
+ charger_callbacks = cb;
+ pr_info("melfas-ts : melfas_register_callback");
+}
+
+static struct melfas_tsi_platform_data mms_ts_pdata = {
+ .max_x = 720,
+ .max_y = 1280,
+ .invert_x = 0,
+ .invert_y = 0,
+ .gpio_int = GPIO_TSP_INT,
+ .gpio_scl = GPIO_TSP_SCL_18V,
+ .gpio_sda = GPIO_TSP_SDA_18V,
+ .power = melfas_power,
+ .mux_fw_flash = melfas_mux_fw_flash,
+ .config_fw_version = "GC_Me_0000",
+ .register_cb = melfas_register_callback,
+};
+
+static struct i2c_board_info i2c_devs3[] = {
+ {
+ I2C_BOARD_INFO(MELFAS_TS_NAME, 0x48),
+ .platform_data = &mms_ts_pdata},
+};
+
+void __init midas_tsp_set_platdata(struct melfas_tsi_platform_data *pdata)
+{
+ if (!pdata)
+ pdata = &mms_ts_pdata;
+
+ i2c_devs3[0].platform_data = pdata;
+}
+
+void __init midas_tsp_init(void)
+{
+ int gpio;
+ int ret;
+ pr_info("melfas-ts : GC TSP init() is called");
+
+ /* TSP_INT: XEINT_4 */
+ gpio = GPIO_TSP_INT;
+ ret = gpio_request(gpio, "TSP_INT");
+ if (ret)
+ pr_err("melfas-ts : failed to request gpio(TSP_INT)");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ s5p_register_gpio_interrupt(gpio);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+
+ pr_info("melfas-ts : %s touch : %d\n", __func__, i2c_devs3[0].irq);
+
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+}
+
+#else /* CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1 */
+
+/* MELFAS TSP */
+static bool enabled;
+int TSP_VDD_18V(int on)
+{
+ struct regulator *regulator;
+
+ if (enabled == on)
+ return 0;
+
+ regulator = regulator_get(NULL, "touch_1.8v");
+ if (IS_ERR(regulator))
+ return PTR_ERR(regulator);
+
+ if (on) {
+ regulator_enable(regulator);
+ /*printk(KERN_INFO "[TSP] melfas power on\n"); */
+ } else {
+ /*
+ * TODO: If there is a case the regulator must be disabled
+ * (e,g firmware update?), consider regulator_force_disable.
+ */
+ if (regulator_is_enabled(regulator))
+ regulator_disable(regulator);
+ }
+
+ enabled = on;
+ regulator_put(regulator);
+
+ return 0;
+}
+
+int melfas_power(int on)
+{
+ struct regulator *regulator;
+ int ret;
+ if (enabled == on)
+ return 0;
+
+ regulator = regulator_get(NULL, "touch");
+ if (IS_ERR(regulator))
+ return PTR_ERR(regulator);
+
+ printk(KERN_DEBUG "[TSP] %s %s\n", __func__, on ? "on" : "off");
+
+ if (on) {
+ regulator_enable(regulator);
+#if defined(GPIO_OLED_DET)
+#if defined(CONFIG_MACH_SLP_PQ)
+ if (system_rev != 0x3) /* M0_P_Rev0.0 */
+#endif
+ { /*TODO: will remove after divide regulator */
+ ret = gpio_request(GPIO_OLED_DET, "OLED_DET");
+ if (ret)
+ pr_err("failed to request gpio(OLED_DET)\n");
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ gpio_free(GPIO_OLED_DET);
+
+ TSP_VDD_18V(1);
+ }
+#endif
+ } else {
+ /*
+ * TODO: If there is a case the regulator must be disabled
+ * (e,g firmware update?), consider regulator_force_disable.
+ */
+ if (regulator_is_enabled(regulator)) {
+ regulator_disable(regulator);
+#if defined(GPIO_OLED_DET)
+#if defined(CONFIG_MACH_SLP_PQ)
+ if (system_rev != 0x3) /* M0_P_Rev0.0 */
+#endif
+ { /*TODO: will remove after divide regulator */
+ ret = gpio_request(GPIO_OLED_DET, "OLED_DET");
+ if (ret)
+ pr_err
+ ("failed to request gpio(OLED_DET)\n");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET,
+ S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET,
+ GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+
+ TSP_VDD_18V(0);
+ }
+#endif
+ }
+ }
+
+ enabled = on;
+ regulator_put(regulator);
+
+ return 0;
+}
+
+int is_melfas_vdd_on(void)
+{
+ int ret;
+ /* 3.3V */
+ static struct regulator *regulator;
+
+ if (!regulator) {
+ regulator = regulator_get(NULL, "touch");
+ if (IS_ERR(regulator)) {
+ ret = PTR_ERR(regulator);
+ pr_err("could not get touch, rc = %d\n", ret);
+ return ret;
+ }
+/*
+ ret = regulator_set_voltage(regulator, 3300000, 3300000);
+ if (ret) {
+ pr_err("%s: unable to set ldo17 voltage to 3.3V\n",
+ __func__);
+ return ret;
+ } */
+ }
+
+ if (regulator_is_enabled(regulator))
+ return 1;
+ else
+ return 0;
+}
+
+int melfas_mux_fw_flash(bool to_gpios)
+{
+ pr_info("%s:to_gpios=%d\n", __func__, to_gpios);
+
+ /* TOUCH_EN is always an output */
+ if (to_gpios) {
+ if (gpio_request(GPIO_TSP_SCL_18V, "GPIO_TSP_SCL"))
+ pr_err("failed to request gpio(GPIO_TSP_SCL)\n");
+ if (gpio_request(GPIO_TSP_SDA_18V, "GPIO_TSP_SDA"))
+ pr_err("failed to request gpio(GPIO_TSP_SDA)\n");
+
+ gpio_direction_output(GPIO_TSP_INT, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+
+ gpio_direction_output(GPIO_TSP_SCL_18V, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ gpio_direction_output(GPIO_TSP_SDA_18V, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ } else {
+ gpio_direction_output(GPIO_TSP_INT, 1);
+ gpio_direction_input(GPIO_TSP_INT);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ /*s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_INPUT); */
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ /*S3C_GPIO_PULL_UP */
+
+ gpio_direction_output(GPIO_TSP_SCL_18V, 1);
+ gpio_direction_input(GPIO_TSP_SCL_18V);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ gpio_direction_output(GPIO_TSP_SDA_18V, 1);
+ gpio_direction_input(GPIO_TSP_SDA_18V);
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ gpio_free(GPIO_TSP_SCL_18V);
+ gpio_free(GPIO_TSP_SDA_18V);
+ }
+ return 0;
+}
+
+void melfas_set_touch_i2c(void)
+{
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_UP);
+ gpio_free(GPIO_TSP_SDA_18V);
+ gpio_free(GPIO_TSP_SCL_18V);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ /* s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); */
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+}
+
+void melfas_set_touch_i2c_to_gpio(void)
+{
+ int ret;
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_UP);
+ ret = gpio_request(GPIO_TSP_SDA_18V, "GPIO_TSP_SDA");
+ if (ret)
+ pr_err("failed to request gpio(GPIO_TSP_SDA)\n");
+ ret = gpio_request(GPIO_TSP_SCL_18V, "GPIO_TSP_SCL");
+ if (ret)
+ pr_err("failed to request gpio(GPIO_TSP_SCL)\n");
+
+}
+
+int get_lcd_type;
+void __init midas_tsp_set_lcdtype(int lcd_type)
+{
+ get_lcd_type = lcd_type;
+}
+
+int melfas_get_lcdtype(void)
+{
+ return get_lcd_type;
+}
+struct tsp_callbacks *charger_callbacks;
+struct tsp_callbacks {
+ void (*inform_charger)(struct tsp_callbacks *, bool);
+};
+
+void tsp_charger_infom(bool en)
+{
+ if (charger_callbacks && charger_callbacks->inform_charger)
+ charger_callbacks->inform_charger(charger_callbacks, en);
+}
+
+static void melfas_register_callback(void *cb)
+{
+ charger_callbacks = cb;
+ pr_debug("[TSP] melfas_register_callback\n");
+}
+
+static struct melfas_tsi_platform_data mms_ts_pdata = {
+ .max_x = 720,
+ .max_y = 1280,
+#if !defined(CONFIG_MACH_C1) && !defined(CONFIG_MACH_C1VZW) && \
+ !defined(CONFIG_MACH_M0) && \
+ !defined(CONFIG_MACH_M3) && \
+ !defined(CONFIG_MACH_P4NOTE)
+ .invert_x = 720,
+ .invert_y = 1280,
+#else
+ .invert_x = 0,
+ .invert_y = 0,
+#endif
+ .gpio_int = GPIO_TSP_INT,
+ .gpio_scl = GPIO_TSP_SCL_18V,
+ .gpio_sda = GPIO_TSP_SDA_18V,
+ .power = melfas_power,
+ .mux_fw_flash = melfas_mux_fw_flash,
+ .is_vdd_on = is_melfas_vdd_on,
+ .config_fw_version = "I9300_Me_0507",
+/* .set_touch_i2c = melfas_set_touch_i2c, */
+/* .set_touch_i2c_to_gpio = melfas_set_touch_i2c_to_gpio, */
+ .lcd_type = melfas_get_lcdtype,
+ .register_cb = melfas_register_callback,
+};
+
+static struct i2c_board_info i2c_devs3[] = {
+ {
+ I2C_BOARD_INFO(MELFAS_TS_NAME, 0x48),
+ .platform_data = &mms_ts_pdata},
+};
+
+void __init midas_tsp_set_platdata(struct melfas_tsi_platform_data *pdata)
+{
+ if (!pdata)
+ pdata = &mms_ts_pdata;
+
+ i2c_devs3[0].platform_data = pdata;
+}
+
+void __init midas_tsp_init(void)
+{
+ int gpio;
+ int ret;
+ printk(KERN_INFO "[TSP] midas_tsp_init() is called\n");
+
+ /* TSP_INT: XEINT_4 */
+ gpio = GPIO_TSP_INT;
+ ret = gpio_request(gpio, "TSP_INT");
+ if (ret)
+ pr_err("failed to request gpio(TSP_INT)\n");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ /* s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); */
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ s5p_register_gpio_interrupt(gpio);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+
+ printk(KERN_INFO "%s touch : %d\n", __func__, i2c_devs3[0].irq);
+
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+}
+#endif /* CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1 */
+
+/*
+ * Flexrate supports reducing cpufreq ondemand polling rate
+ * based on the user input events including touch events.
+ * This reduces response time if the touch event triggers tasks that require
+ * heavy CPU loads and does not incur unnecessary CPUFreq-up if the touch
+ * event does not trigger such tasks.
+ */
+#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE
+static void flexrate_work(struct work_struct *work)
+{
+ cpufreq_ondemand_flexrate_request(10000, 10);
+}
+
+#include <linux/pm_qos_params.h>
+static struct pm_qos_request_list busfreq_qos;
+static void flexrate_qos_cancel(struct work_struct *work)
+{
+ pm_qos_update_request(&busfreq_qos, 0);
+}
+
+static DECLARE_WORK(flex_work, flexrate_work);
+static DECLARE_DELAYED_WORK(busqos_work, flexrate_qos_cancel);
+
+void midas_tsp_request_qos(void *data)
+{
+ if (!work_pending(&flex_work))
+ schedule_work_on(0, &flex_work);
+
+ /* Guarantee that the bus runs at >= 266MHz */
+ if (!pm_qos_request_active(&busfreq_qos))
+ pm_qos_add_request(&busfreq_qos, PM_QOS_BUS_DMA_THROUGHPUT,
+ 266000);
+ else {
+ cancel_delayed_work_sync(&busqos_work);
+ pm_qos_update_request(&busfreq_qos, 266000);
+ }
+
+ /* Cancel the QoS request after 1/10 sec */
+ schedule_delayed_work_on(0, &busqos_work, HZ / 5);
+}
+#endif
diff --git a/arch/arm/mach-exynos/midas.h b/arch/arm/mach-exynos/midas.h
new file mode 100644
index 0000000..62df16e
--- /dev/null
+++ b/arch/arm/mach-exynos/midas.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-exynos/midas.h
+ */
+
+#ifndef __MIDAS_H__
+#define __MIDAS_H__
+
+static inline int i2c_add_devices(int busnum, struct i2c_board_info *infos,
+ int size)
+{
+ struct i2c_adapter *i2c_adap;
+ int i;
+ i2c_adap = i2c_get_adapter(busnum);
+ if (!i2c_adap) {
+ pr_err("%s: ERROR i2c bus %d not found\n", __func__, busnum);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < size; i++) {
+ struct i2c_client *client = i2c_new_device(i2c_adap, infos + i);
+ if (client)
+ dev_info(&client->dev, "%s - added %s successfully\n",
+ __func__, infos[i].type);
+ else
+ dev_err(&i2c_adap->dev,
+ "%s - added %s at bus i2c bus %d failed\n",
+ __func__, infos[i].type, busnum);
+
+ }
+ i2c_put_adapter(i2c_adap);
+
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mach-exynos/naples-camera.c b/arch/arm/mach-exynos/naples-camera.c
new file mode 100644
index 0000000..f2f83cf
--- /dev/null
+++ b/arch/arm/mach-exynos/naples-camera.c
@@ -0,0 +1,860 @@
+/*
+ * linux/arch/arm/mach-exynos/naples-naples.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+
+#include <linux/regulator/machine.h>
+
+#include <plat/devs.h>
+#include <plat/csis.h>
+#include <plat/pd.h>
+#include <plat/gpio-cfg.h>
+
+#include <media/exynos_flite.h>
+
+#include <media/s5k4ecgx_platform.h>
+#include <media/db8131m_platform.h>
+
+struct class *camera_class;
+struct device *s5k4ecgx_dev; /*sys/class/camera/rear*/
+struct device *db8131m_dev; /*sys/class/camera/front*/
+
+/* flash_type: FLASH[0], TORCH[1] */
+static int max77693_led_ctrl(int ctrl)
+{
+ int ret = 0;
+
+ pr_info("%s, flash_type[%d]", __func__, ctrl);
+
+ /* Flash TORCH_EN(FLASHEN) */
+ ret = gpio_request(GPIO_TORCH_EN, "GPJ1");
+ if (ret) {
+ pr_err("fail to request gpio(GPIO_TORCH_EN)");
+ return ret;
+ }
+
+ /* Flash TORCH_SET(TORCHEN) */
+ ret = gpio_request(GPIO_TORCH_SET, "GPJ1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_TORCH_SET)");
+ return ret;
+ }
+
+ if (ctrl == CAM_FLASH_ON)
+ /* FLSH mode */
+ ret = gpio_direction_output(GPIO_TORCH_EN, 1);
+ else if (ctrl == CAM_FLASH_TORCH)
+ /* TORCH mode */
+ ret = gpio_direction_output(GPIO_TORCH_SET, 1);
+ else {
+ ret = gpio_direction_output(GPIO_TORCH_EN, 0);
+ ret |= gpio_direction_output(GPIO_TORCH_SET, 0);
+ }
+
+ gpio_free(GPIO_TORCH_EN);
+ gpio_free(GPIO_TORCH_SET);
+
+ if (unlikely((ret) < 0)) { \
+ pr_err("fail to %s: err = %d", "Flash control", ret); \
+ }
+
+ return ret;
+}
+
+#if defined(CONFIG_VIDEO_FIMC)
+/*
+ * External camera reset
+ * Because the most of cameras take i2c bus signal, so that
+ * you have to reset at the boot time for other i2c slave devices.
+ * This function also called at fimc_init_camera()
+ * Do optimization for cameras on your platform.
+ */
+int s3c_csis_power(int enable)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ /* mipi_1.1v ,mipi_1.8v are always powered-on.
+ * If they are off, we then power them on.
+ */
+ if (enable) {
+ /* VMIPI_1.0V */
+ regulator = regulator_get(NULL, "vmipi_1.0v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ pr_warn("%s: vmipi_1.1v is off. so ON",
+ __func__);
+ ret = regulator_enable(regulator);
+ }
+ regulator_put(regulator);
+
+ /* VMIPI_1.8V */
+ regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(regulator))
+ goto error_out;
+ if (!regulator_is_enabled(regulator)) {
+ pr_warn("%s: vmipi_1.8v is off. so ON",
+ __func__);
+ ret = regulator_enable(regulator);
+ }
+ regulator_put(regulator);
+ pr_warn("%s: vmipi_1.0v and vmipi_1.8v were ON",
+ __func__);
+ }
+
+ return 0;
+
+error_out:
+ pr_err("%s: ERROR: failed to check mipi-power", __func__);
+ return 0;
+}
+
+#ifdef WRITEBACK_ENABLED
+static int get_i2c_busnum_writeback(void)
+{
+ return 0;
+}
+
+static struct i2c_board_info __initdata writeback_i2c_info = {
+ I2C_BOARD_INFO("WriteBack", 0x0),
+};
+
+static struct s3c_platform_camera writeback = {
+ .id = CAMERA_WB,
+ .fmt = ITU_601_YCBCR422_8BIT,
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .get_i2c_busnum = get_i2c_busnum_writeback,
+ .info = &writeback_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_YUV444,
+ .line_length = 800,
+ .width = 480,
+ .height = 800,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 480,
+ .height = 800,
+ },
+
+ .initialized = 0,
+};
+#endif
+
+#define CAM_CHECK_ERR_RET(x, msg) \
+ if (unlikely((x) < 0)) { \
+ pr_err("fail to %s: err = %d", msg, x); \
+ return x; \
+ }
+#define CAM_CHECK_ERR(x, msg) \
+ if (unlikely((x) < 0)) { \
+ pr_err("fail to %s: err = %d", msg, x); \
+ }
+
+static int s5k4ecgx_gpio_request(void)
+{
+ int ret = 0;
+
+ ret = gpio_request(GPIO_5M_CAM_RESET, "GPF1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_5M_CAM_RESET)");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_5M_CAM_nSTBY, "GPM0");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_5M_CAM_nSTBY)");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int s5k4ecgx_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ pr_debug("%s: in", __func__);
+
+ s5k4ecgx_gpio_request();
+
+ /* CAM_SENSOR_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_sensor_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_io_1.8v");
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_a2.8v");
+
+ /* CAM_DVDD_1.5V(1.3M Core 1.8V) */
+ regulator = regulator_get(NULL, "cam_dvdd_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_dvdd_1.5v");
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core_1.2v");
+
+ /* VT_CAM_nSTBY(1.3M EN) LOW */
+ ret = gpio_request(GPIO_VT_CAM_nSTBY, "GPM0");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_VT_CAM_nSTBY)");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "low VT_CAM_nSTBY");
+
+ /* CAM_VT_nRST(1.3M RESET) LOW */
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPM1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_CAM_VT_nRST)");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "low CAM_VT_nRST");
+
+ /* CAM_AF_2.8V */
+ regulator = regulator_get(NULL, "cam_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_af_2.8v");
+
+ mdelay(1); /* 10us */
+
+ /* 5M_CAM_nSTBY(5M STBY) */
+ ret = gpio_direction_output(GPIO_5M_CAM_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "high 5M_CAM_nSTBY");
+
+ mdelay(1); /* 15us */
+
+ /* 5M_CAM_RESET(5M RESET) */
+ ret = gpio_direction_output(GPIO_5M_CAM_RESET, 1);
+ CAM_CHECK_ERR_RET(ret, "high 5M_CAM_RESET");
+
+ mdelay(1); /* 60us */
+
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_5M_CAM_nSTBY);
+ gpio_free(GPIO_5M_CAM_RESET);
+
+ return ret;
+}
+
+static int s5k4ecgx_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ pr_debug("%s: in", __func__);
+
+ s5k4ecgx_gpio_request();
+
+ /* VT_CAM_nSTBY(1.3M EN) LOW */
+ ret = gpio_request(GPIO_VT_CAM_nSTBY, "GPM0");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_VT_CAM_nSTBY)");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "low VT_CAM_nSTBY");
+
+ /* CAM_VT_nRST(1.3M RESET) LOW */
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPM1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_CAM_VT_nRST)");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "low CAM_VT_nRST");
+
+ /* 5M_CAM_RESET(5M RESET) LOW */
+ ret = gpio_direction_output(GPIO_5M_CAM_RESET, 0);
+ CAM_CHECK_ERR_RET(ret, "low 5M_CAM_RESET");
+
+ mdelay(1); /* 50us */
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+
+ /* 5M_CAM_nSTBY(5M STBY) LOW */
+ ret = gpio_direction_output(GPIO_5M_CAM_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "low 5M_CAM_nSTBY");
+
+ /* CAM_AF_2.8V */
+ regulator = regulator_get(NULL, "cam_af_2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_af_2.8v");
+
+ /* CAM_DVDD_1.5V(1.3M Core 1.8V) */
+ regulator = regulator_get(NULL, "cam_dvdd_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_dvdd_1.5v");
+
+ /* CAM_SENSOR_IO_1.8V */
+ regulator = regulator_get(NULL, "cam_sensor_io_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_sensor_io_1.8v");
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_sensor_a2.8v");
+
+ /* CAM_ISP_CORE_1.2V */
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_isp_core_1.2v");
+
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_5M_CAM_RESET);
+ gpio_free(GPIO_5M_CAM_nSTBY);
+
+ return ret;
+}
+
+static int s5k4ecgx_power(int enable)
+{
+ int ret = 0;
+
+ pr_info("%s %s", __func__, enable ? "on" : "down");
+
+ if (enable) {
+ ret = s5k4ecgx_power_on();
+
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = s5k4ecgx_power_down();
+
+ ret = s3c_csis_power(enable);
+
+error_out:
+ return ret;
+}
+
+static int s5k4ecgx_get_i2c_busnum(void)
+{
+ /* HW I2C Num 0 */
+ return 0;
+}
+
+static const char *s5k4ecgx_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct s5k4ecgx_platform_data s5k4ecgx_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+ .flash_ctrl = max77693_led_ctrl,
+};
+
+static struct i2c_board_info s5k4ecgx_i2c_info = {
+ I2C_BOARD_INFO("S5K4ECGX", 0xAC >> 1),
+ .platform_data = &s5k4ecgx_plat,
+};
+
+static struct s3c_platform_camera s5k4ecgx = {
+ .id = CAMERA_CSI_C,
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT, /*ITU_601_YCBCR422_8BIT,*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .mipi_lanes = 2,
+ .mipi_settle = 12, /* only CONFIG_MIPI_CSI_ADV_FEATURE */
+ .mipi_align = 32, /* only CONFIG_MIPI_CSI_ADV_FEATURE */
+
+ .get_i2c_busnum = s5k4ecgx_get_i2c_busnum,
+ .get_clk_name = s5k4ecgx_get_clk_name,
+ .info = &s5k4ecgx_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_VYUY,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 1,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = s5k4ecgx_power,
+};
+
+
+static int db8131m_gpio_request(void)
+{
+ int ret = 0;
+
+ ret = gpio_request(GPIO_VT_CAM_nSTBY, "GPM0");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_VT_CAM_nSTBY)");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPM1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_CAM_VT_nRST)");
+ return ret;
+ }
+
+ ret = gpio_request(GPIO_VT_CAM_ID, "GPF1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_VT_CAM_ID)");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int db8131m_power_on(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ pr_debug("%s: in", __func__);
+
+ db8131m_gpio_request();
+
+ /* 5M_CAM_nSTBY(5M STBY) LOW */
+ ret = gpio_request(GPIO_5M_CAM_nSTBY, "GPM0");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_5M_CAM_nSTBY)");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_5M_CAM_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "low 5M_CAM_nSTBY");
+
+ /* 5M_CAM_RESET(5M RESET) LOW */
+ ret = gpio_request(GPIO_5M_CAM_RESET, "GPF1");
+ if (ret) {
+ pr_err("faile to request gpio(GPIO_5M_CAM_RESET)");
+ return ret;
+ }
+ ret = gpio_direction_output(GPIO_5M_CAM_RESET, 0);
+ CAM_CHECK_ERR_RET(ret, "low 5M_CAM_RESET");
+
+ /* VT_CAM_1.8V(VDDIO) */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable vt_cam_1.8v");
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_sensor_a2.8v");
+
+ /* CAM_DVDD_1.5V(1.3M Core 1.8V) */
+ regulator = regulator_get(NULL, "cam_dvdd_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_dvdd_1.5v");
+
+ /* CAM_ISP_CORE_1.2V ENABLE */
+ regulator = regulator_get(NULL, "cam_isp_core_1.2v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ ret = regulator_enable(regulator);
+ CAM_CHECK_ERR_RET(ret, "enable cam_isp_core_1.2v");
+
+ mdelay(2); /* 1ms */
+
+ /* CAM_ISP_CORE_1.2V DISABLE */
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_isp_core_1.2v");
+
+ /* VT_CAM_nSTBY(1.3M EN) EN */
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 1);
+ CAM_CHECK_ERR_RET(ret, "high VT_CAM_nSTBY");
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_SFN(2));
+ CAM_CHECK_ERR_RET(ret, "cfg mclk");
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_NONE);
+
+ mdelay(1); /* 20us */
+
+ /* CAM_VT_nRST(1.3M RESET) EN */
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 1);
+ CAM_CHECK_ERR_RET(ret, "high CAM_VT_nRST");
+
+ mdelay(5); /* 70000 cycle */
+
+ gpio_free(GPIO_5M_CAM_nSTBY);
+ gpio_free(GPIO_5M_CAM_RESET);
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_VT_CAM_ID);
+
+ return ret;
+}
+
+static int db8131m_power_down(void)
+{
+ struct regulator *regulator;
+ int ret = 0;
+
+ pr_debug("%s: in", __func__);
+
+ db8131m_gpio_request();
+
+ /* VT_CAM_nSTBY(1.3M EN) DIS */
+ ret = gpio_direction_output(GPIO_VT_CAM_nSTBY, 0);
+ CAM_CHECK_ERR_RET(ret, "low VT_CAM_nSTBY");
+
+ /* CAM_VT_nRST(1.3M RESET) DIS */
+ ret = gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ CAM_CHECK_ERR_RET(ret, "low CAM_VT_nRST");
+
+ /* MCLK */
+ ret = s3c_gpio_cfgpin(GPIO_CAM_MCLK, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CAM_MCLK, S3C_GPIO_PULL_DOWN);
+ CAM_CHECK_ERR(ret, "cfg mclk");
+
+ /* CAM_DVDD_1.5V(1.3M Core 1.8V) */
+ regulator = regulator_get(NULL, "cam_dvdd_1.5v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_dvdd_1.5v");
+
+ /* CAM_SENSOR_A2.8V */
+ regulator = regulator_get(NULL, "cam_sensor_a2.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable cam_sensor_a2.8v");
+
+ /* VT_CAM_1.8V(VDDIO) */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ ret = regulator_force_disable(regulator);
+ regulator_put(regulator);
+ CAM_CHECK_ERR_RET(ret, "disable vt_cam_1.8v");
+
+ gpio_free(GPIO_VT_CAM_nSTBY);
+ gpio_free(GPIO_CAM_VT_nRST);
+ gpio_free(GPIO_VT_CAM_ID);
+
+ return ret;
+}
+
+static int db8131m_power(int enable)
+{
+ int ret = 0;
+
+ pr_err("%s %s", __func__, enable ? "on" : "down");
+
+ if (enable) {
+ ret = db8131m_power_on();
+
+ if (unlikely(ret))
+ goto error_out;
+ } else
+ ret = db8131m_power_down();
+
+ ret = s3c_csis_power(enable);
+
+error_out:
+ return ret;
+}
+
+static int db8131m_get_i2c_busnum(void)
+{
+ /* SW gpio I2C Num 20 */
+ return 20; /*I2C_VTCAM*/
+}
+
+static const char *db8131m_get_clk_name(void)
+{
+ return "sclk_cam0";
+}
+
+static struct s5k4ecgx_platform_data db8131m_plat = {
+ .default_width = 640,
+ .default_height = 480,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .freq = 24000000,
+ .is_mipi = 1,
+};
+
+static struct i2c_board_info db8131m_i2c_info = {
+ I2C_BOARD_INFO("DB8131M", 0x8A >> 1),
+ .platform_data = &db8131m_plat,
+};
+
+static struct s3c_platform_camera db8131m = {
+ .id = CAMERA_CSI_D,
+ .type = CAM_TYPE_MIPI,
+ .fmt = MIPI_CSI_YCBCR422_8BIT, /*ITU_601_YCBCR422_8BIT,*/
+ .order422 = CAM_ORDER422_8BIT_CBYCRY,
+ .mipi_lanes = 1,
+ .mipi_settle = 12, /* only CONFIG_MIPI_CSI_ADV_FEATURE */
+ .mipi_align = 32, /* only CONFIG_MIPI_CSI_ADV_FEATURE */
+
+ .get_i2c_busnum = db8131m_get_i2c_busnum,
+ .get_clk_name = db8131m_get_clk_name,
+ .info = &db8131m_i2c_info,
+ .pixelformat = V4L2_PIX_FMT_UYVY,
+ .srclk_name = "xusbxti",
+ .clk_rate = 24000000,
+ .line_length = 640,
+ .width = 640,
+ .height = 480,
+ .window = {
+ .left = 0,
+ .top = 0,
+ .width = 640,
+ .height = 480,
+ },
+
+ /* Polarity */
+ .inv_pclk = 0,
+ .inv_vsync = 0,
+ .inv_href = 0,
+ .inv_hsync = 0,
+ .reset_camera = 0,
+ .initialized = 0,
+ .cam_power = db8131m_power,
+};
+
+/* Interface setting */
+static struct s3c_platform_fimc fimc_plat = {
+ .default_cam = CAMERA_CSI_C,
+#ifdef WRITEBACK_ENABLED
+ .default_cam = CAMERA_WB,
+#endif
+ .camera = {
+ &s5k4ecgx, /* 5M CAM */
+ &db8131m, /* 1.3M CAM */
+#ifdef WRITEBACK_ENABLED
+ &writeback,
+#endif
+ },
+ .hw_ver = 0x51,
+};
+#endif /* CONFIG_VIDEO_FIMC */
+
+static ssize_t s5k4ecgx_camera_rear_flash(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int err = 0;
+
+ if (buf[0] == '0')
+ err = max77693_led_ctrl(CAM_FLASH_OFF);
+ else
+ err = max77693_led_ctrl(CAM_FLASH_TORCH);
+
+ if (err < 0)
+ pr_err("failed to s5k4ecgx_camera_rear_flash!\n");
+
+ return count;
+}
+
+ssize_t s5k4ecgx_camera_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *cam_type;
+ pr_info("%s\n", __func__);
+
+ cam_type = "SLSI_S5K4ECGX";
+
+ return sprintf(buf, "%s\n", cam_type);
+}
+
+static ssize_t s5k4ecgx_camera_rear_camfw_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *fw_type;
+ pr_info("%s\n", __func__);
+
+ fw_type = "fw is not supported";
+
+ return sprintf(buf, "%s\n", fw_type);
+}
+static DEVICE_ATTR(rear_flash, S_IWUSR | S_IWGRP, NULL,
+ s5k4ecgx_camera_rear_flash);
+static DEVICE_ATTR(rear_camtype, S_IRUGO,
+ s5k4ecgx_camera_type_show, NULL);
+static DEVICE_ATTR(rear_camfw, S_IRUGO,
+ s5k4ecgx_camera_rear_camfw_show, NULL);
+
+ssize_t db8131m_camera_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *cam_type;
+ pr_info("%s\n", __func__);
+
+ cam_type = "Dongbu_DB8131M";
+
+ return sprintf(buf, "%s\n", cam_type);
+}
+
+static ssize_t db8131m_camera_rear_camfw_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *fw_type;
+ pr_info("%s\n", __func__);
+
+ fw_type = "fw is not supported";
+
+ return sprintf(buf, "%s\n", fw_type);
+}
+static DEVICE_ATTR(front_camtype, S_IRUGO,
+ db8131m_camera_type_show, NULL);
+static DEVICE_ATTR(front_camfw, S_IRUGO,
+ db8131m_camera_rear_camfw_show, NULL);
+
+void __init midas_camera_init(void)
+{
+#ifdef CONFIG_VIDEO_FIMC
+ s3c_fimc0_set_platdata(&fimc_plat);
+ s3c_fimc1_set_platdata(&fimc_plat);
+ s3c_fimc2_set_platdata(NULL);
+ s3c_fimc3_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#ifdef CONFIG_VIDEO_FIMC_MIPI
+ s3c_csis0_set_platdata(NULL);
+ s3c_csis1_set_platdata(NULL);
+#ifdef CONFIG_EXYNOS_DEV_PD
+ s3c_device_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s3c_device_csis1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+#endif
+#endif
+#endif /* CONFIG_VIDEO_FIMC */
+
+ camera_class = class_create(THIS_MODULE, "camera");
+
+ if (!s5k4ecgx_dev) {
+ s5k4ecgx_dev = device_create(camera_class,
+ NULL, 0, NULL, "rear");
+ if (IS_ERR(s5k4ecgx_dev)) {
+ pr_err("s5k4ecgx_dev : failed to create device!\n");
+ } else {
+ if (device_create_file(s5k4ecgx_dev,
+ &dev_attr_rear_flash) < 0) {
+ pr_err("failed to create device file, %s\n",
+ dev_attr_rear_flash.attr.name);
+ }
+ if (device_create_file(s5k4ecgx_dev,
+ &dev_attr_rear_camtype)
+ < 0) {
+ pr_err("failed to create device file, %s\n",
+ dev_attr_rear_camtype.attr.name);
+ }
+ if (device_create_file(s5k4ecgx_dev,
+ &dev_attr_rear_camfw) < 0) {
+ pr_err("failed to create device file, %s\n",
+ dev_attr_rear_camfw.attr.name);
+ }
+ }
+ }
+ if (!db8131m_dev) {
+ db8131m_dev = device_create(camera_class,
+ NULL, 0, NULL, "front");
+ if (IS_ERR(db8131m_dev)) {
+ pr_err("db8131m_dev : failed to create device!\n");
+ } else {
+ if (device_create_file(db8131m_dev,
+ &dev_attr_front_camtype)
+ < 0) {
+ pr_err("failed to create device file, %s\n",
+ dev_attr_front_camtype.attr.name);
+ }
+ if (device_create_file(db8131m_dev,
+ &dev_attr_front_camfw) < 0) {
+ pr_err("failed to create device file, %s\n",
+ dev_attr_front_camfw.attr.name);
+ }
+ }
+ }
+}
diff --git a/arch/arm/mach-exynos/naples-gpio.c b/arch/arm/mach-exynos/naples-gpio.c
new file mode 100644
index 0000000..145197c
--- /dev/null
+++ b/arch/arm/mach-exynos/naples-gpio.c
@@ -0,0 +1,1424 @@
+/*
+ * linux/arch/arm/mach-exynos/naples-gpio.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - GPIO setting in set board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio-naples.h>
+#include <plat/cpu.h>
+#include <mach/pmu.h>
+
+static struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+/* this is sample code for midas board */
+static struct gpio_init_data midas_init_gpios[] = {
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SDA_1.8V */
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SCL_1.8V */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M3) || defined(CONFIG_MACH_C1CTC)
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SDA_1.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SCL_1.8V */
+#endif
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* EAR_DET */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_INT */
+ {EXYNOS4_GPX0(7), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS4_GPX1(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_IRQ */
+
+ {EXYNOS4_GPX2(0), S3C_GPIO_SFN(2), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_UP */
+ {EXYNOS4_GPX2(1), S3C_GPIO_SFN(2), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_DOWN */
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* FUEL_ALERT */
+ {EXYNOS4_GPX2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ADC_INT */
+ {EXYNOS4_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKEUP */
+
+ {EXYNOS4_GPX3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WPC_INT */
+ {EXYNOS4_GPX3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_WAKE */
+
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV4}, /* WLAN_EN */
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+};
+
+/* this table only for midas board */
+static unsigned int exynos4_sleep_gpio_table_common[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_M3) || \
+ defined(CONFIG_MACH_SLP_NAPLES)
+ /* GPF1(6) M0, C1 PDA_ACTIVE, let cp know AP sleep status*/
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, /*UART_SEL*/
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M3) || defined(CONFIG_MACH_C1CTC)
+ /* GLP2(4) CMC_CPU_RESET, hold high */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* NC */
+#else
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_NAPLES) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS)
+ /* GPX3(2) M0 CP_PMU_RESET, hold high */
+ {EXYNOS4_GPX3(2), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+#endif
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ /* GPY4(2) S2Plus PDA_ACTIVE, let cp know AP sleep status*/
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#endif
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* PMIC_DVS1(Q) / NC(D) */
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* PMIC_DVS2(Q) / NC(D) */
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* PMIC_DVS3(Q) / NC(D) */
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ /* BUCK2_SEL(Q) / NC(D) */
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* BUCK3_SEL(Q) / NC(D) */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* BUCK4_SEL(Q) / NC(D) */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static unsigned int exynos4210_sleep_gpio_table[][3] = {
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static unsigned int exynos4212_sleep_gpio_table[][3] = {
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ) || \
+ defined(CONFIG_MACH_JENGA) || defined(CONFIG_MACH_S2PLUS) || \
+ defined(CONFIG_MACH_SLP_NAPLES)
+ /* GPM3(3) M0, CP_RESET_REQ hold high */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_S2PLUS)
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* MICBAS_EN */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* SUB_MICBIAS_EN */
+#else
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int exynos4212_sleep_gpio_table_c2c[][3] = {
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+};
+
+/*
+ * M0 GPIO Init Table
+ */
+static struct gpio_init_data m0_init_gpios[] = {
+ {EXYNOS4_GPA1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPA1(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_C1CTC)
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SDA_1.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_SCL_1.8V */
+#endif
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* EAR_DET */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_INT */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX0(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPX0(7), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS4_GPX1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX1(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* NFC_IRQ */
+
+ {EXYNOS4_GPX2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* FUEL_ALERT */
+ {EXYNOS4_GPX2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ADC_INT */
+ {EXYNOS4_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKEUP */
+
+ {EXYNOS4_GPX3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WPC_INT */
+ {EXYNOS4_GPX3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_WAKE */
+ {EXYNOS4_GPX3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV4}, /* WLAN_EN */
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV3}, /* CAM_MCLK */
+};
+
+/*
+ * M0 GPIO Sleep Table
+ */
+static unsigned int m0_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* FM_RST */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ /* CMC221 Active States */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN}, /* NC */
+#else
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_NAPLES)
+ /* GPF1(6) M0, C1 PDA_ACTIVE, let cp know AP sleep status*/
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(3) */
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(7) */
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+ defined(CONFIG_MACH_C1CTC)
+ /* GLP2(4) CMC_CPU_RESET, hold high */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* NC */
+#else
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN},/*USB_SEL*/
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1) ||\
+ defined(CONFIG_MACH_C1VZW) || defined(CONFIG_MACH_C1ATT) ||\
+ defined(CONFIG_MACH_S2PLUS)
+ /* GPIO_PS_ALS_EN */
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_NAPLES)
+ /* GPM3(3) M0, CP_RESET_REQ hold high */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* m0_sleep_gpio_table */
+
+/*
+ * S2Plus GPIO Sleep Table
+ */
+static unsigned int s2plus_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* FM_RST */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(3) */
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* NAND_D(7) */
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ /* GPM3(3) M0, CP_RESET_REQ hold high */
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_TXD */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* ISP_RXD */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SCL */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* VT_CAM_SDA */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* S2Plus_sleep_gpio_table */
+
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+/* To save power consumption, gpio pin set before enterling sleep */
+void midas_config_sleep_gpio_table(void)
+{
+#ifdef CONFIG_NAPLES_COMMON
+ config_sleep_gpio_table(ARRAY_SIZE(m0_sleep_gpio_table),
+ m0_sleep_gpio_table);
+#else
+ config_sleep_gpio_table(ARRAY_SIZE(exynos4_sleep_gpio_table_common),
+ exynos4_sleep_gpio_table_common);
+
+ if (!soc_is_exynos4210()) {
+ if (exynos4_is_c2c_use()) {
+ config_sleep_gpio_table(
+ ARRAY_SIZE(exynos4212_sleep_gpio_table_c2c),
+ exynos4212_sleep_gpio_table_c2c);
+ } else {
+ config_sleep_gpio_table(
+ ARRAY_SIZE(exynos4212_sleep_gpio_table),
+ exynos4212_sleep_gpio_table);
+ }
+ } else {
+ config_sleep_gpio_table(ARRAY_SIZE(exynos4210_sleep_gpio_table),
+ exynos4210_sleep_gpio_table);
+ }
+#endif
+}
+
+/* Intialize gpio set in midas board */
+void midas_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ pr_debug("%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(m0_init_gpios); i++) {
+ gpio = m0_init_gpios[i].num;
+ if (gpio <= EXYNOS4212_GPV4(1)) {
+ s3c_gpio_cfgpin(gpio, m0_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, m0_init_gpios[i].pud);
+
+ if (m0_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, m0_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, m0_init_gpios[i].drv);
+ }
+ }
+}
diff --git a/arch/arm/mach-exynos/naples-power.c b/arch/arm/mach-exynos/naples-power.c
new file mode 100644
index 0000000..caed0c4
--- /dev/null
+++ b/arch/arm/mach-exynos/naples-power.c
@@ -0,0 +1,1118 @@
+/*
+ * naples-power.c - Power Management of MIDAS Project
+ *
+ * Copyright (C) 2012 Samsung Electrnoics
+ * Chiwoong Byun <woong.byun@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-naples.h>
+#include <mach/irqs.h>
+
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max77686.h>
+#include <linux/mfd/max77693.h>
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#endif
+
+#ifdef CONFIG_REGULATOR_MAX8997
+/* MOTOR */
+#ifdef CONFIG_VIBETONZ
+static void max8997_motor_init(void)
+{
+ gpio_request(GPIO_VIBTONE_EN, "VIBTONE_EN");
+ s3c_gpio_cfgpin(GPIO_VIBTONE_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_VIBTONE_EN, S3C_GPIO_PULL_NONE);
+}
+
+static void max8997_motor_en(bool en)
+{
+ gpio_direction_output(GPIO_VIBTONE_EN, en);
+}
+
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 44000,
+ .period = 44642,
+ .reg2 = MOTOR_LRA | EXT_PWM | DIVIDER_128,
+ .init_hw = max8997_motor_init,
+ .motor_en = max8997_motor_en,
+ .pwm_id = 1,
+};
+#endif
+
+/* max8997 */
+static struct regulator_consumer_supply ldo1_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim"),
+};
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo6_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo7_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim"),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.3v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vlcd_2.2v", NULL),
+ REGULATOR_SUPPLY("VDD3", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply max8997_buck1 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max8997_buck3 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max8997_buck4 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo1, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo6, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo7, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo11, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo13, "VCC_3.3V_LCD", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo14, "VCC_1.8V_IO", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo15, "VDD_2.2V_LCD", 2200000, 2200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo16, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data max8997_buck1_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 950000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck1,
+};
+
+static struct regulator_init_data max8997_buck2_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 900000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max8997_buck2),
+ .consumer_supplies = max8997_buck2,
+};
+
+static struct regulator_init_data max8997_buck3_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 950000,
+ .max_uV = 1150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck3,
+};
+
+static struct regulator_init_data max8997_buck4_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck4,
+};
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_BUCK1, &max8997_buck1_data, },
+ { MAX8997_BUCK2, &max8997_buck2_data, },
+ { MAX8997_BUCK3, &max8997_buck3_data, },
+ { MAX8997_BUCK4, &max8997_buck4_data, },
+ { MAX8997_LDO1, &ldo1_init_data, },
+ { MAX8997_LDO6, &ldo6_init_data, },
+ { MAX8997_LDO7, &ldo7_init_data, },
+ { MAX8997_LDO8, &ldo8_init_data, },
+ { MAX8997_LDO11, &ldo11_init_data, },
+ { MAX8997_LDO12, &ldo12_init_data, },
+ { MAX8997_LDO13, &ldo13_init_data, },
+ { MAX8997_LDO14, &ldo14_init_data, },
+ { MAX8997_LDO15, &ldo15_init_data, },
+ { MAX8997_LDO16, &ldo16_init_data, },
+ { MAX8997_LDO17, &ldo17_init_data, },
+ { MAX8997_LDO18, &ldo18_init_data, },
+};
+
+struct max8997_platform_data exynos4_max8997_info = {
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = max8997_regulators,
+ .buck1_max_vol = 1100000,
+ .buck2_max_vol = 1100000,
+ .buck5_max_vol = 1100000,
+ .buck_set1 = EXYNOS4212_GPJ1(1),
+ .buck_set2 = EXYNOS4212_GPJ1(2),
+ .buck_set3 = EXYNOS4_GPL0(0),
+#ifdef CONFIG_VIBETONZ
+ .motor = &max8997_motor,
+#endif
+};
+#elif defined(CONFIG_REGULATOR_MAX77686)
+/* max77686 */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo3_supply[] = {};
+#endif
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_dvdd_1.5v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.9v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb2_1.9v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_io_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("touch_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("vcc_3.0v_lcd", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e39a0x02"),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+
+static struct regulator_consumer_supply max77686_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynoss4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply max77686_buck9 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+static struct regulator_consumer_supply max77686_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo5, "VCC_1.8V_IO", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo9, "CAM_DVDD_1.5V", 1500000, 1500000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo11, "VABB1_1.9V", 1900000, 1900000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo14, "VABB2_1.9V", 1900000, 1900000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "CAM_SENSOR_IO_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "TSP_AVDD_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "VDD_1.8V_TSP", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo25, "VCC_3.3V_LCD", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "VCC_MOTOR_3.0V", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+#if defined(CONFIG_MACH_SLP_PQ)
+static struct regulator_init_data ldo24_pq11_init_data = {
+ .constraints = {
+ .name = "VDD_1.8V_TSP",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 0,
+ .boot_on = 0,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 0,
+ .disabled = 1,
+ }
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = ldo24_supply,
+};
+#endif
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck1),
+ .consumer_supplies = max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck3),
+ .consumer_supplies = max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1150000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck4),
+ .consumer_supplies = max77686_buck4,
+};
+
+static struct regulator_init_data max77686_buck9_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck9,
+};
+
+static struct regulator_init_data max77686_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_enp32khz),
+ .consumer_supplies = max77686_enp32khz,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_BUCK9, &max77686_buck9_data,},
+ {MAX77686_LDO3, &ldo3_init_data,},
+ {MAX77686_LDO5, &ldo5_init_data,},
+ {MAX77686_LDO8, &ldo8_init_data,},
+ {MAX77686_LDO9, &ldo9_init_data,},
+ {MAX77686_LDO10, &ldo10_init_data,},
+ {MAX77686_LDO11, &ldo11_init_data,},
+ {MAX77686_LDO12, &ldo12_init_data,},
+ {MAX77686_LDO14, &ldo14_init_data,},
+ {MAX77686_LDO17, &ldo17_init_data,},
+ {MAX77686_LDO18, &ldo18_init_data,},
+ {MAX77686_LDO19, &ldo19_init_data,},
+ {MAX77686_LDO21, &ldo21_init_data,},
+ {MAX77686_LDO23, &ldo23_init_data,},
+ {MAX77686_LDO24, &ldo24_init_data,},
+ {MAX77686_LDO25, &ldo25_init_data,},
+ {MAX77686_LDO26, &ldo26_init_data,},
+ {MAX77686_P32KH, &max77686_enp32khz_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO3] = {MAX77686_LDO3, MAX77686_OPMODE_NORMAL},
+ [MAX77686_LDO12] = {MAX77686_LDO12, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+struct max77686_platform_data exynos4_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+
+ .buck234_gpio_dvs = {
+ GPIO_PMIC_DVS1,
+ GPIO_PMIC_DVS2,
+ GPIO_PMIC_DVS3,
+ },
+ .buck234_gpio_selb = {
+ GPIO_BUCK2_SEL,
+ GPIO_BUCK3_SEL,
+ GPIO_BUCK4_SEL,
+ },
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1100000, /* 1.1V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1100000, /* 1.1V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+};
+
+void midas_power_init(void)
+{
+#if defined(CONFIG_MACH_M0)
+ if (system_rev == 0 || system_rev == 3)
+#elif defined(CONFIG_MACH_C1)
+ if (system_rev <= 1 || system_rev == 3)
+#elif defined(CONFIG_MACH_C1VZW)
+ if (system_rev == 0)
+#endif
+ ldo8_init_data.constraints.always_on = 1;
+ ldo10_init_data.constraints.always_on = 1;
+}
+#endif /* CONFIG_REGULATOR_MAX77686 */
+
+void midas_power_set_muic_pdata(void *pdata, int gpio)
+{
+ gpio_request(gpio, "AP_PMIC_IRQ");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+#ifdef CONFIG_REGULATOR_MAX8997
+ exynos4_max8997_info.muic = pdata;
+#endif
+}
+
+void midas_power_gpio_init(void)
+{
+#ifdef CONFIG_REGULATOR_MAX8997
+ int gpio;
+
+ gpio = EXYNOS4212_GPJ1(1);
+ gpio_request(gpio, "BUCK_SET1");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = EXYNOS4212_GPJ1(2);
+ gpio_request(gpio, "BUCK_SET2");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = EXYNOS4_GPL0(0);
+ gpio_request(gpio, "BUCK_SET3");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+#endif
+}
+
+#ifdef CONFIG_MFD_MAX77693
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+static struct regulator_consumer_supply charger_supply[] = {
+ REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 0,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct regulator_init_data charger_init_data = {
+ .constraints = {
+ .name = "CHARGER",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_CURRENT,
+ .boot_on = 1,
+ .min_uA = 60000,
+ .max_uA = 2580000,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(charger_supply),
+ .consumer_supplies = charger_supply,
+};
+
+struct max77693_regulator_data max77693_regulators[] = {
+ {MAX77693_ESAFEOUT1, &safeout1_init_data,},
+ {MAX77693_ESAFEOUT2, &safeout2_init_data,},
+ {MAX77693_CHARGER, &charger_init_data,},
+};
+
+#if defined(CONFIG_MACH_SLP_PQ)
+/* this initcall replace ldo24 from VDD 2.2 to VDD 1.8 for evt1.1 board. */
+static int __init regulator_init_with_rev(void)
+{
+ /* SLP PQ Promixa evt1.1 */
+ if (system_rev != 3) {
+ ldo24_supply[0].supply = "touch_1.8v";
+ ldo24_supply[0].dev_name = NULL;
+
+ memcpy(&ldo24_init_data, &ldo24_pq11_init_data,
+ sizeof(struct regulator_init_data));
+ }
+ return 0;
+}
+
+postcore_initcall(regulator_init_with_rev);
+#endif /* CONFIG_MACH_SLP_PQ */
+#endif /* CONFIG_MFD_MAX77693 */
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+/* S5M8767 Regulator */
+
+static struct regulator_consumer_supply ldo1_supply[] = { };
+
+static struct regulator_consumer_supply ldo2_supply[] = { };
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo3_supply[] = {};
+#endif
+
+static struct regulator_consumer_supply ldo5_supply[] = { };
+
+static struct regulator_consumer_supply ldo6_supply[] = { };
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("cam_dvdd_1.5v", NULL),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb2_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo15_supply[] = { };
+
+static struct regulator_consumer_supply ldo16_supply[] = { };
+
+static struct regulator_consumer_supply ldo17_supply[] = { };
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo20_supply[] = {
+ REGULATOR_SUPPLY("vcc_3.0v_lcd", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e39a0x"),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+
+static struct regulator_consumer_supply ldo22_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_a2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_io_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo27_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo28_supply[] = {
+ REGULATOR_SUPPLY("touch_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m8767_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck6 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+static struct regulator_consumer_supply s5m8767_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+REGULATOR_INIT(ldo1, "VALIVE_1.0V_AP", 1000000, 1000000, 1, 0, 0);
+REGULATOR_INIT(ldo2, "VM1M2_1.2V_AP", 1200000, 1200000, 1, 0, 0);
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo5, "VDDQ_MMC_2.8V", 2800000, 2800000, 1, 0, 0);
+REGULATOR_INIT(ldo6, "VMPLL_1.0V_AP", 1000000, 1000000, 1, 0, 0);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 0,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo9, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VT_CAM_DVDD_1.5V", 1500000, 1500000, 0,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo11, "VABB1_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo13, "VMIPI_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo14, "VABB2_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo15, "VHSIC_1.0V_AP", 1000000, 1000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo16, "VHSIC_1.8V_AP", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "VCC_2.8V_AP", 2800000, 2800000, 1, 0, 0);
+REGULATOR_INIT(ldo19, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo20, "VCC_3.0V_LCD", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VCC_MOTOR_3.0V", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo22, "CAM_SENSOR_A2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "TSP_AVDD_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo25, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo27, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo28, "TSP_VDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data s5m8767_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck1),
+ .consumer_supplies = s5m8767_buck1,
+};
+
+static struct regulator_init_data s5m8767_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck2,
+};
+
+static struct regulator_init_data s5m8767_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck3),
+ .consumer_supplies = s5m8767_buck3,
+};
+
+static struct regulator_init_data s5m8767_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1150000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck4),
+ .consumer_supplies = s5m8767_buck4,
+};
+
+static struct regulator_init_data s5m8767_buck6_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck6,
+};
+
+static struct regulator_init_data s5m8767_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_enp32khz),
+ .consumer_supplies = s5m8767_enp32khz,
+};
+
+static struct s5m_regulator_data s5m8767_regulators[] = {
+ {S5M8767_BUCK1, &s5m8767_buck1_data,},
+ {S5M8767_BUCK2, &s5m8767_buck2_data,},
+ {S5M8767_BUCK3, &s5m8767_buck3_data,},
+ {S5M8767_BUCK4, &s5m8767_buck4_data,},
+ {S5M8767_BUCK6, &s5m8767_buck6_data,},
+ {S5M8767_LDO1, &ldo1_init_data,},
+ {S5M8767_LDO2, &ldo2_init_data,},
+ {S5M8767_LDO3, &ldo3_init_data,},
+ {S5M8767_LDO5, &ldo5_init_data,},
+ {S5M8767_LDO6, &ldo6_init_data,},
+ {S5M8767_LDO8, &ldo8_init_data,},
+ {S5M8767_LDO9, &ldo9_init_data,},
+ {S5M8767_LDO10, &ldo10_init_data,},
+ {S5M8767_LDO11, &ldo11_init_data,},
+ {S5M8767_LDO12, &ldo12_init_data,},
+ {S5M8767_LDO13, &ldo13_init_data,},
+ {S5M8767_LDO14, &ldo14_init_data,},
+ {S5M8767_LDO15, &ldo15_init_data,},
+ {S5M8767_LDO16, &ldo16_init_data,},
+ {S5M8767_LDO17, &ldo17_init_data,},
+ {S5M8767_LDO19, &ldo19_init_data,},
+ {S5M8767_LDO20, &ldo20_init_data,},
+ {S5M8767_LDO21, &ldo21_init_data,},
+ {S5M8767_LDO22, &ldo22_init_data,},
+ {S5M8767_LDO23, &ldo23_init_data,},
+ {S5M8767_LDO24, &ldo24_init_data,},
+ {S5M8767_LDO25, &ldo25_init_data,},
+ {S5M8767_LDO26, &ldo26_init_data,},
+ {S5M8767_LDO27, &ldo27_init_data,},
+ {S5M8767_LDO28, &ldo28_init_data,},
+};
+
+struct s5m_opmode_data s5m8767_opmode_data[S5M8767_REG_MAX] = {
+ [S5M8767_LDO3] = {S5M8767_LDO3, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO12] = {S5M8767_LDO12, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK1] = {S5M8767_BUCK1, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK2] = {S5M8767_BUCK2, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK3] = {S5M8767_BUCK3, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK4] = {S5M8767_BUCK4, S5M_OPMODE_STANDBY},
+};
+
+struct s5m_platform_data exynos4_s5m8767_info = {
+ .device_type = S5M8767X,
+ .num_regulators = ARRAY_SIZE(s5m8767_regulators),
+ .regulators = s5m8767_regulators,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = s5m8767_opmode_data,
+
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1100000, /* 1.1V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1100000, /* 1.1V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+
+ .buck_ramp_delay = 10,
+ .buck_default_idx = 3,
+
+ .buck_gpios[0] = GPIO_BUCK2_SEL,
+ .buck_gpios[1] = GPIO_BUCK3_SEL,
+ .buck_gpios[2] = GPIO_BUCK4_SEL,
+/*
+ .buck234_gpio_dvs = {
+ GPIO_PMIC_DVS1,
+ GPIO_PMIC_DVS2,
+ GPIO_PMIC_DVS3,
+ },
+ .buck234_gpio_selb = {
+ GPIO_BUCK2_SEL,
+ GPIO_BUCK3_SEL,
+ GPIO_BUCK4_SEL,
+ },
+*/
+};
+
+void midas_power_init(void)
+{
+ ldo8_init_data.constraints.always_on = 1;
+ ldo10_init_data.constraints.always_on = 1;
+}
+
+/* End of S5M8767 */
+#endif
diff --git a/arch/arm/mach-exynos/naples-tsp.c b/arch/arm/mach-exynos/naples-tsp.c
new file mode 100644
index 0000000..b83de4c
--- /dev/null
+++ b/arch/arm/mach-exynos/naples-tsp.c
@@ -0,0 +1,317 @@
+/*
+ * linux/arch/arm/mach-exynos/naples-tsp.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <plat/gpio-cfg.h>
+#include <linux/delay.h>
+#include <mach/naples-tsp.h>
+#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT224
+#include <linux/i2c/mxt224.h>
+#define TSP_IRQ_READY_DELAY 45
+/*-------------MXT224 TOUCH DRIVER by Xtopher----------*/
+
+#define MXT224_MAX_MT_FINGERS 10
+/*
+ Configuration for MXT224-E
+*/
+#define MXT224E_THRESHOLD_BATT 50
+#define MXT224E_THRESHOLD_CHRG 40
+#define MXT224E_CALCFG_BATT 0x42
+#define MXT224E_CALCFG_CHRG 0x52
+#define MXT224E_ATCHFRCCALTHR_NORMAL 40
+#define MXT224E_ATCHFRCCALRATIO_NORMAL 55
+#define MXT224E_GHRGTIME_BATT 27
+#define MXT224E_GHRGTIME_CHRG 22
+#define MXT224E_ATCHCALST 4
+#define MXT224E_ATCHCALTHR 35
+#define MXT224E_BLEN_BATT 32
+#define MXT224E_BLEN_CHRG 16
+#define MXT224E_MOVFILTER_BATT 46
+#define MXT224E_MOVFILTER_CHRG 46
+#define MXT224E_ACTVSYNCSPERX_NORMAL 32
+#define MXT224E_NEXTTCHDI_NORMAL 0
+
+static u8 t7_config_e[] = {GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25/* ACTV2IDLETO: 25 * 200ms = 5s */};
+static u8 t8_config_e[] = {GEN_ACQUISITIONCONFIG_T8,
+ 27, 0, 5, 1, 0, 0, 5, 35, 40, 55};
+
+/* NEXTTCHDI added */
+static u8 t9_config_e[] = {TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 19, 11, 0, 32, 50, 2, 0,
+ 10,
+ 15, /* MOVHYSTI */
+ 1, 46, MXT224_MAX_MT_FINGERS, 5, 40, 10, 191, 3,
+ 27, 2, 10, 10, 10, 10, 143, 40, 143, 80,
+ 18, 15, 50, 50, 3};
+
+static u8 t15_config_e[] = {TOUCH_KEYARRAY_T15, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0};
+static u8 t18_config_e[] = {SPT_COMCONFIG_T18, 0, 0};
+static u8 t23_config_e[] = {TOUCH_PROXIMITY_T23, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static u8 t25_config_e[] = {SPT_SELFTEST_T25, 0, 0, 0, 0, 0, 0,
+ 0, 0};
+static u8 t40_config_e[] = {PROCI_GRIPSUPPRESSION_T40, 0, 0,
+ 0, 0, 0};
+static u8 t42_config_e[] = {PROCI_TOUCHSUPPRESSION_T42, 0,
+ 0, 0, 0, 0, 0, 0, 0};
+static u8 t46_config_e[] = {SPT_CTECONFIG_T46, 0, 3, 24, 32, 0,
+ 0, 1, 0, 0};
+static u8 t47_config_e[] = {PROCI_STYLUS_T47, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0};
+
+static u8 t38_config_e[] = {SPT_USERDATA_T38, 0, 1, 15, 19, 45, 40, 0, 0};
+
+static u8 t48_config_chrg_e[] = {PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x52, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 64, 4, 64,
+ 10, 0, 9, 5, 0, 15, 0, 20, 0, 0,
+ 0, 0, 0, 0, 0, 40, 2,/*blen=0,threshold=50*/
+ 15,/* MOVHYSTI */
+ 1, 47,/* MoveFilter 46->47, for chargeing*/
+ 10, 5, 40, 240, 245, 10, 10, 148, 50, 143,
+ 80, 18, 15, 0};
+
+static u8 t48_config_e[] = {PROCG_NOISESUPPRESSION_T48,
+ 3, 132, 0x40, 0, 0, 0, 0, 0, 10, 15,
+ 0, 0, 0, 6, 6, 0, 0, 48, 4, 48,
+ 10, 0, 10, 5, 0, 20, 0, 5, 0, 0, /*byte 27 original value 20*/
+ 0, 0, 0, 0, 32, 50, 2,
+ 15, 1, 46,
+ MXT224_MAX_MT_FINGERS, 5, 40, 10, 10,
+ 10, 10, 143, 40, 143,
+ 80, 18, 15, 0};
+
+static u8 end_config_e[] = {RESERVED_T255};
+
+static const u8 *mxt224e_config[] = {
+ t7_config_e,
+ t8_config_e,
+ t9_config_e,
+ t15_config_e,
+ t18_config_e,
+ t23_config_e,
+ t25_config_e,
+ t40_config_e,
+ t42_config_e,
+ t46_config_e,
+ t47_config_e,
+ t48_config_e,
+ t38_config_e,
+ end_config_e,
+};
+/*
+ Configuration for MXT224
+*/
+#define MXT224_THRESHOLD_BATT 40
+#define MXT224_THRESHOLD_BATT_INIT 55
+#define MXT224_THRESHOLD_CHRG 70
+#define MXT224_NOISE_THRESHOLD_BATT 30
+#define MXT224_NOISE_THRESHOLD_CHRG 40
+#define MXT224_MOVFILTER_BATT 11
+#define MXT224_MOVFILTER_CHRG 46
+#define MXT224_ATCHCALST 9
+#define MXT224_ATCHCALTHR 30
+
+static u8 t7_config[] = { GEN_POWERCONFIG_T7,
+ 48, /* IDLEACQINT */
+ 255, /* ACTVACQINT */
+ 25 /* ACTV2IDLETO: 25 * 200ms = 5s */
+};
+
+static u8 t8_config[] = { GEN_ACQUISITIONCONFIG_T8,
+ 10, 0, 5, 1, 0, 0, MXT224_ATCHCALST, MXT224_ATCHCALTHR
+}; /*byte 3: 0 */
+
+static u8 t9_config[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 131, 0, 0, 19, 11, 0, 32, MXT224_THRESHOLD_BATT, 2, 0,
+ 0,
+ 15, /* MOVHYSTI */
+ 1, MXT224_MOVFILTER_BATT, MXT224_MAX_MT_FINGERS, 5, 40, 10, 191, 3,
+ 27, 2, 0, 0, 0, 0, 143, 55, 143, 90, 18
+};
+
+static u8 t18_config[] = { SPT_COMCONFIG_T18,
+ 0, 1
+};
+
+static u8 t20_config[] = { PROCI_GRIPFACESUPPRESSION_T20,
+ 7, 0, 0, 0, 0, 0, 0, 30, 20, 4, 15, 10
+};
+
+static u8 t22_config[] = { PROCG_NOISESUPPRESSION_T22,
+ 143, 0, 0, 0, 0, 0, 0, 3, MXT224_NOISE_THRESHOLD_BATT, 0, 0, 29, 34, 39,
+ 49, 58, 3
+};
+
+static u8 t28_config[] = { SPT_CTECONFIG_T28,
+ 0, 0, 3, 16, 19, 60
+};
+static u8 end_config[] = { RESERVED_T255 };
+
+static const u8 *mxt224_config[] = {
+ t7_config,
+ t8_config,
+ t9_config,
+ t18_config,
+ t20_config,
+ t22_config,
+ t28_config,
+ end_config,
+};
+
+struct mxt224_callbacks *charger_callbacks;
+void tsp_charger_infom(bool en)
+{
+ if (charger_callbacks && charger_callbacks->inform_charger)
+ charger_callbacks->inform_charger(charger_callbacks, en);
+ pr_debug("[TSP] %s - %s\n", __func__,
+ en ? "on" : "off");
+}
+
+void tsp_register_callback(struct mxt224_callbacks *cb)
+{
+ charger_callbacks = cb;
+}
+
+void tsp_read_ta_status(void *ta_status)
+{
+ *(bool *)ta_status = is_cable_attached;
+}
+
+static int TSP_VDD_1_8V(int on)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "touch_1.8v");
+ if (IS_ERR(regulator))
+ return PTR_ERR(regulator);
+
+ if (on) {
+ regulator_enable(regulator);
+ pr_info("[TSP] Atmel power on\n");
+ } else {
+ /*
+ * TODO: If there is a case the regulator must be disabled
+ * (e,g firmware update?), consider regulator_force_disable.
+ */
+ if (regulator_is_enabled(regulator))
+ regulator_disable(regulator);
+ }
+ regulator_put(regulator);
+
+ return 0;
+}
+
+static void mxt224_power_on(void)
+{
+
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "touch");
+ if (IS_ERR(regulator))
+ return ;
+ regulator_enable(regulator);
+ TSP_VDD_1_8V(1);
+ regulator_put(regulator);
+ msleep(TSP_IRQ_READY_DELAY);
+ pr_info("mxt224_power_on is finished\n");
+}
+
+static void mxt224_power_off(void)
+{
+ struct regulator *regulator;
+ regulator = regulator_get(NULL, "touch");
+ if (IS_ERR(regulator))
+ return ;
+
+ regulator_disable(regulator);
+ TSP_VDD_1_8V(0);
+ regulator_put(regulator);
+ msleep(TSP_IRQ_READY_DELAY);
+ pr_info("mxt224_power_off is finished\n");
+}
+
+static struct mxt224_platform_data mxt224_data = {
+ .max_finger_touches = MXT224_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TSP_INT,
+ .config = mxt224_config,
+ .config_e = mxt224e_config,
+ .t48_config_batt_e = t48_config_e,
+ .t48_config_chrg_e = t48_config_chrg_e,
+ .min_x = 0,
+ .max_x = 540,
+ .min_y = 0,
+ .max_y = 960,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 30,
+ .atchcalst = MXT224_ATCHCALST,
+ .atchcalsthr = MXT224_ATCHCALTHR,
+ .tchthr_batt = MXT224_THRESHOLD_BATT,
+ .tchthr_batt_init = MXT224_THRESHOLD_BATT_INIT,
+ .tchthr_charging = MXT224_THRESHOLD_CHRG,
+ .noisethr_batt = MXT224_NOISE_THRESHOLD_BATT,
+ .noisethr_charging = MXT224_NOISE_THRESHOLD_CHRG,
+ .movfilter_batt = MXT224_MOVFILTER_BATT,
+ .movfilter_charging = MXT224_MOVFILTER_CHRG,
+ .atchcalst_e = MXT224E_ATCHCALST,
+ .atchcalsthr_e = MXT224E_ATCHCALTHR,
+ .tchthr_batt_e = MXT224E_THRESHOLD_BATT,
+ .tchthr_charging_e = MXT224E_THRESHOLD_CHRG,
+ .calcfg_batt_e = MXT224E_CALCFG_BATT,
+ .calcfg_charging_e = MXT224E_CALCFG_CHRG,
+ .atchfrccalthr_e = MXT224E_ATCHFRCCALTHR_NORMAL,
+ .atchfrccalratio_e = MXT224E_ATCHFRCCALRATIO_NORMAL,
+ .chrgtime_batt_e = MXT224E_GHRGTIME_BATT,
+ .chrgtime_charging_e = MXT224E_GHRGTIME_CHRG,
+ .blen_batt_e = MXT224E_BLEN_BATT,
+ .blen_charging_e = MXT224E_BLEN_CHRG,
+ .movfilter_batt_e = MXT224E_MOVFILTER_BATT,
+ .movfilter_charging_e = MXT224E_MOVFILTER_CHRG,
+ .actvsyncsperx_e = MXT224E_ACTVSYNCSPERX_NORMAL,
+ .nexttchdi_e = MXT224E_NEXTTCHDI_NORMAL,
+ .power_on = mxt224_power_on,
+ .power_off = mxt224_power_off,
+ .register_cb = tsp_register_callback,
+ .read_ta_status = tsp_read_ta_status,
+};
+
+static struct i2c_board_info i2c_devs3[] __initdata = {
+ {
+ I2C_BOARD_INFO(MXT224_DEV_NAME, 0x4A),
+ .platform_data = &mxt224_data
+ }
+};
+
+void __init naples_tsp_init(void)
+{
+ int gpio;
+ pr_info("[TSP] naples_tsp_init() is called\n");
+
+ /* TSP_INT: XEINT_4 */
+ gpio = GPIO_TSP_INT;
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ /* s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP); */
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ s5p_register_gpio_interrupt(gpio);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+ i2c_register_board_info(3, i2c_devs3,
+ ARRAY_SIZE(i2c_devs3));
+}
+#endif
diff --git a/arch/arm/mach-exynos/p10-battery.c b/arch/arm/mach-exynos/p10-battery.c
new file mode 100644
index 0000000..e578b55
--- /dev/null
+++ b/arch/arm/mach-exynos/p10-battery.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+
+#include <mach/gpio-p10.h>
+#include <mach/regs-pmu.h> /* S5P_INFORMX */
+
+#include <plat/gpio-cfg.h>
+
+#ifdef CONFIG_STMPE811_ADC
+#include <linux/stmpe811-adc.h>
+#endif
+
+#if defined(CONFIG_BATTERY_SAMSUNG_P1X)
+#include <linux/battery/sec_battery.h>
+#include <linux/battery/sec_fuelgauge.h>
+#include <linux/battery/sec_charger.h>
+
+#define SEC_BATTERY_PMIC_NAME ""
+#define SEC_FUELGAUGE_I2C_ID 9
+#define SEC_CHARGER_I2C_ID 10
+
+static bool sec_bat_adc_none_init(struct platform_device *pdev) { return true; }
+static bool sec_bat_adc_none_exit(void) { return true; }
+static int sec_bat_adc_none_read(unsigned int channel) { return 0; }
+
+static bool sec_bat_adc_ap_init(struct platform_device *pdev) { return true; }
+static bool sec_bat_adc_ap_exit(void) { return true; }
+static int sec_bat_adc_ap_read(unsigned int channel) { return 0; }
+
+/* CHECK ME */
+#define SMTPE811_CHANNEL_ADC_CHECK_1 6
+#define SMTPE811_CHANNEL_VICHG 4 /* Not supported in P10 */
+
+static bool sec_bat_adc_ic_init(struct platform_device *pdev) { return true; }
+static bool sec_bat_adc_ic_exit(void) { return true; }
+static int sec_bat_adc_ic_read(unsigned int channel)
+{
+ int data = 0;
+ int max_voltage = 3300;
+
+ switch (channel) {
+ case SEC_BAT_ADC_CHANNEL_CABLE_CHECK:
+ data = stmpe811_get_adc_data(SMTPE811_CHANNEL_ADC_CHECK_1);
+ data = data * max_voltage / 4095; /* 4096 ? */
+ break;
+ }
+
+ return data;
+}
+
+static bool sec_bat_gpio_init(void)
+{
+#if defined(CONFIG_MACH_P10_LTE_00_BD) || defined(CONFIG_MACH_P10_WIFI_00_BD)
+ s3c_gpio_cfgpin(GPIO_TA_nCONNECTED, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCONNECTED, S3C_GPIO_PULL_NONE);
+#else
+ /* IRQ to detect cable insertion and removal */
+ s3c_gpio_cfgpin(GPIO_TA_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_INT, S3C_GPIO_PULL_NONE);
+#endif
+
+ return true;
+}
+
+static bool sec_fg_gpio_init(void)
+{
+ /* IRQ to detect low battery from fuel gauge */
+ s3c_gpio_cfgpin(GPIO_FUEL_ALERT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_FUEL_ALERT, S3C_GPIO_PULL_UP);
+
+ return true;
+}
+
+static bool sec_chg_gpio_init(void)
+{
+ s3c_gpio_cfgpin(GPIO_TA_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TA_EN, S3C_GPIO_PULL_UP);
+/* gpio_set_value(GPIO_TA_EN, 1); */
+
+ s3c_gpio_cfgpin(GPIO_TA_nCHG, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TA_nCHG, S3C_GPIO_PULL_UP);
+
+#if defined(CONFIG_MACH_P10_LTE_00_BD) || defined(CONFIG_MACH_P10_WIFI_00_BD)
+ /* GPIO_CHG_INT not supported */
+#else
+ /* IRQ to detect charger status change */
+ s3c_gpio_cfgpin(GPIO_CHG_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CHG_INT, S3C_GPIO_PULL_UP);
+#endif
+
+ return true;
+}
+
+static bool sec_bat_is_lpm(void)
+{
+ u32 val = __raw_readl(S5P_INFORM2);
+
+ pr_info("%s: LP charging: (INFORM2) 0x%x\n", __func__, val);
+
+ if (val == 0x1)
+ return true;
+
+ return false;
+}
+
+static void sec_bat_initial_check(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+ int ret = 0;
+
+ value.intval = gpio_get_value(GPIO_TA_nCONNECTED);
+ pr_debug("%s: %d\n", __func__, value.intval);
+
+ ret = psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value);
+ if (ret) {
+ pr_err("%s: fail to set power_suppy ONLINE property(%d)\n",
+ __func__, ret);
+ }
+}
+
+static bool sec_bat_check_jig_status(void)
+{
+ /* TODO: */
+ return false;
+}
+
+static void sec_bat_switch_to_check(void)
+{
+ pr_debug("%s\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_USB_SEL1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL1, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_SEL1, 0);
+
+ mdelay(300);
+}
+
+static void sec_bat_switch_to_normal(void)
+{
+ pr_debug("%s\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_USB_SEL1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL1, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_USB_SEL1, 1);
+}
+
+static int current_cable_type = POWER_SUPPLY_TYPE_BATTERY;
+
+static int sec_bat_check_cable_callback(void)
+{
+ return current_cable_type;
+}
+
+static bool sec_bat_check_cable_result_callback(
+ int cable_type)
+{
+ current_cable_type = cable_type;
+
+ switch (cable_type) {
+ case POWER_SUPPLY_TYPE_USB:
+ pr_info("%s set vbus applied\n",
+ __func__);
+ break;
+ case POWER_SUPPLY_TYPE_BATTERY:
+ pr_info("%s set vbus cut\n",
+ __func__);
+ break;
+ case POWER_SUPPLY_TYPE_MAINS:
+ default:
+ pr_err("%s cable type (%d)\n",
+ __func__, cable_type);
+ return false;
+ }
+
+ return true;
+}
+
+/* callback for battery check
+ * return : bool
+ * true - battery detected, false battery NOT detected
+ */
+static bool sec_bat_check_callback(void) { return true; }
+static bool sec_bat_check_result_callback(void) { return true; }
+
+/* callback for OVP/UVLO check
+ * return : int
+ * battery health
+ */
+static int sec_bat_ovp_uvlo_callback(void)
+{
+ int health;
+ health = POWER_SUPPLY_HEALTH_GOOD;
+
+ return health;
+}
+
+static bool sec_bat_ovp_uvlo_result_callback(int health) { return true; }
+
+/*
+ * val.intval : temperature
+ */
+static bool sec_bat_get_temperature_callback(
+ enum power_supply_property psp,
+ union power_supply_propval *val) { return true; }
+
+static bool sec_fg_fuelalert_process(bool is_fuel_alerted) { return true; }
+
+/* ADC region should be exclusive */
+static sec_bat_adc_region_t cable_adc_value_table[] = {
+ { 0, 500 }, /* POWER_SUPPLY_TYPE_BATTERY */
+ { 0, 0 }, /* POWER_SUPPLY_TYPE_UPS */
+ { 1000, 1500 }, /* POWER_SUPPLY_TYPE_MAINS */
+ { 0, 0 }, /* POWER_SUPPLY_TYPE_USB */
+ { 0, 0 }, /* POWER_SUPPLY_TYPE_OTG */
+ { 0, 0 }, /* POWER_SUPPLY_TYPE_DOCK */
+ { 0, 0 }, /* POWER_SUPPLY_TYPE_MISC */
+};
+
+/* charging current (mA, 0 - NOT supported) */
+/* matching with power_supply_type in power_supply.h */
+static sec_charging_current_t charging_current_table[] = {
+ {0, 0, 0, 0}, /* POWER_SUPPLY_TYPE_BATTERY */
+ {0, 0, 0, 0}, /* POWER_SUPPLY_TYPE_UPS */
+ {2000, 2000, 256, 0}, /* POWER_SUPPLY_TYPE_MAINS */
+ {500, 500, 256, 0}, /* POWER_SUPPLY_TYPE_USB */
+ {500, 500, 256, 0}, /* POWER_SUPPLY_TYPE_USB_DCP */
+ {500, 500, 256, 0}, /* POWER_SUPPLY_TYPE_USB_CDP */
+ {500, 500, 256, 0}, /* POWER_SUPPLY_TYPE_USB_ACA */
+ {0, 0, 0, 0}, /* POWER_SUPPLY_TYPE_OTG */
+ {0, 0, 0, 0}, /* POWER_SUPPLY_TYPE_DOCK */
+ {500, 500, 256, 0}, /* POWER_SUPPLY_TYPE_MISC */
+ {0, 0, 0, 0}, /* POWER_SUPPLY_TYPE_WIRELESS */
+};
+
+/* unit: seconds */
+static int polling_time_table[] = {
+ 10, /* BASIC */
+ 30, /* CHARGING */
+ 30, /* DISCHARGING */
+ 30, /* NOT_CHARGING */
+ 300, /* SLEEP */
+};
+
+/* for MAX17050, MAX17047 */
+static struct battery_data_t p10_battery_data[] = {
+ /* SDI battery data */
+ {
+ .Capacity = 0x2008,
+ .low_battery_comp_voltage = 3600,
+ .low_battery_table = {
+ /* range, slope, offset */
+ {-5000, 0, 0}, /* dummy for top limit */
+ {-1250, 0, 3320},
+ {-750, 97, 3451},
+ {-100, 96, 3461},
+ {0, 0, 3456},
+ },
+ .temp_adjust_table = {
+ /* range, slope, offset */
+ {47000, 122, 8950},
+ {60000, 200, 51000},
+ {100000, 0, 0}, /* dummy for top limit */
+ },
+ .type_str = "SDI",
+ }
+};
+
+static sec_battery_platform_data_t sec_battery_pdata = {
+ /* NO NEED TO BE CHANGED */
+ .initial_check = sec_bat_initial_check,
+ .bat_gpio_init = sec_bat_gpio_init,
+ .fg_gpio_init = sec_fg_gpio_init,
+ .chg_gpio_init = sec_chg_gpio_init,
+
+ .is_lpm = sec_bat_is_lpm,
+ .check_jig_status = sec_bat_check_jig_status,
+ .check_cable_callback =
+ sec_bat_check_cable_callback,
+ .cable_switch_check = sec_bat_switch_to_check,
+ .cable_switch_normal = sec_bat_switch_to_normal,
+ .check_cable_result_callback =
+ sec_bat_check_cable_result_callback,
+ .check_battery_callback =
+ sec_bat_check_callback,
+ .check_battery_result_callback =
+ sec_bat_check_result_callback,
+ .ovp_uvlo_callback = sec_bat_ovp_uvlo_callback,
+ .ovp_uvlo_result_callback =
+ sec_bat_ovp_uvlo_result_callback,
+ .fuelalert_process = sec_fg_fuelalert_process,
+ .get_temperature_callback =
+ sec_bat_get_temperature_callback,
+
+ .adc_api[SEC_BATTERY_ADC_TYPE_NONE] = {
+ .init = sec_bat_adc_none_init,
+ .exit = sec_bat_adc_none_exit,
+ .read = sec_bat_adc_none_read
+ },
+ .adc_api[SEC_BATTERY_ADC_TYPE_AP] = {
+ .init = sec_bat_adc_ap_init,
+ .exit = sec_bat_adc_ap_exit,
+ .read = sec_bat_adc_ap_read
+ },
+ .adc_api[SEC_BATTERY_ADC_TYPE_IC] = {
+ .init = sec_bat_adc_ic_init,
+ .exit = sec_bat_adc_ic_exit,
+ .read = sec_bat_adc_ic_read
+ },
+ .cable_adc_value = cable_adc_value_table,
+ .charging_current = charging_current_table,
+ .polling_time = polling_time_table,
+ /* NO NEED TO BE CHANGED */
+
+ .pmic_name = SEC_BATTERY_PMIC_NAME,
+
+ .adc_check_count = 7,
+ .adc_type = {
+ SEC_BATTERY_ADC_TYPE_IC, /* CABLE_CHECK */
+ SEC_BATTERY_ADC_TYPE_NONE, /* BAT_CHECK */
+ SEC_BATTERY_ADC_TYPE_NONE, /* TEMP */
+ SEC_BATTERY_ADC_TYPE_NONE, /* TEMP_AMB */
+ SEC_BATTERY_ADC_TYPE_NONE, /* FULL_CHECK */
+ },
+
+ /* Battery */
+ .vendor = "SDI SDI",
+ .technology = POWER_SUPPLY_TECHNOLOGY_LION,
+ .battery_data = (void *)p10_battery_data,
+ .bat_gpio_ta_nconnected = GPIO_TA_nCONNECTED,
+ .bat_polarity_ta_nconnected = 1, /* active HIGH */
+ .bat_irq = IRQ_EINT(0), /* GPIO_TA_INT */
+ .bat_irq_attr =
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ .cable_check_type =
+ SEC_BATTERY_CABLE_CHECK_NOUSBCHARGE |
+ SEC_BATTERY_CABLE_CHECK_INT,
+ .cable_source_type = SEC_BATTERY_CABLE_SOURCE_ADC,
+
+ .event_check = false,
+ .event_waiting_time = 60,
+
+ /* Monitor setting */
+ .polling_type = SEC_BATTERY_MONITOR_ALARM,
+ .monitor_initial_count = 3,
+
+ /* Battery check */
+ .battery_check_type = SEC_BATTERY_CHECK_NONE,
+ .check_count = 3,
+
+ /* Battery check by ADC */
+ .check_adc_max = 0,
+ .check_adc_min = 0,
+
+ /* OVP/UVLO check */
+ .ovp_uvlo_check_type = SEC_BATTERY_OVP_UVLO_CHGINT,
+
+ /* Temperature check */
+ .thermal_source = SEC_BATTERY_THERMAL_SOURCE_FG,
+
+ .temp_check_type = SEC_BATTERY_TEMP_CHECK_TEMP,
+ .temp_check_count = 3,
+ .temp_high_threshold_event = 650,
+ .temp_high_recovery_event = 450,
+ .temp_low_threshold_event = 0,
+ .temp_low_recovery_event = -50,
+ .temp_high_threshold_normal = 470,
+ .temp_high_recovery_normal = 400,
+ .temp_low_threshold_normal = 0,
+ .temp_low_recovery_normal = -30,
+ .temp_high_threshold_lpm = 600,
+ .temp_high_recovery_lpm = 420,
+ .temp_low_threshold_lpm = 2,
+ .temp_low_recovery_lpm = -30,
+
+ .full_check_type = SEC_BATTERY_FULLCHARGED_CHGGPIO,
+ .full_check_count = 3,
+ .full_check_adc_1st = 26500, /* CHECK ME */
+ .full_check_adc_2nd = 25800, /* CHECK ME */
+ .chg_gpio_full_check = GPIO_TA_nCHG, /* STAT of bq24191 */
+ .chg_polarity_full_check = 1,
+ .full_condition_type =
+ SEC_BATTERY_FULL_CONDITION_SOC |
+ SEC_BATTERY_FULL_CONDITION_OCV,
+ .full_condition_soc = 99,
+ .full_condition_ocv = 4170,
+
+ .recharge_condition_type =
+ SEC_BATTERY_RECHARGE_CONDITION_SOC |
+ SEC_BATTERY_RECHARGE_CONDITION_VCELL,
+ .recharge_condition_soc = 98,
+ .recharge_condition_avgvcell = 4150,
+ .recharge_condition_vcell = 4150,
+
+ .charging_total_time = 6 * 60 * 60,
+ .recharging_total_time = 90 * 60,
+ .charging_reset_time = 10 * 60,
+
+ /* Fuel Gauge */
+ .fg_irq = IRQ_EINT(19), /* GPIO_FUEL_ALERT */
+ .fg_irq_attr = IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ .fuel_alert_soc = 1,
+ .repeated_fuelalert = false,
+ .capacity_calculation_type =
+ SEC_FUELGAUGE_CAPACITY_TYPE_RAW,
+ /* SEC_FUELGAUGE_CAPACITY_TYPE_SCALE | */
+ /* SEC_FUELGAUGE_CAPACITY_TYPE_ATOMIC, */
+ .capacity_max = 1000,
+ .capacity_min = 0,
+
+ /* Charger */
+ .chg_gpio_en = GPIO_TA_EN,
+ .chg_polarity_en = 0, /* active LOW charge enable */
+ .chg_gpio_status = GPIO_TA_nCHG,
+ .chg_polarity_status = 0,
+#if defined(CONFIG_MACH_P10_LTE_00_BD) || defined(CONFIG_MACH_P10_WIFI_00_BD)
+ .chg_irq = 0,
+ .chg_irq_attr = 0,
+#else
+ .chg_irq = IRQ_EINT(4), /* GPIO_CHG_INT */
+ .chg_irq_attr = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+#endif
+ .chg_float_voltage = 4200,
+};
+
+static struct platform_device sec_device_battery = {
+ .name = "sec-battery",
+ .id = -1,
+ .dev.platform_data = &sec_battery_pdata,
+};
+
+static struct i2c_gpio_platform_data gpio_i2c_data_fuelgauge = {
+ .sda_pin = GPIO_FUEL_SDA_18V,
+ .scl_pin = GPIO_FUEL_SCL_18V,
+};
+
+struct platform_device sec_device_fuelgauge = {
+ .name = "i2c-gpio",
+ .id = SEC_FUELGAUGE_I2C_ID,
+ .dev.platform_data = &gpio_i2c_data_fuelgauge,
+};
+
+static struct i2c_board_info sec_brdinfo_fuelgauge[] __initdata = {
+ {
+ I2C_BOARD_INFO("sec-fuelgauge",
+ SEC_FUELGAUGE_I2C_SLAVEADDR),
+ .platform_data = &sec_battery_pdata,
+ },
+};
+
+static struct i2c_gpio_platform_data gpio_i2c_data_charger = {
+ .sda_pin = GPIO_CHG_SDA_18V,
+ .scl_pin = GPIO_CHG_SCL_18V,
+};
+
+struct platform_device sec_device_charger = {
+ .name = "i2c-gpio",
+ .id = SEC_CHARGER_I2C_ID,
+ .dev.platform_data = &gpio_i2c_data_charger,
+};
+
+static struct i2c_board_info sec_brdinfo_charger[] __initdata = {
+ {
+ I2C_BOARD_INFO("sec-charger",
+ SEC_CHARGER_I2C_SLAVEADDR),
+ .platform_data = &sec_battery_pdata,
+ },
+};
+
+static struct platform_device *sec_battery_devices[] __initdata = {
+ &sec_device_charger,
+ &sec_device_fuelgauge,
+ &sec_device_battery,
+};
+
+void __init p10_battery_init(void)
+{
+ platform_add_devices(
+ sec_battery_devices,
+ ARRAY_SIZE(sec_battery_devices));
+
+ i2c_register_board_info(
+ SEC_CHARGER_I2C_ID,
+ sec_brdinfo_charger,
+ ARRAY_SIZE(sec_brdinfo_charger));
+
+ i2c_register_board_info(
+ SEC_FUELGAUGE_I2C_ID,
+ sec_brdinfo_fuelgauge,
+ ARRAY_SIZE(sec_brdinfo_fuelgauge));
+}
+#endif /* CONFIG_BATTERY_SAMSUNG_P1X */
diff --git a/arch/arm/mach-exynos/p10-gpio.c b/arch/arm/mach-exynos/p10-gpio.c
new file mode 100644
index 0000000..3e6c9d3
--- /dev/null
+++ b/arch/arm/mach-exynos/p10-gpio.c
@@ -0,0 +1,580 @@
+/*
+ * linux/arch/arm/mach-exynos/p10-gpio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - GPIO setting in set board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio-midas.h>
+#include <plat/cpu.h>
+#include <mach/pmu.h>
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+/* this is sample code for p10 board */
+static struct gpio_init_data p10_init_gpios[] = {
+
+ /* BT_UART_RXD */
+ {EXYNOS5_GPA0(0), S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ /* BT_UART_TXD */
+ {EXYNOS5_GPA0(1), S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ /* BT_UART_CTS */
+ {EXYNOS5_GPA0(2), S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ /* BT_UART_RTS */
+ {EXYNOS5_GPA0(3), S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+
+ /* UART switch: configure as output */
+ {EXYNOS5_GPE0(5), S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ /* USB switch: configure as output */
+ {EXYNOS5_GPH0(1), S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS5_GPB2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SDA_1.8V */
+ {EXYNOS5_GPB2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SCL_1.8V */
+
+ {EXYNOS5_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* DET_3.5 */
+ {EXYNOS5_GPX0(2), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS5_GPX2(0), S3C_GPIO_SFN(2), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_UP */
+ {EXYNOS5_GPX2(1), S3C_GPIO_SFN(2), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_DOWN */
+ {EXYNOS5_GPX2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ADC_INT */
+ {EXYNOS5_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKE */
+};
+
+/* Initialize gpio set in p10 board */
+void p10_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(p10_init_gpios); i++) {
+ gpio = p10_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, p10_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, p10_init_gpios[i].pud);
+
+ if (p10_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, p10_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, p10_init_gpios[i].drv);
+ }
+}
+
+/* this table only for p10 board */
+static unsigned int exynos5_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_UP}, /* BT_UART_RXD */
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT1,
+ S3C_GPIO_PULL_NONE}, /* BT_UART_TXD */
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* BT_UART_CTS */
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT1,
+ S3C_GPIO_PULL_NONE}, /* BT_UART_RTS */
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* GPS_UART_RXD */
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* GPS_UART_TXD */
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* GPS_UART_CTS */
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* GPS_UART_RTS */
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* AP_RXD */
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* AP_TXD */
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* TSP_SDA_1.8V */
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* TSP_SCL_1.8V */
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* AP_FLM_RXD */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* AP_FLM_TXD */
+
+ {EXYNOS5_GPA2(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* CHG_SDA_1.8V */
+ {EXYNOS5_GPA2(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* CHG_SCL_1.8V */
+ {EXYNOS5_GPA2(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* AP_PMIC_SDA */
+ {EXYNOS5_GPA2(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* AP_PMIC_SCL */
+ {EXYNOS5_GPA2(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* 5M_SPI_CLK */
+ {EXYNOS5_GPA2(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* 5M_SPI_CS */
+ {EXYNOS5_GPA2(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* 5M_SPI_DI */
+ {EXYNOS5_GPA2(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* 5M_SPI_DO */
+
+ {EXYNOS5_GPB0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* AP_CP_INT */
+ {EXYNOS5_GPB0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CMC221_CPU_RST */
+ {EXYNOS5_GPB0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CMC_SPI_CLK_REQ */
+ {EXYNOS5_GPB0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPB0(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPB1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* BARO_INT */
+ {EXYNOS5_GPB1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPB1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPB1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPB1(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPB2(0), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* LCD_PWM_IN_1.8V */
+ {EXYNOS5_GPB2(1), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* MOTOR_PWM */
+ {EXYNOS5_GPB2(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* CODEC_SDA_1.8V */
+ {EXYNOS5_GPB2(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* CODEC_SCL_1.8V */
+
+ {EXYNOS5_GPB3(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MHL_DSDA_1.8V */
+ {EXYNOS5_GPB3(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MHL_DSCL_1.8V */
+ {EXYNOS5_GPB3(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* GSENSE_SDA_1.8V */
+ {EXYNOS5_GPB3(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS5_GPC0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_CLK */
+ {EXYNOS5_GPC0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_CMD */
+ {EXYNOS5_GPC0(2), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS5_GPC0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(0) */
+ {EXYNOS5_GPC0(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(1) */
+ {EXYNOS5_GPC0(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(2) */
+ {EXYNOS5_GPC0(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(3) */
+
+ {EXYNOS5_GPC1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPC1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPC1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPC1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(4) */
+ {EXYNOS5_GPC1(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(5) */
+ {EXYNOS5_GPC1(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(6) */
+ {EXYNOS5_GPC1(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NAND_D(7) */
+
+ {EXYNOS5_GPC2(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* T_FLASH_CLK */
+ {EXYNOS5_GPC2(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* T_FLASH_CMD */
+ {EXYNOS5_GPC2(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPC2(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(0) */
+ {EXYNOS5_GPC2(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(1) */
+ {EXYNOS5_GPC2(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(2) */
+ {EXYNOS5_GPC2(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* T_FLASH_D(3) */
+
+ {EXYNOS5_GPC3(0), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_CLK */
+ {EXYNOS5_GPC3(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_CMD */
+ {EXYNOS5_GPC3(2), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* OTG_EN */
+ {EXYNOS5_GPC3(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(0) */
+ {EXYNOS5_GPC3(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(1) */
+ {EXYNOS5_GPC3(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(2) */
+ {EXYNOS5_GPC3(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* WLAN_SDIO_D(3) */
+
+ {EXYNOS5_GPD0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* FUEL_SDA_1.8V */
+ {EXYNOS5_GPD0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* FUEL_SCL_1.8V */
+ {EXYNOS5_GPD0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* BSENSE_SDA_1.8V */
+ {EXYNOS5_GPD0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* BSENSE_SCL_1.8V */
+ {EXYNOS5_GPD0(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MHL_SDA_1.8V */
+ {EXYNOS5_GPD0(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MHL_SCL_1.8V */
+ {EXYNOS5_GPD0(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* LCDP_SCL__1.8V */
+ {EXYNOS5_GPD0(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* LCDP_SDA__1.8V */
+
+ {EXYNOS5_GPD1(0), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* HDMI_EN */
+ {EXYNOS5_GPD1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPD1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MOTOR_SDA_1.8V */
+ {EXYNOS5_GPD1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MOTOR_SCL_1.8V */
+ {EXYNOS5_GPD1(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* LCD_ID */
+ {EXYNOS5_GPD1(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CMC_PMIC_PWRON */
+ {EXYNOS5_GPD1(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NFC_EN, NC */
+ {EXYNOS5_GPD1(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NFC_FIRMWARE, NC */
+
+ {EXYNOS5_GPE0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CIS_nRST */
+ {EXYNOS5_GPE0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* CHG_SDA_1.8V */
+ {EXYNOS5_GPE0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* CHG_SCL_1.8V */
+ {EXYNOS5_GPE0(3), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* PDA_ACTIVE */
+ {EXYNOS5_GPE0(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* ACCESSORY_CHECK */
+ {EXYNOS5_GPE0(5), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* UART_SEL */
+ {EXYNOS5_GPE0(6), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* GPS_nRST */
+ {EXYNOS5_GPE0(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* ISP_TXD */
+
+ {EXYNOS5_GPE1(0), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* GPS_EN */
+ {EXYNOS5_GPE1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* ISP_RXD */
+
+ {EXYNOS5_GPF0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* 5M_CAM_SDA_1.8V */
+ {EXYNOS5_GPF0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* 5M_CAM_SCL_1.8V */
+ {EXYNOS5_GPF0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* VT_CAM_SDA_1.8V */
+ {EXYNOS5_GPF0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* VT_CAM_SCL_1.8V */
+
+ {EXYNOS5_GPF1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPF1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPF1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPF1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPG0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* ALS_SDA_1.8V */
+ {EXYNOS5_GPG0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /*ALS_SCL_1.8V */
+ {EXYNOS5_GPG0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* USB3.0_EN */
+ {EXYNOS5_GPG0(3), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* FM34_PWDN */
+ {EXYNOS5_GPG0(4), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* FM34_RESET */
+ {EXYNOS5_GPG0(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* MHL_INT */
+ {EXYNOS5_GPG0(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* MHL_RST */
+
+ {EXYNOS5_GPG1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CAM_FLASH_EN */
+ {EXYNOS5_GPG1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CAM_FLASH_SET */
+ {EXYNOS5_GPG1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* TOUCH_CHG */
+ {EXYNOS5_GPG1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* TOUCH_RESET */
+ {EXYNOS5_GPG1(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* TA_nCHG */
+ {EXYNOS5_GPG1(5), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* TA_EN */
+ {EXYNOS5_GPG1(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CAM_VT_nRST */
+ {EXYNOS5_GPG1(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPG2(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPG2(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* VTCAM_MCLK */
+
+ {EXYNOS5_GPH0(0), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* WLAN_EN */
+ {EXYNOS5_GPH0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* USB_SEL1 */
+ {EXYNOS5_GPH0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPH0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CAM_MCLK */
+
+ {EXYNOS5_GPH1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPH1(1), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* CODEC_LDO_EN */
+ {EXYNOS5_GPH1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* LIGHT_nINT */
+ {EXYNOS5_GPH1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* BT_WAKE */
+ {EXYNOS5_GPH1(4), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* FM34_BYPASS */
+ {EXYNOS5_GPH1(5), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* ACCESSORY_EN */
+ {EXYNOS5_GPH1(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPH1(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* LCD_EN */
+
+ {EXYNOS5_GPV0(0), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* BUCK4_SEL */
+ {EXYNOS5_GPV0(1), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* BUCK3_SEL */
+ {EXYNOS5_GPV0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* 5M_CORE_EN */
+ {EXYNOS5_GPV0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* CAM_IO_EN */
+ {EXYNOS5_GPV0(4), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* BUCK2_SEL */
+ {EXYNOS5_GPV0(5), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* PMIC_DVS3 */
+ {EXYNOS5_GPV0(6), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* PMIC_DVS2 */
+ {EXYNOS5_GPV0(7), S3C_GPIO_SLP_OUT0,
+ S3C_GPIO_PULL_NONE}, /* PMIC_DVS1 */
+
+ {EXYNOS5_GPV1(0), S3C_GPIO_SLP_PREV,
+ S3C_GPIO_PULL_NONE}, /* WLAN_WAKE */
+ {EXYNOS5_GPV1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* HW_REV3 */
+ {EXYNOS5_GPV1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* HW_REV2 */
+ {EXYNOS5_GPV1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* HW_REV1 */
+ {EXYNOS5_GPV1(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* HW_REV0 */
+ {EXYNOS5_GPV1(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV1(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV1(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPV2(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV2(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV2(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV2(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV2(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* HUM_SCL_1.8V */
+ {EXYNOS5_GPV2(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* HUM_SDA_1.8V */
+ {EXYNOS5_GPV2(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MSENSE_SCL_1.8V */
+ {EXYNOS5_GPV2(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* MSENSE_SDA_1.8V */
+
+ {EXYNOS5_GPV3(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* ADC_SCL_1.8V */
+ {EXYNOS5_GPV3(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_NONE}, /* ADC_SDA_1.8V */
+ {EXYNOS5_GPV3(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV3(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV3(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV3(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV3(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPV3(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPY0(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_CSN */
+ {EXYNOS5_GPY0(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY0(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY0(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY0(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_REN */
+ {EXYNOS5_GPY0(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_WEN */
+
+ {EXYNOS5_GPY1(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY1(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY1(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY1(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPY2(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* TF_EN */
+ {EXYNOS5_GPY2(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY2(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY2(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY2(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY2(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPY3(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(0) */
+ {EXYNOS5_GPY3(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(1) */
+ {EXYNOS5_GPY3(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(2) */
+ {EXYNOS5_GPY3(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(3) */
+ {EXYNOS5_GPY3(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(4) */
+ {EXYNOS5_GPY3(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(5) */
+ {EXYNOS5_GPY3(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(6) */
+ {EXYNOS5_GPY3(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(7) */
+
+ {EXYNOS5_GPY4(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(8) */
+ {EXYNOS5_GPY4(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(9) */
+ {EXYNOS5_GPY4(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(10) */
+ {EXYNOS5_GPY4(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(11) */
+ {EXYNOS5_GPY4(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(12) */
+ {EXYNOS5_GPY4(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_A(13) */
+ {EXYNOS5_GPY4(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPY4(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS5_GPY5(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(0) */
+ {EXYNOS5_GPY5(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(1) */
+ {EXYNOS5_GPY5(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(2) */
+ {EXYNOS5_GPY5(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(3) */
+ {EXYNOS5_GPY5(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(4) */
+ {EXYNOS5_GPY5(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(5) */
+ {EXYNOS5_GPY5(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(6) */
+ {EXYNOS5_GPY5(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(7) */
+
+ {EXYNOS5_GPY6(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(8) */
+ {EXYNOS5_GPY6(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(9) */
+ {EXYNOS5_GPY6(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(10) */
+ {EXYNOS5_GPY6(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(11) */
+ {EXYNOS5_GPY6(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(12) */
+ {EXYNOS5_GPY6(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(13) */
+ {EXYNOS5_GPY6(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(14) */
+ {EXYNOS5_GPY6(7), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* DPRAM_D(15) */
+
+ {EXYNOS5_GPZ(0), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* MM_I2S_CLK */
+ {EXYNOS5_GPZ(1), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPZ(2), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* MM_I2S_SYNC */
+ {EXYNOS5_GPZ(3), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* MM_I2S_DI */
+ {EXYNOS5_GPZ(4), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* MM_I2S_DO */
+ {EXYNOS5_GPZ(5), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS5_GPZ(6), S3C_GPIO_SLP_INPUT,
+ S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+/* To save power consumption, gpio pin set before enterling sleep */
+void p10_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(exynos5_sleep_gpio_table),
+ exynos5_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos/p10-input.c b/arch/arm/mach-exynos/p10-input.c
new file mode 100644
index 0000000..0e781a2
--- /dev/null
+++ b/arch/arm/mach-exynos/p10-input.c
@@ -0,0 +1,347 @@
+/*
+ * arch/arm/mach-exynos/p4-input.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT1664S)
+#include <linux/i2c/mxt1664s.h>
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO)
+#include <mach/sec_debug.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#endif
+
+#define GPIO_TOUCH_EN EXYNOS5_GPD1(1)
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_MXT1664S)
+
+static int ts_power_on(void)
+{
+ struct regulator *regulator;
+
+ /* touch reset pin */
+ s3c_gpio_cfgpin(GPIO_TOUCH_RESET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TOUCH_RESET, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TOUCH_RESET, 0);
+
+ /* touch xvdd en pin */
+ s3c_gpio_cfgpin(GPIO_TOUCH_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TOUCH_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TOUCH_EN, 0);
+
+ regulator = regulator_get(NULL, "touch_vdd_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "[TSP]ts_power_on : regulator_get failed\n");
+ return -EIO;
+ }
+
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "touch_avdd");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "[TSP]ts_power_on : regulator_get failed\n");
+ return -EIO;
+ }
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ /* enable touch xvdd */
+ gpio_set_value(GPIO_TOUCH_EN, 1);
+
+ /* reset ic */
+ mdelay(1);
+ gpio_set_value(GPIO_TOUCH_RESET, 1);
+
+ /* touch interrupt pin */
+ /* s3c_gpio_cfgpin(GPIO_TOUCH_CHG, S3C_GPIO_INPUT); */
+
+ s3c_gpio_cfgpin(GPIO_TOUCH_CHG, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_TOUCH_CHG, S3C_GPIO_PULL_NONE);
+
+ msleep(MXT_1664S_HW_RESET_TIME);
+
+ printk(KERN_ERR "mxt_power_on is finished\n");
+
+ return 0;
+}
+
+static int ts_power_off(void)
+{
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "touch_avdd");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "[TSP]ts_power_off : regulator_get failed\n");
+ return -EIO;
+ }
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+
+ /* CAUTION : EVT1 board has CHG_INT problem
+ * so it need a workaround code to ensure charging during sleep mode
+ */
+ if (system_rev != 2) {
+ regulator = regulator_get(NULL, "touch_vdd_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "[TSP]ts_power_on : regulator_get failed\n");
+ return -EIO;
+ }
+
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+
+ regulator_put(regulator);
+ }
+
+ /* touch interrupt pin */
+ s3c_gpio_cfgpin(GPIO_TOUCH_CHG, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_TOUCH_CHG, S3C_GPIO_PULL_NONE);
+
+ /* touch reset pin */
+ s3c_gpio_cfgpin(GPIO_TOUCH_RESET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TOUCH_RESET, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TOUCH_RESET, 0);
+
+ /* touch xvdd en pin */
+ s3c_gpio_cfgpin(GPIO_TOUCH_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TOUCH_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TOUCH_EN, 0);
+
+ printk(KERN_ERR "mxt_power_off is finished\n");
+
+ return 0;
+}
+
+/*
+ Configuration for MXT1664-S
+*/
+#define MXT1664S_MAX_MT_FINGERS 10
+#define MXT1664S_BLEN_BATT 208
+#define MXT1664S_CHRGTIME_BATT 130
+#define MXT1664S_THRESHOLD_BATT 70
+
+static u8 t7_config_s[] = { GEN_POWERCONFIG_T7,
+ 255, 255, 50, 3
+};
+
+static u8 t8_config_s[] = { GEN_ACQUISITIONCONFIG_T8,
+ MXT1664S_CHRGTIME_BATT, 0, 10, 10, 0, 0, 20, 35, 0, 0
+};
+
+static u8 t9_config_s[] = { TOUCH_MULTITOUCHSCREEN_T9,
+ 139, 0, 0, 32, 52, 0, MXT1664S_BLEN_BATT, MXT1664S_THRESHOLD_BATT, 2, 1,
+ 0, 5, 2, 0, MXT1664S_MAX_MT_FINGERS, 10, 20, 20, 63, 6,
+ 255, 9, 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 15, 42, 42, 0, 0
+};
+
+static u8 t15_config_s[] = { TOUCH_KEYARRAY_T15,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+static u8 t18_config_s[] = { SPT_COMCONFIG_T18,
+ 0, 0
+};
+
+static u8 t24_config_s[] = {
+ PROCI_ONETOUCHGESTUREPROCESSOR_T24,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t25_config_s[] = {
+ SPT_SELFTEST_T25,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 200
+};
+
+static u8 t27_config_s[] = {
+ PROCI_TWOTOUCHGESTUREPROCESSOR_T27,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+static u8 t40_config_s[] = { PROCI_GRIPSUPPRESSION_T40,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t42_config_s[] = { PROCI_TOUCHSUPPRESSION_T42,
+ 0, 60, 100, 60, 0, 20, 0, 0, 0, 0
+};
+
+static u8 t43_config_s[] = { SPT_DIGITIZER_T43,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+static u8 t46_config_s[] = { SPT_CTECONFIG_T46,
+ 4, 0, 24, 24, 0, 0, 2, 0, 0, 0,
+ 0
+};
+
+static u8 t47_config_s[] = { PROCI_STYLUS_T47,
+ 73, 20, 45, 4, 5, 30, 1, 120, 3, 32,
+ 0, 0, 15, 0, 32, 230, 0, 0, 0, 0
+};
+
+static u8 t55_config_s[] = {ADAPTIVE_T55,
+ 0, 0, 0, 0, 0, 0
+};
+
+static u8 t56_config_s[] = {PROCI_SHIELDLESS_T56,
+ 1, 0, 1, 24, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 2, 16, 0, 2,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+static u8 t57_config_s[] = {PROCI_EXTRATOUCHSCREENDATA_T57,
+ 226, 25, 0
+};
+
+static u8 t61_config_s[] = {SPT_TIMER_T61,
+ 0, 0, 0, 0, 0
+};
+
+static u8 t62_config_s[] = {PROCG_NOISESUPPRESSION_T62,
+ 3, 0, 0, 23, 2, 0, 0, 0, 50, 0,
+ 0, 0, 0, 0, 5, 0, 10, 3, 5, 144,
+ 50, 20, 48, 20, 100, 16, 16, 4, 255, 0,
+ 0, 0, 0, 0, 176, 80, 2, 5, 1, 48,
+ 10, 20, 30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+static u8 end_config_s[] = { RESERVED_T255 };
+
+static const u8 *MXT1644S_config[] = {
+ t7_config_s,
+ t8_config_s,
+ t9_config_s,
+ t15_config_s,
+ t18_config_s,
+ t24_config_s,
+ t25_config_s,
+ t27_config_s,
+ t40_config_s,
+ t42_config_s,
+ t43_config_s,
+ t46_config_s,
+ t47_config_s,
+ t55_config_s,
+ t56_config_s,
+ t57_config_s,
+ t61_config_s,
+ t62_config_s,
+ end_config_s,
+};
+
+static struct mxt_platform_data mxt_data = {
+ .max_finger_touches = MXT1664S_MAX_MT_FINGERS,
+ .gpio_read_done = GPIO_TOUCH_CHG,
+ .min_x = 0,
+ .max_x = 2559,
+ .min_y = 0,
+ .max_y = 1599,
+ .min_z = 0,
+ .max_z = 255,
+ .min_w = 0,
+ .max_w = 255,
+ .config = MXT1644S_config,
+ .power_on = ts_power_on,
+ .power_off = ts_power_off,
+ .boot_address = 0x26,
+};
+#endif
+
+static struct i2c_board_info i2c_devs3[] __initdata = {
+ {
+ I2C_BOARD_INFO(MXT_DEV_NAME, 0x4A),
+ .platform_data = &mxt_data,
+ }
+};
+
+void __init p10_tsp_init(void)
+{
+ int gpio;
+
+ gpio = GPIO_TOUCH_CHG;
+ gpio_request(gpio, "TSP_INT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_register_gpio_interrupt(GPIO_TOUCH_CHG);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+
+ s3c_i2c3_set_platdata(NULL);
+ i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));
+
+ printk(KERN_ERR "%s touch : %d\n", __func__, i2c_devs3[0].irq);
+}
+
+#if defined(CONFIG_KEYBOARD_GPIO)
+#if defined(CONFIG_SEC_DEBUG)
+#define GPIO_KEYS(_code, _gpio, _active_low, _iswake, _hook) \
+ { \
+ .code = _code, \
+ .gpio = _gpio, \
+ .active_low = _active_low, \
+ .type = EV_KEY, \
+ .wakeup = _iswake, \
+ .debounce_interval = 10, \
+ .isr_hook = _hook, \
+ .value = 1 \
+ }
+
+struct gpio_keys_button p10_buttons[] = {
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN,
+ 1, 0, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+};
+#endif
+
+struct gpio_keys_platform_data p10_gpiokeys_platform_data = {
+ p10_buttons,
+ ARRAY_SIZE(p10_buttons),
+};
+
+static struct platform_device p10_keypad = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &p10_gpiokeys_platform_data,
+ },
+};
+#endif
+
+void __init p10_key_init(void)
+{
+#if defined(CONFIG_KEYBOARD_GPIO)
+ platform_device_register(&p10_keypad);
+#endif
+}
+
diff --git a/arch/arm/mach-exynos/p10-mhl.c b/arch/arm/mach-exynos/p10-mhl.c
new file mode 100644
index 0000000..cb36311
--- /dev/null
+++ b/arch/arm/mach-exynos/p10-mhl.c
@@ -0,0 +1,130 @@
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/sii9234.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include "midas.h"
+
+#ifdef CONFIG_SAMSUNG_MHL
+#define I2C_BUS_ID_MHL 15
+static void sii9234_cfg_gpio(void)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+
+ /* AP_MHL_SDA */
+ s3c_gpio_cfgpin(GPIO_MHL_SDA_18V, S3C_GPIO_SFN(0x0));
+ s3c_gpio_setpull(GPIO_MHL_SDA_18V, S3C_GPIO_PULL_NONE);
+
+ /* AP_MHL_SCL */
+ s3c_gpio_cfgpin(GPIO_MHL_SCL_18V, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_MHL_SCL_18V, S3C_GPIO_PULL_NONE);
+
+
+ gpio_request(GPIO_MHL_INT, "MHL_INT");
+ s5p_register_gpio_interrupt(GPIO_MHL_INT);
+ s3c_gpio_setpull(GPIO_MHL_INT, S3C_GPIO_PULL_DOWN);
+ irq_set_irq_type(MHL_INT_IRQ, IRQ_TYPE_EDGE_RISING);
+ s3c_gpio_cfgpin(GPIO_MHL_INT, GPIO_MHL_INT_AF);
+
+ s3c_gpio_cfgpin(GPIO_HDMI_EN, S3C_GPIO_OUTPUT); /* HDMI_EN */
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_setpull(GPIO_HDMI_EN, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+}
+
+static void sii9234_power_onoff(bool on)
+{
+ printk(KERN_INFO "%s(%d)\n", __func__, on);
+
+ if (on) {
+ /* To avoid floating state of the HPD pin *
+ * in the absence of external pull-up */
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_HIGH);
+
+ s3c_gpio_setpull(GPIO_MHL_SCL_18V, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_setpull(GPIO_MHL_SCL_18V, S3C_GPIO_PULL_NONE);
+
+ /* sii9234_unmaks_interrupt(); // - need to add */
+ /* VCC_SUB_2.0V is always on */
+ } else {
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+
+ /* To avoid floating state of the HPD pin *
+ * in the absence of external pull-up */
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_DOWN);
+ gpio_set_value(GPIO_HDMI_EN, GPIO_LEVEL_LOW);
+
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ }
+}
+
+static void sii9234_reset(void)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_MHL_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_MHL_RST, S3C_GPIO_PULL_NONE);
+
+
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_LOW);
+ usleep_range(10000, 20000);
+ gpio_set_value(GPIO_MHL_RST, GPIO_LEVEL_HIGH);
+}
+
+
+
+static struct sii9234_platform_data sii9234_pdata = {
+ .init = sii9234_cfg_gpio,
+ .mhl_sel = NULL,
+ .hw_onoff = sii9234_power_onoff,
+ .hw_reset = sii9234_reset,
+ .enable_vbus = NULL,
+ .vbus_present = NULL,
+};
+
+static struct i2c_board_info __initdata i2c_devs_sii9234[] = {
+ {
+ I2C_BOARD_INFO("sii9234_mhl_tx", 0x72>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_tpi", 0x7A>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_hdmi_rx", 0x92>>1),
+ .platform_data = &sii9234_pdata,
+ },
+ {
+ I2C_BOARD_INFO("sii9234_cbus", 0xC8>>1),
+ .platform_data = &sii9234_pdata,
+ },
+};
+
+static struct i2c_board_info i2c_dev_hdmi_ddc __initdata = {
+ I2C_BOARD_INFO("s5p_ddc", (0x74 >> 1)),
+};
+
+static int __init p10_mhl_init(void)
+{
+ i2c_add_devices(I2C_BUS_ID_MHL, i2c_devs_sii9234,
+ ARRAY_SIZE(i2c_devs_sii9234));
+
+ i2c_add_devices(sii9234_pdata.ddc_i2c_num, &i2c_dev_hdmi_ddc, 1);
+
+ return 0;
+}
+module_init(p10_mhl_init);
+#endif
diff --git a/arch/arm/mach-exynos/p10-switch.c b/arch/arm/mach-exynos/p10-switch.c
new file mode 100644
index 0000000..977b6e5
--- /dev/null
+++ b/arch/arm/mach-exynos/p10-switch.c
@@ -0,0 +1,239 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/semaphore.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio.h>
+#include <mach/usb_switch.h>
+
+struct device *sec_switch_dev;
+
+enum usb_path_t current_path = USB_PATH_NONE;
+
+static struct semaphore usb_switch_sem;
+
+static bool usb_connected;
+
+static ssize_t show_usb_sel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const char *mode;
+
+ if (current_path & USB_PATH_CP) {
+ /* CP */
+ mode = "MODEM";
+ } else {
+ /* AP */
+ mode = "PDA";
+ }
+
+ pr_info("%s: %s\n", __func__, mode);
+
+ return sprintf(buf, "%s\n", mode);
+}
+
+static ssize_t store_usb_sel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ pr_info("%s: %s\n", __func__, buf);
+
+ if (!strncasecmp(buf, "PDA", 3)) {
+ usb_switch_lock();
+ usb_switch_clr_path(USB_PATH_CP);
+ usb_switch_unlock();
+ } else if (!strncasecmp(buf, "MODEM", 5)) {
+ usb_switch_lock();
+ usb_switch_set_path(USB_PATH_CP);
+ usb_switch_unlock();
+ } else {
+ pr_err("%s: wrong usb_sel value(%s)!!\n", __func__, buf);
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t show_uart_sel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int val_sel;
+ const char *mode;
+
+ val_sel = gpio_get_value(GPIO_UART_SEL);
+
+ if (val_sel == 0) {
+ /* CP */
+ mode = "CP";
+ } else {
+ /* AP */
+ mode = "AP";
+ }
+
+ pr_info("%s: %s\n", __func__, mode);
+
+ return sprintf(buf, "%s\n", mode);
+}
+
+static ssize_t store_uart_sel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int uart_sel = -1;
+
+ pr_info("%s: %s\n", __func__, buf);
+
+ if (!strncasecmp(buf, "AP", 2)) {
+ uart_sel = 1;
+ } else if (!strncasecmp(buf, "CP", 2)) {
+ uart_sel = 0;
+ } else {
+ pr_err("%s: wrong uart_sel value(%s)!!\n", __func__, buf);
+ return -EINVAL;
+ }
+
+ /* 1 for AP, 0 for CP */
+ gpio_set_value(GPIO_UART_SEL, uart_sel);
+
+ return count;
+}
+
+static ssize_t show_usb_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const char *state;
+
+ if (usb_connected)
+ state = "USB_STATE_CONFIGURED";
+ else
+ state = "USB_STATE_NOTCONFIGURED";
+
+ pr_info("%s: %s\n", __func__, state);
+
+ return sprintf(buf, "%s\n", state);
+}
+
+static DEVICE_ATTR(usb_sel, 0664, show_usb_sel, store_usb_sel);
+static DEVICE_ATTR(uart_sel, 0664, show_uart_sel, store_uart_sel);
+static DEVICE_ATTR(usb_state, S_IRUGO, show_usb_state, NULL);
+
+static struct attribute *px_switch_attributes[] = {
+ &dev_attr_usb_sel.attr,
+ &dev_attr_uart_sel.attr,
+ &dev_attr_usb_state.attr,
+ NULL
+};
+
+static const struct attribute_group px_switch_group = {
+ .attrs = px_switch_attributes,
+};
+
+void set_usb_connection_state(bool connected)
+{
+ pr_info("%s: set %s\n", __func__, (connected ? "True" : "False"));
+
+ if (usb_connected != connected) {
+ usb_connected = connected;
+
+ pr_info("%s: send \"usb_state\" sysfs_notify\n", __func__);
+ sysfs_notify(&sec_switch_dev->kobj, NULL, "usb_state");
+ }
+}
+
+static void usb_apply_path(enum usb_path_t path)
+{
+ pr_info("%s: current gpio before changing : sel1:%d\n",
+ __func__, gpio_get_value(GPIO_USB_SEL1));
+ pr_info("%s: target path %x\n", __func__, path);
+
+ if (path & USB_PATH_ADCCHECK) {
+ gpio_set_value(GPIO_USB_SEL1, 0);
+ return;
+ }
+
+ /* default : AP */
+ gpio_set_value(GPIO_USB_SEL1, 1);
+ return;
+
+}
+
+/*
+ Typical usage of usb switch:
+
+ usb_switch_lock(); (alternatively from hard/soft irq context)
+ ( or usb_switch_trylock() )
+ ...
+ usb_switch_set_path(USB_PATH_ADCCHECK);
+ ...
+ usb_switch_set_path(USB_PATH_TA);
+ ...
+ usb_switch_unlock(); (this restores previous usb switch settings)
+*/
+void usb_switch_set_path(enum usb_path_t path)
+{
+ pr_info("%s: %x current_path before changing\n",
+ __func__, current_path);
+
+ current_path |= path;
+ usb_apply_path(current_path);
+}
+
+void usb_switch_clr_path(enum usb_path_t path)
+{
+ pr_info("%s: %x current_path before changing\n",
+ __func__, current_path);
+
+ current_path &= ~path;
+ usb_apply_path(current_path);
+}
+
+int usb_switch_lock(void)
+{
+ return down_interruptible(&usb_switch_sem);
+}
+
+int usb_switch_trylock(void)
+{
+ return down_trylock(&usb_switch_sem);
+}
+
+void usb_switch_unlock(void)
+{
+ up(&usb_switch_sem);
+}
+
+static int __init usb_switch_init(void)
+{
+ int ret;
+
+ gpio_request(GPIO_USB_SEL1, "GPIO_USB_SEL1");
+ gpio_request(GPIO_UART_SEL, "GPIO_UART_SEL");
+
+ gpio_export(GPIO_USB_SEL1, 1);
+ gpio_export(GPIO_UART_SEL, 1);
+
+ BUG_ON(!sec_class);
+ sec_switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
+
+ BUG_ON(!sec_switch_dev);
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL1", GPIO_USB_SEL1);
+ gpio_export_link(sec_switch_dev, "GPIO_UART_SEL", GPIO_UART_SEL);
+
+ /*init_MUTEX(&usb_switch_sem);*/
+ sema_init(&usb_switch_sem, 1);
+
+ /* create sysfs group */
+ ret = sysfs_create_group(&sec_switch_dev->kobj, &px_switch_group);
+ if (ret) {
+ pr_err("failed to create px switch attribute group\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+device_initcall(usb_switch_init);
diff --git a/arch/arm/mach-exynos/p10-wlan.h b/arch/arm/mach-exynos/p10-wlan.h
new file mode 100644
index 0000000..4c71e83
--- /dev/null
+++ b/arch/arm/mach-exynos/p10-wlan.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-s5pv210/u1.h
+ */
+
+#ifndef __P10_H__
+#define __P10_H__
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+extern int brcm_wlan_init(void);
+
+#endif
diff --git a/arch/arm/mach-exynos/p2-gpio.c b/arch/arm/mach-exynos/p2-gpio.c
new file mode 100644
index 0000000..9a7de23
--- /dev/null
+++ b/arch/arm/mach-exynos/p2-gpio.c
@@ -0,0 +1,574 @@
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio.h>
+#include "px.h"
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data p2_init_gpios[] = {
+ {
+ .num = EXYNOS4_GPD0(2), /* MSENSOR_MHL_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD0(3), /* MSENSOR_MHL_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD1(2), /* SENSE_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD1(3), /* SENSE_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPK2(2), /* PS_ALS_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPK3(2), /* PS_ALS_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, { /* GPY0 */
+ .num = EXYNOS4_GPY0(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY0(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY0(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY0(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY0(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY0(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, { /* GPY1 */
+ .num = EXYNOS4_GPY1(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY1(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY1(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY1(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, { /* GPY2 */
+ .num = EXYNOS4_GPY2(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY2(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY2(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY2(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY2(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY2(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, { /* GPY3 */
+ .num = EXYNOS4_GPY3(1),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY3(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, { /* GPY4 */
+ .num = EXYNOS4_GPY4(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, { /* GPY6 */
+ .num = EXYNOS4_GPY6(0),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY6(2),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY6(3),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY6(4),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPY6(5),
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ },
+ /* BT UART */
+ {GPIO_BT_RXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ {GPIO_BT_TXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_BT_CTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_BT_RTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ /* GPS UART */
+ {GPIO_GPS_RXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ {GPIO_GPS_TXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_CTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_RTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+
+ /* UART switch: configure as output */
+ {GPIO_UART_SEL, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* USB switch: configure as output */
+ {GPIO_USB_SEL1, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_SEL2, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_SEL3, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* JIG On */
+ {GPIO_IF_CON_SENSE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* 30PIN CONNECTOR */
+ {GPIO_DOCK_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* MIC */
+ {GPIO_EAR_MIC_BIAS_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+
+ /*** GPX ***/
+ {GPIO_GYRO_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+/* REMOTE_SENSE_IRQ */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_ACCESSORY_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_MSENSE_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_FUEL_ALERT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* {GPIO_BT_HOST_WAKE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE}, */
+ {GPIO_DET_35, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_OTG_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+ /* T_FLASH_DETECT */
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* TA_nCONNECTED */
+ {EXYNOS4_GPX3(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_HDMI_HPD, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+};
+
+void p2_config_gpio_table(void)
+{
+ u32 i, gpio;
+ u32 gps_gpio1, gps_gpio2;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(p2_init_gpios); i++) {
+ gpio = p2_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, p2_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, p2_init_gpios[i].pud);
+
+ if (p2_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, p2_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, p2_init_gpios[i].drv);
+ }
+ /* Set GPIO_GPS_nRST 2.8V Domain for HW rev 05 above
+ * Set GPIO_GPS_nRST 1.8V Domain for HW rev 04 under
+ */
+ if (system_rev >= 5) {
+ gps_gpio1 = GPIO_GPS_nRST_28V;
+ gps_gpio2 = GPIO_GPS_nRST; /* NC */
+ } else {
+ gps_gpio1 = GPIO_GPS_nRST;
+ gps_gpio2 = GPIO_GPS_nRST_28V; /* NC */
+ }
+
+ gpio_set_value(gps_gpio1, 1);
+ s3c_gpio_cfgpin(gps_gpio1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gps_gpio1, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gps_gpio1, 0);
+
+ gpio_set_value(gps_gpio2, 0);
+ s3c_gpio_cfgpin(gps_gpio2, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gps_gpio2, S3C_GPIO_PULL_NONE);
+}
+
+/* this table only for p2 board */
+static unsigned int p2_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* IRDA_nINT */
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* IRDA_nRST */
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /* IRDA_SCL_2.8V */
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* IRDA_SDA_2.8V */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* GPS_nRST 2.8V */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* MHL_SDA_1.8V */
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ /* MHL_SCL_1.8V */
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* USB_SEL2 */
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* GPIO_PDA_ACTIVE */
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* V_ACCESSORY_5V CHECK */
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* USB_SEL3 */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* GPIO_CP_REQ_RESET */
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ /* GPIO_UART_SEL */
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ /* HW_REV0 */
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV1 */
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV2 */
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV3 */
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* GPS_nRST */
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ /* ACCESSORY_EN */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TA_EN */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void p2_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(p2_sleep_gpio_table),
+ p2_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos/p4-gpio.c b/arch/arm/mach-exynos/p4-gpio.c
new file mode 100644
index 0000000..3b691cb
--- /dev/null
+++ b/arch/arm/mach-exynos/p4-gpio.c
@@ -0,0 +1,488 @@
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio.h>
+#include "px.h"
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data p4_init_gpios[] = {
+ {
+ .num = EXYNOS4_GPD0(2), /* MSENSOR_MHL_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD0(3), /* MSENSOR_MHL_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD1(2), /* SENSE_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD1(3), /* SENSE_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPK2(2), /* PS_ALS_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPK3(2), /* PS_ALS_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ },
+ /* BT UART */
+ {GPIO_BT_RXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ {GPIO_BT_TXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_BT_CTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_BT_RTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ /* GPS UART */
+ {GPIO_GPS_RXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ {GPIO_GPS_TXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_CTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_RTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_nRST, S3C_GPIO_OUTPUT, 1, S3C_GPIO_PULL_UP},
+ {GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+
+ /* UART switch: configure as output */
+ {GPIO_UART_SEL, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* USB switch: configure as output */
+ {GPIO_USB_SEL1, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_SEL2, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_SEL3, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* JIG On */
+ {GPIO_IF_CON_SENSE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* 30PIN CONNECTOR */
+ {GPIO_DOCK_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* MIC */
+ {GPIO_EAR_MIC_BIAS_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+
+ /*** GPX ***/
+ {GPIO_GYRO_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_REMOTE_SENSE_IRQ, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+#ifdef CONFIG_SEC_MODEM
+ {GPIO_SIM_DETECT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+#else
+ {GPIO_SIM_DETECT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+#endif
+ {GPIO_ACCESSORY_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_MSENSE_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_FUEL_ALERT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* {GPIO_BT_HOST_WAKE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE}, */
+ {GPIO_DET_35, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_OTG_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+ /* T_FLASH_DETECT */
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* TA_nCONNECTED */
+ {EXYNOS4_GPX3(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_HDMI_HPD, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* NC */
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY3(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+#ifdef CONFIG_SEC_MODEM /* NC Pin for RF version */
+ {GPIO_IPC_RXD, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_IPC_TXD, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+#else /* NC Pin for WIFI version */
+ {EXYNOS4_GPY3(6), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_PHONE_ON, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_IPC_SLAVE_WAKEUP, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_IPC_HOST_WAKEUP, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_CP_DUMP_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_SUSPEND_REQUEST, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_CP_RST, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_PHONE_ACTIVE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_ACTIVE_STATE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_CP_REQ_RESET, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+#endif
+};
+
+void p4_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(p4_init_gpios); i++) {
+ gpio = p4_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, p4_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, p4_init_gpios[i].pud);
+
+ if (p4_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, p4_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, p4_init_gpios[i].drv);
+ }
+}
+
+/* this table only for c1 board */
+static unsigned int p4_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#ifdef CONFIG_SEC_MODEM
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+#ifdef CONFIG_SEC_MODEM
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#ifdef CONFIG_SEC_MODEM
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#ifdef CONFIG_SEC_MODEM
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* MHL_SDA_1.8V */
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ /* MHL_SCL_1.8V */
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#ifdef CONFIG_SEC_MODEM
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ /* USB_SEL2 */
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* GPIO_PDA_ACTIVE */
+#ifdef CONFIG_SEC_MODEM
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* V_ACCESSORY_5V CHECK */
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* USB_SEL3 */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#ifdef CONFIG_SEC_MODEM
+ /* GPIO_CP_REQ_RESET */
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+ /* GPIO_CP_REQ_RESET */
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ /* GPIO_UART_SEL */
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ /* HW_REV0 */
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV1 */
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV2 */
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV3 */
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* ACCESSORY_EN */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TA_EN */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void p4_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(p4_sleep_gpio_table),
+ p4_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos/p4-input.c b/arch/arm/mach-exynos/p4-input.c
new file mode 100644
index 0000000..1420f41
--- /dev/null
+++ b/arch/arm/mach-exynos/p4-input.c
@@ -0,0 +1,378 @@
+/*
+ * arch/arm/mach-exynos/p4-input.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#if defined(CONFIG_RMI4_I2C)
+#include <linux/rmi.h>
+static int synaptics_tsp_pre_suspend(const void *pm_data)
+{
+ if (NULL == pm_data)
+ return -1;
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_SDA_18V, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_SCL_18V, 0);
+
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_INT, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+
+ return 0;
+}
+
+static int synaptics_tsp_post_resume(const void *pm_data)
+{
+ if (NULL == pm_data)
+ return -1;
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 1);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+
+ return 0;
+}
+
+static void synaptics_tsp_reset(void)
+{
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 0);
+ msleep(100);
+ gpio_set_value(GPIO_TSP_RST, 1);
+}
+
+static struct rmi_device_platform_data synaptics_pdata = {
+ .driver_name = "rmi-generic",
+ .sensor_name = "s7301",
+ .attn_gpio = GPIO_TSP_INT,
+ .attn_polarity = RMI_ATTN_ACTIVE_LOW,
+ .axis_align = { },
+ .pm_data = NULL,
+ .pre_suspend = synaptics_tsp_pre_suspend,
+ .post_resume = synaptics_tsp_post_resume,
+ .hw_reset = synaptics_tsp_reset,
+};
+#endif /* CONFIG_RMI4_I2C */
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301)
+#include <linux/synaptics_s7301.h>
+static bool have_tsp_ldo;
+static struct charger_callbacks *charger_callbacks;
+
+void synaptics_ts_charger_infom(bool en)
+{
+ if (charger_callbacks && charger_callbacks->inform_charger)
+ charger_callbacks->inform_charger(charger_callbacks, en);
+}
+
+static void synaptics_ts_register_callback(struct charger_callbacks *cb)
+{
+ charger_callbacks = cb;
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+}
+
+static int synaptics_ts_set_power(bool en)
+{
+ if (!have_tsp_ldo)
+ return -1;
+ printk(KERN_DEBUG "[TSP] %s(%d)\n", __func__, en);
+
+ if (en) {
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_UP);
+
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 1);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 1);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_SFN(0xf));
+ } else {
+ s3c_gpio_cfgpin(GPIO_TSP_SDA_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SDA_18V, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_SDA_18V, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_SCL_18V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_SCL_18V, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_SCL_18V, 0);
+
+ s3c_gpio_cfgpin(GPIO_TSP_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_INT, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 0);
+ s3c_gpio_cfgpin(GPIO_TSP_LDO_ON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_LDO_ON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_LDO_ON, 0);
+ }
+
+ return 0;
+}
+
+static void synaptics_ts_reset(void)
+{
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+ s3c_gpio_cfgpin(GPIO_TSP_RST, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_TSP_RST, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_TSP_RST, 0);
+ msleep(100);
+ gpio_set_value(GPIO_TSP_RST, 1);
+}
+
+static struct synaptics_platform_data synaptics_ts_pdata = {
+ .gpio_attn = GPIO_TSP_INT,
+ .max_x = 1279,
+ .max_y = 799,
+ .max_pressure = 255,
+ .max_width = 100,
+ .x_line = 27,
+ .y_line = 42,
+ .set_power = synaptics_ts_set_power,
+ .hw_reset = synaptics_ts_reset,
+ .register_cb = synaptics_ts_register_callback,
+};
+#endif /* CONFIG_TOUCHSCREEN_SYNAPTICS_S7301 */
+
+static struct i2c_board_info i2c_devs3[] __initdata = {
+ {
+#if defined(CONFIG_RMI4_I2C)
+ I2C_BOARD_INFO(SYNAPTICS_RMI_NAME,
+ SYNAPTICS_RMI_ADDR),
+ .platform_data = &synaptics_pdata,
+#endif /* CONFIG_RMI4_I2C */
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301)
+ I2C_BOARD_INFO(SYNAPTICS_TS_NAME,
+ SYNAPTICS_TS_ADDR),
+ .platform_data = &synaptics_ts_pdata,
+#endif /* CONFIG_TOUCHSCREEN_SYNAPTICS_S7301 */
+ },
+};
+
+void __init p4_tsp_init(u32 system_rev)
+{
+ int gpio;
+
+ printk(KERN_DEBUG "[TSP] %s rev : %u\n",
+ __func__, system_rev);
+
+ gpio = GPIO_TSP_RST;
+ gpio_request(gpio, "TSP_RST");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+
+ gpio = GPIO_TSP_LDO_ON;
+ gpio_request(gpio, "TSP_LDO_ON");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+
+ gpio = GPIO_TSP_INT;
+ gpio_request(gpio, "TSP_INT");
+
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_register_gpio_interrupt(gpio);
+ i2c_devs3[0].irq = gpio_to_irq(gpio);
+ if (1 <= system_rev)
+#if defined(CONFIG_RMI4_I2C)
+ synaptics_pdata.pm_data =
+ (char *)synaptics_pdata.sensor_name;
+#else
+ have_tsp_ldo = true;
+#endif
+
+#ifdef CONFIG_S3C_DEV_I2C3
+ s3c_i2c3_set_platdata(NULL);
+ i2c_register_board_info(3, i2c_devs3,
+ ARRAY_SIZE(i2c_devs3));
+#endif
+}
+
+#if defined(CONFIG_EPEN_WACOM_G5SP)
+#include <linux/wacom_i2c.h>
+static struct wacom_g5_callbacks *wacom_callbacks;
+static int wacom_init_hw(void);
+static int wacom_suspend_hw(void);
+static int wacom_resume_hw(void);
+static int wacom_early_suspend_hw(void);
+static int wacom_late_resume_hw(void);
+static int wacom_reset_hw(void);
+static void wacom_register_callbacks(struct wacom_g5_callbacks *cb);
+
+static struct wacom_g5_platform_data wacom_platform_data = {
+ .x_invert = 0,
+ .y_invert = 0,
+ .xy_switch = 0,
+ .gpio_pendct = GPIO_PEN_PDCT_18V,
+ .init_platform_hw = wacom_init_hw,
+ .suspend_platform_hw = wacom_suspend_hw,
+ .resume_platform_hw = wacom_resume_hw,
+ .early_suspend_platform_hw = wacom_early_suspend_hw,
+ .late_resume_platform_hw = wacom_late_resume_hw,
+ .reset_platform_hw = wacom_reset_hw,
+ .register_cb = wacom_register_callbacks,
+};
+
+static struct i2c_board_info i2c_devs6[] __initdata = {
+ {
+ I2C_BOARD_INFO("wacom_g5sp_i2c", 0x56),
+ .platform_data = &wacom_platform_data,
+ },
+};
+
+static void wacom_register_callbacks(struct wacom_g5_callbacks *cb)
+{
+ wacom_callbacks = cb;
+};
+
+static int wacom_init_hw(void)
+{
+ int ret;
+ ret = gpio_request(GPIO_PEN_LDO_EN, "PEN_LDO_EN");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN] faile to request gpio(GPIO_PEN_LDO_EN)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_LDO_EN, S3C_GPIO_SFN(0x1));
+ s3c_gpio_setpull(GPIO_PEN_LDO_EN, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_PEN_LDO_EN, 1);
+
+ ret = gpio_request(GPIO_PEN_PDCT_18V, "PEN_PDCT");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN] faile to request gpio(GPIO_PEN_PDCT_18V)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_PDCT_18V, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_PEN_PDCT_18V, S3C_GPIO_PULL_UP);
+
+ ret = gpio_request(GPIO_PEN_IRQ_18V, "PEN_IRQ");
+ if (ret) {
+ printk(KERN_ERR "[E-PEN] faile to request gpio(GPIO_PEN_IRQ_18V)\n");
+ return ret;
+ }
+ s3c_gpio_cfgpin(GPIO_PEN_IRQ_18V, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_PEN_IRQ_18V, S3C_GPIO_PULL_DOWN);
+ s5p_register_gpio_interrupt(GPIO_PEN_IRQ_18V);
+ i2c_devs6[0].irq = gpio_to_irq(GPIO_PEN_IRQ_18V);
+ return 0;
+}
+
+static int wacom_suspend_hw(void)
+{
+ return wacom_early_suspend_hw();
+}
+
+static int wacom_resume_hw(void)
+{
+ return wacom_late_resume_hw();
+}
+
+static int wacom_early_suspend_hw(void)
+{
+ gpio_set_value(GPIO_PEN_LDO_EN, 0);
+ return 0;
+}
+
+static int wacom_late_resume_hw(void)
+{
+ gpio_set_value(GPIO_PEN_LDO_EN, 1);
+ return 0;
+}
+
+static int wacom_reset_hw(void)
+{
+ return 0;
+}
+
+void __init p4_wacom_init(void)
+{
+ wacom_init_hw();
+#ifdef CONFIG_S3C_DEV_I2C6
+ s3c_i2c6_set_platdata(NULL);
+ i2c_register_board_info(6, i2c_devs6, ARRAY_SIZE(i2c_devs6));
+#endif
+}
+#endif /* CONFIG_EPEN_WACOM_G5SP */
+
+#if defined(CONFIG_KEYBOARD_GPIO)
+#include <mach/sec_debug.h>
+#include <linux/gpio_keys.h>
+#define GPIO_KEYS(_code, _gpio, _active_low, _iswake, _hook) \
+{ \
+ .code = _code, \
+ .gpio = _gpio, \
+ .active_low = _active_low, \
+ .type = EV_KEY, \
+ .wakeup = _iswake, \
+ .debounce_interval = 10, \
+ .isr_hook = _hook, \
+ .value = 1 \
+}
+
+struct gpio_keys_button p4_buttons[] = {
+ GPIO_KEYS(KEY_VOLUMEUP, GPIO_VOL_UP,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_VOLUMEDOWN, GPIO_VOL_DOWN,
+ 1, 1, sec_debug_check_crash_key),
+ GPIO_KEYS(KEY_POWER, GPIO_nPOWER,
+ 1, 1, sec_debug_check_crash_key),
+};
+
+struct gpio_keys_platform_data p4_gpiokeys_platform_data = {
+ p4_buttons,
+ ARRAY_SIZE(p4_buttons),
+};
+
+static struct platform_device p4_keypad = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &p4_gpiokeys_platform_data,
+ },
+};
+#endif
+void __init p4_key_init(void)
+{
+#if defined(CONFIG_KEYBOARD_GPIO)
+ platform_device_register(&p4_keypad);
+#endif
+}
+
diff --git a/arch/arm/mach-exynos/p4note-gpio.c b/arch/arm/mach-exynos/p4note-gpio.c
new file mode 100644
index 0000000..b28cc00
--- /dev/null
+++ b/arch/arm/mach-exynos/p4note-gpio.c
@@ -0,0 +1,587 @@
+/*
+ * linux/arch/arm/mach-exynos/midas-gpio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - GPIO setting in set board
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio-midas.h>
+#include <plat/cpu.h>
+#include <mach/pmu.h>
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+#ifdef CONFIG_MIDAS_COMMON
+/*
+ * P4NOTE GPIO Init Table
+ */
+static struct gpio_init_data p4note_init_gpios[] = {
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPA1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPA1(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SDA_1.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GSENSE_SCL_1.8V */
+
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ADC_IC_INT */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_INT */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* DET_3.5 */
+ {EXYNOS4_GPX0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* DOCK_INT */
+ {EXYNOS4_GPX0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* REMOTE_SENSE_IRQ */
+ {EXYNOS4_GPX0(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GYRO_INT */
+
+ {EXYNOS4_GPX0(7), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* AP_PMIC_IRQ */
+
+ {EXYNOS4_GPX1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ACCESSORY_INT */
+ {EXYNOS4_GPX1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* TA_INT */
+ {EXYNOS4_GPX1(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* OVP_FLAG */
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPX1(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SIM_DETECT */
+#endif
+
+ {EXYNOS4_GPX2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* FUEL_ALERT */
+ {EXYNOS4_GPX2(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_HOST_WAKEUP */
+ {EXYNOS4_GPX2(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* nPower */
+
+ {EXYNOS4_GPX3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* IF_CON_SENSE */
+ {EXYNOS4_GPX3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* BT_WAKE */
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPX3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CP_PMU_RST */
+#endif
+ {EXYNOS4_GPX3(5), S3C_GPIO_SFN(0xF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* V_ACCESSORY_5V */
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPK1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+#if !defined(CONFIG_SEC_MODEM)
+ {EXYNOS4212_GPM0(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+ {EXYNOS4212_GPM3(0), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PMIC_DVS1 */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* CAM_MCLK */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* VTCAM_MCLK */
+};
+
+/*
+ * P4NOTE GPIO Sleep Table
+ */
+static unsigned int p4note_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(IPC_RXD) */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(IPC_TXD) */
+#else
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* IPC_RXD */
+ /*
+ * UART3-TXD : It should be pulled up during sleep, if this uart is
+ * used for PC connection like a factory command program.
+ * Otherwise, a PC might get null characters like noise.
+ * In addition, LPA mode is also applied to this comment, because
+ * LPA mode invokes this GPIO sleep configuration.
+ */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* IPC_TXD */
+#endif
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_CLK(NC) */
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_SYNC(NC) */
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_IN(NC) */
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* REC_PCM_OUT(NC) */
+#if defined(CONFIG_SEC_MODEM_M0_TD)
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* PEN_PDCT */
+#endif
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* PEN_LDO_EN */
+
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* PEN_IRQ_1.8V */
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* PEN_SDA_1.8V */
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* PEN_SCL_1.8V */
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LED_BACKLIGHT_PWM */
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 3M_SDA_1.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* 3M_SCL_1.8V */
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_HSYNC */
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_VSYNC */
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_DE */
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_PCLK */
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LCD_D */
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* MHL_RST */
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* MHL_INT */
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CLK */
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_CMD */
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* eMMC_EN */
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(0) */
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(1) */
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(2) */
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(3) */
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(4) */
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(5) */
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(6) */
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* NAND_D(7) */
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* ACTIVE_STATE_HSIC */
+#else
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* PS_ALS_SCL_1.8V */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* PS_ALS_SDA_1.8V */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC(IRDA_CONTROL) */
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* HDMI_EN */
+/* {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+/* {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, */
+
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* PDA_ACTIVE */
+#else
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* 3M_nRST */
+/* {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, */
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW)
+ /* GLP2(4) CMC_CPU_RESET, hold high */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* NC */
+#else
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* MOTOR_EN */
+#endif
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CP_ON(NC) */
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* UART_SEL */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* USB_SEL0 */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* USB_SEL1 */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TF_EN */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* Exynos4212 specific gpio */
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_PCLK */
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_VSYNC */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_HSYNC */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_D */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* CAM_MCLK */
+ {EXYNOS4212_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPM0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* MICBIAS_EN */
+ {EXYNOS4212_GPM0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LED_BACKLIGHT_RESET */
+ {EXYNOS4212_GPM0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* TA_nCHG */
+ {EXYNOS4212_GPM0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TSP_RST */
+ {EXYNOS4212_GPM0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* LVDS_nSHDN */
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* 3M_nSTBY */
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* USB_SEL_CP */
+#else
+ {EXYNOS4212_GPM0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4212_GPM1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MOTOR_I2C_SDA */
+ {EXYNOS4212_GPM1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* MOTOR_I2C_SCL */
+ {EXYNOS4212_GPM1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV0 */
+ {EXYNOS4212_GPM1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV1 */
+ {EXYNOS4212_GPM1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV2 */
+ {EXYNOS4212_GPM1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* HW_REV3 */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* 2M_nRST */
+
+ {EXYNOS4212_GPM2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPM2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* SUSPEND_REQUEST_HSIC(NC) */
+
+ {EXYNOS4212_GPM3(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS1 */
+ {EXYNOS4212_GPM3(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS2 */
+ {EXYNOS4212_GPM3(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* PMIC_DVS3 */
+#if defined(CONFIG_SEC_MODEM)
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE}, /* RESET_REQ_N */
+#else
+ {EXYNOS4212_GPM3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4212_GPM3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* AP_DUMP_INT(NC) */
+ {EXYNOS4212_GPM3(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* WLAN_EN */
+ {EXYNOS4212_GPM3(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CAM_MOVIE_EN */
+ {EXYNOS4212_GPM3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* CAM_FLASH_EN */
+
+ {EXYNOS4212_GPM4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* ADC_I2C_SCL_1.8V */
+ {EXYNOS4212_GPM4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* ADC_I2C_SDA_1.8V */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TA_ENABLE */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* 2M_nSTBY */
+ {EXYNOS4212_GPM4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* CODEC_LDO_EN */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* USB_OTG_EN */
+ {EXYNOS4212_GPM4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* MSENSE_INT */
+
+ {EXYNOS4212_GPV0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4212_GPV4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4212_GPV4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+}; /* p4note_sleep_gpio_table */
+
+/*
+ * P4NOTE Rev0.9 GPIO Sleep Table
+ */
+static unsigned int p4note_sleep_gpio_table_rev09[][3] = {
+ {EXYNOS4212_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* EAR_MICBIAS_EN */
+ {EXYNOS4212_GPJ0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* TA_ENABLE */
+ {EXYNOS4212_GPJ0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* CAM_EN2 */
+ {EXYNOS4212_GPJ0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* CAM_EN1 */
+ {EXYNOS4212_GPJ0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* 5M_nSTBY */
+
+ {EXYNOS4212_GPJ1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* VT_CAM_nRST */
+ {EXYNOS4212_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPJ1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE}, /* LINEOUT_EN */
+ {EXYNOS4212_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* 5M_MCLK */
+
+ {EXYNOS4212_GPM0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4212_GPM2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* VT_CAM_MCLK */
+ {EXYNOS4212_GPM4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SCL_1.8V */
+ {EXYNOS4212_GPM4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* VT_CAM_SDA_1.8V */
+ {EXYNOS4212_GPM4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TSP_LDO_ON */
+};
+
+struct p4note_sleep_table {
+ unsigned int (*ptr)[3];
+ int size;
+};
+
+#define GPIO_TABLE(_ptr) \
+ {.ptr = _ptr, \
+ .size = ARRAY_SIZE(_ptr)} \
+
+ #define GPIO_TABLE_NULL \
+ {.ptr = NULL, \
+ .size = 0} \
+
+static struct p4note_sleep_table p4note_sleep_table[] = {
+ GPIO_TABLE(p4note_sleep_gpio_table), /* Rev0.8(0x0) */
+ GPIO_TABLE(p4note_sleep_gpio_table_rev09), /* Rev0.9(0x1) */
+};
+#endif /* CONFIG_MIDAS_COMMON */
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+#ifdef CONFIG_MIDAS_COMMON
+void p4note_config_sleep_gpio_table(void)
+{
+ int i;
+ int index = min(ARRAY_SIZE(p4note_sleep_table), system_rev + 1);
+
+ for (i = 0; i < index; i++) {
+ if (p4note_sleep_table[i].ptr == NULL)
+ continue;
+
+ config_sleep_gpio_table(p4note_sleep_table[i].size,
+ p4note_sleep_table[i].ptr);
+ }
+}
+#endif
+
+/* To save power consumption, gpio pin set before enterling sleep */
+void midas_config_sleep_gpio_table(void)
+{
+ p4note_config_sleep_gpio_table();
+}
+
+/* Intialize gpio set in midas board */
+void midas_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(p4note_init_gpios); i++) {
+ gpio = p4note_init_gpios[i].num;
+ if (gpio <= EXYNOS4212_GPV4(1)) {
+ s3c_gpio_cfgpin(gpio, p4note_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, p4note_init_gpios[i].pud);
+
+ if (p4note_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, p4note_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, p4note_init_gpios[i].drv);
+ }
+ }
+}
diff --git a/arch/arm/mach-exynos/p4note-jack.c b/arch/arm/mach-exynos/p4note-jack.c
new file mode 100644
index 0000000..2a4d0df
--- /dev/null
+++ b/arch/arm/mach-exynos/p4note-jack.c
@@ -0,0 +1,126 @@
+/* arch/arm/mach-exynos/p4note-jack.c
+ *
+ * Copyright (C) 2012 Samsung Electronics Co, Ltd
+ *
+ * Based on mach-exynos/mach-p4notepq.c
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <mach/gpio-midas.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/sec_jack.h>
+
+static void sec_set_jack_micbias(bool on)
+{
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, on);
+}
+
+static struct sec_jack_zone sec_jack_zones[] = {
+ {
+ /* adc == 0, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 0,
+ .delay_ms = 15,
+ .check_count = 20,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 0 < adc <= 1200, unstable zone, default to 3pole if it stays
+ * in this range for 300ms (15ms delays, 20 samples)
+ */
+ .adc_high = 1200,
+ .delay_ms = 10,
+ .check_count = 80,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+ {
+ /* 1200 < adc <= 2600, unstable zone, default to 4pole if it
+ * stays in this range for 800ms (10ms delays, 80 samples)
+ */
+ .adc_high = 2600,
+ .delay_ms = 10,
+ .check_count = 10,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* 2600 < adc <= 3800, 3 pole zone, default to 3pole if it
+ * stays in this range for 100ms (10ms delays, 10 samples)
+ */
+ .adc_high = 3800,
+ .delay_ms = 10,
+ .check_count = 5,
+ .jack_type = SEC_HEADSET_4POLE,
+ },
+ {
+ /* adc > 3800, unstable zone, default to 3pole if it stays
+ * in this range for two seconds (10ms delays, 200 samples)
+ */
+ .adc_high = 0x7fffffff,
+ .delay_ms = 10,
+ .check_count = 200,
+ .jack_type = SEC_HEADSET_3POLE,
+ },
+};
+
+/* To support 3-buttons earjack */
+static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = {
+ {
+ /* 0 <= adc <=190, stable zone */
+ .code = KEY_MEDIA,
+ .adc_low = 0,
+ .adc_high = 190,
+ },
+ {
+ /* 191 <= adc <= 420, stable zone */
+ .code = KEY_VOLUMEUP,
+ .adc_low = 191,
+ .adc_high = 420,
+ },
+ {
+ /* 421 <= adc <= 860, stable zone */
+ .code = KEY_VOLUMEDOWN,
+ .adc_low = 421,
+ .adc_high = 860,
+ },
+};
+
+static struct sec_jack_platform_data sec_jack_data = {
+ .set_micbias_state = sec_set_jack_micbias,
+ .zones = sec_jack_zones,
+ .num_zones = ARRAY_SIZE(sec_jack_zones),
+ .buttons_zones = sec_jack_buttons_zones,
+ .num_buttons_zones = ARRAY_SIZE(sec_jack_buttons_zones),
+ .det_gpio = GPIO_DET_35,
+ .send_end_gpio = GPIO_EAR_SEND_END,
+};
+
+static struct platform_device sec_device_jack = {
+ .name = "sec_jack",
+ .id = 1, /* will be used also for gpio_event id */
+ .dev.platform_data = &sec_jack_data,
+};
+void __init p4note_jack_init(void)
+{
+ /* Ear Microphone BIAS */
+ int err;
+ err = gpio_request(GPIO_EAR_MIC_BIAS_EN, "EAR MIC");
+ if (err) {
+ pr_err(KERN_ERR "GPIO_EAR_MIC_BIAS_EN GPIO set error!\n");
+ return;
+ }
+ gpio_direction_output(GPIO_EAR_MIC_BIAS_EN, 1);
+ gpio_set_value(GPIO_EAR_MIC_BIAS_EN, 0);
+ gpio_free(GPIO_EAR_MIC_BIAS_EN);
+
+ platform_device_register(&sec_device_jack);
+}
diff --git a/arch/arm/mach-exynos/p4note-power.c b/arch/arm/mach-exynos/p4note-power.c
new file mode 100644
index 0000000..14769a6
--- /dev/null
+++ b/arch/arm/mach-exynos/p4note-power.c
@@ -0,0 +1,1112 @@
+/*
+ * midas-power.c - Power Management of MIDAS Project
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Chiwoong Byun <woong.byun@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio-midas.h>
+#include <mach/irqs.h>
+
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max77686.h>
+#include <linux/mfd/max77693.h>
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#endif
+
+#ifdef CONFIG_REGULATOR_MAX8997
+/* MOTOR */
+#ifdef CONFIG_VIBETONZ
+static void max8997_motor_init(void)
+{
+ gpio_request(GPIO_VIBTONE_EN, "VIBTONE_EN");
+ s3c_gpio_cfgpin(GPIO_VIBTONE_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_VIBTONE_EN, S3C_GPIO_PULL_NONE);
+}
+
+static void max8997_motor_en(bool en)
+{
+ gpio_direction_output(GPIO_VIBTONE_EN, en);
+}
+
+static struct max8997_motor_data max8997_motor = {
+ .max_timeout = 10000,
+ .duty = 44000,
+ .period = 44642,
+ .reg2 = MOTOR_LRA | EXT_PWM | DIVIDER_128,
+ .init_hw = max8997_motor_init,
+ .motor_en = max8997_motor_en,
+ .pwm_id = 1,
+};
+#endif
+
+/* max8997 */
+static struct regulator_consumer_supply ldo1_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim"),
+};
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo6_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo7_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim"),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.3v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo15_supply[] = {
+ REGULATOR_SUPPLY("vlcd_2.2v", NULL),
+ REGULATOR_SUPPLY("VDD3", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo16_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo17_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply max8997_buck1 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max8997_buck2[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max8997_buck3 =
+ REGULATOR_SUPPLY("vdd_g3d", NULL);
+
+static struct regulator_consumer_supply max8997_buck4 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo1, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo6, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo7, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo11, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo13, "VCC_3.3V_LCD", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo14, "VCC_1.8V_IO", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo15, "VDD_2.2V_LCD", 2200000, 2200000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo16, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo17, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data max8997_buck1_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 950000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck1,
+};
+
+static struct regulator_init_data max8997_buck2_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 900000,
+ .max_uV = 1100000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max8997_buck2),
+ .consumer_supplies = max8997_buck2,
+};
+
+static struct regulator_init_data max8997_buck3_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 950000,
+ .max_uV = 1150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck3,
+};
+
+static struct regulator_init_data max8997_buck4_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8997_buck4,
+};
+
+static struct max8997_regulator_data max8997_regulators[] = {
+ { MAX8997_BUCK1, &max8997_buck1_data, },
+ { MAX8997_BUCK2, &max8997_buck2_data, },
+ { MAX8997_BUCK3, &max8997_buck3_data, },
+ { MAX8997_BUCK4, &max8997_buck4_data, },
+ { MAX8997_LDO1, &ldo1_init_data, },
+ { MAX8997_LDO6, &ldo6_init_data, },
+ { MAX8997_LDO7, &ldo7_init_data, },
+ { MAX8997_LDO8, &ldo8_init_data, },
+ { MAX8997_LDO11, &ldo11_init_data, },
+ { MAX8997_LDO12, &ldo12_init_data, },
+ { MAX8997_LDO13, &ldo13_init_data, },
+ { MAX8997_LDO14, &ldo14_init_data, },
+ { MAX8997_LDO15, &ldo15_init_data, },
+ { MAX8997_LDO16, &ldo16_init_data, },
+ { MAX8997_LDO17, &ldo17_init_data, },
+ { MAX8997_LDO18, &ldo18_init_data, },
+};
+
+struct max8997_platform_data exynos4_max8997_info = {
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .num_regulators = ARRAY_SIZE(max8997_regulators),
+ .regulators = max8997_regulators,
+ .buck1_max_vol = 1100000,
+ .buck2_max_vol = 1100000,
+ .buck5_max_vol = 1100000,
+ .buck_set1 = EXYNOS4212_GPJ1(1),
+ .buck_set2 = EXYNOS4212_GPJ1(2),
+ .buck_set3 = EXYNOS4_GPL0(0),
+#ifdef CONFIG_VIBETONZ
+ .motor = &max8997_motor,
+#endif
+};
+#elif defined(CONFIG_REGULATOR_MAX77686)
+/* max77686 */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#else
+static struct regulator_consumer_supply ldo3_supply[] = {};
+#endif
+
+static struct regulator_consumer_supply ldo5_supply[] = {
+ REGULATOR_SUPPLY("vcc_1.8v", NULL),
+ REGULATOR_SUPPLY("touchkey", NULL), /*touchkey*/
+};
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
+ REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_mipi_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+ REGULATOR_SUPPLY("vdd_osc", "exynos4-hdmi"),
+};
+
+static struct regulator_consumer_supply ldo11_supply[] = {
+ REGULATOR_SUPPLY("vabb1_1.9v", NULL),
+};
+
+static struct regulator_consumer_supply ldo12_supply[] = {
+ REGULATOR_SUPPLY("votg_3.0v", NULL),
+};
+
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vusbhub_osc_1.8v", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo14_supply[] = {
+ REGULATOR_SUPPLY("vabb2_1.9v", NULL),
+};
+
+static struct regulator_consumer_supply ldo18_supply[] = {
+ REGULATOR_SUPPLY("cam_io_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("vt_core_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("vdd_adc_3.3v", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("cam_a2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("vled_3.3v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("3mp_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply max77686_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply max77686_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynoss4412-busfreq"),
+};
+
+static struct regulator_consumer_supply max77686_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply max77686_buck9 =
+ REGULATOR_SUPPLY("3mp_core_1.2v", NULL);
+
+static struct regulator_consumer_supply max77686_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo5, "VCC_1.8V_IO", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo9, "CAM_ISP_MIPI_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VMIPI_1.8V", 1800000, 1800000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+REGULATOR_INIT(ldo11, "VABB1_1.9V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo12, "VUOTG_3.0V", 3000000, 3000000, 1,
+ REGULATOR_CHANGE_STATUS, 0);
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+REGULATOR_INIT(ldo13, "VUSBHUB_OSC_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo14, "VABB2_1.9V", 1950000, 1950000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo18, "CAM_IO_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "VT_CORE_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "VDD_ADC_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "CAM_A2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#if defined(CONFIG_TARGET_LOCALE_USA)
+REGULATOR_INIT(ldo25, "VLED_3.3V", 3300000, 3300000, 1,
+ REGULATOR_CHANGE_STATUS, 1);
+#else
+REGULATOR_INIT(ldo25, "VLED_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+#endif
+REGULATOR_INIT(ldo26, "3MP_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+#if defined(CONFIG_MACH_SLP_PQ)
+static struct regulator_init_data ldo24_pq11_init_data = {
+ .constraints = {
+ .name = "VDD_1.8V_TSP",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 0,
+ .boot_on = 0,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 0,
+ .disabled = 1,
+ }
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = ldo24_supply,
+};
+#endif
+
+static struct regulator_init_data max77686_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+#ifdef CONFIG_SLP
+ .max_uV = 1100000,
+#else
+ .max_uV = 1050000,
+#endif
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck1),
+ .consumer_supplies = max77686_buck1,
+};
+
+static struct regulator_init_data max77686_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck2,
+};
+
+static struct regulator_init_data max77686_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+#ifdef CONFIG_SLP
+ .max_uV = 1150000,
+#else
+ .max_uV = 1100000,
+#endif
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck3),
+ .consumer_supplies = max77686_buck3,
+};
+
+static struct regulator_init_data max77686_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+#ifdef CONFIG_SLP
+ .max_uV = 1100000,
+#else
+ .max_uV = 1075000,
+#endif
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_buck4),
+ .consumer_supplies = max77686_buck4,
+};
+
+static struct regulator_init_data max77686_buck9_data = {
+ .constraints = {
+ .name = "3MP_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max77686_buck9,
+};
+
+static struct regulator_init_data max77686_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max77686_enp32khz),
+ .consumer_supplies = max77686_enp32khz,
+};
+
+static struct max77686_regulator_data max77686_regulators[] = {
+ {MAX77686_BUCK1, &max77686_buck1_data,},
+ {MAX77686_BUCK2, &max77686_buck2_data,},
+ {MAX77686_BUCK3, &max77686_buck3_data,},
+ {MAX77686_BUCK4, &max77686_buck4_data,},
+ {MAX77686_BUCK9, &max77686_buck9_data,},
+ {MAX77686_LDO3, &ldo3_init_data,},
+ {MAX77686_LDO5, &ldo5_init_data,},
+ {MAX77686_LDO8, &ldo8_init_data,},
+ {MAX77686_LDO9, &ldo9_init_data,},
+ {MAX77686_LDO10, &ldo10_init_data,},
+ {MAX77686_LDO11, &ldo11_init_data,},
+ {MAX77686_LDO12, &ldo12_init_data,},
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ {MAX77686_LDO13, &ldo13_init_data,},
+#endif
+ {MAX77686_LDO14, &ldo14_init_data,},
+ {MAX77686_LDO18, &ldo18_init_data,},
+ {MAX77686_LDO19, &ldo19_init_data,},
+ {MAX77686_LDO21, &ldo21_init_data,},
+ {MAX77686_LDO23, &ldo23_init_data,},
+ {MAX77686_LDO24, &ldo24_init_data,},
+ {MAX77686_LDO25, &ldo25_init_data,},
+ {MAX77686_LDO26, &ldo26_init_data,},
+ {MAX77686_P32KH, &max77686_enp32khz_data,},
+};
+
+struct max77686_opmode_data max77686_opmode_data[MAX77686_REG_MAX] = {
+ [MAX77686_LDO3] = {MAX77686_LDO3, MAX77686_OPMODE_NORMAL},
+ [MAX77686_LDO8] = {MAX77686_LDO8, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO10] = {MAX77686_LDO10, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO11] = {MAX77686_LDO11, MAX77686_OPMODE_STANDBY},
+ [MAX77686_LDO12] = {MAX77686_LDO12, MAX77686_OPMODE_STANDBY},
+#if defined(CONFIG_MACH_C1_KOR_SKT) || defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+ [MAX77686_LDO13] = {MAX77686_LDO13, MAX77686_OPMODE_NORMAL},
+#endif
+ [MAX77686_LDO14] = {MAX77686_LDO14, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK1] = {MAX77686_BUCK1, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK2] = {MAX77686_BUCK2, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK3] = {MAX77686_BUCK3, MAX77686_OPMODE_STANDBY},
+ [MAX77686_BUCK4] = {MAX77686_BUCK4, MAX77686_OPMODE_STANDBY},
+};
+
+struct max77686_platform_data exynos4_max77686_info = {
+ .num_regulators = ARRAY_SIZE(max77686_regulators),
+ .regulators = max77686_regulators,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = max77686_opmode_data,
+ .ramp_rate = MAX77686_RAMP_RATE_27MV,
+
+ .buck234_gpio_dvs = {
+ /* Use DVS2 register of each bucks to supply stable power
+ * after sudden reset */
+ {GPIO_PMIC_DVS1, 1},
+ {GPIO_PMIC_DVS2, 0},
+ {GPIO_PMIC_DVS3, 0},
+ },
+ .buck234_gpio_selb = {
+ GPIO_BUCK2_SEL,
+ GPIO_BUCK3_SEL,
+ GPIO_BUCK4_SEL,
+ },
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1000000, /* 1.0V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1000000, /* 1.0V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+};
+
+void midas_power_init(void)
+{
+ printk(KERN_INFO "%s\n", __func__);
+
+#if defined(CONFIG_C1_KOR_SKT) || defined(CONFIG_C1_KOR_KT) || \
+ defined(CONFIG_C1_KOR_LGT)
+ if (system_rev >= 0x6)
+ ldo13_init_data.constraints.always_on = 1;
+#endif
+}
+#endif /* CONFIG_REGULATOR_MAX77686 */
+
+void midas_power_set_muic_pdata(void *pdata, int gpio)
+{
+ gpio_request(gpio, "AP_PMIC_IRQ");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+#ifdef CONFIG_REGULATOR_MAX8997
+ exynos4_max8997_info.muic = pdata;
+#endif
+}
+
+void midas_power_gpio_init(void)
+{
+#ifdef CONFIG_REGULATOR_MAX8997
+ int gpio;
+
+ gpio = EXYNOS4212_GPJ1(1);
+ gpio_request(gpio, "BUCK_SET1");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = EXYNOS4212_GPJ1(2);
+ gpio_request(gpio, "BUCK_SET2");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ gpio = EXYNOS4_GPL0(0);
+ gpio_request(gpio, "BUCK_SET3");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+#endif
+}
+
+#ifdef CONFIG_MFD_MAX77693
+static struct regulator_consumer_supply safeout1_supply[] = {
+ REGULATOR_SUPPLY("safeout1", NULL),
+};
+
+static struct regulator_consumer_supply safeout2_supply[] = {
+ REGULATOR_SUPPLY("safeout2", NULL),
+};
+
+static struct regulator_consumer_supply charger_supply[] = {
+ REGULATOR_SUPPLY("vinchg1", "charger-manager.0"),
+ REGULATOR_SUPPLY("vinchg1", NULL),
+};
+
+static struct regulator_init_data safeout1_init_data = {
+ .constraints = {
+ .name = "safeout1 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout1_supply),
+ .consumer_supplies = safeout1_supply,
+};
+
+static struct regulator_init_data safeout2_init_data = {
+ .constraints = {
+ .name = "safeout2 range",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ .boot_on = 0,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(safeout2_supply),
+ .consumer_supplies = safeout2_supply,
+};
+
+static struct regulator_init_data charger_init_data = {
+ .constraints = {
+ .name = "CHARGER",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_CURRENT,
+ .boot_on = 1,
+ .min_uA = 60000,
+ .max_uA = 2580000,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(charger_supply),
+ .consumer_supplies = charger_supply,
+};
+
+struct max77693_regulator_data max77693_regulators[] = {
+ {MAX77693_ESAFEOUT1, &safeout1_init_data,},
+ {MAX77693_ESAFEOUT2, &safeout2_init_data,},
+ {MAX77693_CHARGER, &charger_init_data,},
+};
+
+#if defined(CONFIG_MACH_SLP_PQ)
+/* this initcall replace ldo24 from VDD 2.2 to VDD 1.8 for evt1.1 board. */
+static int __init regulator_init_with_rev(void)
+{
+ /* SLP PQ Promixa evt1.1 */
+ if (system_rev != 3) {
+ ldo24_supply[0].supply = "touch_1.8v";
+ ldo24_supply[0].dev_name = NULL;
+
+ memcpy(&ldo24_init_data, &ldo24_pq11_init_data,
+ sizeof(struct regulator_init_data));
+ }
+ return 0;
+}
+
+postcore_initcall(regulator_init_with_rev);
+#endif /* CONFIG_MACH_SLP_PQ */
+#endif /* CONFIG_MFD_MAX77693 */
+
+#if defined(CONFIG_REGULATOR_S5M8767)
+/* S5M8767 Regulator */
+
+#ifdef CONFIG_SND_SOC_WM8994
+static struct regulator_consumer_supply ldo3_supply[] = {
+ REGULATOR_SUPPLY("AVDD2", NULL),
+ REGULATOR_SUPPLY("CPVDD", NULL),
+ REGULATOR_SUPPLY("DBVDD1", NULL),
+ REGULATOR_SUPPLY("DBVDD2", NULL),
+ REGULATOR_SUPPLY("DBVDD3", NULL),
+};
+#endif
+
+static struct regulator_consumer_supply ldo8_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.0v", NULL),
+ REGULATOR_SUPPLY("VDD10", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo9_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo10_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_dvdd_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo13_supply[] = {
+ REGULATOR_SUPPLY("vmipi_1.8v", NULL),
+ REGULATOR_SUPPLY("VDD18", "s5p-mipi-dsim.0"),
+};
+
+static struct regulator_consumer_supply ldo19_supply[] = {
+ REGULATOR_SUPPLY("cam_af_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo20_supply[] = {
+ REGULATOR_SUPPLY("vlcd_3.0v", NULL),
+ REGULATOR_SUPPLY("VCI", "s6e8aa0"),
+};
+
+static struct regulator_consumer_supply ldo21_supply[] = {
+ REGULATOR_SUPPLY("vmotor", NULL),
+};
+
+static struct regulator_consumer_supply ldo22_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_a2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo23_supply[] = {
+ REGULATOR_SUPPLY("vtf_2.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo24_supply[] = {
+ REGULATOR_SUPPLY("touch", NULL),
+};
+
+static struct regulator_consumer_supply ldo25_supply[] = {
+ REGULATOR_SUPPLY("cam_sensor_core_1.2v", NULL),
+};
+
+static struct regulator_consumer_supply ldo26_supply[] = {
+ REGULATOR_SUPPLY("cam_isp_sensor_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo27_supply[] = {
+ REGULATOR_SUPPLY("vt_cam_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply ldo28_supply[] = {
+ REGULATOR_SUPPLY("3_touch_1.8v", NULL),
+};
+
+static struct regulator_consumer_supply s5m8767_buck1[] = {
+ REGULATOR_SUPPLY("vdd_mif", NULL),
+ REGULATOR_SUPPLY("vdd_mif", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck2 =
+ REGULATOR_SUPPLY("vdd_arm", NULL);
+
+static struct regulator_consumer_supply s5m8767_buck3[] = {
+ REGULATOR_SUPPLY("vdd_int", NULL),
+ REGULATOR_SUPPLY("vdd_int", "exynos4212-busfreq"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck4[] = {
+ REGULATOR_SUPPLY("vdd_g3d", NULL),
+ REGULATOR_SUPPLY("vdd_g3d", "mali_dev.0"),
+};
+
+static struct regulator_consumer_supply s5m8767_buck6 =
+ REGULATOR_SUPPLY("cam_isp_core_1.2v", NULL);
+
+static struct regulator_consumer_supply s5m8767_enp32khz[] = {
+ REGULATOR_SUPPLY("lpo_in", "bcm47511"),
+ REGULATOR_SUPPLY("lpo", "bcm4334_bluetooth"),
+};
+
+#define REGULATOR_INIT(_ldo, _name, _min_uV, _max_uV, _always_on, _ops_mask, \
+ _disabled) \
+ static struct regulator_init_data _ldo##_init_data = { \
+ .constraints = { \
+ .name = _name, \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .always_on = _always_on, \
+ .boot_on = _always_on, \
+ .apply_uV = 1, \
+ .valid_ops_mask = _ops_mask, \
+ .state_mem = { \
+ .disabled = _disabled, \
+ .enabled = !(_disabled), \
+ } \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_supply), \
+ .consumer_supplies = &_ldo##_supply[0], \
+ };
+
+REGULATOR_INIT(ldo3, "VCC_1.8V_AP", 1800000, 1800000, 1, 0, 0);
+REGULATOR_INIT(ldo8, "VMIPI_1.0V", 1000000, 1000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo9, "CAM_ISP_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo10, "VT_CAM_DVDD_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo13, "VMIPI_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo19, "CAM_AF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo20, "VCC_3.0V_LCD", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo21, "VCC_MOTOR_3.0V", 3000000, 3000000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo22, "CAM_SENSOR_A2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo23, "VTF_2.8V", 2800000, 2800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo24, "TSP_AVDD_3.3V", 3300000, 3300000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo25, "CAM_SENSOR_CORE_1.2V", 1200000, 1200000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo26, "CAM_ISP_SENSOR_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo27, "VT_CAM_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+REGULATOR_INIT(ldo28, "3_TOUCH_1.8V", 1800000, 1800000, 0,
+ REGULATOR_CHANGE_STATUS, 1);
+
+static struct regulator_init_data s5m8767_buck1_data = {
+ .constraints = {
+ .name = "vdd_mif range",
+ .min_uV = 850000,
+ .max_uV = 1100000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck1),
+ .consumer_supplies = s5m8767_buck1,
+};
+
+static struct regulator_init_data s5m8767_buck2_data = {
+ .constraints = {
+ .name = "vdd_arm range",
+ .min_uV = 850000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck2,
+};
+
+static struct regulator_init_data s5m8767_buck3_data = {
+ .constraints = {
+ .name = "vdd_int range",
+ .min_uV = 850000,
+ .max_uV = 1300000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck3),
+ .consumer_supplies = s5m8767_buck3,
+};
+
+static struct regulator_init_data s5m8767_buck4_data = {
+ .constraints = {
+ .name = "vdd_g3d range",
+ .min_uV = 850000,
+ .max_uV = 1150000,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_buck4),
+ .consumer_supplies = s5m8767_buck4,
+};
+
+static struct regulator_init_data s5m8767_buck6_data = {
+ .constraints = {
+ .name = "CAM_ISP_CORE_1.2V",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &s5m8767_buck6,
+};
+
+static struct regulator_init_data s5m8767_enp32khz_data = {
+ .constraints = {
+ .name = "32KHZ_PMIC",
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ .disabled = 0,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(s5m8767_enp32khz),
+ .consumer_supplies = s5m8767_enp32khz,
+};
+
+static struct s5m_regulator_data s5m8767_regulators[] = {
+ {S5M8767_BUCK1, &s5m8767_buck1_data,},
+ {S5M8767_BUCK2, &s5m8767_buck2_data,},
+ {S5M8767_BUCK3, &s5m8767_buck3_data,},
+ {S5M8767_BUCK4, &s5m8767_buck4_data,},
+ {S5M8767_BUCK6, &s5m8767_buck6_data,},
+ {S5M8767_LDO3, &ldo3_init_data,},
+ {S5M8767_LDO8, &ldo8_init_data,},
+ {S5M8767_LDO9, &ldo9_init_data,},
+ {S5M8767_LDO10, &ldo10_init_data,},
+ {S5M8767_LDO13, &ldo13_init_data,},
+ {S5M8767_LDO19, &ldo19_init_data,},
+ {S5M8767_LDO20, &ldo20_init_data,},
+ {S5M8767_LDO21, &ldo21_init_data,},
+ {S5M8767_LDO22, &ldo22_init_data,},
+ {S5M8767_LDO23, &ldo23_init_data,},
+ {S5M8767_LDO24, &ldo24_init_data,},
+ {S5M8767_LDO25, &ldo25_init_data,},
+ {S5M8767_LDO26, &ldo26_init_data,},
+ {S5M8767_LDO27, &ldo27_init_data,},
+ {S5M8767_LDO28, &ldo28_init_data,},
+};
+
+struct s5m_opmode_data s5m8767_opmode_data[S5M8767_REG_MAX] = {
+ [S5M8767_BUCK1] = {S5M8767_BUCK1, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK2] = {S5M8767_BUCK2, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK3] = {S5M8767_BUCK3, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK4] = {S5M8767_BUCK4, S5M_OPMODE_STANDBY},
+ [S5M8767_BUCK6] = {S5M8767_BUCK6, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO3] = {S5M8767_LDO3, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO8] = {S5M8767_LDO8, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO9] = {S5M8767_LDO9, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO10] = {S5M8767_LDO10, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO19] = {S5M8767_LDO19, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO20] = {S5M8767_LDO20, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO21] = {S5M8767_LDO21, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO22] = {S5M8767_LDO22, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO23] = {S5M8767_LDO23, S5M_OPMODE_STANDBY},
+ [S5M8767_LDO24] = {S5M8767_LDO24, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO25] = {S5M8767_LDO25, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO26] = {S5M8767_LDO26, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO27] = {S5M8767_LDO27, S5M_OPMODE_NORMAL},
+ [S5M8767_LDO28] = {S5M8767_LDO28, S5M_OPMODE_NORMAL},
+};
+
+struct s5m_platform_data exynos4_s5m8767_info = {
+ .device_type = S5M8767X,
+ .num_regulators = ARRAY_SIZE(s5m8767_regulators),
+ .regulators = s5m8767_regulators,
+ .buck2_ramp_enable = true,
+ .buck3_ramp_enable = true,
+ .buck4_ramp_enable = true,
+ .irq_gpio = GPIO_PMIC_IRQ,
+ .irq_base = IRQ_BOARD_PMIC_START,
+ .wakeup = 1,
+
+ .opmode_data = s5m8767_opmode_data,
+ .wtsr_smpl = 1,
+
+ .buck2_voltage[0] = 1100000, /* 1.1V */
+ .buck2_voltage[1] = 1100000, /* 1.1V */
+ .buck2_voltage[2] = 1100000, /* 1.1V */
+ .buck2_voltage[3] = 1100000, /* 1.1V */
+ .buck2_voltage[4] = 1100000, /* 1.1V */
+ .buck2_voltage[5] = 1100000, /* 1.1V */
+ .buck2_voltage[6] = 1100000, /* 1.1V */
+ .buck2_voltage[7] = 1100000, /* 1.1V */
+
+ .buck3_voltage[0] = 1100000, /* 1.1V */
+ .buck3_voltage[1] = 1100000, /* 1.1V */
+ .buck3_voltage[2] = 1100000, /* 1.1V */
+ .buck3_voltage[3] = 1100000, /* 1.1V */
+ .buck3_voltage[4] = 1100000, /* 1.1V */
+ .buck3_voltage[5] = 1100000, /* 1.1V */
+ .buck3_voltage[6] = 1100000, /* 1.1V */
+ .buck3_voltage[7] = 1100000, /* 1.1V */
+
+ .buck4_voltage[0] = 1100000, /* 1.1V */
+ .buck4_voltage[1] = 1100000, /* 1.1V */
+ .buck4_voltage[2] = 1100000, /* 1.1V */
+ .buck4_voltage[3] = 1100000, /* 1.1V */
+ .buck4_voltage[4] = 1100000, /* 1.1V */
+ .buck4_voltage[5] = 1100000, /* 1.1V */
+ .buck4_voltage[6] = 1100000, /* 1.1V */
+ .buck4_voltage[7] = 1100000, /* 1.1V */
+
+ .buck_ramp_delay = 10,
+ .buck_default_idx = 3,
+
+ .buck_gpios[0] = GPIO_BUCK2_SEL,
+ .buck_gpios[1] = GPIO_BUCK3_SEL,
+ .buck_gpios[2] = GPIO_BUCK4_SEL,
+};
+
+void midas_power_init(void)
+{
+#ifdef CONFIG_MACH_S2PLUS
+ ldo8_init_data.constraints.always_on = 1;
+ ldo13_init_data.constraints.always_on = 1;
+#else
+ ldo8_init_data.constraints.always_on = 1;
+ ldo10_init_data.constraints.always_on = 1;
+#endif
+}
+
+/* End of S5M8767 */
+#endif
diff --git a/arch/arm/mach-exynos/p8-gpio.c b/arch/arm/mach-exynos/p8-gpio.c
new file mode 100644
index 0000000..135ec85
--- /dev/null
+++ b/arch/arm/mach-exynos/p8-gpio.c
@@ -0,0 +1,515 @@
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio.h>
+#include "px.h"
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data p8_init_gpios[] = {
+ {
+ .num = EXYNOS4_GPD0(2), /* MSENSOR_MHL_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD0(3), /* MSENSOR_MHL_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD1(2), /* SENSE_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPD1(3), /* SENSE_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPK2(2), /* PS_ALS_SDA_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4_GPK3(2), /* PS_ALS_SCL_2.8V */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV1,
+ }, {
+ .num = EXYNOS4210_GPJ1(3), /* GPIO_CAM_MCLK */
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_DOWN,
+ .drv = S5P_GPIO_DRVSTR_LV3,
+ }, {
+ .num = EXYNOS4_GPB(4), /* GPIO_IRDA_nINT */
+ .cfg = S3C_GPIO_OUTPUT,
+ .val = S3C_GPIO_SETPIN_ZERO,
+ .pud = S3C_GPIO_PULL_NONE,
+ .drv = S5P_GPIO_DRVSTR_LV2,
+ }, {
+ .num = EXYNOS4_GPX0(4), /*TA_nCHG*/
+ .cfg = S3C_GPIO_INPUT,
+ .val = S3C_GPIO_SETPIN_NONE,
+ .pud = S3C_GPIO_PULL_UP,
+ .drv = S5P_GPIO_DRVSTR_LV4,
+ },
+ /* BT UART */
+ {GPIO_BT_RXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ {GPIO_BT_TXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_BT_CTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_BT_RTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ /* GPS UART */
+ {GPIO_GPS_RXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_UP},
+ {GPIO_GPS_TXD, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_CTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_RTS, S3C_GPIO_SFN(2), 2, S3C_GPIO_PULL_NONE},
+ {GPIO_GPS_nRST, S3C_GPIO_OUTPUT, 1, S3C_GPIO_PULL_UP},
+ {GPIO_GPS_PWR_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+
+ /* UART switch: configure as output */
+ {GPIO_UART_SEL, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* USB switch: configure as output */
+ {GPIO_USB_SEL1, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_SEL2, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_SEL3, S3C_GPIO_OUTPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* JIG On */
+ {GPIO_IF_CON_SENSE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* 30PIN CONNECTOR */
+ {GPIO_DOCK_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* MIC */
+ {GPIO_EAR_MIC_BIAS_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+
+ /* TSP */
+ {GPIO_TSP_VENDOR, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /*** GPX ***/
+ {GPIO_GYRO_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_PS_VOUT_WAKE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* REMOTE_SENSE_IRQ */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_UP},
+ {GPIO_ACCESSORY_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_MSENSE_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_FUEL_ALERT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* {GPIO_BT_HOST_WAKE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE}, */
+ {GPIO_DET_35, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_USB_OTG_EN, S3C_GPIO_OUTPUT, 0, S3C_GPIO_PULL_NONE},
+ /* T_FLASH_DETECT */
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ /* TA_nCONNECTED */
+ {EXYNOS4_GPX3(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+ {GPIO_HDMI_HPD, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_NONE},
+
+ /* NC */
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY2(5), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY3(1), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(2), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(3), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY6(4), S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+
+
+ /* for WIFI version */
+#ifndef CONFIG_LINK_DEVICE_HSIC
+ {GPIO_PHONE_ON, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_SIM_DETECT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_IPC_SLAVE_WAKEUP, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_IPC_HOST_WAKEUP, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_CP_DUMP_INT, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_SUSPEND_REQUEST, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_CP_RST, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_PHONE_ACTIVE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_ACTIVE_STATE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_PDA_ACTIVE, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+ {GPIO_CP_REQ_RESET, S3C_GPIO_INPUT, 2, S3C_GPIO_PULL_DOWN},
+#endif
+};
+
+void p8_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(p8_init_gpios); i++) {
+ gpio = p8_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, p8_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, p8_init_gpios[i].pud);
+
+ if (p8_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, p8_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, p8_init_gpios[i].drv);
+ }
+}
+
+/* this table only for c1 board */
+static unsigned int p8_sleep_gpio_table[][3] = {
+ { EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ { EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPA1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPA1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPA1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPA1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPC0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPC1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ /* NC */
+ { EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ /* NC */
+ { EXYNOS4210_GPE1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /* NC */
+ { EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPE2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* AMOLED_RESET_1.8V */
+ { EXYNOS4_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* PANEL_CRACK_DET_1.8V */
+ { EXYNOS4_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPF2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPF3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ /* NC */
+ { EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ /* NC */
+ { EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* NC */
+ { EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ { EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ { EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+
+ { EXYNOS4_GPL0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL0(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ /* WLAN_EN2 */
+ { EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* WLAN_EN */
+ { EXYNOS4_GPL1(2), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPL2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPL2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPX0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP}, /* TA_nCHG */
+
+ { EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ { EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ { EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ /* MHL_SDA_1.8V */
+ { EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ /* MHL_SCL_1.8V */
+ { EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY3(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#ifndef CONFIG_LINK_DEVICE_HSIC
+ { EXYNOS4_GPY3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ /* GPIO_ACTIVE_STATE, EHCI on/off state to CP */
+ { EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ { EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ /* USB_SEL2 */
+ { EXYNOS4_GPY3(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#ifndef CONFIG_LINK_DEVICE_HSIC
+ { EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ /* GPIO_PDA_ACTIVE, AP Sleep, LPA state to CP */
+ { EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ { EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* V_ACCESSORY_5V CHECK */
+ { EXYNOS4_GPY4(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ /* USB_SEL3 */
+ { EXYNOS4_GPY4(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#ifndef CONFIG_LINK_DEVICE_HSIC
+ { EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ /* GPIO_CP_REQ_RESET */
+ { EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#endif
+ /* GPIO_UART_SEL */
+ { EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ /* HW_REV0 */
+ { EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV1 */
+ { EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV2 */
+ { EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ /* HW_REV3 */
+ { EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { EXYNOS4_GPY5(5), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY5(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ /* ACCESSORY_EN */
+ { EXYNOS4_GPY6(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPY6(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPY6(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* TA_EN */
+ { EXYNOS4_GPY6(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ { EXYNOS4_GPZ(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPZ(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPZ(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPZ(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ { EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void p8_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(p8_sleep_gpio_table),
+ p8_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index c5e65a0..88b791a 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/platsmp.c
+/* linux/arch/arm/mach-exynos/platsmp.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -28,15 +28,30 @@
#include <mach/hardware.h>
#include <mach/regs-clock.h>
+#include <mach/regs-pmu.h>
+#include <mach/smc.h>
-extern void exynos4_secondary_startup(void);
+#include <plat/cpu.h>
+#include <plat/exynos4.h>
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+#include <plat/regs-watchdog.h>
+#endif
+
+extern void exynos_secondary_startup(void);
+extern unsigned int gic_bank_offset;
+
+struct _cpu_boot_info {
+ void __iomem *power_base;
+ void __iomem *boot_base;
+};
+
+struct _cpu_boot_info cpu_boot_info[NR_CPUS];
/*
* control for which core is the next to come out of the secondary
* boot "holding pen"
*/
-
-volatile int __cpuinitdata pen_release = -1;
+volatile int pen_release = -1;
/*
* Write pen_release in a way that is guaranteed to be visible to all
@@ -53,6 +68,9 @@ static void write_pen_release(int val)
static void __iomem *scu_base_addr(void)
{
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ return 0;
+
return (void __iomem *)(S5P_VA_SCU);
}
@@ -60,12 +78,21 @@ static DEFINE_SPINLOCK(boot_lock);
void __cpuinit platform_secondary_init(unsigned int cpu)
{
+ void __iomem *dist_base = S5P_VA_GIC_DIST +
+ (gic_bank_offset * cpu);
+ void __iomem *cpu_base = S5P_VA_GIC_CPU +
+ (gic_bank_offset * cpu);
+
+ /* Enable the full line of zero */
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ enable_cache_foz();
+
/*
* if any interrupts are already enabled for the primary
* core (e.g. timer irq), then they will not have been enabled
* for us: do so
*/
- gic_secondary_init(0);
+ gic_secondary_init_base(0, dist_base, cpu_base);
/*
* let the primary processor know we're out of the
@@ -80,9 +107,44 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
+static int exynos_power_up_cpu(unsigned int cpu)
+{
+ unsigned int timeout;
+ unsigned int val;
+ void __iomem *power_base = cpu_boot_info[cpu].power_base;
+
+ val = __raw_readl(power_base);
+ if (!(val & S5P_CORE_LOCAL_PWR_EN)) {
+ __raw_writel(S5P_CORE_LOCAL_PWR_EN, power_base);
+
+ /* wait max 10 ms until cpu is on */
+ timeout = 10;
+ while (timeout) {
+ val = __raw_readl(power_base + 0x4);
+
+ if ((val & S5P_CORE_LOCAL_PWR_EN) == S5P_CORE_LOCAL_PWR_EN)
+ break;
+
+ mdelay(1);
+ timeout--;
+ }
+
+ if (timeout == 0) {
+ printk(KERN_ERR "cpu%d power up failed", cpu);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
+ int ret;
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ unsigned int tmp_wtcon;
+#endif
/*
* Set synchronisation state between this boot processor
@@ -90,6 +152,16 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
*/
spin_lock(&boot_lock);
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ tmp_wtcon = __raw_readl(S3C2410_WTCON);
+#endif
+
+ ret = exynos_power_up_cpu(cpu);
+ if (ret) {
+ spin_unlock(&boot_lock);
+ return ret;
+ }
+
/*
* The secondary processor is waiting to be released from
* the holding pen - release it, then wait for it to flag
@@ -105,17 +177,31 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* the boot monitor to read the system wide flags register,
* and branch to the address found there.
*/
- gic_raise_softirq(cpumask_of(cpu), 1);
-
timeout = jiffies + (1 * HZ);
while (time_before(jiffies, timeout)) {
smp_rmb();
+
+ __raw_writel(BSYM(virt_to_phys(exynos_secondary_startup)),
+ cpu_boot_info[cpu].boot_base);
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ if (soc_is_exynos4412())
+ exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0);
+ else
+ exynos_smc(SMC_CMD_CPU1BOOT, 0, 0, 0);
+#endif
+ smp_send_reschedule(cpu);
+
if (pen_release == -1)
break;
udelay(10);
}
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ __raw_writel(tmp_wtcon, S3C2410_WTCON);
+#endif
+
/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
@@ -125,22 +211,36 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
return pen_release != -1 ? -ENOSYS : 0;
}
+static inline unsigned long exynos5_get_core_count(void)
+{
+ u32 val;
+
+ /* Read L2 control register */
+ asm volatile("mrc p15, 1, %0, c9, c0, 2" : "=r"(val));
+
+ /* core count : [25:24] of L2 control register + 1 */
+ val = ((val >> 24) & 3) + 1;
+
+ return val;
+}
+
/*
* Initialise the CPU possible map early - this describes the CPUs
* which may be present or become present in the system.
*/
-
void __init smp_init_cpus(void)
{
- void __iomem *scu_base = scu_base_addr();
unsigned int i, ncores;
- ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+ void __iomem *scu_base = scu_base_addr();
+
+ ncores = scu_base ? scu_get_core_count(scu_base) :
+ exynos5_get_core_count();
/* sanity check */
if (ncores > NR_CPUS) {
printk(KERN_WARNING
- "EXYNOS4: no. of cores (%d) greater than configured "
+ "EXYNOS: no. of cores (%d) greater than configured "
"maximum of %d - clipping\n",
ncores, NR_CPUS);
ncores = NR_CPUS;
@@ -163,13 +263,23 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
for (i = 0; i < max_cpus; i++)
set_cpu_present(i, true);
- scu_enable(scu_base_addr());
+ if (scu_base_addr())
+ scu_enable(scu_base_addr());
+ else
+ flush_cache_all();
- /*
- * Write the address of secondary startup into the
- * system-wide flags register. The boot monitor waits
- * until it receives a soft interrupt, and then the
- * secondary CPU branches to this address.
- */
- __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), S5P_VA_SYSRAM);
+ /* Set up secondary boot base and core power cofiguration base address */
+ for (i = 1; i < max_cpus; i++) {
+#ifdef CONFIG_ARM_TRUSTZONE
+ cpu_boot_info[i].boot_base = S5P_VA_SYSRAM_NS + 0x1C;
+#else
+ if (soc_is_exynos4210() && (samsung_rev() >= EXYNOS4210_REV_1_1))
+ cpu_boot_info[i].boot_base = S5P_INFORM5;
+ else
+ cpu_boot_info[i].boot_base = S5P_VA_SYSRAM;
+#endif
+ if (soc_is_exynos4412())
+ cpu_boot_info[i].boot_base += (0x4 * i);
+ cpu_boot_info[i].power_base = S5P_ARM_CORE_CONFIGURATION(i);
+ }
}
diff --git a/arch/arm/mach-exynos/pm-exynos4.c b/arch/arm/mach-exynos/pm-exynos4.c
new file mode 100644
index 0000000..e24e519
--- /dev/null
+++ b/arch/arm/mach-exynos/pm-exynos4.c
@@ -0,0 +1,613 @@
+/* linux/arch/arm/mach-exynos/pm-exynos4.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4210 - Power Management support
+ *
+ * Based on arch/arm/mach-s3c2410/pm.c
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/regulator/machine.h>
+
+#if defined(CONFIG_MACH_M0_CTC)
+#include <linux/mfd/max77693.h>
+#endif
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/cputype.h>
+#include <asm/smp_scu.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-srom.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu.h>
+#include <mach/pm-core.h>
+#include <mach/pmu.h>
+#include <mach/smc.h>
+#include <mach/gpio.h>
+
+void (*exynos4_sleep_gpio_table_set)(void);
+
+#ifdef CONFIG_ARM_TRUSTZONE
+#define REG_INFORM0 (S5P_VA_SYSRAM_NS + 0x8)
+#define REG_INFORM1 (S5P_VA_SYSRAM_NS + 0xC)
+#else
+#define REG_INFORM0 (S5P_INFORM0)
+#define REG_INFORM1 (S5P_INFORM1)
+#endif
+
+static struct sleep_save exynos4_set_clksrc[] = {
+ { .reg = EXYNOS4_CLKSRC_MASK_TOP , .val = 0x00000001, },
+ { .reg = EXYNOS4_CLKSRC_MASK_CAM , .val = 0x11111111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_TV , .val = 0x00000111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_LCD0 , .val = 0x00001111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_MAUDIO , .val = 0x00000001, },
+ { .reg = EXYNOS4_CLKSRC_MASK_FSYS , .val = 0x01011111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_PERIL0 , .val = 0x01111111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_PERIL1 , .val = 0x01110111, },
+ { .reg = EXYNOS4_CLKSRC_MASK_DMC , .val = 0x00010000, },
+};
+
+static struct sleep_save exynos4210_set_clksrc[] = {
+ { .reg = EXYNOS4_CLKSRC_MASK_LCD1 , .val = 0x00001111, },
+};
+
+static struct sleep_save exynos4_core_save[] = {
+ /* GIC side */
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x460),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x464),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x468),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x46C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x470),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x474),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x478),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x47C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x480),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x484),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x488),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x48C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x490),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x494),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x498),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x49C),
+
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x860),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x864),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x868),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x86C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x870),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x874),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x878),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x87C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x880),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x884),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x888),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x88C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x890),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x894),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x898),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x89C),
+
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC18),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC1C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC20),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC24),
+
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090),
+};
+
+static struct sleep_save exynos4_regs_save[] = {
+ /* Common GPIO Part1 */
+ SAVE_ITEM(S5P_VA_GPIO + 0x700),
+ SAVE_ITEM(S5P_VA_GPIO + 0x704),
+ SAVE_ITEM(S5P_VA_GPIO + 0x708),
+ SAVE_ITEM(S5P_VA_GPIO + 0x70C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x710),
+ SAVE_ITEM(S5P_VA_GPIO + 0x714),
+ SAVE_ITEM(S5P_VA_GPIO + 0x718),
+ SAVE_ITEM(S5P_VA_GPIO + 0x730),
+ SAVE_ITEM(S5P_VA_GPIO + 0x734),
+ SAVE_ITEM(S5P_VA_GPIO + 0x738),
+ SAVE_ITEM(S5P_VA_GPIO + 0x73C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x900),
+ SAVE_ITEM(S5P_VA_GPIO + 0x904),
+ SAVE_ITEM(S5P_VA_GPIO + 0x908),
+ SAVE_ITEM(S5P_VA_GPIO + 0x90C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x910),
+ SAVE_ITEM(S5P_VA_GPIO + 0x914),
+ SAVE_ITEM(S5P_VA_GPIO + 0x918),
+ SAVE_ITEM(S5P_VA_GPIO + 0x930),
+ SAVE_ITEM(S5P_VA_GPIO + 0x934),
+ SAVE_ITEM(S5P_VA_GPIO + 0x938),
+ SAVE_ITEM(S5P_VA_GPIO + 0x93C),
+ /* Common GPIO Part2 */
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x708),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x70C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x710),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x714),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x718),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x71C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x720),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x908),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x90C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x910),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x914),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x918),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x91C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x920),
+};
+
+static struct sleep_save exynos4210_regs_save[] = {
+ /* SROM side */
+ SAVE_ITEM(S5P_SROM_BW),
+ SAVE_ITEM(S5P_SROM_BC0),
+ SAVE_ITEM(S5P_SROM_BC1),
+ SAVE_ITEM(S5P_SROM_BC2),
+ SAVE_ITEM(S5P_SROM_BC3),
+ /* GPIO Part1 */
+ SAVE_ITEM(S5P_VA_GPIO + 0x71C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x720),
+ SAVE_ITEM(S5P_VA_GPIO + 0x724),
+ SAVE_ITEM(S5P_VA_GPIO + 0x728),
+ SAVE_ITEM(S5P_VA_GPIO + 0x72C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x91C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x920),
+ SAVE_ITEM(S5P_VA_GPIO + 0x924),
+ SAVE_ITEM(S5P_VA_GPIO + 0x928),
+ SAVE_ITEM(S5P_VA_GPIO + 0x92C),
+ /* GPIO Part2 */
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x700),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x704),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x900),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x904),
+};
+
+
+static struct sleep_save exynos4x12_regs_save[] = {
+ /* SROM side */
+ SAVE_ITEM(S5P_SROM_BW),
+ SAVE_ITEM(S5P_SROM_BC0),
+ SAVE_ITEM(S5P_SROM_BC1),
+ SAVE_ITEM(S5P_SROM_BC2),
+ SAVE_ITEM(S5P_SROM_BC3),
+ /* GPIO Part1 */
+ SAVE_ITEM(S5P_VA_GPIO + 0x740),
+ SAVE_ITEM(S5P_VA_GPIO + 0x744),
+ SAVE_ITEM(S5P_VA_GPIO + 0x940),
+ SAVE_ITEM(S5P_VA_GPIO + 0x944),
+ /* GPIO Part2 */
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x724),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x728),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x72C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x730),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x734),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x924),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x928),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x92C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x930),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x934),
+ /* GPIO Part3 */
+ SAVE_ITEM(S5P_VA_GPIO3 + 0x700),
+ SAVE_ITEM(S5P_VA_GPIO3 + 0x900),
+ /* GPIO Part4 */
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x700),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x704),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x708),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x70C),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x710),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x900),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x904),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x908),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x90C),
+ SAVE_ITEM(S5P_VA_GPIO4 + 0x910),
+};
+
+#if defined(CONFIG_CACHE_L2X0)
+static struct sleep_save exynos4_l2cc_save[] = {
+ SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
+ SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
+ SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
+ SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
+ SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
+};
+#endif
+
+void exynos4_cpu_suspend(void)
+{
+ unsigned int tmp;
+
+ if (soc_is_exynos4210()) {
+ /* eMMC power off delay (hidden register)
+ * 0x10020988 => 0: 300msec, 1: 6msec
+ */
+ __raw_writel(1, S5P_PMUREG(0x0988));
+ }
+
+ if ((!soc_is_exynos4210()) && (exynos4_is_c2c_use())) {
+ /* Gating CLK_IEM_APC & Enable CLK_SSS */
+ tmp = __raw_readl(EXYNOS4_CLKGATE_IP_DMC);
+ tmp &= ~(0x1 << 17);
+ tmp |= (0x1 << 4);
+ __raw_writel(tmp, EXYNOS4_CLKGATE_IP_DMC);
+
+ /* Set MAX divider for PWI */
+ tmp = __raw_readl(EXYNOS4_CLKDIV_DMC1);
+ tmp |= (0xF << 8);
+ __raw_writel(tmp, EXYNOS4_CLKDIV_DMC1);
+
+ /* Set clock source for PWI */
+ tmp = __raw_readl(EXYNOS4_CLKSRC_DMC);
+ tmp &= ~EXYNOS4_CLKSRC_DMC_MASK;
+ tmp |= ((0x6 << 16)|(0x1 << 12));
+ __raw_writel(tmp, EXYNOS4_CLKSRC_DMC);
+ }
+
+ outer_flush_all();
+
+ /* Disable the full line of zero */
+ disable_cache_foz();
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+#else
+ /* issue the standby signal into the pm unit. */
+ cpu_do_idle();
+#endif
+}
+
+static int exynos4_pm_prepare(void)
+{
+ int ret = 0;
+
+#if defined(CONFIG_REGULATOR)
+ ret = regulator_suspend_prepare(PM_SUSPEND_MEM);
+#endif
+
+ return ret;
+}
+
+static void __maybe_unused exynos4_pm_finish(void)
+{
+#if defined(CONFIG_REGULATOR)
+ regulator_suspend_finish();
+#endif
+}
+
+static void exynos4_cpu_prepare(void)
+{
+ if (exynos4_sleep_gpio_table_set)
+ exynos4_sleep_gpio_table_set();
+
+ /* Set value of power down register for sleep mode */
+
+ exynos4_sys_powerdown_conf(SYS_SLEEP);
+ __raw_writel(S5P_CHECK_SLEEP, REG_INFORM1);
+
+ /* ensure at least INFORM0 has the resume address */
+
+ __raw_writel(virt_to_phys(s3c_cpu_resume), REG_INFORM0);
+
+ /* Before enter central sequence mode, clock src register have to set */
+
+ s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
+
+ if (soc_is_exynos4210())
+ s3c_pm_do_restore_core(exynos4210_set_clksrc, ARRAY_SIZE(exynos4210_set_clksrc));
+}
+
+static int exynos4_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = exynos4_cpu_prepare;
+ pm_cpu_sleep = exynos4_cpu_suspend;
+
+ pm_prepare = exynos4_pm_prepare;
+#ifdef CONFIG_SLP
+ pm_finish = exynos4_pm_finish;
+#endif
+
+ return 0;
+}
+
+static struct sysdev_driver exynos4_pm_driver = {
+ .add = exynos4_pm_add,
+};
+
+static __init int exynos4_pm_drvinit(void)
+{
+ unsigned int tmp;
+
+ s3c_pm_init();
+
+ /* All wakeup disable */
+
+ tmp = __raw_readl(S5P_WAKEUP_MASK);
+ tmp |= ((0xFF << 8) | (0x1F << 1));
+ __raw_writel(tmp, S5P_WAKEUP_MASK);
+
+ /* Disable XXTI pad in system level normal mode */
+ __raw_writel(0x0, S5P_XXTI_CONFIGURATION);
+
+ return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
+}
+arch_initcall(exynos4_pm_drvinit);
+
+static int exynos4_pm_suspend(void)
+{
+ unsigned long tmp;
+
+ if (!exynos4_is_c2c_use())
+ s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
+
+ s3c_pm_do_save(exynos4_regs_save, ARRAY_SIZE(exynos4_regs_save));
+ if (soc_is_exynos4210())
+ s3c_pm_do_save(exynos4210_regs_save,
+ ARRAY_SIZE(exynos4210_regs_save));
+ else
+ s3c_pm_do_save(exynos4x12_regs_save,
+ ARRAY_SIZE(exynos4x12_regs_save));
+
+ s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
+
+ /* Setting Central Sequence Register for power down mode */
+
+ tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+ tmp &= ~(S5P_CENTRAL_LOWPWR_CFG);
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+
+ /* When enter sleep mode, USE_DELAYED_RESET_ASSERTION have to disable */
+ if (!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(0);
+
+ if (!soc_is_exynos4210()) {
+ tmp = S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0;
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
+
+ if (exynos4_is_c2c_use()) {
+ tmp = __raw_readl(S5P_WAKEUP_MASK_COREBLK);
+ tmp &= ~(1 << 20);
+ __raw_writel(tmp, S5P_WAKEUP_MASK_COREBLK);
+ tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION_COREBLK);
+ tmp &= ~S5P_CENTRAL_SEQ_COREBLK_CONF;
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION_COREBLK);
+ }
+ }
+
+ return 0;
+}
+
+#if !defined(CONFIG_CPU_EXYNOS4210)
+#define CHECK_POINT printk(KERN_DEBUG "%s:%d\n", __func__, __LINE__)
+#else
+#define CHECK_POINT
+#endif
+
+static void exynos4_pm_resume(void)
+{
+ unsigned long tmp;
+
+ /* If PMU failed while entering sleep mode, WFI will be
+ * ignored by PMU and then exiting cpu_do_idle().
+ * S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
+ * in this situation.
+ */
+ tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
+ if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
+ tmp |= S5P_CENTRAL_LOWPWR_CFG;
+ __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
+ /* No need to perform below restore code */
+ pr_info("%s: early_wakeup\n", __func__);
+ goto early_wakeup;
+ }
+
+ /* For release retention */
+
+ __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
+ __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
+
+ s3c_pm_do_restore(exynos4_regs_save, ARRAY_SIZE(exynos4_regs_save));
+ if (soc_is_exynos4210())
+ s3c_pm_do_restore(exynos4210_regs_save,
+ ARRAY_SIZE(exynos4210_regs_save));
+ else
+ s3c_pm_do_restore(exynos4x12_regs_save,
+ ARRAY_SIZE(exynos4x12_regs_save));
+
+#if defined(CONFIG_MACH_M0_CTC)
+{
+ if (max7693_muic_cp_usb_state()) {
+ if (system_rev < 11) {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ } else if (system_rev == 11) {
+ gpio_direction_output(GPIO_USB_BOOT_EN, 1);
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
+ } else {
+ gpio_direction_output(GPIO_USB_BOOT_EN_REV06, 1);
+ }
+ }
+}
+#endif
+
+ CHECK_POINT;
+
+ if (!exynos4_is_c2c_use())
+ s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
+ else {
+ if (!soc_is_exynos4210()) {
+ /* Gating CLK_SSS */
+ tmp = __raw_readl(EXYNOS4_CLKGATE_IP_DMC);
+ tmp &= ~(0x1 << 4);
+ __raw_writel(tmp, EXYNOS4_CLKGATE_IP_DMC);
+ }
+ }
+
+ /* For the suspend-again to check the value */
+ s3c_suspend_wakeup_stat = __raw_readl(S5P_WAKEUP_STAT);
+
+ CHECK_POINT;
+
+ if ((__raw_readl(S5P_WAKEUP_STAT) == 0) && soc_is_exynos4412()) {
+ __raw_writel(0, S5P_EINT_PEND(0));
+ __raw_writel(0, S5P_EINT_PEND(1));
+ __raw_writel(0, S5P_EINT_PEND(2));
+ __raw_writel(0, S5P_EINT_PEND(3));
+ __raw_writel(0x01010001, S5P_ARM_CORE_OPTION(0));
+ __raw_writel(0x00000001, S5P_ARM_CORE_OPTION(1));
+ __raw_writel(0x00000001, S5P_ARM_CORE_OPTION(2));
+ __raw_writel(0x00000001, S5P_ARM_CORE_OPTION(3));
+ }
+
+ scu_enable(S5P_VA_SCU);
+
+ CHECK_POINT;
+
+#ifdef CONFIG_CACHE_L2X0
+#ifdef CONFIG_ARM_TRUSTZONE
+ /*
+ * Restore for Outer cache
+ */
+ exynos_smc(SMC_CMD_L2X0SETUP1, exynos4_l2cc_save[0].val,
+ exynos4_l2cc_save[1].val,
+ exynos4_l2cc_save[2].val);
+
+ CHECK_POINT;
+
+ exynos_smc(SMC_CMD_L2X0SETUP2,
+ L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
+ 0x7C470001, 0xC200FFFF);
+
+ CHECK_POINT;
+
+ exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
+
+ CHECK_POINT;
+
+ exynos_smc(SMC_CMD_L2X0CTRL, 1, 0, 0);
+#else
+ s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
+ outer_inv_all();
+ /* enable L2X0*/
+ writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
+#endif
+ /* Enable the full line of zero */
+ enable_cache_foz();
+#endif
+
+ CHECK_POINT;
+
+early_wakeup:
+ if (!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(1);
+
+ CHECK_POINT;
+
+ /* Clear Check mode */
+ __raw_writel(0x0, REG_INFORM1);
+
+ return;
+}
+
+static struct syscore_ops exynos4_pm_syscore_ops = {
+ .suspend = exynos4_pm_suspend,
+ .resume = exynos4_pm_resume,
+};
+
+static __init int exynos4_pm_syscore_init(void)
+{
+ register_syscore_ops(&exynos4_pm_syscore_ops);
+ return 0;
+}
+arch_initcall(exynos4_pm_syscore_init);
diff --git a/arch/arm/mach-exynos/pm-exynos5.c b/arch/arm/mach-exynos/pm-exynos5.c
new file mode 100644
index 0000000..933ee08
--- /dev/null
+++ b/arch/arm/mach-exynos/pm-exynos5.c
@@ -0,0 +1,466 @@
+/* linux/arch/arm/mach-exynos/pm-exynos5.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 - Power Management support
+ *
+ * Based on arch/arm/mach-s3c2410/pm.c
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/bts.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu5.h>
+#include <mach/pm-core.h>
+#include <mach/pmu.h>
+#include <mach/smc.h>
+
+#include <mach/map-exynos5.h>
+
+void (*exynos5_sleep_gpio_table_set)(void);
+
+#ifdef CONFIG_ARM_TRUSTZONE
+#define REG_INFORM0 (S5P_VA_SYSRAM_NS + 0x8)
+#define REG_INFORM1 (S5P_VA_SYSRAM_NS + 0xC)
+#else
+#define REG_INFORM0 (EXYNOS5_INFORM0)
+#define REG_INFORM1 (EXYNOS5_INFORM1)
+#endif
+
+static struct sleep_save exynos5_set_clksrc[] = {
+ { .reg = EXYNOS5_CLKSRC_MASK_TOP , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_GSCL , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_DISP1_0 , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_MAUDIO , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_FSYS , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_PERIC0 , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_PERIC1 , .val = 0xffffffff, },
+ { .reg = EXYNOS5_CLKSRC_MASK_ISP , .val = 0xffffffff, },
+};
+
+static struct sleep_save exynos5_core_save[] = {
+ /* GIC side */
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
+ SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x10C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x110),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x30C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x310),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x460),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x464),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x468),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x46C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x470),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x474),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x478),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x47C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x480),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x484),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x488),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x48C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x490),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x494),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x498),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x49C),
+
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x860),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x864),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x868),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x86C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x870),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x874),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x878),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x87C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x880),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x884),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x888),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x88C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x890),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x894),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x898),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0x89C),
+
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC18),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC1C),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC20),
+ SAVE_ITEM(S5P_VA_GIC_DIST + 0xC24),
+
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
+ SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
+
+ SAVE_ITEM(S3C_VA_SYS + 0x234),
+};
+
+static struct sleep_save exynos5_regs_save[] = {
+ /* Common GPIO Part1 */
+ SAVE_ITEM(S5P_VA_GPIO + 0x700),
+ SAVE_ITEM(S5P_VA_GPIO + 0x704),
+ SAVE_ITEM(S5P_VA_GPIO + 0x708),
+ SAVE_ITEM(S5P_VA_GPIO + 0x70C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x710),
+ SAVE_ITEM(S5P_VA_GPIO + 0x714),
+ SAVE_ITEM(S5P_VA_GPIO + 0x718),
+ SAVE_ITEM(S5P_VA_GPIO + 0x71C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x720),
+ SAVE_ITEM(S5P_VA_GPIO + 0x724),
+ SAVE_ITEM(S5P_VA_GPIO + 0x728),
+ SAVE_ITEM(S5P_VA_GPIO + 0x72C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x730),
+ SAVE_ITEM(S5P_VA_GPIO + 0x900),
+ SAVE_ITEM(S5P_VA_GPIO + 0x904),
+ SAVE_ITEM(S5P_VA_GPIO + 0x908),
+ SAVE_ITEM(S5P_VA_GPIO + 0x90C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x910),
+ SAVE_ITEM(S5P_VA_GPIO + 0x914),
+ SAVE_ITEM(S5P_VA_GPIO + 0x918),
+ SAVE_ITEM(S5P_VA_GPIO + 0x91C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x920),
+ SAVE_ITEM(S5P_VA_GPIO + 0x924),
+ SAVE_ITEM(S5P_VA_GPIO + 0x928),
+ SAVE_ITEM(S5P_VA_GPIO + 0x92C),
+ SAVE_ITEM(S5P_VA_GPIO + 0x930),
+ /* Common GPIO Part2 */
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x700),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x704),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x708),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x70C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x710),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x714),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x718),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x71C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x720),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x900),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x904),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x908),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x90C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x910),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x914),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x918),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x91C),
+ SAVE_ITEM(S5P_VA_GPIO2 + 0x920),
+};
+
+void exynos5_cpu_suspend(void)
+{
+ unsigned int tmp;
+
+ /* Disable wakeup by EXT_GIC */
+ tmp = __raw_readl(EXYNOS5_WAKEUP_MASK);
+ tmp |= EXYNOS5_DEFAULT_WAKEUP_MACK;
+ __raw_writel(tmp, EXYNOS5_WAKEUP_MASK);
+
+ /*
+ * GPS LPI mask.
+ */
+ if (samsung_rev() < EXYNOS5250_REV_1_0)
+ __raw_writel(0x10000, EXYNOS5_GPS_LPI);
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ exynos4_reset_assert_ctrl(0);
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_SLEEP, 0, 0, 0);
+#else
+ /* issue the standby signal into the pm unit. */
+ cpu_do_idle();
+#endif
+}
+
+static void exynos5_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ if (exynos5_sleep_gpio_table_set)
+ exynos5_sleep_gpio_table_set();
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ /* Disable USE_RETENTION of JPEG_MEM_OPTION */
+ tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION);
+ tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
+ __raw_writel(tmp, EXYNOS5_JPEG_MEM_OPTION);
+ }
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ tmp = __raw_readl(EXYNOS5_ARM_L2_OPTION);
+ tmp &= ~(1 << 4);
+ __raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
+ }
+
+ /* Set value of power down register for sleep mode */
+ exynos5_sys_powerdown_conf(SYS_SLEEP);
+ __raw_writel(S5P_CHECK_SLEEP, REG_INFORM1);
+
+ /* ensure at least INFORM0 has the resume address */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), REG_INFORM0);
+
+ if (exynos4_is_c2c_use()) {
+ tmp = __raw_readl(EXYNOS5_INTRAM_MEM_OPTION);
+ tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
+ __raw_writel(tmp, EXYNOS5_INTRAM_MEM_OPTION);
+ }
+
+ s3c_pm_do_restore_core(exynos5_set_clksrc, ARRAY_SIZE(exynos5_set_clksrc));
+}
+
+static int exynos5_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = exynos5_pm_prepare;
+ pm_cpu_sleep = exynos5_cpu_suspend;
+
+ return 0;
+}
+
+static struct sysdev_driver exynos5_pm_driver = {
+ .add = exynos5_pm_add,
+};
+
+static __init int exynos5_pm_drvinit(void)
+{
+ s3c_pm_init();
+
+ return sysdev_driver_register(&exynos5_sysclass, &exynos5_pm_driver);
+}
+arch_initcall(exynos5_pm_drvinit);
+
+bool isp_pwr_off;
+
+static int exynos5_pm_suspend(void)
+{
+ unsigned long tmp;
+ u32 timeout;
+
+ s3c_pm_do_save(exynos5_core_save, ARRAY_SIZE(exynos5_core_save));
+
+ s3c_pm_do_save(exynos5_regs_save, ARRAY_SIZE(exynos5_regs_save));
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ if (!(__raw_readl(EXYNOS5_ISP_STATUS) & S5P_INT_LOCAL_PWR_EN)) {
+ isp_pwr_off = true;
+ /*
+ * Before enter suspend, ISP power domain should be on
+ */
+ __raw_writel(S5P_INT_LOCAL_PWR_EN,
+ EXYNOS5_ISP_CONFIGURATION);
+ timeout = 1000;
+
+ while (!(__raw_readl(EXYNOS5_ISP_STATUS) & S5P_INT_LOCAL_PWR_EN)) {
+ if (timeout == 0) {
+ printk(KERN_ERR "ISP power domain can not on\n");
+ }
+ timeout--;
+ udelay(1);
+ }
+ }
+ }
+
+ tmp = __raw_readl(EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+ tmp &= ~(EXYNOS5_CENTRAL_LOWPWR_CFG);
+ __raw_writel(tmp, EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+
+ tmp = __raw_readl(EXYNOS5_CENTRAL_SEQ_OPTION);
+
+ tmp = (EXYNOS5_USE_STANDBYWFI_ARM_CORE0 |
+ EXYNOS5_USE_STANDBYWFE_ARM_CORE0);
+
+ __raw_writel(tmp, EXYNOS5_CENTRAL_SEQ_OPTION);
+
+ return 0;
+}
+
+static void exynos5_pm_resume(void)
+{
+ unsigned long tmp, srctmp;
+ u32 timeout;
+
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ exynos4_reset_assert_ctrl(1);
+
+ /* If PMU failed while entering sleep mode, WFI will be
+ * ignored by PMU and then exiting cpu_do_idle().
+ * EXYNOS5_CENTRAL_SEQ_CONFIGURATION bit will not be set
+ * automatically in this situation.
+ */
+ tmp = __raw_readl(EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+
+ if (!(tmp & EXYNOS5_CENTRAL_LOWPWR_CFG)) {
+ tmp |= EXYNOS5_CENTRAL_LOWPWR_CFG;
+ __raw_writel(tmp, EXYNOS5_CENTRAL_SEQ_CONFIGURATION);
+ /* No need to perform below restore code */
+ goto early_wakeup;
+ }
+
+ if ((samsung_rev() < EXYNOS5250_REV_1_0) && isp_pwr_off) {
+ srctmp = __raw_readl(EXYNOS5_CLKSRC_TOP3);
+ /*
+ * To ISP power domain off,
+ * first, ISP_ARM power domain be off.
+ */
+ if ((__raw_readl(EXYNOS5_ISP_ARM_STATUS) & 0x1)) {
+ /* Disable ISP_ARM */
+ timeout = __raw_readl(EXYNOS5_ISP_ARM_OPTION);
+ timeout &= ~EXYNOS5_ISP_ARM_ENABLE;
+ __raw_writel(timeout, EXYNOS5_ISP_ARM_OPTION);
+
+ /* ISP_ARM power off */
+ __raw_writel(0x0, EXYNOS5_ISP_ARM_CONFIGURATION);
+
+ timeout = 1000;
+
+ while (__raw_readl(EXYNOS5_ISP_ARM_STATUS) & 0x1) {
+ if (timeout == 0) {
+ printk(KERN_ERR "ISP_ARM power domain can not off\n");
+ return;
+ }
+ timeout--;
+ udelay(1);
+ }
+ /* CMU_RESET_ISP_ARM off */
+ __raw_writel(0x0, EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG);
+ }
+
+ __raw_writel(0x0, EXYNOS5_ISP_CONFIGURATION);
+
+ /* Wait max 1ms */
+ timeout = 1000;
+ while (__raw_readl(EXYNOS5_ISP_STATUS) & S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ printk(KERN_ERR "Power domain ISP disable failed.\n");
+ return;
+ }
+ timeout--;
+ udelay(1);
+ }
+
+ __raw_writel(srctmp, EXYNOS5_CLKSRC_TOP3);
+
+ isp_pwr_off = false;
+ }
+
+ /* For release retention */
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_MAU_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_GPIO_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_UART_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_MMCA_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_MMCB_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_EBIA_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_EBIB_OPTION);
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_SPI_OPTION);
+
+ /* For Retention release on GPV block */
+ __raw_writel((1 << 28), EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_OPTION);
+
+ /* Disable CPU_nIRQ[0:1] */
+ tmp = ((0x1 << 8) | (0x1 << 0));
+ __raw_writel(tmp, S5P_VA_COMBINER_BASE + 0x54);
+
+ bts_enable(PD_TOP);
+
+ s3c_pm_do_restore(exynos5_regs_save, ARRAY_SIZE(exynos5_regs_save));
+
+ s3c_pm_do_restore_core(exynos5_core_save, ARRAY_SIZE(exynos5_core_save));
+
+early_wakeup:
+ __raw_writel(0x0, REG_INFORM1);
+}
+
+static struct syscore_ops exynos5_pm_syscore_ops = {
+ .suspend = exynos5_pm_suspend,
+ .resume = exynos5_pm_resume,
+};
+
+static __init int exynos5_pm_syscore_init(void)
+{
+ register_syscore_ops(&exynos5_pm_syscore_ops);
+
+ return 0;
+}
+arch_initcall(exynos5_pm_syscore_init);
diff --git a/arch/arm/mach-exynos/pm-hotplug.c b/arch/arm/mach-exynos/pm-hotplug.c
new file mode 100644
index 0000000..d82503d
--- /dev/null
+++ b/arch/arm/mach-exynos/pm-hotplug.c
@@ -0,0 +1,225 @@
+/* linux/arch/arm/mach-s5pv310/pm-hotplug.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV310 - Dynamic CPU hotpluging
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/percpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+
+#include <plat/map-base.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+#include <linux/gpio.h>
+#include <linux/cpufreq.h>
+
+#define CPUMON 1
+
+#define CHECK_DELAY (.5*HZ)
+#define TRANS_LOAD_L 20
+#define TRANS_LOAD_H 50
+
+#define HOTPLUG_UNLOCKED 0
+#define HOTPLUG_LOCKED 1
+
+static struct workqueue_struct *hotplug_wq;
+
+static struct delayed_work hotplug_work;
+
+static unsigned int hotpluging_rate = CHECK_DELAY;
+module_param_named(rate, hotpluging_rate, uint, 0644);
+static unsigned int user_lock;
+module_param_named(lock, user_lock, uint, 0644);
+static unsigned int trans_load_l = TRANS_LOAD_L;
+module_param_named(loadl, trans_load_l, uint, 0644);
+static unsigned int trans_load_h = TRANS_LOAD_H;
+module_param_named(loadh, trans_load_h, uint, 0644);
+
+struct cpu_time_info {
+ cputime64_t prev_cpu_idle;
+ cputime64_t prev_cpu_wall;
+ unsigned int load;
+};
+
+static DEFINE_PER_CPU(struct cpu_time_info, hotplug_cpu_time);
+
+/* mutex can be used since hotplug_timer does not run in
+ timer(softirq) context but in process context */
+static DEFINE_MUTEX(hotplug_lock);
+
+static void hotplug_timer(struct work_struct *work)
+{
+ unsigned int i, avg_load = 0, load = 0;
+ unsigned int cur_freq;
+
+ mutex_lock(&hotplug_lock);
+
+ if (user_lock == 1)
+ goto no_hotplug;
+
+ for_each_online_cpu(i) {
+ struct cpu_time_info *tmp_info;
+ cputime64_t cur_wall_time, cur_idle_time;
+ unsigned int idle_time, wall_time;
+
+ tmp_info = &per_cpu(hotplug_cpu_time, i);
+
+ cur_idle_time = get_cpu_idle_time_us(i, &cur_wall_time);
+
+ idle_time = (unsigned int)cputime64_sub(cur_idle_time,
+ tmp_info->prev_cpu_idle);
+ tmp_info->prev_cpu_idle = cur_idle_time;
+
+ wall_time = (unsigned int)cputime64_sub(cur_wall_time,
+ tmp_info->prev_cpu_wall);
+ tmp_info->prev_cpu_wall = cur_wall_time;
+
+ if (wall_time < idle_time)
+ goto no_hotplug;
+
+ tmp_info->load = 100 * (wall_time - idle_time) / wall_time;
+
+ load += tmp_info->load;
+ }
+
+ avg_load = load / num_online_cpus();
+
+ cur_freq = cpufreq_get(0);
+
+ if (((avg_load < trans_load_l) || (cur_freq <= 200 * 1000)) &&
+ (cpu_online(1) == 1)) {
+ printk(KERN_INFO "cpu1 turning off!\n");
+ cpu_down(1);
+#if CPUMON
+ printk(KERN_ERR "CPUMON D %d\n", avg_load);
+#endif
+ printk(KERN_INFO "cpu1 off end!\n");
+ hotpluging_rate = CHECK_DELAY;
+ } else if (((avg_load > trans_load_h) && (cur_freq > 200 * 1000)) &&
+ (cpu_online(1) == 0)) {
+ printk(KERN_INFO "cpu1 turning on!\n");
+ cpu_up(1);
+#if CPUMON
+ printk(KERN_ERR "CPUMON U %d\n", avg_load);
+#endif
+ printk(KERN_INFO "cpu1 on end!\n");
+ hotpluging_rate = CHECK_DELAY * 4;
+ }
+ no_hotplug:
+
+ queue_delayed_work_on(0, hotplug_wq, &hotplug_work, hotpluging_rate);
+
+ mutex_unlock(&hotplug_lock);
+}
+
+static int exynos4_pm_hotplug_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ static unsigned user_lock_saved;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ mutex_lock(&hotplug_lock);
+ user_lock_saved = user_lock;
+ user_lock = 1;
+ pr_info("%s: saving pm_hotplug lock %x\n",
+ __func__, user_lock_saved);
+ mutex_unlock(&hotplug_lock);
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ mutex_lock(&hotplug_lock);
+ pr_info("%s: restoring pm_hotplug lock %x\n",
+ __func__, user_lock_saved);
+ user_lock = user_lock_saved;
+ mutex_unlock(&hotplug_lock);
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos4_pm_hotplug_notifier = {
+ .notifier_call = exynos4_pm_hotplug_notifier_event,
+};
+
+static int hotplug_reboot_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ mutex_lock(&hotplug_lock);
+ pr_err("%s: disabling pm hotplug\n", __func__);
+ user_lock = 1;
+ mutex_unlock(&hotplug_lock);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block hotplug_reboot_notifier = {
+ .notifier_call = hotplug_reboot_notifier_call,
+};
+
+static int __init exynos4_pm_hotplug_init(void)
+{
+ printk(KERN_INFO "EXYNOS4 PM-hotplug init function\n");
+ /* hotplug_wq = create_workqueue("dynamic hotplug"); */
+ hotplug_wq = alloc_workqueue("dynamic hotplug", 0, 0);
+ if (!hotplug_wq) {
+ printk(KERN_ERR "Creation of hotplug work failed\n");
+ return -EFAULT;
+ }
+
+ INIT_DELAYED_WORK(&hotplug_work, hotplug_timer);
+
+ queue_delayed_work_on(0, hotplug_wq, &hotplug_work, 60 * HZ);
+
+ register_pm_notifier(&exynos4_pm_hotplug_notifier);
+ register_reboot_notifier(&hotplug_reboot_notifier);
+
+ return 0;
+}
+
+late_initcall(exynos4_pm_hotplug_init);
+
+static struct platform_device exynos4_pm_hotplug_device = {
+ .name = "exynos4-dynamic-cpu-hotplug",
+ .id = -1,
+};
+
+static int __init exynos4_pm_hotplug_device_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&exynos4_pm_hotplug_device);
+
+ if (ret) {
+ printk(KERN_ERR "failed at(%d)\n", __LINE__);
+ return ret;
+ }
+
+ printk(KERN_INFO "exynos4_pm_hotplug_device_init: %d\n", ret);
+
+ return ret;
+}
+
+late_initcall(exynos4_pm_hotplug_device_init);
diff --git a/arch/arm/mach-exynos/pmu-exynos4.c b/arch/arm/mach-exynos/pmu-exynos4.c
new file mode 100644
index 0000000..d0b4fbd
--- /dev/null
+++ b/arch/arm/mach-exynos/pmu-exynos4.c
@@ -0,0 +1,447 @@
+/* linux/arch/arm/mach-exynos/pmu-exynos4.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4210 - CPU PMU(Power Management Unit) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <mach/regs-clock.h>
+#include <mach/pmu.h>
+#include <mach/regs-pmu.h>
+
+#include <plat/cpu.h>
+
+static struct exynos4_pmu_conf *exynos4_pmu_config;
+
+static unsigned int entry_cnt;
+
+static struct exynos4_pmu_conf exynos4210_pmu_config[] = {
+ /* { .reg = address, .val = { AFTR, LPA, SLEEP } */
+ { S5P_ARM_CORE0_SYS, { 0, 0, 2 } },
+ { S5P_DIS_IRQ_ARM_CORE0_LOCAL_SYS, { 0, 0, 0 } },
+ { S5P_DIS_IRQ_ARM_CORE0_CENTRAL_SYS, { 0, 0, 0 } },
+ { S5P_ARM_CORE1_SYS, { 0, 0, 2 } },
+ { S5P_DIS_IRQ_ARM_CORE1_LOCAL_SYS, { 0, 0, 0 } },
+ { S5P_DIS_IRQ_ARM_CORE1_CENTRAL_SYS, { 0, 0, 0 } },
+ { S5P_ARM_COMMON_SYS, { 0, 0, 2 } },
+ { S5P_ARM_L2_0_SYS, { 2, 2, 3 } },
+ { S5P_ARM_L2_1_SYS, { 2, 2, 3 } },
+ { S5P_CMU_ACLKSTOP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_SCLKSTOP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_SYS, { 1, 1, 0 } },
+ { S5P_APLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_MPLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_VPLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_EPLL_SYSCLK_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_GPS_ALIVE_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_GPSALIVE_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_CAM_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_TV_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_MFC_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_G3D_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_LCD0_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_LCD1_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_CMU_CLKSTOP_GPS_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_CAM_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_TV_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_MFC_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_G3D_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_LCD0_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_LCD1_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_GPS_SYS, { 1, 1, 0 } },
+ { S5P_TOP_BUS_SYS, { 3, 0, 0 } },
+ { S5P_TOP_RETENTION_SYS, { 1, 0, 1 } },
+ { S5P_TOP_PWR_SYS, { 3, 0, 3 } },
+ { S5P_LOGIC_RESET_SYS, { 1, 1, 0 } },
+ { S5P_ONENAND_MEM_SYS, { 3, 0, 0 } },
+ { S5P_MODIMIF_MEM_SYS, { 3, 0, 0 } },
+ { S5P_G2D_ACP_MEM_SYS, { 3, 0, 0 } },
+ { S5P_USBOTG_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SDMMC_MEM_SYS, { 3, 0, 0 } },
+ { S5P_CSSYS_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SECSS_MEM_SYS, { 3, 0, 0 } },
+ { S5P_PCIE_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SATA_MEM_SYS, { 3, 0, 0 } },
+ { S5P_PAD_RETENTION_DRAM_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_PAD_RETENTION_GPIO_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_UART_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MMCA_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MMCB_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_EBIA_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_EBIB_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ISOLATION_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ALV_SEL_SYS, { 1, 0, 0 } },
+ { S5P_XXTI_SYS, { 1, 1, 0 } },
+ { S5P_EXT_REGULATOR_SYS, { 1, 1, 0 } },
+ { S5P_GPIO_MODE_SYS, { 1, 0, 0 } },
+ { S5P_GPIO_MODE_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_CAM_SYS, { 7, 0, 0 } },
+ { S5P_TV_SYS, { 7, 0, 0 } },
+ { S5P_MFC_SYS, { 7, 0, 0 } },
+ { S5P_G3D_SYS, { 7, 0, 0 } },
+ { S5P_LCD0_SYS, { 7, 0, 0 } },
+ { S5P_LCD1_SYS, { 7, 0, 0 } },
+ { S5P_MAUDIO_SYS, { 7, 7, 0 } },
+ { S5P_GPS_SYS, { 7, 0, 0 } },
+ { S5P_GPS_ALIVE_SYS, { 7, 0, 0 } },
+ { S5P_XUSBXTI_SYS, { 1, 1, 0 } },
+};
+
+static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
+ { S5P_ARM_CORE0_SYS, { 0, 0, 2 } },
+ { S5P_DIS_IRQ_ARM_CORE0_LOCAL_SYS, { 0, 0, 0 } },
+ { S5P_DIS_IRQ_ARM_CORE0_CENTRAL_SYS, { 0, 0, 0 } },
+ { S5P_ARM_CORE1_SYS, { 0, 0, 2 } },
+ { S5P_DIS_IRQ_ARM_CORE1_LOCAL_SYS, { 0, 0, 0 } },
+ { S5P_DIS_IRQ_ARM_CORE1_CENTRAL_SYS, { 0, 0, 0 } },
+ { S5P_ISP_ARM_SYS, { 1, 0, 0 } },
+ { S5P_DIS_IRQ_ISP_ARM_LOCAL_SYS, { 0, 0, 0 } },
+ { S5P_DIS_IRQ_ISP_ARM_CENTRAL_SYS, { 1, 0, 0 } },
+ { S5P_ARM_COMMON_SYS, { 0, 0, 2 } },
+ { S5P_ARM_L2_0_SYS, { 0, 0, 3 } },
+ { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_ARM_L2_1_SYS, { 0, 0, 3 } },
+ { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_CMU_ACLKSTOP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_SCLKSTOP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_SYS, { 1, 1, 0 } },
+ { S5P_DRAM_FREQ_DOWN_SYS, { 1, 1, 1 } },
+ { S5P_DDRPHY_DLLOFF_SYS, { 1, 1, 1 } },
+ { S5P_LPDDR_PHY_DLL_LOCK_SYS, { 1, 1, 1 } },
+ { S5P_CMU_ACLKSTOP_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_CMU_SCLKSTOP_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_COREBLK_SYS, { 1, 1, 0 } },
+ { S5P_APLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_MPLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_VPLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_EPLL_SYSCLK_SYS, { 1, 1, 0 } },
+ { S5P_MPLLUSER_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_GPS_ALIVE_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_GPSALIVE_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_CAM_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_TV_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_MFC_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_G3D_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_LCD0_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_ISP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_MAUDIO_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_GPS_SYS, { 0, 0, 0 } },
+
+ { S5P_CMU_RESET_CAM_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_TV_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_MFC_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_G3D_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_LCD0_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_ISP_SYS, { 0, 0, 0 } },
+ { S5P_CMU_RESET_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_CMU_RESET_GPS_SYS, { 1, 0, 0 } },
+ { S5P_TOP_BUS_SYS, { 3, 0, 0 } },
+ { S5P_TOP_RETENTION_SYS, { 1, 0, 1 } },
+ { S5P_TOP_PWR_SYS, { 3, 0, 3 } },
+ { S5P_TOP_BUS_COREBLK_SYS, { 3, 0, 0 } },
+ { S5P_TOP_RETENTION_COREBLK_SYS, { 1, 0, 1 } },
+ { S5P_TOP_PWR_COREBLK_SYS, { 3, 0, 3 } },
+ { S5P_LOGIC_RESET_SYS, { 1, 1, 0 } },
+ { S5P_OSCCLK_GATE_SYS, { 1, 0, 1 } },
+ { S5P_LOGIC_RESET_COREBLK_SYS, { 1, 1, 0 } },
+ { S5P_OSCCLK_GATE_COREBLK_SYS, { 1, 0, 1 } },
+ { S5P_ONENAND_MEM_SYS, { 3, 0, 0 } },
+ { S5P_ONENAND_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_HSI_MEM_SYS, { 3, 0, 0 } },
+ { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_G2D_ACP_MEM_SYS, { 3, 0, 0 } },
+ { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_USBOTG_MEM_SYS, { 3, 0, 0 } },
+ { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_SDMMC_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SDMMC_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_CSSYS_MEM_SYS, { 3, 0, 0 } },
+ { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_SECSS_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_ROTATOR_MEM_SYS, { 3, 0, 0 } },
+ { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_PAD_RETENTION_DRAM_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_PAD_RETENTION_GPIO_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_UART_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MMCA_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MMCB_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_EBIA_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_EBIB_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_GPIO_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ISOLATION_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ISOLATION_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ALV_SEL_SYS, { 1, 0, 0 } },
+ { S5P_XXTI_SYS, { 1, 1, 0 } },
+ { S5P_EXT_REGULATOR_SYS, { 1, 1, 0 } },
+ { S5P_GPIO_MODE_SYS, { 1, 0, 0 } },
+ { S5P_GPIO_MODE_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_GPIO_MODE_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_TOP_ASB_RESET_SYS, { 1, 1, 1 } },
+ { S5P_TOP_ASB_ISOLATION_SYS, { 1, 0, 1 } },
+ { S5P_CAM_SYS, { 7, 0, 0 } },
+ { S5P_TV_SYS, { 7, 0, 0 } },
+ { S5P_MFC_SYS, { 7, 0, 0 } },
+ { S5P_G3D_SYS, { 7, 0, 0 } },
+ { S5P_LCD0_SYS, { 7, 0, 0 } },
+ { S5P_ISP_SYS, { 7, 0, 0 } },
+ { S5P_MAUDIO_SYS, { 7, 7, 0 } },
+ { S5P_GPS_SYS, { 7, 0, 0 } },
+ { S5P_GPS_ALIVE_SYS, { 7, 0, 0 } },
+ { S5P_CMU_SYSCLK_ISP_SYS, { 0, 0, 0 } },
+ { S5P_CMU_SYSCLK_GPS_SYS, { 1, 0, 0 } },
+ { S5P_XUSBXTI_SYS, { 1, 1, 0 } },
+};
+
+static struct exynos4_pmu_conf exynos4412_pmu_config[] = {
+ { S5P_ARM_CORE0_SYS, { 0, 0, 2 } },
+ { S5P_ARM_CORE1_SYS, { 0, 0, 2 } },
+ { S5P_ARM_CORE2_SYS, { 0, 0, 2 } },
+ { S5P_ARM_CORE3_SYS, { 0, 0, 2 } },
+ { S5P_ISP_ARM_SYS, { 1, 0, 0 } },
+ { S5P_DIS_IRQ_ISP_ARM_LOCAL_SYS, { 0, 0, 0 } },
+ { S5P_DIS_IRQ_ISP_ARM_CENTRAL_SYS, { 1, 0, 0 } },
+ { S5P_ARM_COMMON_SYS, { 0, 0, 2 } },
+ { S5P_ARM_L2_0_SYS, { 0, 0, 3 } },
+ { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_ARM_L2_1_SYS, { 0, 0, 3 } },
+ { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_CMU_ACLKSTOP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_SCLKSTOP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_SYS, { 1, 1, 0 } },
+ { S5P_CMU_ACLKSTOP_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_CMU_SCLKSTOP_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_COREBLK_SYS, { 1, 1, 0 } },
+ { S5P_APLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_MPLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_VPLL_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_EPLL_SYSCLK_SYS, { 1, 1, 0 } },
+ { S5P_MPLLUSER_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_GPS_ALIVE_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_GPSALIVE_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_CAM_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_TV_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_MFC_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_G3D_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_LCD0_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_ISP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_MAUDIO_SYS, { 1, 0, 0 } },
+ { S5P_CMU_CLKSTOP_GPS_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_CAM_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_TV_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_MFC_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_G3D_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_LCD0_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_ISP_SYS, { 0, 0, 0 } },
+ { S5P_CMU_RESET_MAUDIO_SYS, { 1, 0, 0 } },
+ { S5P_CMU_RESET_GPS_SYS, { 1, 0, 0 } },
+ { S5P_TOP_BUS_SYS, { 3, 0, 0 } },
+ { S5P_TOP_RETENTION_SYS, { 1, 0, 1 } },
+ { S5P_TOP_PWR_SYS, { 3, 0, 3 } },
+ { S5P_TOP_BUS_COREBLK_SYS, { 3, 0, 0 } },
+ { S5P_TOP_RETENTION_COREBLK_SYS, { 1, 0, 1 } },
+ { S5P_TOP_PWR_COREBLK_SYS, { 3, 0, 3 } },
+ { S5P_LOGIC_RESET_SYS, { 1, 1, 0 } },
+ { S5P_OSCCLK_GATE_SYS, { 1, 0, 1 } },
+ { S5P_LOGIC_RESET_COREBLK_SYS, { 1, 1, 0 } },
+ { S5P_OSCCLK_GATE_COREBLK_SYS, { 1, 0, 1 } },
+ { S5P_HSI_MEM_SYS, { 3, 0, 0 } },
+ { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_G2D_ACP_MEM_SYS, { 3, 0, 0 } },
+ { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_USBOTG_MEM_SYS, { 3, 0, 0 } },
+ { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_SDMMC_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SDMMC_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_CSSYS_MEM_SYS, { 3, 0, 0 } },
+ { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_SECSS_MEM_SYS, { 3, 0, 0 } },
+ { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_ROTATOR_MEM_SYS, { 3, 0, 0 } },
+ { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0 } },
+ { S5P_PAD_RETENTION_DRAM_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_PAD_RETENTION_GPIO_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_UART_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MMCA_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_MMCB_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_EBIA_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_EBIB_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_GPIO_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ISOLATION_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ISOLATION_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_PAD_ALV_SEL_SYS, { 1, 0, 0 } },
+ { S5P_XXTI_SYS, { 1, 1, 0 } },
+ { S5P_EXT_REGULATOR_SYS, { 1, 1, 0 } },
+ { S5P_GPIO_MODE_SYS, { 1, 0, 0 } },
+ { S5P_GPIO_MODE_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_GPIO_MODE_MAUDIO_SYS, { 1, 1, 0 } },
+ { S5P_TOP_ASB_RESET_SYS, { 1, 1, 1 } },
+ { S5P_TOP_ASB_ISOLATION_SYS, { 1, 0, 1 } },
+ { S5P_CAM_SYS, { 7, 0, 0 } },
+ { S5P_TV_SYS, { 7, 0, 0 } },
+ { S5P_MFC_SYS, { 7, 0, 0 } },
+ { S5P_G3D_SYS, { 7, 0, 0 } },
+ { S5P_LCD0_SYS, { 7, 0, 0 } },
+ { S5P_ISP_SYS, { 7, 0, 0 } },
+ { S5P_MAUDIO_SYS, { 7, 7, 0 } },
+ { S5P_GPS_SYS, { 7, 0, 0 } },
+ { S5P_GPS_ALIVE_SYS, { 7, 0, 0 } },
+ { S5P_CMU_SYSCLK_ISP_SYS, { 1, 0, 0 } },
+ { S5P_CMU_SYSCLK_GPS_SYS, { 1, 0, 0 } },
+ { S5P_XUSBXTI_SYS, { 1, 1, 0 } },
+};
+
+static struct exynos4_pmu_conf exynos4x12_c2c_pmu_conf[] = {
+ { S5P_CMU_RESET_COREBLK_SYS, { 1, 1, 1 } },
+ { S5P_MPLLUSER_SYSCLK_SYS, { 1, 0, 0 } },
+ { S5P_TOP_RETENTION_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_TOP_PWR_COREBLK_SYS, { 3, 0, 0 } },
+ { S5P_LOGIC_RESET_COREBLK_SYS, { 1, 1, 1 } },
+ { S5P_OSCCLK_GATE_COREBLK_SYS, { 1, 0, 0 } },
+ { S5P_PAD_RETENTION_GPIO_COREBLK_SYS, { 1, 1, 1 } },
+ { S5P_TOP_ASB_RESET_SYS, { 1, 1, 0 } },
+ { S5P_TOP_ASB_ISOLATION_SYS, { 1, 0, 0 } },
+};
+
+static struct exynos4_pmu_conf exynos4212_c2c_pmu_conf[] = {
+ { S5P_LPDDR_PHY_DLL_LOCK_SYS, { 1, 0, 0 } },
+};
+
+static struct exynos4_c2c_pmu_conf exynos4_config_for_c2c[] = {
+ /* Register Address Value */
+ { S5P_TOP_BUS_COREBLK_SYS, 0x0},
+ { S5P_TOP_PWR_COREBLK_SYS, 0x0},
+ { S5P_MPLL_SYSCLK_SYS, 0x0},
+#ifdef CONFIG_MACH_SMDK4212
+ { S5P_XUSBXTI_SYS, 0x0},
+#endif
+};
+
+void exynos4_pmu_xclkout_set(unsigned int enable, enum xclkout_select source)
+{
+ unsigned int tmp;
+
+ if (enable) {
+ tmp = __raw_readl(S5P_PMU_DEBUG);
+ /* CLKOUT enable */
+ tmp &= ~(0xF << S5P_PMU_CLKOUT_SEL_SHIFT | S5P_CLKOUT_DISABLE);
+ tmp |= (source << S5P_PMU_CLKOUT_SEL_SHIFT);
+ __raw_writel(tmp, S5P_PMU_DEBUG);
+ } else {
+ tmp = __raw_readl(S5P_PMU_DEBUG);
+ tmp |= S5P_CLKOUT_DISABLE; /* CLKOUT disable */
+ __raw_writel(tmp, S5P_PMU_DEBUG);
+ }
+ printk(KERN_DEBUG "pmu_debug: 0x%08x\n", __raw_readl(S5P_PMU_DEBUG));
+}
+EXPORT_SYMBOL_GPL(exynos4_pmu_xclkout_set);
+
+void exynos4_sys_powerdown_xusbxti_control(unsigned int enable)
+{
+ unsigned int count = entry_cnt;
+
+ if (enable)
+ exynos4_pmu_config[count - 1].val[SYS_SLEEP] = 0x1;
+ else
+ exynos4_pmu_config[count - 1].val[SYS_SLEEP] = 0x0;
+
+ printk(KERN_DEBUG "xusbxti_control: %ld\n",
+ exynos4_pmu_config[count - 1].val[SYS_SLEEP]);
+}
+EXPORT_SYMBOL_GPL(exynos4_sys_powerdown_xusbxti_control);
+
+void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
+{
+ unsigned int count = entry_cnt;
+ unsigned int tmp;
+
+ for (; count > 0; count--)
+ __raw_writel(exynos4_pmu_config[count - 1].val[mode],
+ exynos4_pmu_config[count - 1].reg);
+
+ if ((!soc_is_exynos4210()) && (exynos4_is_c2c_use())) {
+ for (count = 0 ; count < ARRAY_SIZE(exynos4x12_c2c_pmu_conf) ; count++)
+ __raw_writel(exynos4x12_c2c_pmu_conf[count].val[mode],
+ exynos4x12_c2c_pmu_conf[count].reg);
+
+ if (soc_is_exynos4212())
+ __raw_writel(exynos4212_c2c_pmu_conf[0].val[mode],
+ exynos4212_c2c_pmu_conf[0].reg);
+
+ for (count = 0 ; count < ARRAY_SIZE(exynos4_config_for_c2c) ; count++) {
+ tmp = __raw_readl(exynos4_config_for_c2c[count].reg);
+ tmp |= exynos4_config_for_c2c[count].val;
+ __raw_writel(tmp, exynos4_config_for_c2c[count].reg);
+ }
+ }
+}
+
+void exynos4_c2c_request_pwr_mode(enum c2c_pwr_mode mode)
+{
+ exynos4_config_for_c2c[0].val = 0x3;
+
+ switch (mode) {
+ /* If C2C mode is MAXIMAL LATENCY */
+ case MAX_LATENCY:
+ exynos4_config_for_c2c[1].val = 0x0;
+ if (soc_is_exynos4412() && (samsung_rev() < EXYNOS4412_REV_1_0))
+ exynos4_config_for_c2c[2].val = 0x1;
+ else
+ exynos4_config_for_c2c[2].val = 0x0;
+#ifdef CONFIG_MACH_SMDK4212
+ exynos4_config_for_c2c[3].val = 0x0;
+#endif
+ break;
+ /* If C2C mode is Minimal or Short LATENCY */
+ default:
+ exynos4_config_for_c2c[1].val = 0x3;
+ exynos4_config_for_c2c[2].val = 0x1;
+#ifdef CONFIG_MACH_SMDK4212
+ exynos4_config_for_c2c[3].val = 0x1;
+#endif
+ break;
+ }
+}
+
+static int __init exynos4_pmu_init(void)
+{
+ unsigned int i;
+
+ if(!soc_is_exynos4210())
+ exynos4_reset_assert_ctrl(1);
+
+ if (soc_is_exynos4210()) {
+ exynos4_pmu_config = exynos4210_pmu_config;
+ entry_cnt = ARRAY_SIZE(exynos4210_pmu_config);
+ printk(KERN_INFO "%s: PMU supports 4210(%d)\n",
+ __func__, entry_cnt);
+ } else if (soc_is_exynos4212()) {
+ exynos4_pmu_config = exynos4212_pmu_config;
+ entry_cnt = ARRAY_SIZE(exynos4212_pmu_config);
+ printk(KERN_INFO "%s: PMU supports 4212(%d)\n",
+ __func__, entry_cnt);
+ } else if (soc_is_exynos4412()) {
+ exynos4_pmu_config = exynos4412_pmu_config;
+ entry_cnt = ARRAY_SIZE(exynos4412_pmu_config);
+ printk(KERN_INFO "%s: PMU supports 4412(%d)\n",
+ __func__, entry_cnt);
+ } else {
+ printk(KERN_INFO "%s: PMU not supported\n", __func__);
+ }
+
+ return 0;
+}
+arch_initcall(exynos4_pmu_init);
diff --git a/arch/arm/mach-exynos/pmu-exynos5.c b/arch/arm/mach-exynos/pmu-exynos5.c
new file mode 100644
index 0000000..27ff96c
--- /dev/null
+++ b/arch/arm/mach-exynos/pmu-exynos5.c
@@ -0,0 +1,298 @@
+/* linux/arch/arm/mach-exynos/pmu-exynos5.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS5 - CPU PMU(Power Management Unit) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-pmu5.h>
+#include <mach/pmu.h>
+
+#include <plat/cpu.h>
+
+static struct exynos4_pmu_conf *exynos5_pmu_config;
+
+static unsigned int entry_cnt;
+
+static struct exynos4_pmu_conf exynos52xx_pmu_config[] = {
+ /* { .reg = address, .val = { AFTR, LPA, SLEEP } */
+ { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
+ { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} },
+ { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
+ { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
+ { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
+ { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+};
+
+static struct exynos4_pmu_conf exynos52xx_pmu_config_gps[] = {
+ /* { .reg = address, .val = { AFTR, LPA, SLEEP } */
+ { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
+ { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_GPS_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
+ { EXYNOS5_CMU_CLKSTOP_GPS_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_SYSCLK_GPS_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_CMU_RESET_GPS_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
+};
+
+static struct exynos4_pmu_conf exynos52xx_pmu_c2c_config[] = {
+ /* { .reg = address, .val = { AFTR, LPA, SLEEP } */
+ { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
+ { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
+ { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+ { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
+ { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
+};
+
+void __iomem *list_both_cnt_feed[] = {
+ EXYNOS5_ARM_CORE0_OPTION,
+ EXYNOS5_ARM_CORE1_OPTION,
+ EXYNOS5_ARM_COMMON_OPTION,
+ EXYNOS5_GSCL_OPTION,
+ EXYNOS5_ISP_OPTION,
+ EXYNOS5_MFC_OPTION,
+ EXYNOS5_G3D_OPTION,
+ EXYNOS5_DISP1_OPTION,
+ EXYNOS5_MAU_OPTION,
+ EXYNOS5_TOP_PWR_OPTION,
+ EXYNOS5_TOP_PWR_SYSMEM_OPTION,
+};
+
+void __iomem *list_diable_wfi_wfe[] = {
+ EXYNOS5_ARM_CORE1_OPTION,
+ EXYNOS5_FSYS_ARM_OPTION,
+ EXYNOS5_ISP_ARM_OPTION,
+};
+
+static void exynos5_init_pmu(void)
+{
+ unsigned int i;
+ unsigned int tmp;
+
+ /*
+ * Enable both SC_FEEDBACK and SC_COUNTER
+ */
+ for (i = 0 ; i < ARRAY_SIZE(list_both_cnt_feed) ; i++) {
+ tmp = __raw_readl(list_both_cnt_feed[i]);
+ tmp |= (EXYNOS5_USE_SC_FEEDBACK |
+ EXYNOS5_USE_SC_COUNTER);
+ __raw_writel(tmp, list_both_cnt_feed[i]);
+ }
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ tmp = __raw_readl(EXYNOS5_GPS_OPTION);
+ tmp |= (EXYNOS5_USE_SC_FEEDBACK |
+ EXYNOS5_USE_SC_COUNTER);
+ __raw_writel(tmp, EXYNOS5_GPS_OPTION);
+ }
+
+ /*
+ * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable
+ * MANUAL_L2RSTDISABLE_CONTROL_BITFIELD Enable
+ */
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ tmp = __raw_readl(EXYNOS5_ARM_COMMON_OPTION);
+ tmp |= (EXYNOS5_MANUAL_L2RSTDISABLE_CONTROL |
+ EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN);
+ __raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION);
+ } else {
+ tmp = __raw_readl(EXYNOS5_ARM_COMMON_OPTION);
+ tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
+ __raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION);
+ }
+
+ /*
+ * Disable WFI/WFE on XXX_OPTION
+ */
+ for (i = 0 ; i < ARRAY_SIZE(list_diable_wfi_wfe) ; i++) {
+ tmp = __raw_readl(list_diable_wfi_wfe[i]);
+ tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE |
+ EXYNOS5_OPTION_USE_STANDBYWFI);
+ __raw_writel(tmp, list_diable_wfi_wfe[i]);
+ }
+}
+
+void exynos5_pmu_xclkout_set(unsigned int enable, enum xclkout_select source)
+{
+ unsigned int tmp;
+
+ if (enable) {
+ tmp = __raw_readl(S5P_PMU_DEBUG);
+ /* CLKOUT enable */
+ tmp &= ~ (0xF << S5P_PMU_CLKOUT_SEL_SHIFT | S5P_CLKOUT_DISABLE);
+ tmp |= (source << S5P_PMU_CLKOUT_SEL_SHIFT);
+ __raw_writel(tmp, S5P_PMU_DEBUG);
+ } else {
+ tmp = __raw_readl(S5P_PMU_DEBUG);
+ /* CLKOUT disable */
+ tmp |= S5P_CLKOUT_DISABLE;
+ __raw_writel(tmp, S5P_PMU_DEBUG);
+ }
+
+ printk(KERN_DEBUG "pmu_debug: 0x%08x\n", __raw_readl(S5P_PMU_DEBUG));
+}
+EXPORT_SYMBOL_GPL(exynos5_pmu_xclkout_set);
+
+void exynos5_sys_powerdown_xxti_control(unsigned int enable)
+{
+ unsigned int count = entry_cnt;
+
+ if (enable)
+ exynos5_pmu_config[count - 1].val[SYS_SLEEP] = 0x1;
+ else
+ exynos5_pmu_config[count - 1].val[SYS_SLEEP] = 0x0;
+
+ printk(KERN_DEBUG "xxti_control: %ld\n",
+ exynos5_pmu_config[count - 1].val[SYS_SLEEP]);
+}
+EXPORT_SYMBOL_GPL(exynos5_sys_powerdown_xxti_control);
+
+
+void exynos5_sys_powerdown_conf(enum sys_powerdown mode)
+{
+ unsigned int count = entry_cnt;
+ unsigned int i;
+
+ exynos5_init_pmu();
+
+ for (; count > 0; count--)
+ __raw_writel(exynos5_pmu_config[count - 1].val[mode],
+ exynos5_pmu_config[count - 1].reg);
+
+ if (samsung_rev() < EXYNOS5250_REV_1_0) {
+ for (i = 0; i < ARRAY_SIZE(exynos52xx_pmu_config_gps); i++) {
+ __raw_writel(exynos52xx_pmu_config_gps[i].val[mode],
+ exynos52xx_pmu_config_gps[i].reg);
+ }
+
+ }
+
+ if ((mode != SYS_AFTR) && (exynos4_is_c2c_use())) {
+ pr_info("%s power mode enter with C2C Enabling\n"
+ , (mode == SYS_LPA) ? "LPA" : "SLEEP");
+
+ for (i = 0; i < ARRAY_SIZE(exynos52xx_pmu_c2c_config); i++) {
+ __raw_writel(exynos52xx_pmu_c2c_config[i].val[mode],
+ exynos52xx_pmu_c2c_config[i].reg);
+ }
+ }
+}
+
+static int __init exynos5_pmu_init(void)
+{
+ exynos5_pmu_config = exynos52xx_pmu_config;
+ entry_cnt = ARRAY_SIZE(exynos52xx_pmu_config);
+ printk(KERN_INFO "%s: PMU supports 52XX(%d)\n"
+ , __func__, entry_cnt);
+
+ return 0;
+}
+arch_initcall(exynos5_pmu_init);
diff --git a/arch/arm/mach-exynos/ppc.c b/arch/arm/mach-exynos/ppc.c
new file mode 100644
index 0000000..8c97b1a
--- /dev/null
+++ b/arch/arm/mach-exynos/ppc.c
@@ -0,0 +1,74 @@
+/* linux/arch/arm/mach-exynos/ppc.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - PPMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/ppmu.h>
+
+void exynos4_ppc_reset(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ int i;
+
+ __raw_writel(0x8000000f, ppmu_base + 0xf010);
+ __raw_writel(0x8000000f, ppmu_base + 0xf050);
+ __raw_writel(0x6, ppmu_base + 0xf000);
+ __raw_writel(0x0, ppmu_base + 0xf100);
+
+ ppmu->ccnt = 0;
+ for (i = 0; i < NUMBER_OF_COUNTER; i++)
+ ppmu->count[i] = 0;
+}
+
+void exynos4_ppc_setevent(struct exynos4_ppmu_hw *ppmu,
+ unsigned int evt)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+
+ ppmu->event[0] = evt;
+
+ __raw_writel(((evt << 12) | 0x1), ppmu_base + 0xfc);
+}
+
+void exynos4_ppc_start(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+
+ __raw_writel(0x1, ppmu_base + 0xf000);
+}
+
+void exynos4_ppc_stop(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+
+ __raw_writel(0x0, ppmu_base + 0xf000);
+}
+
+unsigned long long exynos4_ppc_update(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ unsigned int i;
+
+ ppmu->ccnt = __raw_readl(ppmu_base + 0xf100);
+
+ for (i = 0; i < NUMBER_OF_COUNTER; i++)
+ ppmu->count[i] =
+ __raw_readl(ppmu_base + (0xf110 + (0x10 * i)));
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-exynos/ppmu.c b/arch/arm/mach-exynos/ppmu.c
new file mode 100644
index 0000000..44d606c
--- /dev/null
+++ b/arch/arm/mach-exynos/ppmu.c
@@ -0,0 +1,194 @@
+/* linux/arch/arm/mach-exynos/ppmu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - CPU PPMU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/math64.h>
+#include <linux/device.h>
+
+#include <plat/cpu.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/ppmu.h>
+
+static LIST_HEAD(ppmu_list);
+
+unsigned long long ppmu_load[PPMU_END];
+unsigned long long ppmu_load_detail[2][PPMU_END];
+
+void exynos4_ppmu_reset(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ int i;
+
+ __raw_writel(0x3 << 1, ppmu_base);
+ __raw_writel(0x8000000f, ppmu_base + PPMU_CNTENS);
+
+ if (soc_is_exynos4210())
+ for (i = 0; i < NUMBER_OF_COUNTER; i++) {
+ __raw_writel(0x0, ppmu_base + DEVT0_ID + (i * DEVT_ID_OFFSET));
+ __raw_writel(0x0, ppmu_base + DEVT0_IDMSK + (i * DEVT_ID_OFFSET));
+ }
+}
+
+void exynos4_ppmu_setevent(struct exynos4_ppmu_hw *ppmu,
+ unsigned int evt_num)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ __raw_writel(ppmu->event[evt_num], ppmu_base + PPMU_BEVT0SEL + (evt_num * PPMU_BEVTSEL_OFFSET));
+}
+
+void exynos4_ppmu_start(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ __raw_writel(0x1, ppmu_base);
+}
+
+void exynos4_ppmu_stop(struct exynos4_ppmu_hw *ppmu)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ __raw_writel(0x0, ppmu_base);
+}
+
+unsigned long long exynos4_ppmu_update(struct exynos4_ppmu_hw *ppmu, int ch)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ unsigned long long total = 0;
+
+ ppmu->ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
+
+ if (ppmu->ccnt == 0)
+ ppmu->ccnt = MAX_CCNT;
+
+ if (ch >= NUMBER_OF_COUNTER || ppmu->event[ch] == 0)
+ return 0;
+
+ if (ch == 3 && !soc_is_exynos4210())
+ total = (((u64)__raw_readl(ppmu_base + PMCNT_OFFSET(ch)) << 8) |
+ __raw_readl(ppmu_base + PMCNT_OFFSET(ch + 1)));
+ else
+ total = __raw_readl(ppmu_base + PMCNT_OFFSET(ch));
+
+ if (total > ppmu->ccnt)
+ total = ppmu->ccnt;
+
+ ppmu_load_detail[0][ppmu->id] = total * ppmu->weight;
+ ppmu_load_detail[1][ppmu->id] = ppmu->ccnt;
+ return div64_u64((total * ppmu->weight * 100), ppmu->ccnt);
+}
+
+void ppmu_start(struct device *dev)
+{
+ struct exynos4_ppmu_hw *ppmu;
+
+ list_for_each_entry(ppmu, &ppmu_list, node)
+ if (ppmu->dev == dev)
+ exynos4_ppmu_start(ppmu);
+}
+
+void ppmu_update(struct device *dev, int ch)
+{
+ struct exynos4_ppmu_hw *ppmu;
+
+ list_for_each_entry(ppmu, &ppmu_list, node)
+ if (ppmu->dev == dev) {
+ exynos4_ppmu_stop(ppmu);
+ ppmu_load[ppmu->id] = exynos4_ppmu_update(ppmu, ch);
+ exynos4_ppmu_reset(ppmu);
+ }
+}
+
+void ppmu_reset(struct device *dev)
+{
+ struct exynos4_ppmu_hw *ppmu;
+ int i;
+
+ list_for_each_entry(ppmu, &ppmu_list, node) {
+ if (ppmu->dev == dev) {
+ exynos4_ppmu_stop(ppmu);
+ for (i = 0; i < NUMBER_OF_COUNTER; i++)
+ if (ppmu->event[i] != 0)
+ exynos4_ppmu_setevent(ppmu, i);
+ exynos4_ppmu_reset(ppmu);
+ }
+ }
+}
+
+void ppmu_init(struct exynos4_ppmu_hw *ppmu, struct device *dev)
+{
+ void __iomem *ppmu_base = ppmu->hw_base;
+ int i;
+
+ ppmu->dev = dev;
+ list_add(&ppmu->node, &ppmu_list);
+
+ if (soc_is_exynos4210())
+ for (i = 0; i < NUMBER_OF_COUNTER; i++) {
+ __raw_writel(0x0, ppmu_base + DEVT0_ID + (i * DEVT_ID_OFFSET));
+ __raw_writel(0x0, ppmu_base + DEVT0_IDMSK + (i * DEVT_ID_OFFSET));
+ }
+
+ for (i = 0; i < NUMBER_OF_COUNTER; i++)
+ if (ppmu->event[i] != 0)
+ exynos4_ppmu_setevent(ppmu, i);
+}
+
+struct exynos4_ppmu_hw exynos_ppmu[] = {
+ [PPMU_DMC0] = {
+ .id = PPMU_DMC0,
+ .hw_base = S5P_VA_PPMU_DMC0,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+ [PPMU_DMC1] = {
+ .id = PPMU_DMC1,
+ .hw_base = S5P_VA_PPMU_DMC1,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+ [PPMU_CPU] = {
+ .id = PPMU_CPU,
+ .hw_base = S5P_VA_PPMU_CPU,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+#ifdef CONFIG_ARCH_EXYNOS5
+ [PPMU_DDR_C] = {
+ .id = PPMU_DDR_C,
+ .hw_base = S5P_VA_PPMU_DDR_C,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+ [PPMU_DDR_R1] = {
+ .id = PPMU_DDR_R1,
+ .hw_base = S5P_VA_PPMU_DDR_R1,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+ [PPMU_DDR_L] = {
+ .id = PPMU_DDR_L,
+ .hw_base = S5P_VA_PPMU_DDR_L,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+ [PPMU_RIGHT0_BUS] = {
+ .id = PPMU_RIGHT0_BUS,
+ .hw_base = S5P_VA_PPMU_RIGHT0_BUS,
+ .event[3] = RDWR_DATA_COUNT,
+ .weight = DEFAULT_WEIGHT,
+ },
+#endif
+};
diff --git a/arch/arm/mach-exynos/px-switch.c b/arch/arm/mach-exynos/px-switch.c
new file mode 100644
index 0000000..90772ed
--- /dev/null
+++ b/arch/arm/mach-exynos/px-switch.c
@@ -0,0 +1,435 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/semaphore.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <plat/gpio-cfg.h>
+#include <mach/gpio.h>
+#include <mach/usb_switch.h>
+
+struct device *sec_switch_dev;
+
+enum usb_path_t current_path = USB_PATH_NONE;
+
+static struct semaphore usb_switch_sem;
+
+static bool usb_connected;
+
+static ssize_t show_usb_sel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const char *mode;
+
+ if (current_path & USB_PATH_CP) {
+ /* CP */
+ mode = "MODEM";
+ } else {
+ /* AP */
+ mode = "PDA";
+ }
+
+ pr_info("%s: %s\n", __func__, mode);
+
+ return sprintf(buf, "%s\n", mode);
+}
+
+static ssize_t store_usb_sel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ pr_info("%s: %s\n", __func__, buf);
+
+ if (!strncasecmp(buf, "PDA", 3)) {
+ usb_switch_lock();
+ usb_switch_clr_path(USB_PATH_CP);
+ usb_switch_unlock();
+ } else if (!strncasecmp(buf, "MODEM", 5)) {
+ usb_switch_lock();
+ usb_switch_set_path(USB_PATH_CP);
+ usb_switch_unlock();
+ } else {
+ pr_err("%s: wrong usb_sel value(%s)!!\n", __func__, buf);
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t show_uart_sel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int val_sel;
+ const char *mode;
+
+ val_sel = gpio_get_value(GPIO_UART_SEL);
+
+ if (val_sel == 0) {
+ /* CP */
+ mode = "CP";
+ } else {
+ /* AP */
+ mode = "AP";
+ }
+
+ pr_info("%s: %s\n", __func__, mode);
+
+ return sprintf(buf, "%s\n", mode);
+}
+
+static ssize_t store_uart_sel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int uart_sel = -1;
+
+ pr_info("%s: %s\n", __func__, buf);
+
+ if (!strncasecmp(buf, "AP", 2)) {
+ uart_sel = 1;
+ } else if (!strncasecmp(buf, "CP", 2)) {
+ uart_sel = 0;
+ } else {
+ pr_err("%s: wrong uart_sel value(%s)!!\n", __func__, buf);
+ return -EINVAL;
+ }
+
+ /* 1 for AP, 0 for CP */
+ gpio_set_value(GPIO_UART_SEL, uart_sel);
+
+ return count;
+}
+
+static ssize_t show_usb_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ const char *state;
+
+ if (usb_connected)
+ state = "USB_STATE_CONFIGURED";
+ else
+ state = "USB_STATE_NOTCONFIGURED";
+
+ pr_info("%s: %s\n", __func__, state);
+
+ return sprintf(buf, "%s\n", state);
+}
+
+static DEVICE_ATTR(usb_sel, 0664, show_usb_sel, store_usb_sel);
+static DEVICE_ATTR(uart_sel, 0664, show_uart_sel, store_uart_sel);
+static DEVICE_ATTR(usb_state, S_IRUGO, show_usb_state, NULL);
+
+static struct attribute *px_switch_attributes[] = {
+ &dev_attr_usb_sel.attr,
+ &dev_attr_uart_sel.attr,
+ &dev_attr_usb_state.attr,
+ NULL
+};
+
+static const struct attribute_group px_switch_group = {
+ .attrs = px_switch_attributes,
+};
+
+void set_usb_connection_state(bool connected)
+{
+ pr_info("%s: set %s\n", __func__, (connected ? "True" : "False"));
+
+ if (usb_connected != connected) {
+ usb_connected = connected;
+
+ pr_info("%s: send \"usb_state\" sysfs_notify\n", __func__);
+ sysfs_notify(&sec_switch_dev->kobj, NULL, "usb_state");
+ }
+}
+
+static void pmic_safeout2(int onoff)
+{
+#if !defined(CONFIG_MACH_P4NOTE)
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "safeout2");
+ BUG_ON(IS_ERR_OR_NULL(regulator));
+
+ if (onoff) {
+ if (!regulator_is_enabled(regulator)) {
+ regulator_enable(regulator);
+ } else {
+ pr_info("%s: onoff:%d No change in safeout2\n",
+ __func__, onoff);
+ }
+ } else {
+ if (regulator_is_enabled(regulator)) {
+ regulator_force_disable(regulator);
+ } else {
+ pr_info("%s: onoff:%d No change in safeout2\n",
+ __func__, onoff);
+ }
+ }
+
+ regulator_put(regulator);
+#else
+ if (onoff) {
+ if (!gpio_get_value(GPIO_USB_SEL_CP)) {
+ gpio_set_value(GPIO_USB_SEL_CP, onoff);
+ } else {
+ pr_info("%s: onoff:%d No change in safeout2\n",
+ __func__, onoff);
+ }
+ } else {
+ if (gpio_get_value(GPIO_USB_SEL_CP)) {
+ gpio_set_value(GPIO_USB_SEL_CP, onoff);
+ } else {
+ pr_info("%s: onoff:%d No change in safeout2\n",
+ __func__, onoff);
+ }
+ }
+#endif
+}
+
+static void usb_apply_path(enum usb_path_t path)
+{
+#if defined(CONFIG_MACH_P4NOTE)
+ pr_info("%s: current gpio before changing : sel0:%d sel1:%d sel_cp:%d\n",
+ __func__, gpio_get_value(GPIO_USB_SEL0),
+ gpio_get_value(GPIO_USB_SEL1), gpio_get_value(GPIO_USB_SEL_CP));
+ pr_info("%s: target path %x\n", __func__, path);
+#else
+ pr_info("%s: current gpio before changing : sel1:%d sel2:%d sel3:%d\n",
+ __func__, gpio_get_value(GPIO_USB_SEL1),
+ gpio_get_value(GPIO_USB_SEL2), gpio_get_value(GPIO_USB_SEL3));
+ pr_info("%s: target path %x\n", __func__, path);
+#endif
+
+ /* following checks are ordered according to priority */
+ if (path & USB_PATH_ADCCHECK) {
+#if defined(CONFIG_MACH_P4NOTE)
+ gpio_set_value(GPIO_USB_SEL0, 1);
+ gpio_set_value(GPIO_USB_SEL1, 0);
+#else
+ gpio_set_value(GPIO_USB_SEL1, 0);
+ gpio_set_value(GPIO_USB_SEL2, 1);
+ gpio_set_value(GPIO_USB_SEL3, 1);
+#endif
+ goto out_nochange;
+ }
+ if (path & USB_PATH_CP) {
+ pr_info("DEBUG: set USB path to CP\n");
+#if defined(CONFIG_MACH_P4NOTE)
+ gpio_set_value(GPIO_USB_SEL0, 0);
+ gpio_set_value(GPIO_USB_SEL1, 1);
+#else
+ gpio_set_value(GPIO_USB_SEL1, 0);
+ gpio_set_value(GPIO_USB_SEL2, 0);
+ gpio_set_value(GPIO_USB_SEL3, 1);
+#endif
+ mdelay(3);
+ goto out_cp;
+ }
+#if defined(CONFIG_MACH_P4NOTE)
+ if (path & USB_PATH_AP) {
+ gpio_set_value(GPIO_USB_SEL0, 1);
+ gpio_set_value(GPIO_USB_SEL1, 1);
+ goto out_ap;
+ }
+#else
+ if (path & USB_PATH_OTG) {
+ gpio_set_value(GPIO_USB_SEL1, 1);
+ /* don't care SEL2 */
+ gpio_set_value(GPIO_USB_SEL3, 1);
+ goto out_ap;
+ }
+ if (path & USB_PATH_HOST) {
+#ifndef CONFIG_MACH_P8LTE
+ gpio_set_value(GPIO_USB_SEL1, 1);
+#endif
+ /* don't care SEL2 */
+ gpio_set_value(GPIO_USB_SEL3, 0);
+ goto out_ap;
+ }
+#endif
+
+ /* default */
+#if defined(CONFIG_MACH_P4NOTE)
+ gpio_set_value(GPIO_USB_SEL0, 1);
+ gpio_set_value(GPIO_USB_SEL1, 1);
+#else
+ gpio_set_value(GPIO_USB_SEL1, 1);
+#ifdef CONFIG_MACH_P8LTE
+ gpio_set_value(GPIO_USB_SEL2, 1);
+#else
+ gpio_set_value(GPIO_USB_SEL2, 0);
+#endif
+ gpio_set_value(GPIO_USB_SEL3, 1);
+#endif
+
+out_ap:
+ pr_info("%s: %x safeout2 off\n", __func__, path);
+ pmic_safeout2(0);
+ goto sysfs_noti;
+
+out_cp:
+ pr_info("%s: %x safeout2 on\n", __func__, path);
+ pmic_safeout2(1);
+ goto sysfs_noti;
+
+out_nochange:
+ pr_info("%s: %x safeout2 no change\n", __func__, path);
+ return;
+
+sysfs_noti:
+ pr_info("%s: send \"usb_sel\" sysfs_notify\n", __func__);
+ sysfs_notify(&sec_switch_dev->kobj, NULL, "usb_sel");
+ return;
+}
+
+/*
+ Typical usage of usb switch:
+
+ usb_switch_lock(); (alternatively from hard/soft irq context)
+ ( or usb_switch_trylock() )
+ ...
+ usb_switch_set_path(USB_PATH_ADCCHECK);
+ ...
+ usb_switch_set_path(USB_PATH_TA);
+ ...
+ usb_switch_unlock(); (this restores previous usb switch settings)
+*/
+void usb_switch_set_path(enum usb_path_t path)
+{
+ pr_info("%s: %x current_path before changing\n",
+ __func__, current_path);
+
+ current_path |= path;
+ usb_apply_path(current_path);
+}
+
+void usb_switch_clr_path(enum usb_path_t path)
+{
+ pr_info("%s: %x current_path before changing\n",
+ __func__, current_path);
+
+ current_path &= ~path;
+ usb_apply_path(current_path);
+}
+
+int usb_switch_lock(void)
+{
+ return down_interruptible(&usb_switch_sem);
+}
+
+int usb_switch_trylock(void)
+{
+ return down_trylock(&usb_switch_sem);
+}
+
+void usb_switch_unlock(void)
+{
+ up(&usb_switch_sem);
+}
+
+#ifdef CONFIG_MACH_P4NOTE
+static void init_gpio(void)
+{
+ s3c_gpio_cfgpin(GPIO_USB_SEL0, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL0, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_USB_SEL1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL1, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_USB_SEL_CP, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_USB_SEL_CP, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_UART_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+}
+#endif
+
+static int __init usb_switch_init(void)
+{
+ int ret;
+
+#if defined(CONFIG_MACH_P4NOTE)
+ gpio_request(GPIO_USB_SEL0, "GPIO_USB_SEL0");
+ gpio_request(GPIO_USB_SEL1, "GPIO_USB_SEL1");
+ gpio_request(GPIO_USB_SEL_CP, "GPIO_USB_SEL_CP");
+ gpio_request(GPIO_UART_SEL, "GPIO_UART_SEL");
+#else
+ gpio_request(GPIO_USB_SEL1, "GPIO_USB_SEL1");
+ gpio_request(GPIO_USB_SEL2, "GPIO_USB_SEL2");
+ gpio_request(GPIO_USB_SEL3, "GPIO_USB_SEL3");
+#ifdef CONFIG_MACH_P8LTE
+ gpio_request(GPIO_UART_SEL1, "GPIO_UART_SEL1");
+ gpio_request(GPIO_UART_SEL2, "GPIO_UART_SEL2");
+#else
+ gpio_request(GPIO_UART_SEL, "GPIO_UART_SEL");
+#endif
+#endif
+
+#if defined(CONFIG_MACH_P4NOTE)
+ gpio_export(GPIO_USB_SEL0, 1);
+ gpio_export(GPIO_USB_SEL1, 1);
+ gpio_export(GPIO_USB_SEL_CP, 1);
+ gpio_export(GPIO_UART_SEL, 1);
+#else
+ gpio_export(GPIO_USB_SEL1, 1);
+ gpio_export(GPIO_USB_SEL2, 1);
+ gpio_export(GPIO_USB_SEL3, 1);
+#ifdef CONFIG_MACH_P8LTE
+ gpio_export(GPIO_UART_SEL1, 1);
+ gpio_export(GPIO_UART_SEL2, 1);
+#else
+ gpio_export(GPIO_UART_SEL, 1);
+#endif
+#endif
+
+ BUG_ON(!sec_class);
+ sec_switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
+
+ BUG_ON(!sec_switch_dev);
+#if defined(CONFIG_MACH_P4NOTE)
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL0", GPIO_USB_SEL0);
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL1", GPIO_USB_SEL1);
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL_CP", GPIO_USB_SEL_CP);
+ gpio_export_link(sec_switch_dev, "GPIO_UART_SEL", GPIO_UART_SEL);
+#else
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL1", GPIO_USB_SEL1);
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL2", GPIO_USB_SEL2);
+ gpio_export_link(sec_switch_dev, "GPIO_USB_SEL3", GPIO_USB_SEL3);
+#ifdef CONFIG_MACH_P8LTE
+ gpio_export_link(sec_switch_dev, "GPIO_UART_SEL1", GPIO_UART_SEL1);
+ gpio_export_link(sec_switch_dev, "GPIO_UART_SEL2", GPIO_UART_SEL2);
+#else
+ gpio_export_link(sec_switch_dev, "GPIO_UART_SEL", GPIO_UART_SEL);
+#endif
+#endif
+
+ /*init_MUTEX(&usb_switch_sem);*/
+ sema_init(&usb_switch_sem, 1);
+
+#ifdef CONFIG_MACH_P4NOTE
+ init_gpio();
+#endif
+
+#if !defined(CONFIG_MACH_P4NOTE)
+ if (!gpio_get_value(GPIO_USB_SEL1)) {
+#else
+ if ((!gpio_get_value(GPIO_USB_SEL0)) && (gpio_get_value(GPIO_USB_SEL1))) {
+#endif
+ usb_switch_lock();
+ usb_switch_set_path(USB_PATH_CP);
+ usb_switch_unlock();
+ }
+
+ /* create sysfs group */
+ ret = sysfs_create_group(&sec_switch_dev->kobj, &px_switch_group);
+ if (ret) {
+ pr_err("failed to create px switch attribute group\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+device_initcall(usb_switch_init);
diff --git a/arch/arm/mach-exynos/px.h b/arch/arm/mach-exynos/px.h
new file mode 100644
index 0000000..19cc144
--- /dev/null
+++ b/arch/arm/mach-exynos/px.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-exynos/px.h
+ */
+
+#ifndef __PX_H__
+#define __PX_H__
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+#if defined(CONFIG_MACH_P2)
+extern void p2_config_gpio_table(void);
+extern void p2_config_sleep_gpio_table(void);
+#elif defined(CONFIG_MACH_P8)
+extern void p8_config_gpio_table(void);
+extern void p8_config_sleep_gpio_table(void);
+#else /* CONFIG_MACH_P4) */
+extern void p4_config_gpio_table(void);
+extern void p4_config_sleep_gpio_table(void);
+#endif
+
+extern int brcm_wlan_init(void);
+extern void set_gps_uart_op(int onoff);
+
+#endif
diff --git a/arch/arm/mach-exynos/px_thermistor.h b/arch/arm/mach-exynos/px_thermistor.h
new file mode 100644
index 0000000..d3c7412
--- /dev/null
+++ b/arch/arm/mach-exynos/px_thermistor.h
@@ -0,0 +1,204 @@
+/*
+ * arch/arm/mach-s5pv310/px_thermistor.h
+ */
+
+#ifndef __PX_THERMISTOR_H__
+#define __PX_THERMISTOR_H__
+
+#if defined(CONFIG_MACH_P2)
+/* temperature table for ADC CH 7 */
+struct sec_therm_adc_table adc_temp_table[] = {
+ { 240, 700 },
+ { 291, 650 },
+ { 346, 600 },
+ { 405, 550 },
+ { 473, 500 },
+ { 492, 490 },
+ { 507, 480 },
+ { 526, 470 },
+ { 537, 460 },
+ { 555, 450 },
+ { 577, 440 },
+ { 595, 430 },
+ { 612, 420 },
+ { 631, 410 },
+ { 650, 400 },
+ { 746, 350 },
+ { 843, 300 },
+};
+#elif defined(CONFIG_MACH_P8)
+/* temperature table for ADC CH 7 */
+struct sec_therm_adc_table adc_temp_table[] = {
+ { 289, 700 },
+ { 332, 650 },
+ { 395, 600 },
+ { 459, 550 },
+ { 531, 500 },
+ { 537, 490 },
+ { 562, 480 },
+ { 579, 470 },
+ { 599, 460 },
+ { 615, 450 },
+ { 630, 440 },
+ { 651, 430 },
+ { 668, 420 },
+ { 685, 410 },
+ { 706, 400 },
+ { 793, 350 },
+ { 915, 300 },
+};
+#elif defined(CONFIG_MACH_P8LTE)
+/* temperature table for ADC CH 7 */
+struct sec_therm_adc_table adc_temp_table[] = {
+ { 203, 700 },
+ { 245, 650 },
+ { 295, 600 },
+ { 355, 550 },
+ { 418, 500 },
+ { 436, 490 },
+ { 451, 480 },
+ { 470, 470 },
+ { 485, 460 },
+ { 510, 450 },
+ { 526, 440 },
+ { 546, 430 },
+ { 560, 420 },
+ { 581, 410 },
+ { 596, 400 },
+ { 693, 350 },
+ { 710, 340 },
+ { 734, 330 },
+ { 750, 320 },
+ { 770, 310 },
+ { 792, 300 },
+};
+#elif defined(CONFIG_MACH_P4NOTE)
+/* temperature table for ADC CH 7 */
+struct sec_therm_adc_table adc_temp_table[] = {
+ { 276, 700 },
+ { 321, 650 },
+ { 394, 600 },
+ { 437, 550 },
+ { 505, 500 },
+ { 531, 490 },
+ { 534, 480 },
+ { 549, 470 },
+ { 573, 460 },
+ { 588, 450 },
+ { 610, 440 },
+ { 627, 430 },
+ { 650, 420 },
+ { 663, 410 },
+ { 687, 400 },
+ { 788, 350 },
+ { 903, 300 },
+};
+#else /* end of P2 */
+/* temperature table for ADC CH 7 */
+struct sec_therm_adc_table adc_temp_table[] = {
+ /* ADC, Temperature */
+ { 165, 800 },
+ { 173, 790 },
+ { 179, 780 },
+ { 185, 770 },
+ { 191, 760 },
+ { 197, 750 },
+ { 203, 740 },
+ { 209, 730 },
+ { 215, 720 },
+ { 221, 710 },
+ { 227, 700 },
+ { 236, 690 },
+ { 247, 680 },
+ { 258, 670 },
+ { 269, 660 },
+ { 281, 650 },
+ { 296, 640 },
+ { 311, 630 },
+ { 326, 620 },
+ { 341, 610 },
+ { 356, 600 },
+ { 372, 590 },
+ { 386, 580 },
+ { 400, 570 },
+ { 414, 560 },
+ { 428, 550 },
+ { 442, 540 },
+ { 456, 530 },
+ { 470, 520 },
+ { 484, 510 },
+ { 498, 500 },
+ { 508, 490 },
+ { 517, 480 },
+ { 526, 470 },
+ { 535, 460 },
+ { 544, 450 },
+ { 553, 440 },
+ { 562, 430 },
+ { 576, 420 },
+ { 594, 410 },
+ { 612, 400 },
+ { 630, 390 },
+ { 648, 380 },
+ { 666, 370 },
+ { 684, 360 },
+ { 702, 350 },
+ { 725, 340 },
+ { 749, 330 },
+ { 773, 320 },
+ { 797, 310 },
+ { 821, 300 },
+ { 847, 290 },
+ { 870, 280 },
+ { 893, 270 },
+ { 916, 260 },
+ { 939, 250 },
+ { 962, 240 },
+ { 985, 230 },
+ { 1008, 220 },
+ { 1031, 210 },
+ { 1054, 200 },
+ { 1081, 190 },
+ { 1111, 180 },
+ { 1141, 170 },
+ { 1171, 160 },
+ { 1201, 150 },
+ { 1231, 140 },
+ { 1261, 130 },
+ { 1291, 120 },
+ { 1321, 110 },
+ { 1351, 100 },
+ { 1358, 90 },
+ { 1364, 80 },
+ { 1370, 70 },
+ { 1376, 60 },
+ { 1382, 50 },
+ { 1402, 40 },
+ { 1422, 30 },
+ { 1442, 20 },
+ { 1462, 10 },
+ { 1482, 0 },
+ { 1519, -10 },
+ { 1528, -20 },
+ { 1546, -30 },
+ { 1563, -40 },
+ { 1587, -50 },
+ { 1601, -60 },
+ { 1614, -70 },
+ { 1625, -80 },
+ { 1641, -90 },
+ { 1663, -100 },
+ { 1680, -110 },
+ { 1695, -120 },
+ { 1710, -130 },
+ { 1725, -140 },
+ { 1740, -150 },
+ { 1755, -160 },
+ { 1770, -170 },
+ { 1785, -180 },
+ { 1800, -190 },
+ { 1815, -200 },
+};
+#endif
+
+#endif /* __PX_THERMISTOR_H__ */
diff --git a/arch/arm/mach-exynos/q1-gpio.c b/arch/arm/mach-exynos/q1-gpio.c
new file mode 100644
index 0000000..829dfc1
--- /dev/null
+++ b/arch/arm/mach-exynos/q1-gpio.c
@@ -0,0 +1,441 @@
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio.h>
+#include "u1.h"
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data q1_init_gpios[] = {
+ {EXYNOS4_GPC1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SDA_1.8V */
+ {EXYNOS4_GPC1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SCL_1.8V */
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MHL_SDA_2.8V */
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MHL_SCL_2.8V */
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* 8M_CAM_SDA_2.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* 8M_CAM_SCL_2.8V */
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SENSE_SDA_2.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SENSE_SCL_2.8V */
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV2}, /* CAM_MCLK */
+ {EXYNOS4_GPK1(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPK2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_SDA_2.8V */
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_SCL_2.8V */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+ {EXYNOS4_GPL2(4), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MOTOR_EN */
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_UP */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_DOWN */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_BOOT_MODE */
+ {EXYNOS4_GPX1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX1(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_FUEL_ALERT */
+ {EXYNOS4_GPX3(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX3(2), S3C_GPIO_SFN(GPIO_DET_35_AF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_DET_35 */
+ {EXYNOS4_GPX3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1,},
+ {EXYNOS4_GPY2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY4(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY4(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+};
+
+/* this table only for q1 board */
+static unsigned int q1_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_SEC_MODEM_M0_TD)
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+void u1_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ for (i = 0; i < ARRAY_SIZE(q1_init_gpios); i++) {
+ gpio = q1_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, q1_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, q1_init_gpios[i].pud);
+
+ if (q1_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, q1_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, q1_init_gpios[i].drv);
+ }
+}
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+
+ /* GPX GPIO setting */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(7), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(EXYNOS4_GPX1(7), S3C_GPIO_PULL_DOWN);
+}
+
+void u1_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(q1_sleep_gpio_table),
+ q1_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos/reserve_mem-exynos4.c b/arch/arm/mach-exynos/reserve_mem-exynos4.c
new file mode 100644
index 0000000..23af3f7
--- /dev/null
+++ b/arch/arm/mach-exynos/reserve_mem-exynos4.c
@@ -0,0 +1,156 @@
+/* linux/arch/arm/mach-exynos/reserve_mem-exynos4.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * reserve_mem helper functions for EXYNOS4
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/setup.h>
+#include <linux/io.h>
+#include <mach/memory.h>
+#include <plat/media.h>
+#include <mach/media.h>
+
+struct s5p_media_device media_devs[] = {
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .id = S5P_MDEV_MFC,
+ .name = "mfc",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .id = S5P_MDEV_MFC,
+ .name = "mfc",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .id = S5P_MDEV_FIMD,
+ .name = "fimd",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_MACH_U1
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM
+ {
+ .id = S5P_MDEV_PMEM,
+ .name = "pmem",
+ .bank = 0,
+ .memsize = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1
+ {
+ .id = S5P_MDEV_PMEM_GPU1,
+ .name = "pmem_gpu1",
+ .bank = 0,
+ .memsize = CONFIG_ANDROID_PMEM_MEMSIZE_PMEM_GPU1 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .id = S5P_MDEV_FIMC0,
+ .name = "fimc0",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .id = S5P_MDEV_FIMC1,
+ .name = "fimc1",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .id = S5P_MDEV_FIMC2,
+ .name = "fimc2",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3
+ {
+ .id = S5P_MDEV_FIMC3,
+ .name = "fimc3",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .id = S5P_MDEV_JPEG,
+ .name = "jpeg",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .id = S5P_MDEV_FIMG2D,
+ .name = "fimg2d",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT
+ {
+ .id = S5P_MDEV_TVOUT,
+ .name = "tvout",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP
+ {
+ .id = S5P_MDEV_SRP,
+ .name = "srp",
+ .bank = 0,
+ .memsize = CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+};
+
+int nr_media_devs = (sizeof(media_devs) / sizeof(media_devs[0]));
+
diff --git a/arch/arm/mach-exynos/s2p-panel.c b/arch/arm/mach-exynos/s2p-panel.c
new file mode 100644
index 0000000..fdecf83c
--- /dev/null
+++ b/arch/arm/mach-exynos/s2p-panel.c
@@ -0,0 +1,1047 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ld9040.h>
+
+#define SLEEPMSEC 0x1000
+#define ENDDEF 0x2000
+#define DEFMASK 0xFF00
+#define COMMAND_ONLY 0xFE
+#define DATA_ONLY 0xFF
+
+static const unsigned short SEQ_INIT_DISPLAY_SETTING[] = {
+ /* USER_SETTING */
+ 0xF0, 0x5A,
+ DATA_ONLY, 0x5A,
+ /* ACL ON */
+ 0xC1, 0x4D,
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x0F, DATA_ONLY, 0x16, DATA_ONLY, 0x1D,
+ DATA_ONLY, 0x24, DATA_ONLY, 0x2A, DATA_ONLY, 0x31, DATA_ONLY, 0x38,
+ DATA_ONLY, 0x3F, DATA_ONLY, 0x46,
+ /* PANEL CONDITION */
+ 0xF8, 0x05,
+ DATA_ONLY, 0x5E,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x0D,
+ DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x32,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x07,
+ DATA_ONLY, 0x07,
+ DATA_ONLY, 0x20,
+ DATA_ONLY, 0x20,
+ DATA_ONLY, 0x20,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ /* DISPLAY_CONDITION */
+ 0xF2, 0x02,
+ DATA_ONLY, 0x06,
+ DATA_ONLY, 0x0A,
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ /* GTCON */
+ 0xF7, 0x09,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ /* MANPWR */
+ 0xB0, 0x04,
+ /* PWR_CTRL */
+ 0xF4, 0x0A,
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x25,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x44,
+ DATA_ONLY, 0x02,
+ DATA_ONLY, 0x88,
+ /* ELVSS_ON */
+ 0xB1, 0x0D,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x16,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_INIT_ETC_SETTING[] = {
+ /* GAMMA_SET1 */
+ 0xF9, 0x00,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ /* GAMMA_CTRL */
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ /* SLEEP OUT */
+ 0x11, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_USER_SETTING[] = {
+ 0xF0, 0x5A,
+
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+static const unsigned short SEQ_ACL_ON[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x0F, DATA_ONLY, 0x16, DATA_ONLY, 0x1D,
+ DATA_ONLY, 0x24, DATA_ONLY, 0x2A, DATA_ONLY, 0x31, DATA_ONLY, 0x38,
+ DATA_ONLY, 0x3F, DATA_ONLY, 0x46,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_40P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x06, DATA_ONLY, 0x11, DATA_ONLY, 0x1A, DATA_ONLY, 0x20,
+ DATA_ONLY, 0x25, DATA_ONLY, 0x29, DATA_ONLY, 0x2D, DATA_ONLY, 0x30,
+ DATA_ONLY, 0x33, DATA_ONLY, 0x35,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_43P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x07, DATA_ONLY, 0x12, DATA_ONLY, 0x1C, DATA_ONLY, 0x23,
+ DATA_ONLY, 0x29, DATA_ONLY, 0x2D, DATA_ONLY, 0x31, DATA_ONLY, 0x34,
+ DATA_ONLY, 0x37, DATA_ONLY, 0x3A,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+
+
+
+static const unsigned short SEQ_ACL_45P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x07, DATA_ONLY, 0x13, DATA_ONLY, 0x1E, DATA_ONLY, 0x25,
+ DATA_ONLY, 0x2B, DATA_ONLY, 0x30, DATA_ONLY, 0x34, DATA_ONLY, 0x37,
+ DATA_ONLY, 0x3A, DATA_ONLY, 0x3D,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_47P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x07, DATA_ONLY, 0x14, DATA_ONLY, 0x20, DATA_ONLY, 0x28,
+ DATA_ONLY, 0x2E, DATA_ONLY, 0x33, DATA_ONLY, 0x37, DATA_ONLY, 0x3B,
+ DATA_ONLY, 0x3E, DATA_ONLY, 0x41,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_48P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x15, DATA_ONLY, 0x20, DATA_ONLY, 0x29,
+ DATA_ONLY, 0x2F, DATA_ONLY, 0x34, DATA_ONLY, 0x39, DATA_ONLY, 0x3D,
+ DATA_ONLY, 0x40, DATA_ONLY, 0x43,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_50P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x16, DATA_ONLY, 0x22, DATA_ONLY, 0x2B,
+ DATA_ONLY, 0x31, DATA_ONLY, 0x37, DATA_ONLY, 0x3B, DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x43, DATA_ONLY, 0x46,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short *ACL_cutoff_set[] = {
+ SEQ_ACL_OFF,
+ SEQ_ACL_40P,
+ SEQ_ACL_43P,
+ SEQ_ACL_45P,
+ SEQ_ACL_47P,
+ SEQ_ACL_48P,
+ SEQ_ACL_50P,
+};
+
+static const unsigned short SEQ_ELVSS_ON[] = {
+ 0xB1, 0x0D,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x16,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ELVSS_49[] = {
+ 0xB2, 0x10,
+
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_41[] = {
+ 0xB2, 0x17,
+ DATA_ONLY, 0x17,
+ DATA_ONLY, 0x17,
+ DATA_ONLY, 0x17,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_39[] = {
+ 0xB2, 0x1A,
+ DATA_ONLY, 0x1A,
+ DATA_ONLY, 0x1A,
+ DATA_ONLY, 0x1A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_35[] = {
+ 0xB2, 0x1E,
+ DATA_ONLY, 0x1E,
+ DATA_ONLY, 0x1E,
+ DATA_ONLY, 0x1E,
+ ENDDEF, 0x00
+};
+
+static const unsigned short *SEQ_ELVSS_set[] = {
+ SEQ_ELVSS_35,
+ SEQ_ELVSS_39,
+ SEQ_ELVSS_41,
+ SEQ_ELVSS_49,
+};
+
+static const unsigned short SEQ_GTCON[] = {
+ 0xF7, 0x09,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_PANEL_CONDITION[] = {
+ 0xF8, 0x05,
+ DATA_ONLY, 0x5E,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x0D,
+ DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x32,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x07,
+ DATA_ONLY, 0x07,
+ DATA_ONLY, 0x20,
+ DATA_ONLY, 0x20,
+ DATA_ONLY, 0x20,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GAMMA_SET1[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GAMMA_CTRL[] = {
+ 0xFB, 0x02,
+
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GAMMA_START[] = {
+ 0xF9, COMMAND_ONLY,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_APON[] = {
+ 0xF3, 0x00,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x0A,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPCTL[] = {
+ 0xF2, 0x02,
+
+ DATA_ONLY, 0x06,
+ DATA_ONLY, 0x0A,
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_MANPWR[] = {
+ 0xB0, 0x04,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_PWR_CTRL[] = {
+ 0xF4, 0x0A,
+
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x25,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x44,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SLPOUT[] = {
+ 0x11, COMMAND_ONLY,
+ SLEEPMSEC, 120,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SLPIN[] = {
+ 0x10, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPON[] = {
+ 0x29, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPOFF[] = {
+ 0x28, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VCI1_1ST_EN[] = {
+ 0xF3, 0x10,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VL1_EN[] = {
+ 0xF3, 0x11,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VL2_EN[] = {
+ 0xF3, 0x13,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VCI1_2ND_EN[] = {
+ 0xF3, 0x33,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VL3_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VREG1_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0x01,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VGH_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0x11,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VGL_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0x31,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VMOS_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VINT_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xF1,
+ /* DATA_ONLY, 0x71, VMOS/VBL/VBH not used */
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VBH_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xF9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_VBL_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xFD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GAM_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xFF,
+ /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SD_AMP_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xFF,
+ /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
+ DATA_ONLY, 0x80,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GLS_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xFF,
+ /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELS_EN[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xFF,
+ /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
+ DATA_ONLY, 0x83,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_EL_ON[] = {
+ 0xF3, 0x37,
+
+ DATA_ONLY, 0xFF,
+ /* DATA_ONLY, 0x73, VMOS/VBL/VBH not used */
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03,
+ /* DATA_ONLY, 0x02, VMOS/VBL/VBH not used */
+ ENDDEF, 0x00
+};
+
+#define MAX_GAMMA_LEVEL 25
+#define GAMMA_TABLE_COUNT 21
+
+/* [U1] OCTA 4.27 XVGA - gamma value: 2.2 */
+
+static const unsigned int ld9040_22_300[] = {
+ 0x00, 0xCA, 0xC4, 0xB8, 0xC6, 0x00, 0xAB
+, 0x00, 0xC3, 0xC1, 0xB4, 0xC0, 0x00, 0xD1
+, 0x00, 0xC6, 0xC2, 0xB1, 0xBF, 0x00, 0xDF
+};
+
+static const unsigned int ld9040_22_290[] = {
+ 0x00, 0xCB, 0xC5, 0xB8, 0xC6, 0x00, 0xAA
+, 0x00, 0xC3, 0xC2, 0xB5, 0xC1, 0x00, 0xCF
+, 0x00, 0xC7, 0xC2, 0xB2, 0xBF, 0x00, 0xDE
+};
+
+static const unsigned int ld9040_22_280[] = {
+ 0x00, 0xCC, 0xC5, 0xBA, 0xC6, 0x00, 0xA7
+, 0x00, 0xC3, 0xC1, 0xB6, 0xC2, 0x00, 0xCB
+, 0x00, 0xC7, 0xC2, 0xB4, 0xBF, 0x00, 0xDA
+};
+
+static const unsigned int ld9040_22_270[] = {
+ 0x00, 0xCC, 0xC4, 0xBB, 0xC7, 0x00, 0xA3
+, 0x00, 0xC3, 0xC2, 0xB6, 0xC2, 0x00, 0xC8
+, 0x00, 0xC8, 0xC1, 0xB3, 0xC1, 0x00, 0xD6
+};
+static const unsigned int ld9040_22_260[] = {
+ 0x00, 0xCD, 0xC5, 0xB6, 0xC8, 0x00, 0xA3
+, 0x00, 0xC3, 0xC3, 0xB6, 0xC3, 0x00, 0xC8
+, 0x00, 0xC8, 0xC3, 0xB4, 0xC2, 0x00, 0xD5
+};
+
+static const unsigned int ld9040_22_250[] = {
+ 0x00, 0xCC, 0xC5, 0xBD, 0xCA, 0x00, 0xA0
+, 0x00, 0xC3, 0xC3, 0xB8, 0xC4, 0x00, 0xC4
+, 0x00, 0xC8, 0xC2, 0xB5, 0xC3, 0x00, 0xD2
+};
+
+static const unsigned int ld9040_22_240[] = {
+ 0x00, 0xCC, 0xC5, 0xBD, 0xCA, 0x00, 0x9E
+, 0x00, 0xC4, 0xC4, 0xB8, 0xC4, 0x00, 0xC1
+, 0x00, 0xC9, 0xC3, 0xB6, 0xC2, 0x00, 0xCF
+};
+
+static const unsigned int ld9040_22_230[] = {
+ 0x00, 0xCD, 0xC6, 0xBD, 0xCA, 0x00, 0x9B
+, 0x00, 0xC3, 0xC4, 0xB9, 0xC4, 0x00, 0xBE
+, 0x00, 0xCA, 0xC4, 0xB6, 0xC3, 0x00, 0xCB
+};
+
+static const unsigned int ld9040_22_220[] = {
+ 0x00, 0xCD, 0xC6, 0xBD, 0xCC, 0x00, 0x98
+, 0x00, 0xC3, 0xC5, 0xB9, 0xC5, 0x00, 0xBA
+, 0x00, 0xC9, 0xC4, 0xB7, 0xC4, 0x00, 0xC7
+};
+
+static const unsigned int ld9040_22_210[] = {
+ 0x00, 0xCE, 0xC7, 0xBD, 0xCC, 0x00, 0x95
+, 0x00, 0xC3, 0xC4, 0xBA, 0xC6, 0x00, 0xB7
+, 0x00, 0xCA, 0xC5, 0xB8, 0xC4, 0x00, 0xC3
+};
+
+static const unsigned int ld9040_22_200[] = {
+ 0x00, 0xCF, 0xC7, 0xBE, 0xCD, 0x00, 0x92
+, 0x00, 0xC3, 0xC5, 0xBA, 0xC7, 0x00, 0xB3
+, 0x00, 0xCB, 0xC5, 0xB9, 0xC4, 0x00, 0xC0
+};
+
+static const unsigned int ld9040_22_190[] = {
+ 0x00, 0xCE, 0xC8, 0xBF, 0xCD, 0x00, 0x8F
+, 0x00, 0xC3, 0xC5, 0xBA, 0xC8, 0x00, 0xAF
+, 0x00, 0xCA, 0xC5, 0xBA, 0xC5, 0x00, 0xBC
+};
+
+static const unsigned int ld9040_22_180[] = {
+ 0x00, 0xCE, 0xC7, 0xC1, 0xCD, 0x00, 0x8C
+, 0x00, 0xC4, 0xC5, 0xBB, 0xC8, 0x00, 0xAC
+, 0x00, 0xCA, 0xC4, 0xBB, 0xC6, 0x00, 0xB8
+};
+
+static const unsigned int ld9040_22_170[] = {
+ 0x00, 0xCE, 0xC7, 0xC1, 0xCF, 0x00, 0x88
+, 0x00, 0xC3, 0xC5, 0xBC, 0xCA, 0x00, 0xA7
+, 0x00, 0xCB, 0xC5, 0xBB, 0xC7, 0x00, 0xB3
+};
+
+static const unsigned int ld9040_22_160[] = {
+ 0x00, 0xCE, 0xC9, 0xC1, 0xCF, 0x00, 0x85
+, 0x00, 0xC2, 0xC6, 0xBD, 0xCA, 0x00, 0xA3
+, 0x00, 0xCB, 0xC6, 0xBB, 0xC8, 0x00, 0xAF
+};
+
+static const unsigned int ld9040_22_150[] = {
+ 0x00, 0xCF, 0xC9, 0xC1, 0xD1, 0x00, 0x82
+, 0x00, 0xC3, 0xC6, 0xBE, 0xCB, 0x00, 0x9F
+, 0x00, 0xCC, 0xC6, 0xBB, 0xC9, 0x00, 0xAB
+};
+
+static const unsigned int ld9040_22_140[] = {
+ 0x00, 0xCF, 0xCA, 0xC1, 0xD0, 0x00, 0x7F
+, 0x00, 0xC3, 0xC6, 0xBF, 0xCB, 0x00, 0x9B
+, 0x00, 0xCC, 0xC8, 0xBD, 0xC9, 0x00, 0xA6
+};
+
+static const unsigned int ld9040_22_130[] = {
+ 0x00, 0xCF, 0xCB, 0xC2, 0xD1, 0x00, 0x7B
+, 0x00, 0xC2, 0xC7, 0xBF, 0xCC, 0x00, 0x97
+, 0x00, 0xCC, 0xC8, 0xBE, 0xCB, 0x00, 0xA1
+};
+
+static const unsigned int ld9040_22_120[] = {
+ 0x00, 0xD0, 0xCB, 0xC2, 0xD3, 0x00, 0x77
+, 0x00, 0xC2, 0xC8, 0xC0, 0xCD, 0x00, 0x92
+, 0x00, 0xCD, 0xC8, 0xBE, 0xCC, 0x00, 0x9C
+};
+
+static const unsigned int ld9040_22_110[] = {
+ 0x00, 0xD0, 0xCB, 0xC3, 0xD3, 0x00, 0x74
+, 0x00, 0xC2, 0xC8, 0xC1, 0xCE, 0x00, 0x8D
+, 0x00, 0xCD, 0xC8, 0xBF, 0xCC, 0x00, 0x98
+};
+
+static const unsigned int ld9040_22_100[] = {
+ 0x00, 0xD1, 0xCB, 0xC5, 0xD4, 0x00, 0x6F
+, 0x00, 0xC2, 0xC8, 0xC2, 0xCF, 0x00, 0x88
+, 0x00, 0xCE, 0xC9, 0xC0, 0xCE, 0x00, 0x92
+};
+
+static const unsigned int ld9040_22_90[] = {
+ 0x00, 0xD2, 0xCA, 0xC5, 0xD4, 0x00, 0x6A
+, 0x00, 0xC0, 0xC8, 0xC2, 0xD0, 0x00, 0x82
+, 0x00, 0xCE, 0xC9, 0xC0, 0xCF, 0x00, 0x8B
+};
+
+static const unsigned int ld9040_22_80[] = {
+ 0x00, 0xD2, 0xCB, 0xC6, 0xD7, 0x00, 0x65
+, 0x00, 0xC0, 0xC9, 0xC3, 0xD2, 0x00, 0x7C
+, 0x00, 0xCE, 0xCA, 0xC2, 0xD1, 0x00, 0x85
+};
+
+static const unsigned int ld9040_22_70[] = {
+ 0x00, 0xD4, 0xCD, 0xC7, 0xD7, 0x00, 0x60
+, 0x00, 0xBC, 0xCB, 0xC4, 0xD3, 0x00, 0x76
+, 0x00, 0xCF, 0xCC, 0xC3, 0xD2, 0x00, 0x7F
+};
+
+static const unsigned int ld9040_22_60[] = {
+ 0x00, 0xD5, 0xCD, 0xC8, 0xD7, 0x00, 0x5B
+, 0x00, 0xBA, 0xCA, 0xC5, 0xD4, 0x00, 0x71
+, 0x00, 0xD0, 0xCC, 0xC5, 0xD3, 0x00, 0x78
+};
+
+static const unsigned int ld9040_22_50[] = {
+ 0x00, 0xD6, 0xCE, 0xCA, 0xD8, 0x00, 0x55
+, 0x00, 0xB9, 0xCA, 0xC6, 0xD6, 0x00, 0x69
+, 0x00, 0xD1, 0xCC, 0xC6, 0xD5, 0x00, 0x71
+};
+
+static const unsigned int ld9040_22_40[] = {
+ 0x00, 0xD9, 0xCE, 0xCA, 0xD9, 0x00, 0x4F
+, 0x00, 0xB5, 0xCA, 0xC7, 0xD8, 0x00, 0x61
+, 0x00, 0xD2, 0xCE, 0xC6, 0xD6, 0x00, 0x69
+};
+
+static const unsigned int ld9040_22_30_dimming[] = {
+ 0x00, 0xD9, 0xD3, 0xCC, 0xDA, 0x00, 0x46
+, 0x00, 0xB1, 0xC9, 0xC9, 0xD9, 0x00, 0x58
+, 0x00, 0xD2, 0xD0, 0xC9, 0xD8, 0x00, 0x5E
+};
+
+static const unsigned int *p22Gamma_set[] = {
+ ld9040_22_30_dimming,
+ ld9040_22_40,
+ ld9040_22_70,
+ ld9040_22_90,
+ ld9040_22_100,
+ ld9040_22_110,
+ ld9040_22_120,
+ ld9040_22_130,
+ ld9040_22_140,
+ ld9040_22_150,
+ ld9040_22_160,
+ ld9040_22_170,
+ ld9040_22_180,
+ ld9040_22_190,
+ ld9040_22_200,
+ ld9040_22_210,
+ ld9040_22_220,
+ ld9040_22_230,
+ ld9040_22_240,
+ ld9040_22_250,
+ ld9040_22_260,
+ ld9040_22_270,
+ ld9040_22_280,
+ ld9040_22_290,
+ ld9040_22_300,
+};
+
+/* OCTA 4.52 XVGA - gamma value: 1.9 */
+static const unsigned int ld9040_19_300[] = {
+ 0x00, 0xCD, 0xC8, 0xC0, 0xCC, 0x00, 0xAA,
+ 0x00, 0xC9, 0xC7, 0xBA, 0xC6, 0x00, 0xD0,
+ 0x00, 0xCA, 0xC5, 0xB8, 0xC6, 0x00, 0xDE
+};
+
+static const unsigned int ld9040_19_290[] = {
+ 0x00, 0xCF, 0xC7, 0xC0, 0xCE, 0x00, 0xAB,
+ 0x00, 0xCA, 0xC7, 0xBB, 0xC8, 0x00, 0xD0,
+ 0x00, 0xCC, 0xC5, 0xB8, 0xC7, 0x00, 0xDF
+};
+
+static const unsigned int ld9040_19_280[] = {
+ 0x00, 0xCF, 0xC9, 0xC0, 0xCD, 0x00, 0xA9,
+ 0x00, 0xCA, 0xC8, 0xBC, 0xC8, 0x00, 0xCD,
+ 0x00, 0xCB, 0xC7, 0xB9, 0xC6, 0x00, 0xDC
+};
+
+static const unsigned int ld9040_19_270[] = {
+ 0x00, 0xD0, 0xCA, 0xC0, 0xCD, 0x00, 0xA7,
+ 0x00, 0xCA, 0xC8, 0xBC, 0xC9, 0x00, 0xCA,
+ 0x00, 0xCB, 0xC8, 0xBA, 0xC6, 0x00, 0xD9
+};
+
+static const unsigned int ld9040_19_260[] = {
+ 0x00, 0xD0, 0xCA, 0xC1, 0xCD, 0x00, 0xA5,
+ 0x00, 0xCA, 0xC7, 0xBE, 0xC9, 0x00, 0xC7,
+ 0x00, 0xCC, 0xC7, 0xBB, 0xC7, 0x00, 0xD6
+};
+
+static const unsigned int ld9040_19_250[] = {
+ 0x00, 0xD0, 0xCC, 0xC1, 0xCD, 0x00, 0xA2,
+ 0x00, 0xCB, 0xC8, 0xBD, 0xCA, 0x00, 0xC4,
+ 0x00, 0xCC, 0xC8, 0xBB, 0xC8, 0x00, 0xD2
+};
+
+static const unsigned int ld9040_19_240[] = {
+ 0x00, 0xCF, 0xCB, 0xC2, 0xCE, 0x00, 0xA0,
+ 0x00, 0xCB, 0xC8, 0xBE, 0xCA, 0x00, 0xC1,
+ 0x00, 0xCB, 0xC8, 0xBC, 0xC8, 0x00, 0xCF
+};
+
+static const unsigned int ld9040_19_230[] = {
+ 0x00, 0xCF, 0xCA, 0xC3, 0xD0, 0x00, 0x9C,
+ 0x00, 0xCB, 0xC8, 0xBF, 0xCB, 0x00, 0xBD,
+ 0x00, 0xCD, 0xC7, 0xBC, 0xCA, 0x00, 0xCA
+};
+
+static const unsigned int ld9040_19_220[] = {
+ 0x00, 0xCF, 0xCB, 0xC4, 0xD0, 0x00, 0x99,
+ 0x00, 0xCB, 0xCA, 0xBF, 0xCB, 0x00, 0xBA,
+ 0x00, 0xCC, 0xC8, 0xBD, 0xCB, 0x00, 0xC6
+};
+
+static const unsigned int ld9040_19_210[] = {
+ 0x00, 0xD0, 0xCA, 0xC4, 0xD1, 0x00, 0x96,
+ 0x00, 0xCB, 0xC9, 0xC0, 0xCC, 0x00, 0xB6,
+ 0x00, 0xCD, 0xC8, 0xBD, 0xCB, 0x00, 0xC3
+};
+
+static const unsigned int ld9040_19_200[] = {
+ 0x00, 0xD1, 0xCB, 0xC4, 0xD2, 0x00, 0x93,
+ 0x00, 0xCB, 0xCA, 0xC0, 0xCD, 0x00, 0xB2,
+ 0x00, 0xCD, 0xCA, 0xBE, 0xCB, 0x00, 0xBF
+};
+
+
+static const unsigned int ld9040_19_190[] = {
+ 0x00, 0xD1, 0xCC, 0xC5, 0xD2, 0x00, 0x90,
+ 0x00, 0xCB, 0xCA, 0xC1, 0xCE, 0x00, 0xAE,
+ 0x00, 0xCD, 0xCA, 0xC0, 0xCB, 0x00, 0xBB
+};
+
+
+static const unsigned int ld9040_19_180[] = {
+ 0x00, 0xD2, 0xCC, 0xC5, 0xD2, 0x00, 0x8D,
+ 0x00, 0xCC, 0xC9, 0xC2, 0xCE, 0x00, 0xAB,
+ 0x00, 0xCD, 0xCA, 0xC0, 0xCC, 0x00, 0xB7
+};
+
+
+static const unsigned int ld9040_19_170[] = {
+ 0x00, 0xD2, 0xCC, 0xC6, 0xD3, 0x00, 0x89,
+ 0x00, 0xCC, 0xCA, 0xC2, 0xCF, 0x00, 0xA7,
+ 0x00, 0xCE, 0xC9, 0xC1, 0xCE, 0x00, 0xB2
+};
+
+static const unsigned int ld9040_19_160[] = {
+ 0x00, 0xD2, 0xCC, 0xC6, 0xD5, 0x00, 0x86,
+ 0x00, 0xCC, 0xCB, 0xC2, 0xCF, 0x00, 0xA3,
+ 0x00, 0xCF, 0xC9, 0xC0, 0xCF, 0x00, 0xAF
+};
+
+static const unsigned int ld9040_19_150[] = {
+ 0x00, 0xD1, 0xCD, 0xC7, 0xD6, 0x00, 0x82,
+ 0x00, 0xCB, 0xCC, 0xC4, 0xD0, 0x00, 0x9F,
+ 0x00, 0xCE, 0xCA, 0xC1, 0xCF, 0x00, 0xAA
+};
+
+static const unsigned int ld9040_19_140[] = {
+ 0x00, 0xD2, 0xCD, 0xC6, 0xD8, 0x00, 0x7E,
+ 0x00, 0xCB, 0xCC, 0xC4, 0xD3, 0x00, 0x99,
+ 0x00, 0xCF, 0xCB, 0xC1, 0xD1, 0x00, 0xA5
+};
+
+static const unsigned int ld9040_19_130[] = {
+ 0x00, 0xD3, 0xCE, 0xC7, 0xD6, 0x00, 0x7B,
+ 0x00, 0xCB, 0xCD, 0xC5, 0xD2, 0x00, 0x96,
+ 0x00, 0xD0, 0xCD, 0xC3, 0xCF, 0x00, 0xA1
+};
+
+static const unsigned int ld9040_19_120[] = {
+ 0x00, 0xD4, 0xCE, 0xC8, 0xD7, 0x00, 0x77,
+ 0x00, 0xCB, 0xCD, 0xC6, 0xD3, 0x00, 0x91,
+ 0x00, 0xD0, 0xCC, 0xC5, 0xD1, 0x00, 0x9B
+};
+
+static const unsigned int ld9040_19_110[] = {
+ 0x00, 0xD4, 0xCF, 0xC9, 0xD6, 0x00, 0x74,
+ 0x00, 0xCC, 0xCE, 0xC6, 0xD4, 0x00, 0x8C,
+ 0x00, 0xCF, 0xCD, 0xC6, 0xD1, 0x00, 0x97
+};
+
+static const unsigned int ld9040_19_100[] = {
+ 0x00, 0xD4, 0xCD, 0xCB, 0xD8, 0x00, 0x6F,
+ 0x00, 0xCB, 0xCE, 0xC7, 0xD5, 0x00, 0x87,
+ 0x00, 0xD0, 0xCD, 0xC5, 0xD4, 0x00, 0x91
+};
+
+static const unsigned int ld9040_19_90[] = {
+ 0x00, 0xD6, 0xCF, 0xCA, 0xDA, 0x00, 0x6A,
+ 0x00, 0xCB, 0xCF, 0xC8, 0xD7, 0x00, 0x81,
+ 0x00, 0xD2, 0xCE, 0xC5, 0xD6, 0x00, 0x8B
+};
+
+
+static const unsigned int ld9040_19_80[] = {
+ 0x00, 0xD7, 0xCF, 0xCB, 0xDA, 0x00, 0x66,
+ 0x00, 0xCB, 0xCF, 0xCA, 0xD7, 0x00, 0x7C,
+ 0x00, 0xD3, 0xCF, 0xC7, 0xD5, 0x00, 0x86
+};
+
+static const unsigned int ld9040_19_70[] = {
+ 0x00, 0xD7, 0xD1, 0xCC, 0xDA, 0x00, 0x61,
+ 0x00, 0xCA, 0xD0, 0xCA, 0xD8, 0x00, 0x77,
+ 0x00, 0xD2, 0xD1, 0xC9, 0xD6, 0x00, 0x7F
+};
+
+static const unsigned int ld9040_19_60[] = {
+ 0x00, 0xD9, 0xD0, 0xCD, 0xDA, 0x00, 0x5D,
+ 0x00, 0xCC, 0xCF, 0xCB, 0xD9, 0x00, 0x70,
+ 0x00, 0xD4, 0xD0, 0xCA, 0xD8, 0x00, 0x78
+};
+
+static const unsigned int ld9040_19_50[] = {
+ 0x00, 0xD8, 0xD2, 0xCF, 0xDB, 0x00, 0x56,
+ 0x00, 0xCA, 0xD1, 0xCC, 0xDB, 0x00, 0x69,
+ 0x00, 0xD3, 0xD1, 0xCC, 0xDA, 0x00, 0x70
+};
+
+static const unsigned int ld9040_19_40[] = {
+ 0x00, 0xDA, 0xD2, 0xD1, 0xDC, 0x00, 0x4F,
+ 0x00, 0xC6, 0xD2, 0xCF, 0xDB, 0x00, 0x61,
+ 0x00, 0xD4, 0xD2, 0xCE, 0xDB, 0x00, 0x68
+};
+
+static const unsigned int ld9040_19_30_dimming[] = {
+ 0x00, 0xDC, 0xD5, 0xD2, 0xDE, 0x00, 0x46,
+ 0x00, 0xC3, 0xD2, 0xCF, 0xDE, 0x00, 0x58,
+ 0x00, 0xD3, 0xD4, 0xCF, 0xDD, 0x00, 0x5E
+};
+
+static const unsigned int *p19Gamma_set[] = {
+ ld9040_19_30_dimming,
+ ld9040_19_40,
+ ld9040_19_70,
+ ld9040_19_90,
+ ld9040_19_100,
+ ld9040_19_110,
+ ld9040_19_120,
+ ld9040_19_130,
+ ld9040_19_140,
+ ld9040_19_150,
+ ld9040_19_160,
+ ld9040_19_170,
+ ld9040_19_180,
+ ld9040_19_190,
+ ld9040_19_200,
+ ld9040_19_210,
+ ld9040_19_220,
+ ld9040_19_230,
+ ld9040_19_240,
+ ld9040_19_250,
+ ld9040_19_260,
+ ld9040_19_270,
+ ld9040_19_280,
+ ld9040_19_290,
+ ld9040_19_300,
+};
+
+struct ld9040_panel_data s2plus_panel_data = {
+ .seq_display_set = SEQ_INIT_DISPLAY_SETTING,
+ .seq_etc_set = SEQ_INIT_ETC_SETTING,
+ .seq_user_set = SEQ_USER_SETTING,
+ .seq_panelcondition_set = SEQ_PANEL_CONDITION,
+ .seq_displayctl_set = SEQ_DISPCTL,
+ .seq_gtcon_set = SEQ_GTCON,
+ .seq_manpwr_set = SEQ_MANPWR,
+ .seq_pwrctl_set = SEQ_PWR_CTRL,
+ .seq_gamma_set1 = SEQ_GAMMA_SET1,
+ .display_on = SEQ_DISPON,
+ .display_off = SEQ_DISPOFF,
+ .sleep_in = SEQ_SLPIN,
+ .sleep_out = SEQ_SLPOUT,
+ .gamma_start = SEQ_GAMMA_START,
+ .gamma_ctrl = SEQ_GAMMA_CTRL,
+ .gamma19_table = p19Gamma_set,
+ .gamma22_table = p22Gamma_set,
+ .acl_table = ACL_cutoff_set,
+ .elvss_table = SEQ_ELVSS_set,
+ .acl_on = SEQ_ACL_ON,
+ .elvss_on = SEQ_ELVSS_ON,
+ .gamma_table_size = ARRAY_SIZE(p22Gamma_set),
+};
+
+
diff --git a/arch/arm/mach-exynos/s2plus-panel.c b/arch/arm/mach-exynos/s2plus-panel.c
new file mode 100644
index 0000000..58dd374
--- /dev/null
+++ b/arch/arm/mach-exynos/s2plus-panel.c
@@ -0,0 +1,1672 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ld9040.h>
+#include "s2plus-panel.h"
+
+
+static const unsigned short SEQ_SM2_ELVSS_44[] = {
+ 0xB2, 0x15,
+ DATA_ONLY, 0x15,
+ DATA_ONLY, 0x15,
+ DATA_ONLY, 0x15,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_37[] = {
+ 0xB2, 0x1C,
+ DATA_ONLY, 0x1C,
+ DATA_ONLY, 0x1C,
+ DATA_ONLY, 0x1C,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_34[] = {
+ 0xB2, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_30[] = {
+ 0xB2, 0x23,
+ DATA_ONLY, 0x23,
+ DATA_ONLY, 0x23,
+ DATA_ONLY, 0x23,
+ ENDDEF, 0x00
+};
+
+static const unsigned short *SEQ_SM2_ELVSS_set[] = {
+ SEQ_SM2_ELVSS_30,
+ SEQ_SM2_ELVSS_34,
+ SEQ_SM2_ELVSS_37,
+ SEQ_SM2_ELVSS_44,
+};
+
+
+static const unsigned short SEQ_PWR_CTRL[] = {
+ 0xF4, 0x0A,
+
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x25,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x44,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", SM2 A1 Panel Gamma Data */
+static const unsigned short ld9040_sm2_a1_22_300[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_290[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_280[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_270[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_260[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_250[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9A,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_240[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_230[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x94,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_220[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_210[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB4,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_200[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_190[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_180[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_170[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_160[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9D,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_150[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9D,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_140[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_130[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9A,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_120[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x90,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_110[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6D,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_100[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x93,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x79,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x87,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_90[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x65,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x92,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+
+static const unsigned short ld9040_sm2_a1_22_80[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_70[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5B,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x76,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_60[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x63,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_50[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x50,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x68,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_40[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x49,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_30_dimming[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x41,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x80,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_19_300[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_290[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_280[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_270[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_260[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_250[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_240[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_230[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x94,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_220[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_210[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_200[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_190[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_180[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_170[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_160[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_150[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9D,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_140[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x79,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_130[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_120[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x90,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_110[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_100[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x87,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_90[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x66,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_80[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x61,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_70[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_60[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x63,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_50[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x67,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_40[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x48,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_30_dimming[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x40,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x93,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", SM2 A1 Panel Gamma Table */
+static const unsigned short *psm2_a1_22Gamma_set[] = {
+ ld9040_sm2_a1_22_30_dimming,
+ ld9040_sm2_a1_22_40,
+ ld9040_sm2_a1_22_70,
+ ld9040_sm2_a1_22_90,
+ ld9040_sm2_a1_22_100,
+ ld9040_sm2_a1_22_110,
+ ld9040_sm2_a1_22_120,
+ ld9040_sm2_a1_22_130,
+ ld9040_sm2_a1_22_140,
+ ld9040_sm2_a1_22_150,
+ ld9040_sm2_a1_22_160,
+ ld9040_sm2_a1_22_170,
+ ld9040_sm2_a1_22_180,
+ ld9040_sm2_a1_22_190,
+ ld9040_sm2_a1_22_200,
+ ld9040_sm2_a1_22_210,
+ ld9040_sm2_a1_22_220,
+ ld9040_sm2_a1_22_230,
+ ld9040_sm2_a1_22_240,
+ ld9040_sm2_a1_22_250,
+ ld9040_sm2_a1_22_260,
+ ld9040_sm2_a1_22_270,
+ ld9040_sm2_a1_22_280,
+ ld9040_sm2_a1_22_290,
+ ld9040_sm2_a1_22_300,
+};
+
+static const unsigned short *psm2_a1_19Gamma_set[] = {
+ ld9040_sm2_a1_19_30_dimming,
+ ld9040_sm2_a1_19_40,
+ ld9040_sm2_a1_19_70,
+ ld9040_sm2_a1_19_90,
+ ld9040_sm2_a1_19_100,
+ ld9040_sm2_a1_19_110,
+ ld9040_sm2_a1_19_120,
+ ld9040_sm2_a1_19_130,
+ ld9040_sm2_a1_19_140,
+ ld9040_sm2_a1_19_150,
+ ld9040_sm2_a1_19_160,
+ ld9040_sm2_a1_19_170,
+ ld9040_sm2_a1_19_180,
+ ld9040_sm2_a1_19_190,
+ ld9040_sm2_a1_19_200,
+ ld9040_sm2_a1_19_210,
+ ld9040_sm2_a1_19_220,
+ ld9040_sm2_a1_19_230,
+ ld9040_sm2_a1_19_240,
+ ld9040_sm2_a1_19_250,
+ ld9040_sm2_a1_19_260,
+ ld9040_sm2_a1_19_270,
+ ld9040_sm2_a1_19_280,
+ ld9040_sm2_a1_19_290,
+ ld9040_sm2_a1_19_300,
+};
+
+
+struct ld9040_panel_data s2plus_panel_data = {
+ .seq_user_set = SEQ_USER_SETTING,
+ .seq_displayctl_set = SEQ_DISPCTL,
+ .seq_gtcon_set = SEQ_GTCON,
+ .seq_panelcondition_set = SEQ_PANEL_CONDITION,
+ .seq_pwrctl_set = SEQ_PWR_CTRL,
+ .display_on = SEQ_DISPON,
+ .display_off = SEQ_DISPOFF,
+ .sleep_in = SEQ_SLPIN,
+ .sleep_out = SEQ_SLPOUT,
+ .acl_on = SEQ_ACL_ON,
+ .acl_table = ACL_cutoff_set,
+ .elvss_on = SEQ_ELVSS_ON,
+ .elvss_table = SEQ_SM2_ELVSS_set,
+ .gamma19_table = psm2_a1_19Gamma_set,
+ .gamma22_table = psm2_a1_22Gamma_set,
+ .lcdtype = LCDTYPE_SM2_A1,
+};
diff --git a/arch/arm/mach-exynos/s2plus-panel.h b/arch/arm/mach-exynos/s2plus-panel.h
new file mode 100644
index 0000000..9640f8b
--- /dev/null
+++ b/arch/arm/mach-exynos/s2plus-panel.h
@@ -0,0 +1,215 @@
+/*
+ * arch/arm/mach-exynos/s2plus-panel.h
+ */
+
+#ifndef __S2PLUS_PANEL_H__
+#define __S2PLUS_PANEL_H__
+
+#define SLEEPMSEC 0x1000
+#define ENDDEF 0x2000
+#define DEFMASK 0xFF00
+#define COMMAND_ONLY 0xFE
+#define DATA_ONLY 0xFF
+
+
+static const unsigned short SEQ_USER_SETTING[] = {
+ 0xF0, 0x5A,
+
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPCTL[] = {
+ 0xF2, 0x02,
+
+ DATA_ONLY, 0x06,
+ DATA_ONLY, 0x0A,
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GTCON[] = {
+ 0xF7, 0x09,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_PANEL_CONDITION[] = {
+ 0xF8, 0x05,
+ DATA_ONLY, 0x5E,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x0D,
+ DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x32,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x07,
+ DATA_ONLY, 0x05,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SLPOUT[] = {
+ 0x11, COMMAND_ONLY,
+ SLEEPMSEC, 120,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SLPIN[] = {
+ 0x10, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPON[] = {
+ 0x29, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPOFF[] = {
+ 0x28, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_ON[] = {
+ 0xB1, 0x0F,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x16,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_ON[] = {
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_40P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x06, DATA_ONLY, 0x11, DATA_ONLY, 0x1A, DATA_ONLY, 0x20,
+ DATA_ONLY, 0x25, DATA_ONLY, 0x29, DATA_ONLY, 0x2D, DATA_ONLY, 0x30,
+ DATA_ONLY, 0x33, DATA_ONLY, 0x35,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_43P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x07, DATA_ONLY, 0x12, DATA_ONLY, 0x1C, DATA_ONLY, 0x23,
+ DATA_ONLY, 0x29, DATA_ONLY, 0x2D, DATA_ONLY, 0x31, DATA_ONLY, 0x34,
+ DATA_ONLY, 0x37, DATA_ONLY, 0x3A,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_45P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x07, DATA_ONLY, 0x13, DATA_ONLY, 0x1E, DATA_ONLY, 0x25,
+ DATA_ONLY, 0x2B, DATA_ONLY, 0x30, DATA_ONLY, 0x34, DATA_ONLY, 0x37,
+ DATA_ONLY, 0x3A, DATA_ONLY, 0x3D,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_47P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x07, DATA_ONLY, 0x14, DATA_ONLY, 0x20, DATA_ONLY, 0x28,
+ DATA_ONLY, 0x2E, DATA_ONLY, 0x33, DATA_ONLY, 0x37, DATA_ONLY, 0x3B,
+ DATA_ONLY, 0x3E, DATA_ONLY, 0x41,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_48P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x15, DATA_ONLY, 0x20, DATA_ONLY, 0x29,
+ DATA_ONLY, 0x2F, DATA_ONLY, 0x34, DATA_ONLY, 0x39, DATA_ONLY, 0x3D,
+ DATA_ONLY, 0x40, DATA_ONLY, 0x43,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_50P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x16, DATA_ONLY, 0x22, DATA_ONLY, 0x2B,
+ DATA_ONLY, 0x31, DATA_ONLY, 0x37, DATA_ONLY, 0x3B, DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x43, DATA_ONLY, 0x46,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short *ACL_cutoff_set[] = {
+ SEQ_ACL_OFF,
+ SEQ_ACL_40P,
+ SEQ_ACL_43P,
+ SEQ_ACL_45P,
+ SEQ_ACL_47P,
+ SEQ_ACL_48P,
+ SEQ_ACL_50P,
+};
+
+#endif
diff --git a/arch/arm/mach-exynos/sec-common.c b/arch/arm/mach-exynos/sec-common.c
new file mode 100644
index 0000000..e099239
--- /dev/null
+++ b/arch/arm/mach-exynos/sec-common.c
@@ -0,0 +1,18 @@
+#include <linux/device.h>
+#include <linux/err.h>
+
+struct class *sec_class;
+EXPORT_SYMBOL(sec_class);
+
+static int __init midas_class_create(void)
+{
+ sec_class = class_create(THIS_MODULE, "sec");
+ if (IS_ERR(sec_class)) {
+ pr_err("Failed to create class(sec)!\n");
+ return PTR_ERR(sec_class);
+ }
+
+ return 0;
+}
+
+subsys_initcall(midas_class_create);
diff --git a/arch/arm/mach-exynos/sec-reboot.c b/arch/arm/mach-exynos/sec-reboot.c
new file mode 100644
index 0000000..075f107
--- /dev/null
+++ b/arch/arm/mach-exynos/sec-reboot.c
@@ -0,0 +1,133 @@
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+#include <mach/system.h>
+#include <mach/regs-pmu.h>
+#include <mach/gpio.h>
+
+/* charger cable state */
+extern bool is_cable_attached;
+static void sec_power_off(void)
+{
+ int poweroff_try = 0;
+
+ local_irq_disable();
+
+ pr_emerg("%s : cable state=%d\n", __func__, is_cable_attached);
+
+ while (1) {
+ /* Check reboot charging */
+ if (is_cable_attached || (poweroff_try >= 5)) {
+ pr_emerg
+ ("%s: charger connected(%d) or power"
+ "off failed(%d), reboot!\n",
+ __func__, is_cable_attached, poweroff_try);
+ writel(0x0, S5P_INFORM2); /* To enter LP charging */
+
+ flush_cache_all();
+ outer_flush_all();
+ arch_reset(0, 0);
+
+ pr_emerg("%s: waiting for reboot\n", __func__);
+ while (1);
+ }
+
+ /* wait for power button release */
+ if (gpio_get_value(GPIO_nPOWER)) {
+ pr_emerg("%s: set PS_HOLD low\n", __func__);
+
+ /* power off code
+ * PS_HOLD Out/High -->
+ * Low PS_HOLD_CONTROL, R/W, 0x1002_330C
+ */
+ writel(readl(S5P_PS_HOLD_CONTROL) & 0xFFFFFEFF,
+ S5P_PS_HOLD_CONTROL);
+
+ ++poweroff_try;
+ pr_emerg
+ ("%s: Should not reach here! (poweroff_try:%d)\n",
+ __func__, poweroff_try);
+ } else {
+ /* if power button is not released, wait and check TA again */
+ pr_info("%s: PowerButton is not released.\n", __func__);
+ }
+ mdelay(1000);
+ }
+}
+
+#define REBOOT_MODE_PREFIX 0x12345670
+#define REBOOT_MODE_NONE 0
+#define REBOOT_MODE_DOWNLOAD 1
+#define REBOOT_MODE_UPLOAD 2
+#define REBOOT_MODE_CHARGING 3
+#define REBOOT_MODE_RECOVERY 4
+#define REBOOT_MODE_FOTA 5
+#define REBOOT_MODE_FOTA_BL 6 /* update bootloader */
+
+#define REBOOT_SET_PREFIX 0xabc00000
+#define REBOOT_SET_DEBUG 0x000d0000
+#define REBOOT_SET_SWSEL 0x000e0000
+#define REBOOT_SET_SUD 0x000f0000
+
+static void sec_reboot(char str, const char *cmd)
+{
+ local_irq_disable();
+
+ pr_emerg("%s (%d, %s)\n", __func__, str, cmd ? cmd : "(null)");
+
+ writel(0x12345678, S5P_INFORM2); /* Don't enter lpm mode */
+
+ if (!cmd) {
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_NONE, S5P_INFORM3);
+ } else {
+ unsigned long value;
+ if (!strcmp(cmd, "fota"))
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_FOTA,
+ S5P_INFORM3);
+ else if (!strcmp(cmd, "fota_bl"))
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_FOTA_BL,
+ S5P_INFORM3);
+ else if (!strcmp(cmd, "recovery"))
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_RECOVERY,
+ S5P_INFORM3);
+ else if (!strcmp(cmd, "download"))
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_DOWNLOAD,
+ S5P_INFORM3);
+ else if (!strcmp(cmd, "upload"))
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_UPLOAD,
+ S5P_INFORM3);
+ else if (!strncmp(cmd, "debug", 5)
+ && !kstrtoul(cmd + 5, 0, &value))
+ writel(REBOOT_SET_PREFIX | REBOOT_SET_DEBUG | value,
+ S5P_INFORM3);
+ else if (!strncmp(cmd, "swsel", 5)
+ && !kstrtoul(cmd + 5, 0, &value))
+ writel(REBOOT_SET_PREFIX | REBOOT_SET_SWSEL | value,
+ S5P_INFORM3);
+ else if (!strncmp(cmd, "sud", 3)
+ && !kstrtoul(cmd + 3, 0, &value))
+ writel(REBOOT_SET_PREFIX | REBOOT_SET_SUD | value,
+ S5P_INFORM3);
+ else
+ writel(REBOOT_MODE_PREFIX | REBOOT_MODE_NONE,
+ S5P_INFORM3);
+ }
+
+ flush_cache_all();
+ outer_flush_all();
+ arch_reset(0, 0);
+
+ pr_emerg("%s: waiting for reboot\n", __func__);
+ while (1);
+}
+
+static int __init sec_reboot_init(void)
+{
+ /* to support system shut down */
+ pm_power_off = sec_power_off;
+ arm_pm_restart = sec_reboot;
+ return 0;
+}
+
+subsys_initcall(sec_reboot_init);
diff --git a/arch/arm/mach-exynos/sec-switch.c b/arch/arm/mach-exynos/sec-switch.c
new file mode 100644
index 0000000..7b8726c
--- /dev/null
+++ b/arch/arm/mach-exynos/sec-switch.c
@@ -0,0 +1,513 @@
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio_event.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <plat/udc-hs.h>
+/*#include <linux/mmc/host.h>*/
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-private.h>
+#include <linux/mfd/max77686.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/gpio.h>
+
+#include <linux/power_supply.h>
+#include <linux/battery/samsung_battery.h>
+
+#include <linux/switch.h>
+#include <linux/sii9234.h>
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#endif
+#include <linux/pm_runtime.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#ifdef CONFIG_JACK_MON
+#include <linux/jack.h>
+#endif
+
+#ifdef CONFIG_MACH_SLP_NAPLES
+#include <mach/naples-tsp.h>
+#endif
+#ifdef CONFIG_MACH_MIDAS
+#include <linux/platform_data/mms_ts.h>
+#endif
+
+static struct switch_dev switch_dock = {
+ .name = "dock",
+};
+
+extern struct class *sec_class;
+
+struct device *switch_dev;
+EXPORT_SYMBOL(switch_dev);
+
+/* charger cable state */
+bool is_cable_attached;
+bool is_jig_attached;
+
+static ssize_t midas_switch_show_vbus(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i;
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator)) {
+ pr_warn("%s: fail to get regulator\n", __func__);
+ return sprintf(buf, "UNKNOWN\n");
+ }
+ if (regulator_is_enabled(regulator))
+ i = sprintf(buf, "VBUS is enabled\n");
+ else
+ i = sprintf(buf, "VBUS is disabled\n");
+ regulator_put(regulator);
+
+ return i;
+}
+
+static ssize_t midas_switch_store_vbus(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int disable, ret, usb_mode;
+ struct regulator *regulator;
+ /* struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget); */
+
+ if (!strncmp(buf, "0", 1))
+ disable = 0;
+ else if (!strncmp(buf, "1", 1))
+ disable = 1;
+ else {
+ pr_warn("%s: Wrong command\n", __func__);
+ return count;
+ }
+
+ pr_info("%s: disable=%d\n", __func__, disable);
+ usb_mode =
+ disable ? USB_CABLE_DETACHED_WITHOUT_NOTI : USB_CABLE_ATTACHED;
+ /* ret = udc->change_usb_mode(usb_mode); */
+ ret = -1;
+ if (ret < 0)
+ pr_err("%s: fail to change mode!!!\n", __func__);
+
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator)) {
+ pr_warn("%s: fail to get regulator\n", __func__);
+ return count;
+ }
+
+ if (disable) {
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ } else {
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ }
+ regulator_put(regulator);
+
+ return count;
+}
+
+DEVICE_ATTR(disable_vbus, 0664, midas_switch_show_vbus,
+ midas_switch_store_vbus);
+
+static int __init midas_sec_switch_init(void)
+{
+ int ret;
+ switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
+
+ if (IS_ERR(switch_dev))
+ pr_err("Failed to create device(switch)!\n");
+
+ ret = device_create_file(switch_dev, &dev_attr_disable_vbus);
+ if (ret)
+ pr_err("Failed to create device file(disable_vbus)!\n");
+
+ return 0;
+};
+
+int max77693_muic_charger_cb(enum cable_type_muic cable_type)
+{
+#ifdef CONFIG_BATTERY_MAX77693_CHARGER
+ struct power_supply *psy = power_supply_get_by_name("max77693-charger");
+ union power_supply_propval value;
+#endif
+ pr_info("%s: %d\n", __func__, cable_type);
+
+ switch (cable_type) {
+ case CABLE_TYPE_NONE_MUIC:
+ case CABLE_TYPE_OTG_MUIC:
+ case CABLE_TYPE_JIG_UART_OFF_MUIC:
+ case CABLE_TYPE_MHL_MUIC:
+ is_cable_attached = false;
+ break;
+ case CABLE_TYPE_USB_MUIC:
+ case CABLE_TYPE_JIG_USB_OFF_MUIC:
+ case CABLE_TYPE_JIG_USB_ON_MUIC:
+ is_cable_attached = true;
+ break;
+ case CABLE_TYPE_MHL_VB_MUIC:
+ is_cable_attached = true;
+ break;
+ case CABLE_TYPE_TA_MUIC:
+ case CABLE_TYPE_CARDOCK_MUIC:
+ case CABLE_TYPE_DESKDOCK_MUIC:
+ case CABLE_TYPE_SMARTDOCK_MUIC:
+ case CABLE_TYPE_JIG_UART_OFF_VB_MUIC:
+ is_cable_attached = true;
+ break;
+ default:
+ pr_err("%s: invalid type:%d\n", __func__, cable_type);
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_BATTERY_MAX77693_CHARGER
+ if (!psy) {
+ pr_err("%s: fail to get max77693-charger psy\n", __func__);
+ return 0;
+ }
+
+ value.intval = cable_type;
+ psy->set_property(psy, POWER_SUPPLY_PROP_ONLINE, &value);
+#endif
+
+#if defined(CONFIG_MACH_SLP_NAPLES) || defined(CONFIG_MACH_MIDAS)
+#ifndef CONFIG_MACH_GC1
+ tsp_charger_infom(is_cable_attached);
+#endif
+#endif
+#ifdef CONFIG_JACK_MON
+ jack_event_handler("charger", is_cable_attached);
+#endif
+
+ return 0;
+}
+
+int max77693_get_jig_state(void)
+{
+ pr_info("%s: %d\n", __func__, is_jig_attached);
+ return is_jig_attached;
+}
+EXPORT_SYMBOL(max77693_get_jig_state);
+
+void max77693_set_jig_state(int jig_state)
+{
+ pr_info("%s: %d\n", __func__, jig_state);
+ is_jig_attached = jig_state;
+}
+
+/* usb cable call back function */
+void max77693_muic_usb_cb(u8 usb_mode)
+{
+ struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget);
+#ifdef CONFIG_USB_HOST_NOTIFY
+ struct host_notifier_platform_data *host_noti_pdata =
+ host_notifier_device.dev.platform_data;
+#endif
+
+ pr_info("MUIC usb_cb:%d\n", usb_mode);
+ if (gadget) {
+ switch (usb_mode) {
+ case USB_CABLE_DETACHED:
+ pr_info("usb: muic: USB_CABLE_DETACHED(%d)\n",
+ usb_mode);
+ usb_gadget_vbus_disconnect(gadget);
+ break;
+ case USB_CABLE_ATTACHED:
+ pr_info("usb: muic: USB_CABLE_ATTACHED(%d)\n",
+ usb_mode);
+ usb_gadget_vbus_connect(gadget);
+ break;
+ default:
+ pr_info("usb: muic: invalid mode%d\n", usb_mode);
+ }
+ }
+
+ if (usb_mode == USB_OTGHOST_ATTACHED
+ || usb_mode == USB_POWERED_HOST_ATTACHED) {
+#ifdef CONFIG_USB_HOST_NOTIFY
+ if (usb_mode == USB_OTGHOST_ATTACHED)
+ host_noti_pdata->booster(1);
+ else
+ host_noti_pdata->powered_booster(1);
+
+ host_noti_pdata->ndev.mode = NOTIFY_HOST_MODE;
+ if (host_noti_pdata->usbhostd_start)
+ host_noti_pdata->usbhostd_start();
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ehci.dev);
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ohci.dev);
+#endif
+ } else if (usb_mode == USB_OTGHOST_DETACHED
+ || usb_mode == USB_POWERED_HOST_DETACHED) {
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ohci.dev);
+#endif
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ehci.dev);
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ host_noti_pdata->ndev.mode = NOTIFY_NONE_MODE;
+ if (host_noti_pdata->usbhostd_stop)
+ host_noti_pdata->usbhostd_stop();
+ if (usb_mode == USB_OTGHOST_DETACHED)
+ host_noti_pdata->booster(0);
+ else
+ host_noti_pdata->powered_booster(0);
+#endif
+ }
+
+#ifdef CONFIG_JACK_MON
+ if (usb_mode == USB_OTGHOST_ATTACHED
+ || usb_mode == USB_POWERED_HOST_ATTACHED)
+ jack_event_handler("host", USB_CABLE_ATTACHED);
+ else if (usb_mode == USB_OTGHOST_DETACHED
+ || usb_mode == USB_POWERED_HOST_DETACHED)
+ jack_event_handler("host", USB_CABLE_DETACHED);
+ else if ((usb_mode == USB_CABLE_ATTACHED)
+ || (usb_mode == USB_CABLE_DETACHED))
+ jack_event_handler("usb", usb_mode);
+#endif
+}
+
+/*extern void MHL_On(bool on);*/
+void max77693_muic_mhl_cb(int attached)
+{
+ pr_info("MUIC attached:%d\n", attached);
+ if (attached == MAX77693_MUIC_ATTACHED) {
+ /*MHL_On(1);*/ /* GPIO_LEVEL_HIGH */
+ pr_info("MHL Attached !!\n");
+#ifdef CONFIG_SAMSUNG_MHL
+#ifdef CONFIG_MACH_MIDAS
+ sii9234_wake_lock();
+#endif
+ mhl_onoff_ex(1);
+#endif
+ } else {
+ /*MHL_On(0);*/ /* GPIO_LEVEL_LOW */
+ pr_info("MHL Detached !!\n");
+#ifdef CONFIG_SAMSUNG_MHL
+ mhl_onoff_ex(false);
+#ifdef CONFIG_MACH_MIDAS
+ sii9234_wake_unlock();
+#endif
+#endif
+ }
+}
+
+bool max77693_muic_is_mhl_attached(void)
+{
+ int val;
+#ifdef CONFIG_SAMSUNG_USE_11PIN_CONNECTOR
+ val = max77693_muic_get_status1_adc1k_value();
+ pr_info("%s(1): %d\n", __func__, val);
+ return val;
+#else
+ const int err = -1;
+ int ret;
+
+ ret = gpio_request(GPIO_MHL_SEL, "MHL_SEL");
+ if (ret) {
+ pr_err("fail to request gpio %s\n", "GPIO_MHL_SEL");
+ return err;
+ }
+ val = gpio_get_value(GPIO_MHL_SEL);
+ pr_info("%s(2): %d\n", __func__, val);
+ gpio_free(GPIO_MHL_SEL);
+ return !!val;
+#endif
+}
+
+void max77693_muic_deskdock_cb(bool attached)
+{
+ pr_info("MUIC deskdock attached=%d\n", attached);
+ if (attached) {
+#ifdef CONFIG_JACK_MON
+ jack_event_handler("cradle", 1);
+#endif
+ switch_set_state(&switch_dock, 1);
+ } else {
+#ifdef CONFIG_JACK_MON
+ jack_event_handler("cradle", 0);
+#endif
+ switch_set_state(&switch_dock, 0);
+ }
+}
+
+void max77693_muic_cardock_cb(bool attached)
+{
+ pr_info("MUIC cardock attached=%d\n", attached);
+ pr_info("##MUIC [ %s ]- func : %s !!\n", __FILE__, __func__);
+ if (attached) {
+#ifdef CONFIG_JACK_MON
+ jack_event_handler("cradle", 2);
+#endif
+ switch_set_state(&switch_dock, 2);
+ } else {
+#ifdef CONFIG_JACK_MON
+ jack_event_handler("cradle", 0);
+#endif
+ switch_set_state(&switch_dock, 0);
+ }
+}
+
+void max77693_muic_init_cb(void)
+{
+ int ret;
+
+ /* for CarDock, DeskDock */
+ ret = switch_dev_register(&switch_dock);
+
+ pr_info("MUIC ret=%d\n", ret);
+
+ if (ret < 0)
+ pr_err("Failed to register dock switch. %d\n", ret);
+}
+
+int max77693_muic_cfg_uart_gpio(void)
+{
+ int uart_val, path;
+ pr_info("## MUIC func : %s ! please path: (uart:%d - usb:%d)\n",
+ __func__, gpio_get_value(GPIO_UART_SEL),
+ gpio_get_value(GPIO_USB_SEL));
+ uart_val = gpio_get_value(GPIO_UART_SEL);
+ path = uart_val ? UART_PATH_AP : UART_PATH_CP;
+#ifdef CONFIG_LTE_VIA_SWITCH
+ if (path == UART_PATH_CP && !gpio_get_value(GPIO_LTE_VIA_UART_SEL))
+ path = UART_PATH_LTE;
+#endif
+ pr_info("##MUIC [ %s ]- func : %s! path:%d\n", __FILE__, __func__,
+ path);
+ return path;
+}
+
+void max77693_muic_jig_uart_cb(int path)
+{
+ pr_info("func:%s : (path=%d\n", __func__, path);
+ switch (path) {
+ case UART_PATH_AP:
+ gpio_set_value(GPIO_UART_SEL, GPIO_LEVEL_HIGH);
+ break;
+ case UART_PATH_CP:
+ gpio_set_value(GPIO_UART_SEL, GPIO_LEVEL_LOW);
+#ifdef CONFIG_LTE_VIA_SWITCH
+ gpio_set_value(GPIO_LTE_VIA_UART_SEL, GPIO_LEVEL_HIGH);
+#endif
+ break;
+#ifdef CONFIG_LTE_VIA_SWITCH
+ case UART_PATH_LTE:
+ gpio_set_value(GPIO_UART_SEL, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_LTE_VIA_UART_SEL, GPIO_LEVEL_LOW);
+ break;
+#endif
+ default:
+ pr_info("func %s: invalid value!!\n", __func__);
+ }
+
+}
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+int max77693_muic_host_notify_cb(int enable)
+{
+ struct host_notifier_platform_data *host_noti_pdata =
+ host_notifier_device.dev.platform_data;
+
+ struct host_notify_dev *ndev = &host_noti_pdata->ndev;
+
+ if (!ndev) {
+ pr_err("%s: ndev is null.\n", __func__);
+ return -1;
+ }
+
+ ndev->booster = enable ? NOTIFY_POWER_ON : NOTIFY_POWER_OFF;
+ pr_info("%s: mode %d, enable %d\n", __func__, ndev->mode, enable);
+ return ndev->mode;
+}
+#endif
+
+int max77693_muic_set_safeout(int path)
+{
+ struct regulator *regulator;
+
+ pr_info("MUIC safeout path=%d\n", path);
+
+ if (path == CP_USB_MODE) {
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ /* AP_USB_MODE || AUDIO_MODE */
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+struct max77693_muic_data max77693_muic = {
+ .usb_cb = max77693_muic_usb_cb,
+ .charger_cb = max77693_muic_charger_cb,
+ .mhl_cb = max77693_muic_mhl_cb,
+ .is_mhl_attached = max77693_muic_is_mhl_attached,
+ .set_safeout = max77693_muic_set_safeout,
+ .init_cb = max77693_muic_init_cb,
+ .deskdock_cb = max77693_muic_deskdock_cb,
+ .cardock_cb = max77693_muic_cardock_cb,
+#if !defined(CONFIG_MACH_GC1)
+ .cfg_uart_gpio = max77693_muic_cfg_uart_gpio,
+ .jig_uart_cb = max77693_muic_jig_uart_cb,
+#endif /* CONFIG_MACH_GC1 */
+#ifdef CONFIG_USB_HOST_NOTIFY
+ .host_notify_cb = max77693_muic_host_notify_cb,
+#else
+ .host_notify_cb = NULL,
+#endif
+#if !defined(CONFIG_MACH_GC1)
+ .gpio_usb_sel = GPIO_USB_SEL,
+#else
+ .gpio_usb_sel = -1,
+#endif /* CONFIG_MACH_GC1 */
+ .jig_state = max77693_set_jig_state,
+};
+
+device_initcall(midas_sec_switch_init);
diff --git a/arch/arm/mach-exynos/sec-switch_max8997.c b/arch/arm/mach-exynos/sec-switch_max8997.c
new file mode 100644
index 0000000..51f9c31
--- /dev/null
+++ b/arch/arm/mach-exynos/sec-switch_max8997.c
@@ -0,0 +1,496 @@
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio_event.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/input.h>
+#include <plat/udc-hs.h>
+/*#include <linux/mmc/host.h>*/
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+/* #include <linux/mfd/max77686.h> */
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+#include <linux/power_supply.h>
+#include <linux/battery/samsung_battery.h>
+#endif
+#include <linux/switch.h>
+#include <linux/sii9234.h>
+
+#ifdef CONFIG_USB_HOST_NOTIFY
+#include <linux/host_notify.h>
+#endif
+#include <linux/pm_runtime.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#ifdef CONFIG_JACK_MON
+#include <linux/jack.h>
+#endif
+
+#define MUIC_DEBUG 1
+#ifdef MUIC_DEBUG
+#define MUIC_PRINT_LOG() \
+ pr_info("MUIC:[%s] func:%s\n", __FILE__, __func__);
+#else
+#define MUIC_PRINT_LOG() {}
+#endif
+
+static struct switch_dev switch_dock = {
+ .name = "dock",
+};
+
+extern struct class *sec_class;
+
+struct device *switch_dev;
+EXPORT_SYMBOL(switch_dev);
+
+static int uart_switch_init(void);
+
+static ssize_t u1_switch_show_vbus(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i;
+ struct regulator *regulator;
+
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator)) {
+ pr_warn("%s: fail to get regulator\n", __func__);
+ return sprintf(buf, "UNKNOWN\n");
+ }
+ if (regulator_is_enabled(regulator))
+ i = sprintf(buf, "VBUS is enabled\n");
+ else
+ i = sprintf(buf, "VBUS is disabled\n");
+ MUIC_PRINT_LOG();
+ regulator_put(regulator);
+
+ return i;
+}
+
+static ssize_t u1_switch_store_vbus(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int disable, ret, usb_mode;
+ struct regulator *regulator;
+ /* struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget); */
+
+ MUIC_PRINT_LOG();
+ if (!strncmp(buf, "0", 1))
+ disable = 0;
+ else if (!strncmp(buf, "1", 1))
+ disable = 1;
+ else {
+ pr_warn("%s: Wrong command\n", __func__);
+ return count;
+ }
+
+ pr_info("%s: disable=%d\n", __func__, disable);
+ usb_mode =
+ disable ? USB_CABLE_DETACHED_WITHOUT_NOTI : USB_CABLE_ATTACHED;
+ /* ret = udc->change_usb_mode(usb_mode); */
+ ret = -1;
+ if (ret < 0)
+ pr_err("%s: fail to change mode!!!\n", __func__);
+
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator)) {
+ pr_warn("%s: fail to get regulator\n", __func__);
+ return count;
+ }
+
+ if (disable) {
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ } else {
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ }
+ regulator_put(regulator);
+
+ return count;
+}
+
+DEVICE_ATTR(disable_vbus, 0664, u1_switch_show_vbus,
+ u1_switch_store_vbus);
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+#include "../../../drivers/usb/gadget/s3c_udc.h"
+/* usb access control for SEC DM */
+struct device *usb_lock;
+static int is_usb_locked;
+
+int u1_switch_get_usb_lock_state(void)
+{
+ return is_usb_locked;
+}
+EXPORT_SYMBOL(u1_switch_get_usb_lock_state);
+
+static ssize_t u1_switch_show_usb_lock(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (is_usb_locked)
+ return snprintf(buf, PAGE_SIZE, "USB_LOCK");
+ else
+ return snprintf(buf, PAGE_SIZE, "USB_UNLOCK");
+}
+
+static ssize_t u1_switch_store_usb_lock(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int lock;
+ struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget);
+
+ if (!strncmp(buf, "0", 1))
+ lock = 0;
+ else if (!strncmp(buf, "1", 1))
+ lock = 1;
+ else {
+ pr_warn("%s: Wrong command\n", __func__);
+ return count;
+ }
+
+ if (IS_ERR_OR_NULL(udc))
+ return count;
+
+ pr_info("%s: lock=%d\n", __func__, lock);
+
+ if (lock != is_usb_locked) {
+ is_usb_locked = lock;
+
+ if (lock) {
+ if (udc->udc_enabled)
+ usb_gadget_vbus_disconnect(&udc->gadget);
+ }
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(enable, 0664,
+ u1_switch_show_usb_lock, u1_switch_store_usb_lock);
+#endif
+
+static int __init u1_sec_switch_init(void)
+{
+ int ret;
+ switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
+
+ if (IS_ERR(switch_dev))
+ pr_err("Failed to create device(switch)!\n");
+
+ ret = device_create_file(switch_dev, &dev_attr_disable_vbus);
+ if (ret)
+ pr_err("Failed to create device file(disable_vbus)!\n");
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ usb_lock = device_create(sec_class, switch_dev,
+ MKDEV(0, 0), NULL, ".usb_lock");
+
+ if (IS_ERR(usb_lock))
+ pr_err("Failed to create device (usb_lock)!\n");
+
+ if (device_create_file(usb_lock, &dev_attr_enable) < 0)
+ pr_err("Failed to create device file(.usblock/enable)!\n");
+#endif
+
+#if !defined(CONFIG_MACH_U1CAMERA_BD)
+ ret = uart_switch_init();
+ if (ret)
+ pr_err("Failed to create uart_switch\n");
+#endif /* CONFIG_MACH_U1CAMERA_BD */
+
+ return 0;
+};
+
+static int uart_switch_init(void)
+{
+ int ret, val;
+ MUIC_PRINT_LOG();
+
+ ret = gpio_request(GPIO_UART_SEL, "UART_SEL");
+ if (ret < 0) {
+ pr_err("Failed to request GPIO_UART_SEL!\n");
+ return -ENODEV;
+ }
+ s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+ val = gpio_get_value(GPIO_UART_SEL);
+ pr_info("##MUIC [ %s ]- func : %s !! val:-%d-\n", __FILE__, __func__,
+ val);
+ gpio_direction_output(GPIO_UART_SEL, val);
+
+ gpio_export(GPIO_UART_SEL, 1);
+
+ gpio_export_link(switch_dev, "uart_sel", GPIO_UART_SEL);
+
+ return 0;
+}
+
+#if 0
+int max77693_muic_charger_cb(enum cable_type_muic cable_type)
+{
+ MUIC_PRINT_LOG();
+ return 0;
+}
+
+#define RETRY_CNT_LIMIT 100
+/* usb cable call back function */
+void max77693_muic_usb_cb(u8 usb_mode)
+{
+ struct usb_gadget *gadget = platform_get_drvdata(&s3c_device_usbgadget);
+#ifdef CONFIG_USB_EHCI_S5P
+ struct usb_hcd *ehci_hcd = platform_get_drvdata(&s5p_device_ehci);
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ struct usb_hcd *ohci_hcd = platform_get_drvdata(&s5p_device_ohci);
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ struct host_notifier_platform_data *host_noti_pdata =
+ host_notifier_device.dev.platform_data;
+#endif
+ int retry_cnt = 1;
+
+ pr_info("MUIC usb_cb:%d\n", usb_mode);
+ if (gadget) {
+ switch (usb_mode) {
+ case USB_CABLE_DETACHED:
+ pr_info("usb: muic: USB_CABLE_DETACHED(%d)\n",
+ usb_mode);
+ usb_gadget_vbus_disconnect(gadget);
+ break;
+ case USB_CABLE_ATTACHED:
+ pr_info("usb: muic: USB_CABLE_ATTACHED(%d)\n",
+ usb_mode);
+ usb_gadget_vbus_connect(gadget);
+ break;
+ default:
+ pr_info("usb: muic: invalid mode%d\n", usb_mode);
+ }
+ }
+
+ if (usb_mode == USB_OTGHOST_ATTACHED) {
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ehci.dev);
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_get_sync(&s5p_device_ohci.dev);
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ host_noti_pdata->ndev.mode = NOTIFY_HOST_MODE;
+ if (host_noti_pdata->usbhostd_start)
+ host_noti_pdata->usbhostd_start();
+
+ host_noti_pdata->booster(1);
+#endif
+ } else if (usb_mode == USB_OTGHOST_DETACHED) {
+#ifdef CONFIG_USB_EHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ehci.dev);
+ /* waiting for ehci root hub suspend is done */
+ while (ehci_hcd->state != HC_STATE_SUSPENDED) {
+ msleep(50);
+ if (retry_cnt++ > RETRY_CNT_LIMIT) {
+ printk(KERN_ERR "ehci suspend not completed\n");
+ break;
+ }
+ }
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ pm_runtime_put_sync(&s5p_device_ohci.dev);
+ /* waiting for ohci root hub suspend is done */
+ while (ohci_hcd->state != HC_STATE_SUSPENDED) {
+ msleep(50);
+ if (retry_cnt++ > RETRY_CNT_LIMIT) {
+ printk(KERN_ERR
+ "ohci suspend is not completed\n");
+ break;
+ }
+ }
+#endif
+#ifdef CONFIG_USB_HOST_NOTIFY
+ host_noti_pdata->ndev.mode = NOTIFY_NONE_MODE;
+ if (host_noti_pdata->usbhostd_stop)
+ host_noti_pdata->usbhostd_stop();
+
+ host_noti_pdata->booster(0);
+#endif
+ }
+
+#ifdef CONFIG_JACK_MON
+ if (usb_mode == USB_OTGHOST_ATTACHED)
+ jack_event_handler("host", USB_CABLE_ATTACHED);
+ else if (usb_mode == USB_OTGHOST_DETACHED)
+ jack_event_handler("host", USB_CABLE_DETACHED);
+ else if ((usb_mode == USB_CABLE_ATTACHED)
+ || (usb_mode == USB_CABLE_DETACHED))
+ jack_event_handler("usb", usb_mode);
+#endif
+}
+
+/*extern void MHL_On(bool on);*/
+void max77693_muic_mhl_cb(int attached)
+{
+ MUIC_PRINT_LOG();
+ pr_info("MUIC attached:%d\n", attached);
+ if (attached == MAX77693_MUIC_ATTACHED) {
+ /*MHL_On(1);*/ /* GPIO_LEVEL_HIGH */
+ pr_info("MHL Attached !!\n");
+#ifdef CONFIG_SAMSUNG_MHL
+ sii9234_mhl_detection_sched();
+#endif
+ } else {
+ /*MHL_On(0);*/ /* GPIO_LEVEL_LOW */
+ pr_info("MHL Detached !!\n");
+ }
+}
+
+bool max77693_muic_is_mhl_attached(void)
+{
+ int val;
+ MUIC_PRINT_LOG();
+ gpio_request(GPIO_MHL_SEL, "MHL_SEL");
+ val = gpio_get_value(GPIO_MHL_SEL);
+ pr_info("MUIC val:%d\n", val);
+ gpio_free(GPIO_MHL_SEL);
+
+ return !!val;
+}
+
+void max77693_muic_deskdock_cb(bool attached)
+{
+ MUIC_PRINT_LOG();
+ pr_info("MUIC deskdock attached=%d\n", attached);
+ if (attached)
+ switch_set_state(&switch_dock, 1);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+void max77693_muic_cardock_cb(bool attached)
+{
+ MUIC_PRINT_LOG();
+ pr_info("MUIC cardock attached=%d\n", attached);
+ pr_info("##MUIC [ %s ]- func : %s !!\n", __FILE__, __func__);
+ if (attached)
+ switch_set_state(&switch_dock, 2);
+ else
+ switch_set_state(&switch_dock, 0);
+}
+
+void max77693_muic_init_cb(void)
+{
+ int ret;
+
+ /* for CarDock, DeskDock */
+ ret = switch_dev_register(&switch_dock);
+
+ MUIC_PRINT_LOG();
+ pr_info("MUIC ret=%d\n", ret);
+
+ if (ret < 0)
+ pr_err("Failed to register dock switch. %d\n", ret);
+}
+
+int max77693_muic_cfg_uart_gpio(void)
+{
+ int val, path;
+ pr_info("## MUIC func : %s ! please path: (uart:%d - usb:%d)\n",
+ __func__, gpio_get_value(GPIO_UART_SEL),
+ gpio_get_value(GPIO_USB_SEL));
+ val = gpio_get_value(GPIO_UART_SEL);
+ path = val ? UART_PATH_AP : UART_PATH_CP;
+ pr_info("##MUIC [ %s ]- func : %s !! -- val:%d -- path:%d\n", __FILE__,
+ __func__, val, path);
+
+ return path;
+}
+
+void max77693_muic_jig_uart_cb(int path)
+{
+ int val;
+
+ val = path == UART_PATH_AP ? 1 : 0;
+ pr_info("##MUIC [ %s ]- func : %s !! -- val:%d\n", __FILE__, __func__,
+ val);
+ gpio_set_value(GPIO_UART_SEL, val);
+}
+
+int max77693_muic_host_notify_cb(int enable)
+{
+ MUIC_PRINT_LOG();
+ pr_info("MUIC host_noti enable=%d\n", enable);
+ return 0;
+}
+
+int max77693_muic_set_safeout(int path)
+{
+ struct regulator *regulator;
+
+ MUIC_PRINT_LOG();
+ pr_info("MUIC safeout path=%d\n", path);
+
+ if (path == CP_USB_MODE) {
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+ } else {
+ /* AP_USB_MODE || AUDIO_MODE */
+ regulator = regulator_get(NULL, "safeout1");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (!regulator_is_enabled(regulator))
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ regulator = regulator_get(NULL, "safeout2");
+ if (IS_ERR(regulator))
+ return -ENODEV;
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+ }
+
+ return 0;
+}
+
+struct max77693_muic_data max77693_muic = {
+ .usb_cb = max77693_muic_usb_cb,
+ .charger_cb = max77693_muic_charger_cb,
+ .mhl_cb = max77693_muic_mhl_cb,
+ .is_mhl_attached = max77693_muic_is_mhl_attached,
+ .set_safeout = max77693_muic_set_safeout,
+ .init_cb = max77693_muic_init_cb,
+ .deskdock_cb = max77693_muic_deskdock_cb,
+ .cardock_cb = max77693_muic_cardock_cb,
+ .cfg_uart_gpio = max77693_muic_cfg_uart_gpio,
+ .jig_uart_cb = max77693_muic_jig_uart_cb,
+ .host_notify_cb = max77693_muic_host_notify_cb,
+ .gpio_usb_sel = GPIO_USB_SEL,
+};
+#endif
+
+device_initcall(u1_sec_switch_init);
diff --git a/arch/arm/mach-exynos/sec_debug.c b/arch/arm/mach-exynos/sec_debug.c
new file mode 100644
index 0000000..2e19097
--- /dev/null
+++ b/arch/arm/mach-exynos/sec_debug.c
@@ -0,0 +1,1241 @@
+/*
+ * sec_debug.c
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/ctype.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <mach/regs-pmu.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/bootmem.h>
+#include <linux/kmsg_dump.h>
+#include <linux/kallsyms.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+
+#include <plat/system-reset.h>
+#include <mach/sec_debug.h>
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+#include <asm/mach/map.h>
+#include <plat/regs-watchdog.h>
+
+/* klaatu - schedule log */
+#ifdef CONFIG_SEC_DEBUG_SCHED_LOG
+#define SCHED_LOG_MAX 2048
+
+struct sched_log {
+ struct task_log {
+ unsigned long long time;
+ char comm[TASK_COMM_LEN];
+ pid_t pid;
+ } task[NR_CPUS][SCHED_LOG_MAX];
+ struct irq_log {
+ unsigned long long time;
+ int irq;
+ void *fn;
+ int en;
+ } irq[NR_CPUS][SCHED_LOG_MAX];
+ struct work_log {
+ unsigned long long time;
+ struct worker *worker;
+ struct work_struct *work;
+ work_func_t f;
+ } work[NR_CPUS][SCHED_LOG_MAX];
+};
+#endif /* CONFIG_SEC_DEBUG_SCHED_LOG */
+
+#ifdef CONFIG_SEC_DEBUG_AUXILIARY_LOG
+#define AUX_LOG_CPU_CLOCK_MAX 64
+#define AUX_LOG_LOGBUF_LOCK_MAX 64
+#define AUX_LOG_LENGTH 128
+
+struct auxiliary_info {
+ unsigned long long time;
+ int cpu;
+ char log[AUX_LOG_LENGTH];
+};
+
+/* This structure will be modified if some other items added for log */
+struct auxiliary_log {
+ struct auxiliary_info CpuClockLog[AUX_LOG_CPU_CLOCK_MAX];
+ struct auxiliary_info LogBufLockLog[AUX_LOG_LOGBUF_LOCK_MAX];
+};
+
+#else
+#endif
+
+#ifdef CONFIG_SEC_DEBUG_SEMAPHORE_LOG
+#define SEMAPHORE_LOG_MAX 100
+struct sem_debug {
+ struct list_head list;
+ struct semaphore *sem;
+ struct task_struct *task;
+ pid_t pid;
+ int cpu;
+ /* char comm[TASK_COMM_LEN]; */
+};
+
+enum {
+ READ_SEM,
+ WRITE_SEM
+};
+
+#define RWSEMAPHORE_LOG_MAX 100
+struct rwsem_debug {
+ struct list_head list;
+ struct rw_semaphore *sem;
+ struct task_struct *task;
+ pid_t pid;
+ int cpu;
+ int direction;
+ /* char comm[TASK_COMM_LEN]; */
+};
+
+#endif /* CONFIG_SEC_DEBUG_SEMAPHORE_LOG */
+
+/* layout of SDRAM
+ 0: magic (4B)
+ 4~1023: panic string (1020B)
+ 1024~0x1000: panic dumper log
+ 0x4000: copy of magic
+ */
+#define SEC_DEBUG_MAGIC_PA S5P_PA_SDRAM
+#define SEC_DEBUG_MAGIC_VA phys_to_virt(SEC_DEBUG_MAGIC_PA)
+
+enum sec_debug_upload_cause_t {
+ UPLOAD_CAUSE_INIT = 0xCAFEBABE,
+ UPLOAD_CAUSE_KERNEL_PANIC = 0x000000C8,
+ UPLOAD_CAUSE_FORCED_UPLOAD = 0x00000022,
+ UPLOAD_CAUSE_CP_ERROR_FATAL = 0x000000CC,
+ UPLOAD_CAUSE_USER_FAULT = 0x0000002F,
+ UPLOAD_CAUSE_HSIC_DISCONNECTED = 0x000000DD,
+};
+
+struct sec_debug_mmu_reg_t {
+ int SCTLR;
+ int TTBR0;
+ int TTBR1;
+ int TTBCR;
+ int DACR;
+ int DFSR;
+ int DFAR;
+ int IFSR;
+ int IFAR;
+ int DAFSR;
+ int IAFSR;
+ int PMRRR;
+ int NMRRR;
+ int FCSEPID;
+ int CONTEXT;
+ int URWTPID;
+ int UROTPID;
+ int POTPIDR;
+};
+
+/* ARM CORE regs mapping structure */
+struct sec_debug_core_t {
+ /* COMMON */
+ unsigned int r0;
+ unsigned int r1;
+ unsigned int r2;
+ unsigned int r3;
+ unsigned int r4;
+ unsigned int r5;
+ unsigned int r6;
+ unsigned int r7;
+ unsigned int r8;
+ unsigned int r9;
+ unsigned int r10;
+ unsigned int r11;
+ unsigned int r12;
+
+ /* SVC */
+ unsigned int r13_svc;
+ unsigned int r14_svc;
+ unsigned int spsr_svc;
+
+ /* PC & CPSR */
+ unsigned int pc;
+ unsigned int cpsr;
+
+ /* USR/SYS */
+ unsigned int r13_usr;
+ unsigned int r14_usr;
+
+ /* FIQ */
+ unsigned int r8_fiq;
+ unsigned int r9_fiq;
+ unsigned int r10_fiq;
+ unsigned int r11_fiq;
+ unsigned int r12_fiq;
+ unsigned int r13_fiq;
+ unsigned int r14_fiq;
+ unsigned int spsr_fiq;
+
+ /* IRQ */
+ unsigned int r13_irq;
+ unsigned int r14_irq;
+ unsigned int spsr_irq;
+
+ /* MON */
+ unsigned int r13_mon;
+ unsigned int r14_mon;
+ unsigned int spsr_mon;
+
+ /* ABT */
+ unsigned int r13_abt;
+ unsigned int r14_abt;
+ unsigned int spsr_abt;
+
+ /* UNDEF */
+ unsigned int r13_und;
+ unsigned int r14_und;
+ unsigned int spsr_und;
+
+};
+
+/* enable/disable sec_debug feature
+ * level = 0 when enable = 0 && enable_user = 0
+ * level = 1 when enable = 1 && enable_user = 0
+ * level = 0x10001 when enable = 1 && enable_user = 1
+ * The other cases are not considered
+ */
+union sec_debug_level_t sec_debug_level = { .en.kernel_fault = 1, };
+
+module_param_named(enable, sec_debug_level.en.kernel_fault, ushort, 0644);
+module_param_named(enable_user, sec_debug_level.en.user_fault, ushort, 0644);
+module_param_named(level, sec_debug_level.uint_val, uint, 0644);
+
+/* klaatu - schedule log */
+#ifdef CONFIG_SEC_DEBUG_SCHED_LOG
+static struct sched_log sec_debug_log __cacheline_aligned;
+/*
+static struct sched_log sec_debug_log[NR_CPUS][SCHED_LOG_MAX]
+ __cacheline_aligned;
+*/
+static atomic_t task_log_idx[NR_CPUS] = { ATOMIC_INIT(-1), ATOMIC_INIT(-1) };
+static atomic_t irq_log_idx[NR_CPUS] = { ATOMIC_INIT(-1), ATOMIC_INIT(-1) };
+static atomic_t work_log_idx[NR_CPUS] = { ATOMIC_INIT(-1), ATOMIC_INIT(-1) };
+static struct sched_log (*psec_debug_log) = (&sec_debug_log);
+/*
+static struct sched_log (*psec_debug_log)[NR_CPUS][SCHED_LOG_MAX]
+ = (&sec_debug_log);
+*/
+#ifdef CONFIG_SEC_DEBUG_IRQ_EXIT_LOG
+static unsigned long long gExcpIrqExitTime[NR_CPUS];
+#endif
+
+#ifdef CONFIG_SEC_DEBUG_AUXILIARY_LOG
+static struct auxiliary_log gExcpAuxLog __cacheline_aligned;
+static struct auxiliary_log *gExcpAuxLogPtr;
+static atomic_t gExcpAuxCpuClockLogIdx = ATOMIC_INIT(-1);
+static atomic_t gExcpAuxLogBufLockLogIdx = ATOMIC_INIT(-1);
+#endif
+
+static int checksum_sched_log(void)
+{
+ int sum = 0, i;
+ for (i = 0; i < sizeof(sec_debug_log); i++)
+ sum += *((char *)&sec_debug_log + i);
+
+ return sum;
+}
+
+#ifdef CONFIG_SEC_DEBUG_SCHED_LOG_NONCACHED
+static void map_noncached_sched_log_buf(void)
+{
+ struct map_desc slog_buf_iodesc[] = {
+ {
+ .virtual = (unsigned long)S3C_VA_SLOG_BUF,
+ .length = 0x200000,
+ .type = MT_DEVICE
+ }
+ };
+
+ slog_buf_iodesc[0].pfn = __phys_to_pfn
+ ((unsigned long)((virt_to_phys(&sec_debug_log)&0xfff00000)));
+ iotable_init(slog_buf_iodesc, ARRAY_SIZE(slog_buf_iodesc));
+ psec_debug_log = (void *)(S3C_VA_SLOG_BUF +
+ (((unsigned long)(&sec_debug_log))&0x000fffff));
+}
+#endif
+
+#ifdef CONFIG_SEC_DEBUG_AUXILIARY_LOG
+static void map_noncached_aux_log_buf(void)
+{
+ struct map_desc auxlog_buf_iodesc[] = {
+ {
+ .virtual = (unsigned long)S3C_VA_AUXLOG_BUF,
+ .length = 0x200000,
+ .type = MT_DEVICE
+ }
+ };
+
+ auxlog_buf_iodesc[0].pfn = __phys_to_pfn
+ ((unsigned long)((virt_to_phys(&gExcpAuxLog)&0xfff00000)));
+ iotable_init(auxlog_buf_iodesc, ARRAY_SIZE(auxlog_buf_iodesc));
+ gExcpAuxLogPtr = (void *)(S3C_VA_AUXLOG_BUF +
+ (((unsigned long)(&gExcpAuxLog))&0x000fffff));
+}
+#endif
+
+#else
+static int checksum_sched_log(void)
+{
+ return 0;
+}
+#endif
+
+/* klaatu - semaphore log */
+#ifdef CONFIG_SEC_DEBUG_SEMAPHORE_LOG
+struct sem_debug sem_debug_free_head;
+struct sem_debug sem_debug_done_head;
+int sem_debug_free_head_cnt;
+int sem_debug_done_head_cnt;
+int sem_debug_init = 0;
+spinlock_t sem_debug_lock;
+
+/* rwsemaphore logging */
+struct rwsem_debug rwsem_debug_free_head;
+struct rwsem_debug rwsem_debug_done_head;
+int rwsem_debug_free_head_cnt;
+int rwsem_debug_done_head_cnt;
+int rwsem_debug_init = 0;
+spinlock_t rwsem_debug_lock;
+
+#endif /* CONFIG_SEC_DEBUG_SEMAPHORE_LOG */
+
+DEFINE_PER_CPU(struct sec_debug_core_t, sec_debug_core_reg);
+DEFINE_PER_CPU(struct sec_debug_mmu_reg_t, sec_debug_mmu_reg);
+DEFINE_PER_CPU(enum sec_debug_upload_cause_t, sec_debug_upload_cause);
+
+/* core reg dump function*/
+static inline void sec_debug_save_core_reg(struct sec_debug_core_t *core_reg)
+{
+ /* we will be in SVC mode when we enter this function. Collect
+ SVC registers along with cmn registers. */
+ asm("str r0, [%0,#0]\n\t" /* R0 is pushed first to core_reg */
+ "mov r0, %0\n\t" /* R0 will be alias for core_reg */
+ "str r1, [r0,#4]\n\t" /* R1 */
+ "str r2, [r0,#8]\n\t" /* R2 */
+ "str r3, [r0,#12]\n\t" /* R3 */
+ "str r4, [r0,#16]\n\t" /* R4 */
+ "str r5, [r0,#20]\n\t" /* R5 */
+ "str r6, [r0,#24]\n\t" /* R6 */
+ "str r7, [r0,#28]\n\t" /* R7 */
+ "str r8, [r0,#32]\n\t" /* R8 */
+ "str r9, [r0,#36]\n\t" /* R9 */
+ "str r10, [r0,#40]\n\t" /* R10 */
+ "str r11, [r0,#44]\n\t" /* R11 */
+ "str r12, [r0,#48]\n\t" /* R12 */
+ /* SVC */
+ "str r13, [r0,#52]\n\t" /* R13_SVC */
+ "str r14, [r0,#56]\n\t" /* R14_SVC */
+ "mrs r1, spsr\n\t" /* SPSR_SVC */
+ "str r1, [r0,#60]\n\t"
+ /* PC and CPSR */
+ "sub r1, r15, #0x4\n\t" /* PC */
+ "str r1, [r0,#64]\n\t"
+ "mrs r1, cpsr\n\t" /* CPSR */
+ "str r1, [r0,#68]\n\t"
+ /* SYS/USR */
+ "mrs r1, cpsr\n\t" /* switch to SYS mode */
+ "and r1, r1, #0xFFFFFFE0\n\t"
+ "orr r1, r1, #0x1f\n\t"
+ "msr cpsr,r1\n\t"
+ "str r13, [r0,#72]\n\t" /* R13_USR */
+ "str r14, [r0,#76]\n\t" /* R14_USR */
+ /* FIQ */
+ "mrs r1, cpsr\n\t" /* switch to FIQ mode */
+ "and r1,r1,#0xFFFFFFE0\n\t"
+ "orr r1,r1,#0x11\n\t"
+ "msr cpsr,r1\n\t"
+ "str r8, [r0,#80]\n\t" /* R8_FIQ */
+ "str r9, [r0,#84]\n\t" /* R9_FIQ */
+ "str r10, [r0,#88]\n\t" /* R10_FIQ */
+ "str r11, [r0,#92]\n\t" /* R11_FIQ */
+ "str r12, [r0,#96]\n\t" /* R12_FIQ */
+ "str r13, [r0,#100]\n\t" /* R13_FIQ */
+ "str r14, [r0,#104]\n\t" /* R14_FIQ */
+ "mrs r1, spsr\n\t" /* SPSR_FIQ */
+ "str r1, [r0,#108]\n\t"
+ /* IRQ */
+ "mrs r1, cpsr\n\t" /* switch to IRQ mode */
+ "and r1, r1, #0xFFFFFFE0\n\t"
+ "orr r1, r1, #0x12\n\t"
+ "msr cpsr,r1\n\t"
+ "str r13, [r0,#112]\n\t" /* R13_IRQ */
+ "str r14, [r0,#116]\n\t" /* R14_IRQ */
+ "mrs r1, spsr\n\t" /* SPSR_IRQ */
+ "str r1, [r0,#120]\n\t"
+ /* MON */
+ "mrs r1, cpsr\n\t" /* switch to monitor mode */
+ "and r1, r1, #0xFFFFFFE0\n\t"
+ "orr r1, r1, #0x16\n\t"
+ "msr cpsr,r1\n\t"
+ "str r13, [r0,#124]\n\t" /* R13_MON */
+ "str r14, [r0,#128]\n\t" /* R14_MON */
+ "mrs r1, spsr\n\t" /* SPSR_MON */
+ "str r1, [r0,#132]\n\t"
+ /* ABT */
+ "mrs r1, cpsr\n\t" /* switch to Abort mode */
+ "and r1, r1, #0xFFFFFFE0\n\t"
+ "orr r1, r1, #0x17\n\t"
+ "msr cpsr,r1\n\t"
+ "str r13, [r0,#136]\n\t" /* R13_ABT */
+ "str r14, [r0,#140]\n\t" /* R14_ABT */
+ "mrs r1, spsr\n\t" /* SPSR_ABT */
+ "str r1, [r0,#144]\n\t"
+ /* UND */
+ "mrs r1, cpsr\n\t" /* switch to undef mode */
+ "and r1, r1, #0xFFFFFFE0\n\t"
+ "orr r1, r1, #0x1B\n\t"
+ "msr cpsr,r1\n\t"
+ "str r13, [r0,#148]\n\t" /* R13_UND */
+ "str r14, [r0,#152]\n\t" /* R14_UND */
+ "mrs r1, spsr\n\t" /* SPSR_UND */
+ "str r1, [r0,#156]\n\t"
+ /* restore to SVC mode */
+ "mrs r1, cpsr\n\t" /* switch to SVC mode */
+ "and r1, r1, #0xFFFFFFE0\n\t"
+ "orr r1, r1, #0x13\n\t"
+ "msr cpsr,r1\n\t" : /* output */
+ : "r"(core_reg) /* input */
+ : "%r0", "%r1" /* clobbered registers */
+ );
+
+ return;
+}
+
+static inline void sec_debug_save_mmu_reg(struct sec_debug_mmu_reg_t *mmu_reg)
+{
+ asm("mrc p15, 0, r1, c1, c0, 0\n\t" /* SCTLR */
+ "str r1, [%0]\n\t"
+ "mrc p15, 0, r1, c2, c0, 0\n\t" /* TTBR0 */
+ "str r1, [%0,#4]\n\t"
+ "mrc p15, 0, r1, c2, c0,1\n\t" /* TTBR1 */
+ "str r1, [%0,#8]\n\t"
+ "mrc p15, 0, r1, c2, c0,2\n\t" /* TTBCR */
+ "str r1, [%0,#12]\n\t"
+ "mrc p15, 0, r1, c3, c0,0\n\t" /* DACR */
+ "str r1, [%0,#16]\n\t"
+ "mrc p15, 0, r1, c5, c0,0\n\t" /* DFSR */
+ "str r1, [%0,#20]\n\t"
+ "mrc p15, 0, r1, c6, c0,0\n\t" /* DFAR */
+ "str r1, [%0,#24]\n\t"
+ "mrc p15, 0, r1, c5, c0,1\n\t" /* IFSR */
+ "str r1, [%0,#28]\n\t"
+ "mrc p15, 0, r1, c6, c0,2\n\t" /* IFAR */
+ "str r1, [%0,#32]\n\t"
+ /* Don't populate DAFSR and RAFSR */
+ "mrc p15, 0, r1, c10, c2,0\n\t" /* PMRRR */
+ "str r1, [%0,#44]\n\t"
+ "mrc p15, 0, r1, c10, c2,1\n\t" /* NMRRR */
+ "str r1, [%0,#48]\n\t"
+ "mrc p15, 0, r1, c13, c0,0\n\t" /* FCSEPID */
+ "str r1, [%0,#52]\n\t"
+ "mrc p15, 0, r1, c13, c0,1\n\t" /* CONTEXT */
+ "str r1, [%0,#56]\n\t"
+ "mrc p15, 0, r1, c13, c0,2\n\t" /* URWTPID */
+ "str r1, [%0,#60]\n\t"
+ "mrc p15, 0, r1, c13, c0,3\n\t" /* UROTPID */
+ "str r1, [%0,#64]\n\t"
+ "mrc p15, 0, r1, c13, c0,4\n\t" /* POTPIDR */
+ "str r1, [%0,#68]\n\t" : /* output */
+ : "r"(mmu_reg) /* input */
+ : "%r1", "memory" /* clobbered register */
+ );
+}
+
+static inline void sec_debug_save_context(void)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ sec_debug_save_mmu_reg(&per_cpu(sec_debug_mmu_reg, smp_processor_id()));
+ sec_debug_save_core_reg(&per_cpu
+ (sec_debug_core_reg, smp_processor_id()));
+
+ pr_emerg("(%s) context saved(CPU:%d)\n", __func__, smp_processor_id());
+ local_irq_restore(flags);
+}
+
+static void sec_debug_set_upload_magic(unsigned magic, char *str)
+{
+ pr_emerg("(%s) %x\n", __func__, magic);
+
+ *(unsigned int *)SEC_DEBUG_MAGIC_VA = magic;
+ *(unsigned int *)(SEC_DEBUG_MAGIC_VA + 0x4000) = magic;
+
+ if (str)
+ strncpy((char *)SEC_DEBUG_MAGIC_VA + 4, str, SZ_1K - 4);
+
+ flush_cache_all();
+
+ outer_flush_all();
+}
+
+static int sec_debug_normal_reboot_handler(struct notifier_block *nb,
+ unsigned long l, void *p)
+{
+ sec_debug_set_upload_magic(0x0, NULL);
+
+ return 0;
+}
+
+static void sec_debug_set_upload_cause(enum sec_debug_upload_cause_t type)
+{
+ per_cpu(sec_debug_upload_cause, smp_processor_id()) = type;
+
+ /* to check VDD_ALIVE / XnRESET issue */
+ __raw_writel(type, S5P_INFORM3);
+ __raw_writel(type, S5P_INFORM4);
+ __raw_writel(type, S5P_INFORM6);
+
+ pr_emerg("(%s) %x\n", __func__, type);
+}
+
+/*
+ * Called from dump_stack()
+ * This function call does not necessarily mean that a fatal error
+ * had occurred. It may be just a warning.
+ */
+static inline int sec_debug_dump_stack(void)
+{
+ if (!sec_debug_level.en.kernel_fault)
+ return -1;
+
+ sec_debug_save_context();
+
+ /* flush L1 from each core.
+ L2 will be flushed later before reset. */
+ flush_cache_all();
+
+ return 0;
+}
+
+static inline void sec_debug_hw_reset(void)
+{
+ pr_emerg("(%s) %s\n", __func__, linux_banner);
+ pr_emerg("(%s) rebooting...\n", __func__);
+
+ flush_cache_all();
+
+ outer_flush_all();
+
+ arch_reset(0, 0);
+
+ while (1) ;
+}
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+static inline void sec_debug_disable_watchdog(void)
+{
+ writel(0, S3C2410_WTCON);
+ pr_err("(%s) disable watchdog reset while printing log\n", __func__);
+}
+#endif
+
+static int sec_debug_panic_handler(struct notifier_block *nb,
+ unsigned long l, void *buf)
+{
+ if (!sec_debug_level.en.kernel_fault)
+ return -1;
+
+ local_irq_disable();
+
+ sec_debug_set_upload_magic(0x66262564, buf);
+
+ if (!strcmp(buf, "User Fault"))
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_USER_FAULT);
+ else if (!strcmp(buf, "Crash Key"))
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_FORCED_UPLOAD);
+ else if (!strncmp(buf, "CP Crash", 8))
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_CP_ERROR_FATAL);
+ else if (!strcmp(buf, "HSIC Disconnected"))
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_HSIC_DISCONNECTED);
+ else
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_KERNEL_PANIC);
+
+ pr_err("(%s) checksum_sched_log: %x\n", __func__, checksum_sched_log());
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ sec_debug_disable_watchdog();
+#endif
+ show_state();
+
+ sec_debug_dump_stack();
+ sec_debug_hw_reset();
+
+ return 0;
+}
+
+#ifdef CONFIG_SEC_DEBUG_FUPLOAD_DUMP_MORE
+static void dump_state_and_upload(void);
+#endif
+
+void sec_debug_check_crash_key(unsigned int code, int value)
+{
+ static bool volup_p;
+ static bool voldown_p;
+ static int loopcount;
+
+ if (!sec_debug_level.en.kernel_fault)
+ return;
+
+ /* Must be deleted later */
+#if defined(CONFIG_MACH_MIDAS) || defined(CONFIG_SLP)
+ pr_info("%s:key code(%d) value(%d)\n",
+ __func__, code, value);
+#endif
+
+ /* Enter Force Upload
+ * Hold volume down key first
+ * and then press power key twice
+ * and volume up key should not be pressed
+ */
+ if (value) {
+ if (code == KEY_VOLUMEUP)
+ volup_p = true;
+ if (code == KEY_VOLUMEDOWN)
+ voldown_p = true;
+ if (!volup_p && voldown_p) {
+ if (code == KEY_POWER) {
+ pr_info
+ ("%s: count for enter forced upload : %d\n",
+ __func__, ++loopcount);
+ if (loopcount == 2) {
+#ifdef CONFIG_FB_S5P
+ read_lcd_register();
+#endif
+#ifdef CONFIG_SEC_DEBUG_FUPLOAD_DUMP_MORE
+ dump_state_and_upload();
+#else
+ panic("Crash Key");
+#endif
+ }
+ }
+ }
+ } else {
+ if (code == KEY_VOLUMEUP)
+ volup_p = false;
+ if (code == KEY_VOLUMEDOWN) {
+ loopcount = 0;
+ voldown_p = false;
+ }
+ }
+}
+
+static struct notifier_block nb_reboot_block = {
+ .notifier_call = sec_debug_normal_reboot_handler
+};
+
+static struct notifier_block nb_panic_block = {
+ .notifier_call = sec_debug_panic_handler,
+};
+
+static void sec_kmsg_dump(struct kmsg_dumper *dumper,
+ enum kmsg_dump_reason reason, const char *s1,
+ unsigned long l1, const char *s2, unsigned long l2)
+{
+ char *ptr = (char *)SEC_DEBUG_MAGIC_VA + SZ_1K;
+ int total_chars = SZ_4K - SZ_1K;
+ int total_lines = 50;
+ int last_chars; /* no of chars which fits in total_chars *and* in total_lines */
+
+ for (last_chars = 0;
+ l2 && l2 > last_chars && total_lines > 0
+ && total_chars > 0; ++last_chars, --total_chars) {
+ if (s2[l2 - last_chars] == '\n')
+ --total_lines;
+ }
+ s2 += (l2 - last_chars);
+ l2 = last_chars;
+
+ for (last_chars = 0;
+ l1 && l1 > last_chars && total_lines > 0
+ && total_chars > 0; ++last_chars, --total_chars) {
+ if (s1[l1 - last_chars] == '\n')
+ --total_lines;
+ }
+ s1 += (l1 - last_chars);
+ l1 = last_chars;
+
+ while (l1-- > 0)
+ *ptr++ = *s1++;
+ while (l2-- > 0)
+ *ptr++ = *s2++;
+}
+
+static struct kmsg_dumper sec_dumper = {
+ .dump = sec_kmsg_dump,
+};
+
+__init int sec_debug_init(void)
+{
+ if (!sec_debug_level.en.kernel_fault)
+ return -1;
+
+ sec_debug_set_upload_magic(0x66262564, NULL);
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_INIT);
+
+#ifdef CONFIG_SEC_DEBUG_SCHED_LOG_NONCACHED
+ map_noncached_sched_log_buf();
+#endif
+
+#ifdef CONFIG_SEC_DEBUG_AUXILIARY_LOG
+ map_noncached_aux_log_buf();
+#endif
+
+ kmsg_dump_register(&sec_dumper);
+
+ register_reboot_notifier(&nb_reboot_block);
+
+ atomic_notifier_chain_register(&panic_notifier_list, &nb_panic_block);
+
+ return 0;
+}
+
+int get_sec_debug_level(void)
+{
+ return sec_debug_level.uint_val;
+}
+
+/* klaatu - schedule log */
+#ifdef CONFIG_SEC_DEBUG_SCHED_LOG
+void __sec_debug_task_log(int cpu, struct task_struct *task)
+{
+ unsigned i;
+
+ i = atomic_inc_return(&task_log_idx[cpu]) & (SCHED_LOG_MAX - 1);
+ psec_debug_log->task[cpu][i].time = cpu_clock(cpu);
+ strcpy(psec_debug_log->task[cpu][i].comm, task->comm);
+ psec_debug_log->task[cpu][i].pid = task->pid;
+}
+
+void __sec_debug_irq_log(unsigned int irq, void *fn, int en)
+{
+ int cpu = raw_smp_processor_id();
+ unsigned i;
+
+ i = atomic_inc_return(&irq_log_idx[cpu]) & (SCHED_LOG_MAX - 1);
+ psec_debug_log->irq[cpu][i].time = cpu_clock(cpu);
+ psec_debug_log->irq[cpu][i].irq = irq;
+ psec_debug_log->irq[cpu][i].fn = (void *)fn;
+ psec_debug_log->irq[cpu][i].en = en;
+}
+
+void __sec_debug_work_log(struct worker *worker,
+ struct work_struct *work, work_func_t f)
+{
+ int cpu = raw_smp_processor_id();
+ unsigned i;
+
+ i = atomic_inc_return(&work_log_idx[cpu]) & (SCHED_LOG_MAX - 1);
+ psec_debug_log->work[cpu][i].time = cpu_clock(cpu);
+ psec_debug_log->work[cpu][i].worker = worker;
+ psec_debug_log->work[cpu][i].work = work;
+ psec_debug_log->work[cpu][i].f = f;
+}
+
+#ifdef CONFIG_SEC_DEBUG_IRQ_EXIT_LOG
+void sec_debug_irq_last_exit_log(void)
+{
+ int cpu = raw_smp_processor_id();
+ gExcpIrqExitTime[cpu] = cpu_clock(cpu);
+}
+#endif
+#endif /* CONFIG_SEC_DEBUG_SCHED_LOG */
+
+#ifdef CONFIG_SEC_DEBUG_AUXILIARY_LOG
+void sec_debug_aux_log(int idx, char *fmt, ...)
+{
+ va_list args;
+ char buf[128];
+ unsigned i;
+ int cpu = raw_smp_processor_id();
+
+ if (!gExcpAuxLogPtr)
+ return;
+
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+
+ switch (idx) {
+ case SEC_DEBUG_AUXLOG_CPU_BUS_CLOCK_CHANGE:
+ i = atomic_inc_return(&gExcpAuxCpuClockLogIdx)
+ & (AUX_LOG_CPU_CLOCK_MAX - 1);
+ (*gExcpAuxLogPtr).CpuClockLog[i].time = cpu_clock(cpu);
+ (*gExcpAuxLogPtr).CpuClockLog[i].cpu = cpu;
+ strncpy((*gExcpAuxLogPtr).CpuClockLog[i].log,
+ buf, AUX_LOG_LENGTH);
+ break;
+ case SEC_DEBUG_AUXLOG_LOGBUF_LOCK_CHANGE:
+ i = atomic_inc_return(&gExcpAuxLogBufLockLogIdx)
+ & (AUX_LOG_LOGBUF_LOCK_MAX - 1);
+ (*gExcpAuxLogPtr).LogBufLockLog[i].time = cpu_clock(cpu);
+ (*gExcpAuxLogPtr).LogBufLockLog[i].cpu = cpu;
+ strncpy((*gExcpAuxLogPtr).LogBufLockLog[i].log,
+ buf, AUX_LOG_LENGTH);
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
+/* klaatu - semaphore log */
+#ifdef CONFIG_SEC_DEBUG_SEMAPHORE_LOG
+void debug_semaphore_init(void)
+{
+ int i = 0;
+ struct sem_debug *sem_debug = NULL;
+
+ spin_lock_init(&sem_debug_lock);
+ sem_debug_free_head_cnt = 0;
+ sem_debug_done_head_cnt = 0;
+
+ /* initialize list head of sem_debug */
+ INIT_LIST_HEAD(&sem_debug_free_head.list);
+ INIT_LIST_HEAD(&sem_debug_done_head.list);
+
+ for (i = 0; i < SEMAPHORE_LOG_MAX; i++) {
+ /* malloc semaphore */
+ sem_debug = kmalloc(sizeof(struct sem_debug), GFP_KERNEL);
+ /* add list */
+ list_add(&sem_debug->list, &sem_debug_free_head.list);
+ sem_debug_free_head_cnt++;
+ }
+
+ sem_debug_init = 1;
+}
+
+void debug_semaphore_down_log(struct semaphore *sem)
+{
+ struct list_head *tmp;
+ struct sem_debug *sem_dbg;
+ unsigned long flags;
+
+ if (!sem_debug_init)
+ return;
+
+ spin_lock_irqsave(&sem_debug_lock, flags);
+ list_for_each(tmp, &sem_debug_free_head.list) {
+ sem_dbg = list_entry(tmp, struct sem_debug, list);
+ sem_dbg->task = current;
+ sem_dbg->sem = sem;
+ /* strcpy(sem_dbg->comm,current->group_leader->comm); */
+ sem_dbg->pid = current->pid;
+ sem_dbg->cpu = smp_processor_id();
+ list_del(&sem_dbg->list);
+ list_add(&sem_dbg->list, &sem_debug_done_head.list);
+ sem_debug_free_head_cnt--;
+ sem_debug_done_head_cnt++;
+ break;
+ }
+ spin_unlock_irqrestore(&sem_debug_lock, flags);
+}
+
+void debug_semaphore_up_log(struct semaphore *sem)
+{
+ struct list_head *tmp;
+ struct sem_debug *sem_dbg;
+ unsigned long flags;
+
+ if (!sem_debug_init)
+ return;
+
+ spin_lock_irqsave(&sem_debug_lock, flags);
+ list_for_each(tmp, &sem_debug_done_head.list) {
+ sem_dbg = list_entry(tmp, struct sem_debug, list);
+ if (sem_dbg->sem == sem && sem_dbg->pid == current->pid) {
+ list_del(&sem_dbg->list);
+ list_add(&sem_dbg->list, &sem_debug_free_head.list);
+ sem_debug_free_head_cnt++;
+ sem_debug_done_head_cnt--;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&sem_debug_lock, flags);
+}
+
+/* rwsemaphore logging */
+void debug_rwsemaphore_init(void)
+{
+ int i = 0;
+ struct rwsem_debug *rwsem_debug = NULL;
+
+ spin_lock_init(&rwsem_debug_lock);
+ rwsem_debug_free_head_cnt = 0;
+ rwsem_debug_done_head_cnt = 0;
+
+ /* initialize list head of sem_debug */
+ INIT_LIST_HEAD(&rwsem_debug_free_head.list);
+ INIT_LIST_HEAD(&rwsem_debug_done_head.list);
+
+ for (i = 0; i < RWSEMAPHORE_LOG_MAX; i++) {
+ /* malloc semaphore */
+ rwsem_debug = kmalloc(sizeof(struct rwsem_debug), GFP_KERNEL);
+ /* add list */
+ list_add(&rwsem_debug->list, &rwsem_debug_free_head.list);
+ rwsem_debug_free_head_cnt++;
+ }
+
+ rwsem_debug_init = 1;
+}
+
+void debug_rwsemaphore_down_log(struct rw_semaphore *sem, int dir)
+{
+ struct list_head *tmp;
+ struct rwsem_debug *sem_dbg;
+ unsigned long flags;
+
+ if (!rwsem_debug_init)
+ return;
+
+ spin_lock_irqsave(&rwsem_debug_lock, flags);
+ list_for_each(tmp, &rwsem_debug_free_head.list) {
+ sem_dbg = list_entry(tmp, struct rwsem_debug, list);
+ sem_dbg->task = current;
+ sem_dbg->sem = sem;
+ /* strcpy(sem_dbg->comm,current->group_leader->comm); */
+ sem_dbg->pid = current->pid;
+ sem_dbg->cpu = smp_processor_id();
+ sem_dbg->direction = dir;
+ list_del(&sem_dbg->list);
+ list_add(&sem_dbg->list, &rwsem_debug_done_head.list);
+ rwsem_debug_free_head_cnt--;
+ rwsem_debug_done_head_cnt++;
+ break;
+ }
+ spin_unlock_irqrestore(&rwsem_debug_lock, flags);
+}
+
+void debug_rwsemaphore_up_log(struct rw_semaphore *sem)
+{
+ struct list_head *tmp;
+ struct rwsem_debug *sem_dbg;
+ unsigned long flags;
+
+ if (!rwsem_debug_init)
+ return;
+
+ spin_lock_irqsave(&rwsem_debug_lock, flags);
+ list_for_each(tmp, &rwsem_debug_done_head.list) {
+ sem_dbg = list_entry(tmp, struct rwsem_debug, list);
+ if (sem_dbg->sem == sem && sem_dbg->pid == current->pid) {
+ list_del(&sem_dbg->list);
+ list_add(&sem_dbg->list, &rwsem_debug_free_head.list);
+ rwsem_debug_free_head_cnt++;
+ rwsem_debug_done_head_cnt--;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&rwsem_debug_lock, flags);
+}
+#endif /* CONFIG_SEC_DEBUG_SEMAPHORE_LOG */
+
+#ifdef CONFIG_SEC_DEBUG_USER
+void sec_user_fault_dump(void)
+{
+ if (sec_debug_level.en.kernel_fault == 1
+ && sec_debug_level.en.user_fault == 1)
+ panic("User Fault");
+}
+
+static int sec_user_fault_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * offs)
+{
+ char buf[100];
+
+ if (count > sizeof(buf) - 1)
+ return -EINVAL;
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+ buf[count] = '\0';
+
+ if (strncmp(buf, "dump_user_fault", 15) == 0)
+ sec_user_fault_dump();
+
+ return count;
+}
+
+static const struct file_operations sec_user_fault_proc_fops = {
+ .write = sec_user_fault_write,
+};
+
+static int __init sec_debug_user_fault_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ entry = proc_create("user_fault", S_IWUGO, NULL,
+ &sec_user_fault_proc_fops);
+ if (!entry)
+ return -ENOMEM;
+ return 0;
+}
+
+device_initcall(sec_debug_user_fault_init);
+#endif
+
+int sec_debug_magic_init(void)
+{
+ if (reserve_bootmem(SEC_DEBUG_MAGIC_PA, SZ_4K, BOOTMEM_EXCLUSIVE)) {
+ pr_err("%s: failed reserving magic code area\n", __func__);
+ return -ENOMEM;
+ }
+
+ pr_info("%s: success reserving magic code area\n", __func__);
+ return 0;
+}
+
+#ifdef CONFIG_SEC_DEBUG_FUPLOAD_DUMP_MORE
+static void dump_one_task_info(struct task_struct *tsk, bool is_main)
+{
+ char state_array[] = {'R', 'S', 'D', 'T', 't', 'Z', 'X', 'x', 'K', 'W'};
+ unsigned char idx = 0;
+ unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
+ unsigned long wchan;
+ unsigned long pc = 0;
+ char symname[KSYM_NAME_LEN];
+ int permitted;
+ struct mm_struct *mm;
+
+ permitted = ptrace_may_access(tsk, PTRACE_MODE_READ);
+ mm = get_task_mm(tsk);
+ if (mm) {
+ if (permitted)
+ pc = KSTK_EIP(tsk);
+ }
+
+ wchan = get_wchan(tsk);
+ if (lookup_symbol_name(wchan, symname) < 0) {
+ if (!ptrace_may_access(tsk, PTRACE_MODE_READ))
+ sprintf(symname, "_____");
+ else
+ sprintf(symname, "%lu", wchan);
+ }
+
+ while (state) {
+ idx++;
+ state >>= 1;
+ }
+
+ pr_info("%8d %8d %8d %16lld %c(%d) %3d %08x %08x %08x %c %16s [%s]\n",
+ tsk->pid, (int)(tsk->utime), (int)(tsk->stime),
+ tsk->se.exec_start, state_array[idx], (int)(tsk->state),
+ task_cpu(tsk), (int)wchan, (int)pc, (int)tsk,
+ is_main ? '*' : ' ', tsk->comm, symname);
+
+ if (tsk->state == TASK_RUNNING
+ || tsk->state == TASK_UNINTERRUPTIBLE
+ || tsk->mm == NULL) {
+ show_stack(tsk, NULL);
+ pr_info("\n");
+ }
+}
+
+static inline struct task_struct *get_next_thread(struct task_struct *tsk)
+{
+ return container_of(tsk->thread_group.next,
+ struct task_struct,
+ thread_group);
+}
+
+static void dump_all_task_info(void)
+{
+ struct task_struct *frst_tsk;
+ struct task_struct *curr_tsk;
+ struct task_struct *frst_thr;
+ struct task_struct *curr_thr;
+
+ pr_info("\n");
+ pr_info(" current proc : %d %s\n", current->pid, current->comm);
+ pr_info(" -------------------------------------------------------------------------------------------------------------\n");
+ pr_info(" pid uTime sTime exec(ns) stat cpu wchan user_pc task_struct comm sym_wchan\n");
+ pr_info(" -------------------------------------------------------------------------------------------------------------\n");
+
+ /* processes */
+ frst_tsk = &init_task;
+ curr_tsk = frst_tsk;
+ while (curr_tsk != NULL) {
+ dump_one_task_info(curr_tsk, true);
+ /* threads */
+ if (curr_tsk->thread_group.next != NULL) {
+ frst_thr = get_next_thread(curr_tsk);
+ curr_thr = frst_thr;
+ if (frst_thr != curr_tsk) {
+ while (curr_thr != NULL) {
+ dump_one_task_info(curr_thr, false);
+ curr_thr = get_next_thread(curr_thr);
+ if (curr_thr == curr_tsk)
+ break;
+ }
+ }
+ }
+ curr_tsk = container_of(curr_tsk->tasks.next,
+ struct task_struct, tasks);
+ if (curr_tsk == frst_tsk)
+ break;
+ }
+ pr_info(" -----------------------------------------------------------------------------------\n");
+}
+
+#ifndef arch_irq_stat_cpu
+#define arch_irq_stat_cpu(cpu) 0
+#endif
+#ifndef arch_irq_stat
+#define arch_irq_stat() 0
+#endif
+#ifndef arch_idle_time
+#define arch_idle_time(cpu) 0
+#endif
+
+static void dump_cpu_stat(void)
+{
+ int i, j;
+ unsigned long jif;
+ cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
+ cputime64_t guest, guest_nice;
+ u64 sum = 0;
+ u64 sum_softirq = 0;
+ unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
+ struct timespec boottime;
+ unsigned int per_irq_sum;
+
+ char *softirq_to_name[NR_SOFTIRQS] = {
+ "HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
+ "TASKLET", "SCHED", "HRTIMER", "RCU"
+ };
+
+ user = nice = system = idle = iowait = cputime64_zero;
+ irq = softirq = steal = cputime64_zero;
+ guest = guest_nice = cputime64_zero;
+
+ getboottime(&boottime);
+ jif = boottime.tv_sec;
+ for_each_possible_cpu(i) {
+ user = cputime64_add(user, kstat_cpu(i).cpustat.user);
+ nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
+ system = cputime64_add(system, kstat_cpu(i).cpustat.system);
+ idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
+ idle = cputime64_add(idle, arch_idle_time(i));
+ iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
+ irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
+ softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
+
+ for_each_irq_nr(j) {
+ sum += kstat_irqs_cpu(j, i);
+ }
+ sum += arch_irq_stat_cpu(i);
+ for (j = 0; j < NR_SOFTIRQS; j++) {
+ unsigned int softirq_stat = kstat_softirqs_cpu(j, i);
+ per_softirq_sums[j] += softirq_stat;
+ sum_softirq += softirq_stat;
+ }
+ }
+ sum += arch_irq_stat();
+ pr_info("\n");
+ pr_info(" cpu user:%llu nice:%llu system:%llu idle:%llu "
+ "iowait:%llu irq:%llu softirq:%llu %llu %llu " "%llu\n",
+ (unsigned long long)cputime64_to_clock_t(user),
+ (unsigned long long)cputime64_to_clock_t(nice),
+ (unsigned long long)cputime64_to_clock_t(system),
+ (unsigned long long)cputime64_to_clock_t(idle),
+ (unsigned long long)cputime64_to_clock_t(iowait),
+ (unsigned long long)cputime64_to_clock_t(irq),
+ (unsigned long long)cputime64_to_clock_t(softirq),
+ (unsigned long long)0, /* steal */
+ (unsigned long long)0, /* guest */
+ (unsigned long long)0); /* guest_nice */
+ pr_info(" -----------------------------------------------------------------------------------\n");
+ for_each_online_cpu(i) {
+ /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
+ user = kstat_cpu(i).cpustat.user;
+ nice = kstat_cpu(i).cpustat.nice;
+ system = kstat_cpu(i).cpustat.system;
+ idle = kstat_cpu(i).cpustat.idle;
+ idle = cputime64_add(idle, arch_idle_time(i));
+ iowait = kstat_cpu(i).cpustat.iowait;
+ irq = kstat_cpu(i).cpustat.irq;
+ softirq = kstat_cpu(i).cpustat.softirq;
+ /* steal = kstat_cpu(i).cpustat.steal; */
+ /* guest = kstat_cpu(i).cpustat.guest; */
+ /* guest_nice = kstat_cpu(i).cpustat.guest_nice; */
+ pr_info(" cpu %d user:%llu nice:%llu system:%llu "
+ "idle:%llu iowait:%llu irq:%llu softirq:%llu "
+ "%llu %llu " "%llu\n",
+ i,
+ (unsigned long long)cputime64_to_clock_t(user),
+ (unsigned long long)cputime64_to_clock_t(nice),
+ (unsigned long long)cputime64_to_clock_t(system),
+ (unsigned long long)cputime64_to_clock_t(idle),
+ (unsigned long long)cputime64_to_clock_t(iowait),
+ (unsigned long long)cputime64_to_clock_t(irq),
+ (unsigned long long)cputime64_to_clock_t(softirq),
+ (unsigned long long)0, /* steal */
+ (unsigned long long)0, /* guest */
+ (unsigned long long)0); /* guest_nice */
+ }
+ pr_info(" -----------------------------------------------------------------------------------\n");
+ pr_info("\n");
+ pr_info(" irq : %llu", (unsigned long long)sum);
+ pr_info(" -----------------------------------------------------------------------------------\n");
+ /* sum again ? it could be updated? */
+ for_each_irq_nr(j) {
+ per_irq_sum = 0;
+ for_each_possible_cpu(i)
+ per_irq_sum += kstat_irqs_cpu(j, i);
+ if (per_irq_sum) {
+ pr_info(" irq-%4d : %8u %s\n",
+ j, per_irq_sum, irq_to_desc(j)->action ?
+ irq_to_desc(j)->action->name ?: "???" : "???");
+ }
+ }
+ pr_info(" -----------------------------------------------------------------------------------\n");
+ pr_info("\n");
+ pr_info(" softirq : %llu", (unsigned long long)sum_softirq);
+ pr_info(" -----------------------------------------------------------------------------------\n");
+ for (i = 0; i < NR_SOFTIRQS; i++)
+ if (per_softirq_sums[i])
+ pr_info(" softirq-%d : %8u %s\n",
+ i, per_softirq_sums[i], softirq_to_name[i]);
+ pr_info(" -----------------------------------------------------------------------------------\n");
+}
+
+static void dump_state_and_upload(void)
+{
+ if (!sec_debug_level.en.kernel_fault)
+ return;
+
+ sec_debug_set_upload_magic(0x66262564, NULL);
+
+ sec_debug_set_upload_cause(UPLOAD_CAUSE_FORCED_UPLOAD);
+
+ pr_err("(%s) checksum_sched_log: %x\n", __func__, checksum_sched_log());
+
+#ifdef CONFIG_SEC_WATCHDOG_RESET
+ sec_debug_disable_watchdog();
+#endif
+ dump_all_task_info();
+ dump_cpu_stat();
+
+ show_state_filter(TASK_STATE_MAX); /* no backtrace */
+
+ sec_debug_dump_stack();
+ sec_debug_hw_reset();
+}
+#endif /* CONFIG_SEC_DEBUG_FUPLOAD_DUMP_MORE */
diff --git a/arch/arm/mach-exynos/sec_gaf.c b/arch/arm/mach-exynos/sec_gaf.c
new file mode 100644
index 0000000..a8aa7f0
--- /dev/null
+++ b/arch/arm/mach-exynos/sec_gaf.c
@@ -0,0 +1,224 @@
+/*
+ * sec_gaf.c
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <asm/pgtable.h>
+
+static struct GAForensicINFO {
+ unsigned short ver;
+ unsigned int size;
+ unsigned short task_struct_struct_state;
+ unsigned short task_struct_struct_comm;
+ unsigned short task_struct_struct_tasks;
+ unsigned short task_struct_struct_pid;
+ unsigned short task_struct_struct_stack;
+ unsigned short task_struct_struct_mm;
+ unsigned short mm_struct_struct_start_data;
+ unsigned short mm_struct_struct_end_data;
+ unsigned short mm_struct_struct_start_brk;
+ unsigned short mm_struct_struct_brk;
+ unsigned short mm_struct_struct_start_stack;
+ unsigned short mm_struct_struct_arg_start;
+ unsigned short mm_struct_struct_arg_end;
+ unsigned short mm_struct_struct_pgd;
+ unsigned short mm_struct_struct_mmap;
+ unsigned short vm_area_struct_struct_vm_start;
+ unsigned short vm_area_struct_struct_vm_end;
+ unsigned short vm_area_struct_struct_vm_next;
+ unsigned short vm_area_struct_struct_vm_file;
+ unsigned short thread_info_struct_cpu_context;
+ unsigned short cpu_context_save_struct_sp;
+ unsigned short file_struct_f_path;
+ unsigned short path_struct_mnt;
+ unsigned short path_struct_dentry;
+ unsigned short dentry_struct_d_parent;
+ unsigned short dentry_struct_d_name;
+ unsigned short qstr_struct_name;
+ unsigned short vfsmount_struct_mnt_mountpoint;
+ unsigned short vfsmount_struct_mnt_root;
+ unsigned short vfsmount_struct_mnt_parent;
+ unsigned int pgdir_shift;
+ unsigned int ptrs_per_pte;
+ unsigned int phys_offset;
+ unsigned int page_offset;
+ unsigned int page_shift;
+ unsigned int page_size;
+ unsigned short task_struct_struct_thread_group;
+ unsigned short task_struct_struct_utime;
+ unsigned short task_struct_struct_stime;
+ unsigned short list_head_struct_next;
+ unsigned short list_head_struct_prev;
+ unsigned short rq_struct_curr;
+
+ unsigned short thread_info_struct_cpu;
+
+ unsigned short task_struct_struct_prio;
+ unsigned short task_struct_struct_static_prio;
+ unsigned short task_struct_struct_normal_prio;
+ unsigned short task_struct_struct_rt_priority;
+
+ unsigned short task_struct_struct_se;
+
+ unsigned short sched_entity_struct_exec_start;
+ unsigned short sched_entity_struct_sum_exec_runtime;
+ unsigned short sched_entity_struct_prev_sum_exec_runtime;
+
+ unsigned short task_struct_struct_sched_info;
+
+ unsigned short sched_info_struct_pcount;
+ unsigned short sched_info_struct_run_delay;
+ unsigned short sched_info_struct_last_arrival;
+ unsigned short sched_info_struct_last_queued;
+
+ unsigned short task_struct_struct_blocked_on;
+
+ unsigned short mutex_waiter_struct_list;
+ unsigned short mutex_waiter_struct_task;
+
+ unsigned short sched_entity_struct_cfs_rq_struct;
+ unsigned short cfs_rq_struct_rq_struct;
+ unsigned short gaf_fp;
+ unsigned short GAFINFOCheckSum;
+} GAFINFO = {
+ .ver = 0x0300, /* by dh3s.choi 2010 12 14 */
+ .size = sizeof(GAFINFO),
+ .task_struct_struct_state = offsetof(struct task_struct, state),
+ .task_struct_struct_comm = offsetof(struct task_struct, comm),
+ .task_struct_struct_tasks = offsetof(struct task_struct, tasks),
+ .task_struct_struct_pid = offsetof(struct task_struct, pid),
+ .task_struct_struct_stack = offsetof(struct task_struct, stack),
+ .task_struct_struct_mm = offsetof(struct task_struct, mm),
+ .mm_struct_struct_start_data = offsetof(struct mm_struct, start_data),
+ .mm_struct_struct_end_data = offsetof(struct mm_struct, end_data),
+ .mm_struct_struct_start_brk = offsetof(struct mm_struct, start_brk),
+ .mm_struct_struct_brk = offsetof(struct mm_struct, brk),
+ .mm_struct_struct_start_stack = offsetof(struct mm_struct, start_stack),
+ .mm_struct_struct_arg_start = offsetof(struct mm_struct, arg_start),
+ .mm_struct_struct_arg_end = offsetof(struct mm_struct, arg_end),
+ .mm_struct_struct_pgd = offsetof(struct mm_struct, pgd),
+ .mm_struct_struct_mmap = offsetof(struct mm_struct, mmap),
+ .vm_area_struct_struct_vm_start = offsetof(struct vm_area_struct, vm_start),
+ .vm_area_struct_struct_vm_end = offsetof(struct vm_area_struct, vm_end),
+ .vm_area_struct_struct_vm_next = offsetof(struct vm_area_struct, vm_next),
+ .vm_area_struct_struct_vm_file = offsetof(struct vm_area_struct, vm_file),
+ .thread_info_struct_cpu_context = offsetof(struct thread_info, cpu_context),
+ .cpu_context_save_struct_sp = offsetof(struct cpu_context_save, sp),
+ .file_struct_f_path = offsetof(struct file, f_path),
+ .path_struct_mnt = offsetof(struct path, mnt),
+ .path_struct_dentry = offsetof(struct path, dentry),
+ .dentry_struct_d_parent = offsetof(struct dentry, d_parent),
+ .dentry_struct_d_name = offsetof(struct dentry, d_name),
+ .qstr_struct_name = offsetof(struct qstr, name),
+ .vfsmount_struct_mnt_mountpoint = offsetof(struct vfsmount, mnt_mountpoint),
+ .vfsmount_struct_mnt_root = offsetof(struct vfsmount, mnt_root),
+ .vfsmount_struct_mnt_parent = offsetof(struct vfsmount, mnt_parent),
+ .pgdir_shift = PGDIR_SHIFT,
+ .ptrs_per_pte = PTRS_PER_PTE,
+ /* .phys_offset = PHYS_OFFSET, */
+ .page_offset = PAGE_OFFSET,
+ .page_shift = PAGE_SHIFT,
+ .page_size = PAGE_SIZE,
+ .task_struct_struct_thread_group = offsetof(struct task_struct, thread_group),
+ .task_struct_struct_utime = offsetof(struct task_struct, utime),
+ .task_struct_struct_stime = offsetof(struct task_struct, stime),
+ .list_head_struct_next = offsetof(struct list_head, next),
+ .list_head_struct_prev = offsetof(struct list_head, prev),
+
+ .rq_struct_curr = 0,
+
+ .thread_info_struct_cpu = offsetof(struct thread_info, cpu),
+
+ .task_struct_struct_prio = offsetof(struct task_struct, prio),
+ .task_struct_struct_static_prio = offsetof(struct task_struct, static_prio),
+ .task_struct_struct_normal_prio = offsetof(struct task_struct, normal_prio),
+ .task_struct_struct_rt_priority = offsetof(struct task_struct, rt_priority),
+
+ .task_struct_struct_se = offsetof(struct task_struct, se),
+
+ .sched_entity_struct_exec_start = offsetof(struct sched_entity, exec_start),
+ .sched_entity_struct_sum_exec_runtime = offsetof(struct sched_entity, sum_exec_runtime),
+ .sched_entity_struct_prev_sum_exec_runtime = offsetof(struct sched_entity, prev_sum_exec_runtime),
+
+#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
+ .task_struct_struct_sched_info = offsetof(struct task_struct, sched_info),
+ .sched_info_struct_pcount = offsetof(struct sched_info, pcount),
+ .sched_info_struct_run_delay = offsetof(struct sched_info, run_delay),
+ .sched_info_struct_last_arrival = offsetof(struct sched_info, last_arrival),
+ .sched_info_struct_last_queued = offsetof(struct sched_info, last_queued),
+#else
+ .task_struct_struct_sched_info = 0x1223,
+ .sched_info_struct_pcount = 0x1224,
+ .sched_info_struct_run_delay = 0x1225,
+ .sched_info_struct_last_arrival = 0x1226,
+ .sched_info_struct_last_queued = 0x1227,
+#endif
+
+#ifdef CONFIG_DEBUG_MUTEXES
+ .task_struct_struct_blocked_on = offsetof(struct task_struct, blocked_on),
+ .mutex_waiter_struct_list = offsetof(struct mutex_waiter, list),
+ .mutex_waiter_struct_task = offsetof(struct mutex_waiter, task),
+#else
+ .task_struct_struct_blocked_on = 0x1228,
+ .mutex_waiter_struct_list = 0x1229,
+ .mutex_waiter_struct_task = 0x122a,
+#endif
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ .sched_entity_struct_cfs_rq_struct = offsetof(struct sched_entity, cfs_rq),
+#else
+ .sched_entity_struct_cfs_rq_struct = 0x1223,
+#endif
+
+ .cfs_rq_struct_rq_struct = 0,
+
+#ifdef CONFIG_FRAME_POINTER
+ .gaf_fp = 1,
+#else
+ .gaf_fp = 0,
+#endif
+
+ .GAFINFOCheckSum = 0
+};
+
+void sec_gaf_supply_rqinfo(unsigned short curr_offset, unsigned short rq_offset)
+{
+ unsigned short *checksum = &(GAFINFO.GAFINFOCheckSum);
+ unsigned char *memory = (unsigned char *)&GAFINFO;
+ unsigned char address;
+ /*
+ * Add GAForensic init for preventing symbol removal for optimization.
+ */
+ GAFINFO.phys_offset = PHYS_OFFSET;
+ GAFINFO.rq_struct_curr = curr_offset;
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ GAFINFO.cfs_rq_struct_rq_struct = rq_offset;
+#else
+ GAFINFO.cfs_rq_struct_rq_struct = 0x1224;
+#endif
+
+ for (*checksum = 0, address = 0;
+ address < (sizeof(GAFINFO) - sizeof(GAFINFO.GAFINFOCheckSum));
+ address++) {
+ if ((*checksum) & 0x8000)
+ (*checksum) =
+ (((*checksum) << 1) | 1) ^ memory[address];
+ else
+ (*checksum) = ((*checksum) << 1) ^ memory[address];
+ }
+}
+EXPORT_SYMBOL(sec_gaf_supply_rqinfo);
+
+static int __init sec_gaf_init(void)
+{
+ GAFINFO.phys_offset = PHYS_OFFSET;
+ return 0;
+}
+
+core_initcall(sec_gaf_init);
diff --git a/arch/arm/mach-exynos/sec_getlog.c b/arch/arm/mach-exynos/sec_getlog.c
new file mode 100644
index 0000000..06a0be6
--- /dev/null
+++ b/arch/arm/mach-exynos/sec_getlog.c
@@ -0,0 +1,126 @@
+/*
+ * sec_getlog.c
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/setup.h>
+
+static struct {
+ u32 special_mark_1;
+ u32 special_mark_2;
+ u32 special_mark_3;
+ u32 special_mark_4;
+ void *p_fb; /* it must be physical address */
+ u32 xres;
+ u32 yres;
+ u32 bpp; /* color depth : 16 or 24 */
+ u32 frames; /* frame buffer count : 2 */
+} frame_buf_mark = {
+ .special_mark_1 = (('*' << 24) | ('^' << 16) | ('^' << 8) | ('*' << 0)),
+ .special_mark_2 = (('I' << 24) | ('n' << 16) | ('f' << 8) | ('o' << 0)),
+ .special_mark_3 = (('H' << 24) | ('e' << 16) | ('r' << 8) | ('e' << 0)),
+ .special_mark_4 = (('f' << 24) | ('b' << 16) | ('u' << 8) | ('f' << 0)),
+};
+
+void sec_getlog_supply_fbinfo(void *p_fb, u32 xres, u32 yres, u32 bpp,
+ u32 frames)
+{
+ if (p_fb) {
+ pr_info("%s: 0x%p %d %d %d %d\n", __func__, p_fb, xres, yres,
+ bpp, frames);
+ frame_buf_mark.p_fb = p_fb;
+ frame_buf_mark.xres = xres;
+ frame_buf_mark.yres = yres;
+ frame_buf_mark.bpp = bpp;
+ frame_buf_mark.frames = frames;
+ }
+}
+EXPORT_SYMBOL(sec_getlog_supply_fbinfo);
+
+static struct {
+ u32 special_mark_1;
+ u32 special_mark_2;
+ u32 special_mark_3;
+ u32 special_mark_4;
+ u32 log_mark_version;
+ u32 framebuffer_mark_version;
+ void *this; /* this is used for addressing
+ log buffer in 2 dump files */
+ struct {
+ u32 size; /* memory block's size */
+ u32 addr; /* memory block'sPhysical address */
+ } mem[2];
+} marks_ver_mark = {
+ .special_mark_1 = (('*' << 24) | ('^' << 16) | ('^' << 8) | ('*' << 0)),
+ .special_mark_2 = (('I' << 24) | ('n' << 16) | ('f' << 8) | ('o' << 0)),
+ .special_mark_3 = (('H' << 24) | ('e' << 16) | ('r' << 8) | ('e' << 0)),
+ .special_mark_4 = (('v' << 24) | ('e' << 16) | ('r' << 8) | ('s' << 0)),
+ .log_mark_version = 1,
+ .framebuffer_mark_version = 1,
+ .this = &marks_ver_mark,
+};
+
+/* mark for GetLog extraction */
+static struct {
+ u32 special_mark_1;
+ u32 special_mark_2;
+ u32 special_mark_3;
+ u32 special_mark_4;
+ void *p_main;
+ void *p_radio;
+ void *p_events;
+ void *p_system;
+} plat_log_mark = {
+ .special_mark_1 = (('*' << 24) | ('^' << 16) | ('^' << 8) | ('*' << 0)),
+ .special_mark_2 = (('I' << 24) | ('n' << 16) | ('f' << 8) | ('o' << 0)),
+ .special_mark_3 = (('H' << 24) | ('e' << 16) | ('r' << 8) | ('e' << 0)),
+ .special_mark_4 = (('p' << 24) | ('l' << 16) | ('o' << 8) | ('g' << 0)),
+};
+
+void sec_getlog_supply_loggerinfo(void *p_main,
+ void *p_radio, void *p_events, void *p_system)
+{
+ pr_info("%s: 0x%p 0x%p 0x%p 0x%p\n", __func__, p_main, p_radio,
+ p_events, p_system);
+ plat_log_mark.p_main = p_main;
+ plat_log_mark.p_radio = p_radio;
+ plat_log_mark.p_events = p_events;
+ plat_log_mark.p_system = p_system;
+}
+EXPORT_SYMBOL(sec_getlog_supply_loggerinfo);
+
+static struct {
+ u32 special_mark_1;
+ u32 special_mark_2;
+ u32 special_mark_3;
+ u32 special_mark_4;
+ void *klog_buf;
+} kernel_log_mark = {
+ .special_mark_1 = (('*' << 24) | ('^' << 16) | ('^' << 8) | ('*' << 0)),
+ .special_mark_2 = (('I' << 24) | ('n' << 16) | ('f' << 8) | ('o' << 0)),
+ .special_mark_3 = (('H' << 24) | ('e' << 16) | ('r' << 8) | ('e' << 0)),
+ .special_mark_4 = (('k' << 24) | ('l' << 16) | ('o' << 8) | ('g' << 0)),
+};
+
+void sec_getlog_supply_kloginfo(void *klog_buf)
+{
+ pr_info("%s: 0x%p\n", __func__, klog_buf);
+ kernel_log_mark.klog_buf = klog_buf;
+}
+EXPORT_SYMBOL(sec_getlog_supply_kloginfo);
+
+static int __init sec_getlog_init(void)
+{
+ marks_ver_mark.mem[0].size =
+ meminfo.bank[0].size + meminfo.bank[1].size;
+ marks_ver_mark.mem[0].addr = meminfo.bank[0].start;
+ marks_ver_mark.mem[1].size =
+ meminfo.bank[2].size + meminfo.bank[3].size;
+ marks_ver_mark.mem[1].addr = meminfo.bank[2].start;
+
+ return 0;
+}
+
+core_initcall(sec_getlog_init);
diff --git a/arch/arm/mach-exynos/sec_log.c b/arch/arm/mach-exynos/sec_log.c
new file mode 100644
index 0000000..b55e7da
--- /dev/null
+++ b/arch/arm/mach-exynos/sec_log.c
@@ -0,0 +1,171 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+
+#include <mach/sec_debug.h>
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+#include <asm/mach/map.h>
+
+/*
+ * Example usage: sec_log=256K@0x45000000
+ * In above case, log_buf size is 256KB and its base address is
+ * 0x45000000 physically. Actually, *(int *)(base - 8) is log_magic and
+ * *(int *)(base - 4) is log_ptr. So we reserve (size + 8) bytes from
+ * (base - 8).
+ */
+#define LOG_MAGIC 0x4d474f4c /* "LOGM" */
+
+/* These variables are also protected by logbuf_lock */
+static unsigned *sec_log_ptr;
+static char *sec_log_buf;
+static unsigned sec_log_size;
+
+#ifdef CONFIG_SEC_LOG_LAST_KMSG
+static char *last_kmsg_buffer;
+static unsigned last_kmsg_size;
+static void __init sec_log_save_old(void);
+#else
+static inline void sec_log_save_old(void)
+{
+}
+#endif
+
+extern void register_log_char_hook(void (*f) (char c));
+
+#ifdef CONFIG_SEC_LOG_NONCACHED
+static struct map_desc log_buf_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_KLOG_BUF,
+ .type = MT_DEVICE
+ }
+};
+#endif
+
+static inline void emit_sec_log_char(char c)
+{
+ if (sec_log_buf && sec_log_ptr) {
+ sec_log_buf[*sec_log_ptr & (sec_log_size - 1)] = c;
+ (*sec_log_ptr)++;
+ }
+}
+
+static int __init sec_log_setup(char *str)
+{
+ unsigned size = memparse(str, &str);
+ unsigned long base = 0;
+ unsigned *sec_log_mag;
+
+ /* If we encounter any problem parsing str ... */
+ if (!size || size != roundup_pow_of_two(size) || *str != '@'
+ || kstrtoul(str + 1, 0, &base))
+ goto out;
+
+ if (reserve_bootmem(base - 8, size + 8, BOOTMEM_EXCLUSIVE)) {
+ pr_err("%s: failed reserving size %d + 8 "
+ "at base 0x%lx - 8\n", __func__, size, base);
+ goto out;
+ }
+#ifdef CONFIG_SEC_LOG_NONCACHED
+ log_buf_iodesc[0].pfn = __phys_to_pfn((unsigned long)base - 0x100000);
+ log_buf_iodesc[0].length = (unsigned long)(size + 0x100000);
+ iotable_init(log_buf_iodesc, ARRAY_SIZE(log_buf_iodesc));
+ sec_log_mag = (S3C_VA_KLOG_BUF + 0x100000) - 8;
+ sec_log_ptr = (S3C_VA_KLOG_BUF + 0x100000) - 4;
+ sec_log_buf = S3C_VA_KLOG_BUF + 0x100000;
+#else
+ sec_log_mag = phys_to_virt(base) - 8;
+ sec_log_ptr = phys_to_virt(base) - 4;
+ sec_log_buf = phys_to_virt(base);
+#endif
+ sec_log_size = size;
+ pr_info("%s: *sec_log_mag:%x *sec_log_ptr:%x "
+ "sec_log_buf:%p sec_log_size:%d\n",
+ __func__, *sec_log_mag, *sec_log_ptr, sec_log_buf,
+ sec_log_size);
+
+ if (*sec_log_mag != LOG_MAGIC) {
+ pr_info("%s: no old log found\n", __func__);
+ *sec_log_ptr = 0;
+ *sec_log_mag = LOG_MAGIC;
+ } else
+ sec_log_save_old();
+
+ register_log_char_hook(emit_sec_log_char);
+
+ sec_getlog_supply_kloginfo(phys_to_virt(base));
+
+out:
+ return 0;
+}
+
+__setup("sec_log=", sec_log_setup);
+
+#ifdef CONFIG_SEC_LOG_LAST_KMSG
+static void __init sec_log_save_old(void)
+{
+ /* provide previous log as last_kmsg */
+ last_kmsg_size =
+ min((unsigned)(1 << CONFIG_LOG_BUF_SHIFT), *sec_log_ptr);
+ last_kmsg_buffer = (char *)alloc_bootmem(last_kmsg_size);
+
+ if (last_kmsg_size && last_kmsg_buffer) {
+ unsigned i;
+ for (i = 0; i < last_kmsg_size; i++)
+ last_kmsg_buffer[i] =
+ sec_log_buf[(*sec_log_ptr - last_kmsg_size +
+ i) & (sec_log_size - 1)];
+
+ pr_info("%s: saved old log at %d@%p\n",
+ __func__, last_kmsg_size, last_kmsg_buffer);
+ } else
+ pr_err("%s: failed saving old log %d@%p\n",
+ __func__, last_kmsg_size, last_kmsg_buffer);
+}
+
+static ssize_t sec_log_read_old(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ loff_t pos = *offset;
+ ssize_t count;
+
+ if (pos >= last_kmsg_size)
+ return 0;
+
+ count = min(len, (size_t) (last_kmsg_size - pos));
+ if (copy_to_user(buf, last_kmsg_buffer + pos, count))
+ return -EFAULT;
+
+ *offset += count;
+ return count;
+}
+
+static const struct file_operations last_kmsg_file_ops = {
+ .owner = THIS_MODULE,
+ .read = sec_log_read_old,
+};
+
+static int __init sec_log_late_init(void)
+{
+ struct proc_dir_entry *entry;
+
+ if (last_kmsg_buffer == NULL)
+ return 0;
+
+ entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
+ if (!entry) {
+ pr_err("%s: failed to create proc entry\n", __func__);
+ return 0;
+ }
+
+ entry->proc_fops = &last_kmsg_file_ops;
+ entry->size = last_kmsg_size;
+ return 0;
+}
+
+late_initcall(sec_log_late_init);
+#endif
diff --git a/arch/arm/mach-exynos/sec_thermistor.c b/arch/arm/mach-exynos/sec_thermistor.c
new file mode 100644
index 0000000..2ae7ef3
--- /dev/null
+++ b/arch/arm/mach-exynos/sec_thermistor.c
@@ -0,0 +1,285 @@
+/* sec_thermistor.c
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <plat/adc.h>
+#include <mach/sec_thermistor.h>
+
+#define ADC_SAMPLING_CNT 7
+
+struct sec_therm_info {
+ struct device *dev;
+ struct sec_therm_platform_data *pdata;
+ struct s3c_adc_client *padc;
+ struct delayed_work polling_work;
+
+ int curr_temperature;
+ int curr_temp_adc;
+};
+
+static ssize_t sec_therm_show_temperature(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct sec_therm_info *info = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", info->curr_temperature);
+}
+
+static ssize_t sec_therm_show_temp_adc(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct sec_therm_info *info = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", info->curr_temp_adc);
+}
+
+static DEVICE_ATTR(temperature, S_IRUGO, sec_therm_show_temperature, NULL);
+static DEVICE_ATTR(temp_adc, S_IRUGO, sec_therm_show_temp_adc, NULL);
+
+static struct attribute *sec_therm_attributes[] = {
+ &dev_attr_temperature.attr,
+ &dev_attr_temp_adc.attr,
+ NULL
+};
+
+static const struct attribute_group sec_therm_group = {
+ .attrs = sec_therm_attributes,
+};
+
+static int sec_therm_get_adc_data(struct sec_therm_info *info)
+{
+ int adc_ch;
+ int adc_data;
+ int adc_max = 0;
+ int adc_min = 0;
+ int adc_total = 0;
+ int i;
+ int err_value;
+
+ adc_ch = info->pdata->adc_channel;
+
+ for (i = 0; i < ADC_SAMPLING_CNT; i++) {
+ adc_data = s3c_adc_read(info->padc, adc_ch);
+
+ if (adc_data < 0) {
+ dev_err(info->dev, "%s : err(%d) returned, skip read\n",
+ __func__, adc_data);
+ err_value = adc_data;
+ goto err;
+ }
+
+ if (i != 0) {
+ if (adc_data > adc_max)
+ adc_max = adc_data;
+ else if (adc_data < adc_min)
+ adc_min = adc_data;
+ } else {
+ adc_max = adc_data;
+ adc_min = adc_data;
+ }
+ adc_total += adc_data;
+ }
+
+ return (adc_total - adc_max - adc_min) / (ADC_SAMPLING_CNT - 2);
+err:
+ return err_value;
+}
+
+static int convert_adc_to_temper(struct sec_therm_info *info, unsigned int adc)
+{
+ int low = 0;
+ int high = 0;
+ int mid = 0;
+
+ if (!info->pdata->adc_table || !info->pdata->adc_arr_size) {
+ /* using fake temp */
+ return 300;
+ }
+
+ high = info->pdata->adc_arr_size - 1;
+
+ while (low <= high) {
+ mid = (low + high) / 2;
+ if (info->pdata->adc_table[mid].adc > adc)
+ high = mid - 1;
+ else if (info->pdata->adc_table[mid].adc < adc)
+ low = mid + 1;
+ else
+ break;
+ }
+ return info->pdata->adc_table[mid].temperature;
+}
+
+static void notify_change_of_temperature(struct sec_therm_info *info)
+{
+ char temp_buf[20];
+ char siop_buf[20];
+ char *envp[2];
+ int env_offset = 0;
+ int siop_level = -1;
+
+ snprintf(temp_buf, sizeof(temp_buf), "TEMPERATURE=%d",
+ info->curr_temperature);
+ envp[env_offset++] = temp_buf;
+
+ if (info->pdata->get_siop_level)
+ siop_level =
+ info->pdata->get_siop_level(info->curr_temperature);
+ if (siop_level >= 0) {
+ snprintf(siop_buf, sizeof(siop_buf), "SIOP_LEVEL=%d",
+ siop_level);
+ envp[env_offset++] = siop_buf;
+ dev_info(info->dev, "%s: uevent: %s\n", __func__, siop_buf);
+ }
+ envp[env_offset] = NULL;
+
+ dev_info(info->dev, "%s: uevent: %s\n", __func__, temp_buf);
+ kobject_uevent_env(&info->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+static void sec_therm_polling_work(struct work_struct *work)
+{
+ struct sec_therm_info *info =
+ container_of(work, struct sec_therm_info, polling_work.work);
+ int adc;
+ int temper;
+
+ adc = sec_therm_get_adc_data(info);
+ dev_dbg(info->dev, "%s: adc=%d\n", __func__, adc);
+
+ if (adc < 0)
+ goto out;
+
+ temper = convert_adc_to_temper(info, adc);
+ dev_dbg(info->dev, "%s: temper=%d\n", __func__, temper);
+
+ /* if temperature was changed, notify to framework */
+ if (info->curr_temperature != temper) {
+ info->curr_temp_adc = adc;
+ info->curr_temperature = temper;
+ notify_change_of_temperature(info);
+ }
+out:
+ schedule_delayed_work(&info->polling_work,
+ msecs_to_jiffies(info->pdata->polling_interval));
+}
+
+static __devinit int sec_therm_probe(struct platform_device *pdev)
+{
+ struct sec_therm_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct sec_therm_info *info;
+ int ret = 0;
+
+ dev_info(&pdev->dev, "%s: SEC Thermistor Driver Loading\n", __func__);
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, info);
+
+ info->dev = &pdev->dev;
+ info->pdata = pdata;
+
+ info->padc = s3c_adc_register(pdev, NULL, NULL, 0);
+
+ ret = sysfs_create_group(&info->dev->kobj, &sec_therm_group);
+
+ if (ret) {
+ dev_err(info->dev,
+ "failed to create sysfs attribute group\n");
+ }
+
+ INIT_DELAYED_WORK_DEFERRABLE(&info->polling_work,
+ sec_therm_polling_work);
+ schedule_delayed_work(&info->polling_work,
+ msecs_to_jiffies(info->pdata->polling_interval));
+
+ return ret;
+}
+
+static int __devexit sec_therm_remove(struct platform_device *pdev)
+{
+ struct sec_therm_info *info = platform_get_drvdata(pdev);
+
+ if (!info)
+ return 0;
+
+ sysfs_remove_group(&info->dev->kobj, &sec_therm_group);
+
+ cancel_delayed_work(&info->polling_work);
+ s3c_adc_release(info->padc);
+ kfree(info);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sec_therm_suspend(struct device *dev)
+{
+ struct sec_therm_info *info = dev_get_drvdata(dev);
+
+ cancel_delayed_work(&info->polling_work);
+
+ return 0;
+}
+
+static int sec_therm_resume(struct device *dev)
+{
+ struct sec_therm_info *info = dev_get_drvdata(dev);
+
+ schedule_delayed_work(&info->polling_work,
+ msecs_to_jiffies(info->pdata->polling_interval));
+ return 0;
+}
+#else
+#define sec_therm_suspend NULL
+#define sec_therm_resume NULL
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops sec_thermistor_pm_ops = {
+ .suspend = sec_therm_suspend,
+ .resume = sec_therm_resume,
+};
+
+static struct platform_driver sec_thermistor_driver = {
+ .driver = {
+ .name = "sec-thermistor",
+ .owner = THIS_MODULE,
+ .pm = &sec_thermistor_pm_ops,
+ },
+ .probe = sec_therm_probe,
+ .remove = __devexit_p(sec_therm_remove),
+};
+
+static int __init sec_therm_init(void)
+{
+ return platform_driver_register(&sec_thermistor_driver);
+}
+module_init(sec_therm_init);
+
+static void __exit sec_therm_exit(void)
+{
+ platform_driver_unregister(&sec_thermistor_driver);
+}
+module_exit(sec_therm_exit);
+
+MODULE_AUTHOR("ms925.kim@samsung.com");
+MODULE_DESCRIPTION("sec thermistor driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/sec_watchdog.c b/arch/arm/mach-exynos/sec_watchdog.c
new file mode 100644
index 0000000..b903b80
--- /dev/null
+++ b/arch/arm/mach-exynos/sec_watchdog.c
@@ -0,0 +1,205 @@
+/* sec_watchdog.c copied from herring-watchdog.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <plat/regs-watchdog.h>
+#include <mach/map.h>
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/cpu.h>
+
+#ifdef CONFIG_SEC_DEBUG
+#include <mach/sec_debug.h>
+#endif
+
+/* PCLK(=PERIR=ACLK_100)/256/128 (~3200:1s) */
+#define TPS 3200
+#if defined(CONFIG_MACH_P4) && defined(CONFIG_TARGET_LOCALE_USA)
+#define PET_BY_WORKQUEUE
+#else
+#define PET_BY_DIRECT_TIMER
+#endif
+
+/* reset timeout in seconds */
+static unsigned watchdog_reset = 20;
+module_param_named(sec_reset, watchdog_reset, uint, 0644);
+
+/* pet timeout in seconds
+ * 0 means off, 5 is proper */
+static unsigned watchdog_pet = CONFIG_SEC_WATCHDOG_PET_TIME;
+module_param_named(sec_pet, watchdog_pet, uint, 0644);
+
+#if defined(PET_BY_WORKQUEUE)
+static struct workqueue_struct *watchdog_wq;
+static void watchdog_workfunc(struct work_struct *work);
+static DECLARE_DELAYED_WORK(watchdog_work, watchdog_workfunc);
+#elif defined(PET_BY_DIRECT_TIMER)
+static struct timer_list pet_watchdog_timer;
+static void pet_watchdog_timer_fn(unsigned long data);
+#else
+static struct hrtimer watchdog_timer;
+static enum hrtimer_restart watchdog_timerfunc(struct hrtimer *timer);
+#endif
+
+static struct clk *wd_clk;
+static spinlock_t wdt_lock;
+
+#if defined(PET_BY_WORKQUEUE)
+static void watchdog_workfunc(struct work_struct *work)
+{
+ pr_info("%s kicking...%x\n", __func__, readl(S3C2410_WTCNT));
+ writel(watchdog_reset * TPS, S3C2410_WTCNT);
+ queue_delayed_work_on(0, watchdog_wq, &watchdog_work,
+ watchdog_pet * HZ);
+}
+#elif defined(PET_BY_DIRECT_TIMER)
+static void pet_watchdog_timer_fn(unsigned long data)
+{
+ pr_info("%s kicking...%x\n", __func__, readl(S3C2410_WTCNT));
+ writel(watchdog_reset * TPS, S3C2410_WTCNT);
+ pet_watchdog_timer.expires += watchdog_pet * HZ;
+ add_timer_on(&pet_watchdog_timer, 0);
+}
+#else
+static enum hrtimer_restart watchdog_timerfunc(struct hrtimer *timer)
+{
+ pr_info("%s kicking...%x\n", __func__, readl(S3C2410_WTCNT));
+ writel(watchdog_reset * TPS, S3C2410_WTCNT);
+ hrtimer_start(&watchdog_timer,
+ ktime_set(watchdog_pet, 0), HRTIMER_MODE_REL);
+ return HRTIMER_NORESTART;
+}
+#endif
+
+static void watchdog_start(void)
+{
+ unsigned int val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&wdt_lock, flags);
+
+ /* set to PCLK / 256 / 128 */
+ val = S3C2410_WTCON_DIV128;
+ val |= S3C2410_WTCON_PRESCALE(255);
+ writel(val, S3C2410_WTCON);
+
+ /* program initial count */
+ writel(watchdog_reset * TPS, S3C2410_WTCNT);
+ writel(watchdog_reset * TPS, S3C2410_WTDAT);
+
+ /* start timer */
+ val |= S3C2410_WTCON_RSTEN | S3C2410_WTCON_ENABLE;
+ writel(val, S3C2410_WTCON);
+ spin_unlock_irqrestore(&wdt_lock, flags);
+
+ /* make sure we're ready to pet the dog */
+#if defined(PET_BY_WORKQUEUE)
+ queue_delayed_work_on(0, watchdog_wq, &watchdog_work,
+ watchdog_pet * HZ);
+#elif defined(PET_BY_DIRECT_TIMER)
+ pet_watchdog_timer.expires = jiffies + watchdog_pet * HZ;
+ add_timer_on(&pet_watchdog_timer, 0);
+#else
+ hrtimer_start(&watchdog_timer,
+ ktime_set(watchdog_pet, 0), HRTIMER_MODE_REL);
+#endif
+}
+
+static void watchdog_stop(void)
+{
+ writel(0, S3C2410_WTCON);
+#if defined(PET_BY_WORKQUEUE)
+ /* do nothing? */
+#elif defined(PET_BY_DIRECT_TIMER)
+ del_timer(&pet_watchdog_timer);
+#else
+ hrtimer_cancel(&watchdog_timer);
+#endif
+}
+
+static int watchdog_probe(struct platform_device *pdev)
+{
+ wd_clk = clk_get(NULL, "watchdog");
+ BUG_ON(!wd_clk);
+ clk_enable(wd_clk);
+
+ spin_lock_init(&wdt_lock);
+
+ /* watchdog can be disabled by providing either
+ * "exynos4210_watchdog.sec_pet=0" or
+ * "exynos4210_watchdog.sec_reset=0" to CMDLINE */
+ if (!watchdog_reset || !watchdog_pet) {
+ clk_disable(wd_clk);
+ return -ENODEV;
+ }
+
+#if defined(PET_BY_WORKQUEUE)
+ watchdog_wq = create_singlethread_workqueue("pet_watchdog");
+ watchdog_start();
+#elif defined(PET_BY_DIRECT_TIMER)
+ init_timer(&pet_watchdog_timer);
+ pet_watchdog_timer.function = pet_watchdog_timer_fn;
+ watchdog_start();
+#else
+ hrtimer_init(&watchdog_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ watchdog_timer.function = watchdog_timerfunc;
+ watchdog_start();
+#endif
+
+ return 0;
+}
+
+static int watchdog_suspend(struct device *dev)
+{
+ watchdog_stop();
+ return 0;
+}
+
+static int watchdog_resume(struct device *dev)
+{
+ watchdog_start();
+ return 0;
+}
+
+static const struct dev_pm_ops watchdog_pm_ops = {
+ .suspend_noirq = watchdog_suspend,
+ .resume_noirq = watchdog_resume,
+};
+
+static struct platform_driver watchdog_driver = {
+ .probe = watchdog_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "watchdog-reset",
+ .pm = &watchdog_pm_ops,
+ },
+};
+
+static int __init watchdog_init(void)
+{
+ return platform_driver_register(&watchdog_driver);
+}
+
+module_init(watchdog_init);
diff --git a/arch/arm/mach-exynos/secmem-allocdev.c b/arch/arm/mach-exynos/secmem-allocdev.c
new file mode 100644
index 0000000..ce0b3d4
--- /dev/null
+++ b/arch/arm/mach-exynos/secmem-allocdev.c
@@ -0,0 +1,331 @@
+/*
+ * arch/arm/mach-exynos/secmem-allocdev.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/cma.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/memory.h>
+#include <asm/cacheflush.h>
+
+#include <plat/devs.h>
+#include <plat/pd.h>
+
+#include <mach/secmem.h>
+#include <mach/dev.h>
+
+#define MFC_SEC_MAGIC_CHUNK0 0x13cdbf16
+#define MFC_SEC_MAGIC_CHUNK1 0x8b803342
+#define MFC_SEC_MAGIC_CHUNK2 0x5e87f4f5
+#define MFC_SEC_MAGIC_CHUNK3 0x3bd05317
+
+struct miscdevice secmem;
+struct secmem_crypto_driver_ftn *crypto_driver;
+#if defined(CONFIG_ION)
+extern struct ion_device *ion_exynos;
+#endif
+
+#if defined(CONFIG_MACH_MIDAS)
+static char *secmem_info[] = {
+ "mfc", /* 0 */
+ "fimc", /* 1 */
+ "mfc-shm", /* 2 */
+ "sectbl", /* 3 */
+ "fimd", /* 4 */
+ NULL
+};
+#else
+static char *secmem_info[] = {
+ "mfc", /* 0 */
+ "fimc", /* 1 */
+ "mfc-shm", /* 2 */
+ "sectbl", /* 3 */
+ "video", /* 4 */
+ "fimd", /* 5 */
+ NULL
+};
+#endif
+
+static bool drm_onoff = false;
+
+#define SECMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
+
+static int secmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ unsigned long size = vma->vm_end - vma->vm_start;
+
+ BUG_ON(!SECMEM_IS_PAGE_ALIGNED(vma->vm_start));
+ BUG_ON(!SECMEM_IS_PAGE_ALIGNED(vma->vm_end));
+
+ vma->vm_flags |= VM_RESERVED;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ size, vma->vm_page_prot)) {
+ printk(KERN_ERR "%s : remap_pfn_range() failed!\n", __func__);
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+static long secmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case SECMEM_IOC_CHUNKINFO:
+ {
+ struct cma_info info;
+ struct secchunk_info minfo;
+ char **mname;
+ int nbufs = 0;
+
+ for (mname = secmem_info; *mname != NULL; mname++)
+ nbufs++;
+
+ if (nbufs == 0)
+ return -ENOMEM;
+
+ if (copy_from_user(&minfo, (void __user *)arg, sizeof(minfo)))
+ return -EFAULT;
+
+ if (minfo.index < 0)
+ return -EINVAL;
+
+ if (minfo.index >= nbufs) {
+ minfo.index = -1; /* No more memory region */
+ } else {
+
+ if (cma_info(&info, secmem.this_device,
+ secmem_info[minfo.index]))
+ return -EINVAL;
+
+ minfo.base = info.lower_bound;
+ minfo.size = info.total_size;
+ }
+
+ if (copy_to_user((void __user *)arg, &minfo, sizeof(minfo)))
+ return -EFAULT;
+ }
+ break;
+
+#if defined(CONFIG_ION) && defined(CONFIG_CPU_EXYNOS5250)
+ case SECMEM_IOC_GET_FD_PHYS_ADDR:
+ {
+ struct ion_client *client;
+ struct secfd_info fd_info;
+ struct ion_fd_data data;
+ size_t len;
+
+ if (copy_from_user(&fd_info, (int __user *)arg,
+ sizeof(fd_info)))
+ return -EFAULT;
+
+ client = ion_client_create(ion_exynos, -1, "DRM");
+ if (IS_ERR(client))
+ printk(KERN_ERR "%s: Failed to get ion_client of DRM\n",
+ __func__);
+
+ data.fd = fd_info.fd;
+ data.handle = ion_import_fd(client, data.fd);
+ printk(KERN_DEBUG "%s: fd from user space = %d\n",
+ __func__, fd_info.fd);
+ if (IS_ERR(data.handle))
+ printk(KERN_ERR "%s: Failed to get ion_handle of DRM\n",
+ __func__);
+
+ if (ion_phys(client, data.handle, &fd_info.phys, &len))
+ printk(KERN_ERR "%s: Failed to get phys. addr of DRM\n",
+ __func__);
+
+ printk(KERN_DEBUG "%s: physical addr from kernel space = %lu\n",
+ __func__, fd_info.phys);
+
+ ion_free(client, data.handle);
+ ion_client_destroy(client);
+
+ if (copy_to_user((void __user *)arg, &fd_info, sizeof(fd_info)))
+ return -EFAULT;
+ break;
+ }
+#endif
+ case SECMEM_IOC_GET_DRM_ONOFF:
+ if (copy_to_user((void __user *)arg, &drm_onoff, sizeof(int)))
+ return -EFAULT;
+ break;
+ case SECMEM_IOC_SET_DRM_ONOFF:
+ {
+ int val = 0;
+
+ if (copy_from_user(&val, (int __user *)arg, sizeof(int)))
+ return -EFAULT;
+
+ if (val) {
+ if (drm_onoff == false) {
+ drm_onoff = true;
+ pm_runtime_forbid((*(secmem.this_device)).parent);
+ } else
+ printk(KERN_ERR "%s: DRM is already on\n", __func__);
+ } else {
+ if (drm_onoff == true) {
+ drm_onoff = false;
+ pm_runtime_allow((*(secmem.this_device)).parent);
+ } else
+ printk(KERN_ERR "%s: DRM is already off\n", __func__);
+ }
+ break;
+ }
+ case SECMEM_IOC_GET_CRYPTO_LOCK:
+ {
+ int i;
+ int ret;
+
+ if (crypto_driver) {
+ for (i = 0; i < 100; i++) {
+ ret = crypto_driver->lock();
+ if (ret == 0)
+ break;
+ printk(KERN_ERR "%s : Retry to get sync lock.\n",
+ __func__);
+ }
+ return ret;
+ }
+ break;
+ }
+ case SECMEM_IOC_RELEASE_CRYPTO_LOCK:
+ {
+ if (crypto_driver)
+ return crypto_driver->release();
+ break;
+ }
+ case SECMEM_IOC_GET_ADDR:
+ {
+ struct secmem_region region;
+
+ if (copy_from_user(&region, (void __user *)arg,
+ sizeof(struct secmem_region)))
+ return -EFAULT;
+
+ if (!region.len) {
+ printk(KERN_ERR "Get secmem address size error. [size : %ld]\n", region.len);
+ return -EFAULT;
+ }
+
+ region.virt_addr = kmalloc(region.len, GFP_KERNEL | GFP_DMA);
+ if (!region.virt_addr) {
+ printk(KERN_ERR "%s: Get memory address failed. [size : %ld]\n", __func__, region.len);
+ return -EFAULT;
+ }
+ region.phys_addr = virt_to_phys(region.virt_addr);
+
+ dma_map_single(secmem.this_device, region.virt_addr, region.len, DMA_TO_DEVICE);
+
+ if (copy_to_user((void __user *)arg, &region,
+ sizeof(struct secmem_region)))
+ return -EFAULT;
+ break;
+ }
+ case SECMEM_IOC_RELEASE_ADDR:
+ {
+ struct secmem_region region;
+
+ if (copy_from_user(&region, (void __user *)arg,
+ sizeof(struct secmem_region)))
+ return -EFAULT;
+
+ if (!region.virt_addr) {
+ printk(KERN_ERR "Get secmem address error. [address : %x]\n", (uint32_t)region.virt_addr);
+ return -EFAULT;
+ }
+
+ kfree(region.virt_addr);
+ break;
+ }
+
+ case SECMEM_IOC_MFC_MAGIC_KEY:
+ {
+ uint32_t mfc_shm_virtaddr;
+ struct cma_info info;
+ struct secchunk_info minfo;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ if (cma_info(&info, secmem.this_device, "mfc-shm"))
+ return -EINVAL;
+#elif defined(CONFIG_CPU_EXYNOS5250)
+ if (cma_info(&info, secmem.this_device, "mfc_sh"))
+ return -EINVAL;
+#endif
+
+ minfo.base = info.lower_bound;
+ minfo.size = info.total_size;
+
+ mfc_shm_virtaddr = (uint32_t)phys_to_virt(minfo.base);
+
+ *(uint32_t *)(mfc_shm_virtaddr) = MFC_SEC_MAGIC_CHUNK0;
+ *(uint32_t *)(mfc_shm_virtaddr + 0x4) = MFC_SEC_MAGIC_CHUNK1;
+ *(uint32_t *)(mfc_shm_virtaddr + 0x8) = MFC_SEC_MAGIC_CHUNK2;
+ *(uint32_t *)(mfc_shm_virtaddr + 0xC) = MFC_SEC_MAGIC_CHUNK3;
+ break;
+ }
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+void secmem_crypto_register(struct secmem_crypto_driver_ftn *ftn)
+{
+ crypto_driver = ftn;
+}
+EXPORT_SYMBOL(secmem_crypto_register);
+
+void secmem_crypto_deregister(void)
+{
+ crypto_driver = NULL;
+}
+EXPORT_SYMBOL(secmem_crypto_deregister);
+
+static struct file_operations secmem_fops = {
+ .unlocked_ioctl = &secmem_ioctl,
+ .mmap = secmem_mmap,
+};
+
+static int __init secmem_init(void)
+{
+ int ret;
+ secmem.minor = MISC_DYNAMIC_MINOR;
+ secmem.name = "s5p-smem";
+ secmem.fops = &secmem_fops;
+
+ ret = misc_register(&secmem);
+ if (ret)
+ return ret;
+
+ crypto_driver = NULL;
+
+ pm_runtime_enable(secmem.this_device);
+
+ return 0;
+}
+
+static void __exit secmem_exit(void)
+{
+ __pm_runtime_disable(secmem.this_device, false);
+ misc_deregister(&secmem);
+}
+
+module_init(secmem_init);
+module_exit(secmem_exit);
diff --git a/arch/arm/mach-exynos/setup-c2c.c b/arch/arm/mach-exynos/setup-c2c.c
new file mode 100644
index 0000000..9d18bb6
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-c2c.c
@@ -0,0 +1,151 @@
+/* linux/arch/arm/mach-exynos/setup-c2c.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4212 - Helper functions for setting up C2C device(s) GPIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/c2c.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+void exynos_c2c_set_cprst(void)
+{
+ /* TODO */
+}
+
+void exynos_c2c_clear_cprst(void)
+{
+ /* TODO */
+}
+
+void exynos4_c2c_cfg_gpio(enum c2c_buswidth rx_width, enum c2c_buswidth tx_width,
+ void __iomem *etc8drv_addr)
+{
+ int i;
+
+ /* Set GPIO for C2C Rx */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV0(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++) {
+ s5p_gpio_set_drvstr(EXYNOS4212_GPV0(i), S5P_GPIO_DRVSTR_LV1);
+ s5p_gpio_set_pd_cfg(EXYNOS4212_GPV0(i), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS4212_GPV0(i), S5P_GPIO_PD_DOWN_ENABLE);
+ }
+
+ if (rx_width == C2C_BUSWIDTH_16) {
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV1(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++) {
+ s5p_gpio_set_drvstr(EXYNOS4212_GPV1(i), S5P_GPIO_DRVSTR_LV1);
+ s5p_gpio_set_pd_cfg(EXYNOS4212_GPV1(i), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS4212_GPV1(i), S5P_GPIO_PD_DOWN_ENABLE);
+ }
+ } else if (rx_width == C2C_BUSWIDTH_10) {
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV1(0), 2, S3C_GPIO_SFN(2));
+ for (i = 0; i < 2; i++) {
+ s5p_gpio_set_drvstr(EXYNOS4212_GPV1(i), S5P_GPIO_DRVSTR_LV1);
+ s5p_gpio_set_pd_cfg(EXYNOS4212_GPV1(i), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS4212_GPV1(i), S5P_GPIO_PD_DOWN_ENABLE);
+ }
+ }
+
+ /* Set GPIO for C2C Tx */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV2(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++)
+ s5p_gpio_set_drvstr(EXYNOS4212_GPV2(i), S5P_GPIO_DRVSTR_LV3);
+
+ if (tx_width == C2C_BUSWIDTH_16) {
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV3(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++)
+ s5p_gpio_set_drvstr(EXYNOS4212_GPV3(i), S5P_GPIO_DRVSTR_LV3);
+ } else if (tx_width == C2C_BUSWIDTH_10) {
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV3(0), 2, S3C_GPIO_SFN(2));
+ for (i = 0; i < 2; i++)
+ s5p_gpio_set_drvstr(EXYNOS4212_GPV3(i), S5P_GPIO_DRVSTR_LV3);
+ }
+
+ /* Set GPIO for WakeReqOut/In */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPV4(0), 2, S3C_GPIO_SFN(2));
+ s5p_gpio_set_pd_cfg(EXYNOS4212_GPV4(0), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS4212_GPV4(0), S5P_GPIO_PD_DOWN_ENABLE);
+
+ writel(0x5, etc8drv_addr);
+}
+
+void exynos5_c2c_cfg_gpio(enum c2c_buswidth rx_width, enum c2c_buswidth tx_width,
+ void __iomem *etc8drv_addr)
+{
+ int i;
+
+ /* Set GPIO for C2C Rx */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV0(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++) {
+ s5p_gpio_set_drvstr(EXYNOS5_GPV0(i), S5P_GPIO_DRVSTR_LV1);
+ s5p_gpio_set_pd_cfg(EXYNOS5_GPV0(i), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS5_GPV0(i), S5P_GPIO_PD_DOWN_ENABLE);
+ }
+
+ if (rx_width == C2C_BUSWIDTH_16) {
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV1(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++) {
+ s5p_gpio_set_drvstr(EXYNOS5_GPV1(i), S5P_GPIO_DRVSTR_LV1);
+ s5p_gpio_set_pd_cfg(EXYNOS5_GPV1(i), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS5_GPV1(i), S5P_GPIO_PD_DOWN_ENABLE);
+ }
+ } else if (rx_width == C2C_BUSWIDTH_10) {
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV1(0), 2, S3C_GPIO_SFN(2));
+ for (i = 0; i < 2; i++) {
+ s5p_gpio_set_drvstr(EXYNOS5_GPV1(i), S5P_GPIO_DRVSTR_LV1);
+ s5p_gpio_set_pd_cfg(EXYNOS5_GPV1(i), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS5_GPV1(i), S5P_GPIO_PD_DOWN_ENABLE);
+ }
+ }
+
+ /* Set GPIO for C2C Tx */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV2(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++)
+ s5p_gpio_set_drvstr(EXYNOS5_GPV2(i), S5P_GPIO_DRVSTR_LV3);
+
+ if (tx_width == C2C_BUSWIDTH_16) {
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV3(0), 8, S3C_GPIO_SFN(2));
+ for (i = 0; i < 8; i++)
+ s5p_gpio_set_drvstr(EXYNOS5_GPV3(i), S5P_GPIO_DRVSTR_LV3);
+ } else if (tx_width == C2C_BUSWIDTH_10) {
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV3(0), 2, S3C_GPIO_SFN(2));
+ for (i = 0; i < 2; i++)
+ s5p_gpio_set_drvstr(EXYNOS5_GPV3(i), S5P_GPIO_DRVSTR_LV3);
+ }
+
+ /* Set GPIO for WakeReqOut/In */
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPV4(0), 2, S3C_GPIO_SFN(2));
+ s5p_gpio_set_pd_cfg(EXYNOS5_GPV4(0), S5P_GPIO_PD_INPUT);
+ s5p_gpio_set_pd_pull(EXYNOS5_GPV4(0), S5P_GPIO_PD_DOWN_ENABLE);
+
+ writel(0x5, etc8drv_addr);
+}
+
+void exynos_c2c_cfg_gpio(enum c2c_buswidth rx_width, enum c2c_buswidth tx_width)
+{
+ void __iomem *etc8drv_addr;
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ /* ETC8DRV is used for setting Tx clock drive strength */
+ etc8drv_addr = S5P_VA_GPIO4 + 0xAC;
+ exynos4_c2c_cfg_gpio(rx_width, tx_width, etc8drv_addr);
+ } else if (soc_is_exynos5250()) {
+ /* ETC8DRV is used for setting Tx clock drive strength */
+ etc8drv_addr = S5P_VA_GPIO3 + 0xAC;
+ exynos5_c2c_cfg_gpio(rx_width, tx_width, etc8drv_addr);
+ }
+} \ No newline at end of file
diff --git a/arch/arm/mach-exynos/setup-csis.c b/arch/arm/mach-exynos/setup-csis.c
new file mode 100644
index 0000000..e342aa8
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-csis.c
@@ -0,0 +1,159 @@
+/* linux/arch/arm/mach-exynos/setup-csis.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Base MIPI-CSI2 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <plat/map-s5p.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/csis.h>
+
+#ifdef DEBUG
+#define dbg(fmt, args...) \
+ printk(KERN_INFO "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
+#else
+#define dbg(fmt, args...)
+#endif
+
+struct platform_device; /* don't need the contents */
+
+void s3c_csis0_cfg_gpio(void) { }
+void s3c_csis1_cfg_gpio(void) { }
+
+void s3c_csis0_cfg_phy_global(int on)
+{
+ u32 cfg;
+
+ if (on) {
+ /* MIPI D-PHY Power Enable */
+ cfg = __raw_readl(EXYNOS4_MIPI_CONTROL0);
+ cfg |= EXYNOS4_MIPI_DPHY_S_RESETN;
+ __raw_writel(cfg, EXYNOS4_MIPI_CONTROL0);
+
+ cfg = __raw_readl(EXYNOS4_MIPI_CONTROL0);
+ cfg |= EXYNOS4_MIPI_DPHY_EN;
+ __raw_writel(cfg, EXYNOS4_MIPI_CONTROL0);
+
+ dbg(KERN_INFO "csis0 on\n");
+ } else {
+ /* MIPI Power Disable */
+ cfg = __raw_readl(EXYNOS4_MIPI_CONTROL0);
+ cfg &= ~EXYNOS4_MIPI_DPHY_S_RESETN;
+
+ if (!(cfg & EXYNOS4_MIPI_DPHY_M_RESETN))
+ cfg &= ~EXYNOS4_MIPI_DPHY_EN;
+
+ __raw_writel(cfg, EXYNOS4_MIPI_CONTROL0);
+
+ dbg(KERN_INFO "csis0 off\n");
+ }
+}
+void s3c_csis1_cfg_phy_global(int on)
+{
+ u32 cfg;
+
+ if (on) {
+ /* MIPI D-PHY Power Enable */
+ cfg = __raw_readl(EXYNOS4_MIPI_CONTROL1);
+ cfg |= EXYNOS4_MIPI_DPHY_S_RESETN;
+ __raw_writel(cfg, EXYNOS4_MIPI_CONTROL1);
+
+ cfg = __raw_readl(EXYNOS4_MIPI_CONTROL1);
+ cfg |= EXYNOS4_MIPI_DPHY_EN;
+ __raw_writel(cfg, EXYNOS4_MIPI_CONTROL1);
+
+ dbg(KERN_INFO "csis1 on\n");
+ } else {
+ /* MIPI Power Disable */
+ cfg = __raw_readl(EXYNOS4_MIPI_CONTROL1);
+ cfg &= ~EXYNOS4_MIPI_DPHY_S_RESETN;
+
+ if (!(cfg & EXYNOS4_MIPI_DPHY_M_RESETN))
+ cfg &= ~EXYNOS4_MIPI_DPHY_EN;
+
+ __raw_writel(cfg, EXYNOS4_MIPI_CONTROL1);
+
+ dbg(KERN_INFO "csis1 off\n");
+ }
+}
+int s3c_csis_clk_on(struct platform_device *pdev, struct clk **clk)
+{
+ struct s3c_platform_csis *pdata;
+ struct clk *sclk_csis = NULL;
+ struct clk *mout_mpll = NULL;
+
+ pdata = to_csis_plat(&pdev->dev);
+
+ /* mout_mpll */
+ mout_mpll = clk_get(&pdev->dev, pdata->srclk_name);
+ if (IS_ERR(mout_mpll)) {
+ dev_err(&pdev->dev, "failed to get mout_mpll\n");
+ goto err_clk1;
+ }
+
+ /* sclk_csis */
+ sclk_csis = clk_get(&pdev->dev, pdata->clk_name);
+ if (IS_ERR(sclk_csis)) {
+ dev_err(&pdev->dev, "failed to get sclk_csis\n");
+ goto err_clk2;
+ }
+
+ if (clk_set_parent(sclk_csis, mout_mpll)) {
+ dev_err(&pdev->dev, "Unable to set parent %s of clock %s.\n",
+ mout_mpll->name, sclk_csis->name);
+ goto err_clk3;
+ }
+
+ if (clk_set_rate(sclk_csis, pdata->clk_rate)) {
+ dev_err(&pdev->dev, "%s rate change failed: %lu\n",
+ sclk_csis->name, pdata->clk_rate);
+ goto err_clk3;
+ }
+
+ /* csis */
+ *clk = clk_get(&pdev->dev, "csis");
+ if (IS_ERR(*clk)) {
+ dev_err(&pdev->dev, "failed to get csis clock\n");
+ goto err_clk3;
+ }
+ /* clock enable for csis */
+ clk_enable(*clk);
+ clk_enable(sclk_csis);
+
+ return 0;
+
+err_clk3:
+ clk_put(sclk_csis);
+
+err_clk2:
+ clk_put(mout_mpll);
+
+err_clk1:
+ return -EINVAL;
+}
+int s3c_csis_clk_off(struct platform_device *pdev, struct clk **clk)
+{
+ clk_disable(*clk);
+ clk_put(*clk);
+
+ *clk = NULL;
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/setup-dp.c b/arch/arm/mach-exynos/setup-dp.c
new file mode 100644
index 0000000..92821be
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-dp.c
@@ -0,0 +1,32 @@
+/* linux/arch/arm/mach-exynos/setup-dp.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base Samsung Exynos DP configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <mach/regs-clock.h>
+
+void s5p_dp_phy_init(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_DPTX_PHY_CONTROL);
+ reg |= S5P_DPTX_PHY_ENABLE;
+ __raw_writel(reg, S5P_DPTX_PHY_CONTROL);
+}
+
+void s5p_dp_phy_exit(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_DPTX_PHY_CONTROL);
+ reg &= ~S5P_DPTX_PHY_ENABLE;
+ __raw_writel(reg, S5P_DPTX_PHY_CONTROL);
+}
diff --git a/arch/arm/mach-exynos/setup-dsim.c b/arch/arm/mach-exynos/setup-dsim.c
new file mode 100644
index 0000000..e1ba8eea
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-dsim.c
@@ -0,0 +1,120 @@
+/* linux/arch/arm/mach-exynos/setup-dsim.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * DSIM controller configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <plat/clock.h>
+#include <plat/regs-dsim.h>
+#include <plat/gpio-cfg.h>
+#include <mach/map.h>
+#include <mach/regs-pmu.h>
+
+#define S5P_MIPI_M_RESETN 4
+
+static void s5p_dsim_enable_d_phy(unsigned char enable)
+{
+ unsigned int reg;
+
+ reg = readl(S5P_MIPI_DPHY_CONTROL(0));
+ if (enable)
+ reg |= S5P_MIPI_DPHY_ENABLE;
+ else if (!(reg & S5P_MIPI_DPHY_SRESETN))
+ reg &= ~S5P_MIPI_DPHY_ENABLE;
+ writel(reg, S5P_MIPI_DPHY_CONTROL(0));
+}
+
+static void s5p_dsim_enable_dsi_master(unsigned char enable)
+{
+ unsigned int reg;
+
+ reg = (readl(S5P_MIPI_DPHY_CONTROL(0))) & ~(1 << 2);
+ reg |= (enable << 2);
+ writel(reg, S5P_MIPI_DPHY_CONTROL(0));
+}
+
+void s5p_dsim_enable_clk(void *d_clk, unsigned char enable)
+{
+ int ret = 0;
+ struct clk *dsim_clk = (struct clk *) d_clk;
+
+ if (enable) {
+ ret = clk_enable(dsim_clk);
+ if (ret < 0)
+ printk("failed to clk_enable of dsim\n");
+ } else
+ clk_disable(dsim_clk);
+}
+
+void s5p_dsim_part_reset(void)
+{
+ writel(S5P_MIPI_M_RESETN, S5P_MIPI_DPHY_CONTROL(0));
+}
+
+void s5p_dsim_init_d_phy(unsigned int dsim_base)
+{
+ /* enable D-PHY */
+ s5p_dsim_enable_d_phy(1);
+
+ /* enable DSI master block */
+ s5p_dsim_enable_dsi_master(1);
+}
+
+void s5p_dsim_exit_d_phy(unsigned int dsim_base)
+{
+ /* enable DSI master block */
+ s5p_dsim_enable_dsi_master(0);
+
+ /* enable D-PHY */
+ s5p_dsim_enable_d_phy(0);
+}
+
+static void exynos4_dsim_setup_24bpp(unsigned int start, unsigned int size,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr)
+{
+ s3c_gpio_cfgrange_nopull(start, size, cfg);
+
+ for (; size > 0; size--, start++)
+ s5p_gpio_set_drvstr(start, drvstr);
+}
+
+void exynos4_dsim_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+
+ /*
+ * Set DISPLAY_CONTROL register for Display path selection.
+ *
+ * DISPLAY_CONTROL[1:0]
+ * ---------------------
+ * 00 | MIE
+ * 01 | MDINE
+ * 10 | FIMD : selected
+ * 11 | FIMD
+ */
+#ifdef CONFIG_FB_S5P_MDNIE
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg &= ~(1<<13);
+ reg &= ~(1<<12);
+ reg &= ~(3<<10);
+ reg |= (1<<0);
+ reg &= ~(1<<1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#else
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg |= (1 << 1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#endif
+}
diff --git a/arch/arm/mach-exynos/setup-fb-s5p.c b/arch/arm/mach-exynos/setup-fb-s5p.c
new file mode 100644
index 0000000..21b2199
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-fb-s5p.c
@@ -0,0 +1,970 @@
+/* linux/arch/arm/mach-exynos/setup-fb-s5p.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMD controller configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gcd.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <mach/board_rev.h>
+
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+#include <plat/clock-clksrc.h>
+#include <../../../drivers/video/samsung/s3cfb.h> /* should be fixed */
+
+struct platform_device; /* don't need the contents */
+
+#ifdef CONFIG_FB_S5P
+#if !defined(CONFIG_FB_S5P_MIPI_DSIM)
+static void s3cfb_gpio_setup_24bpp(unsigned int start, unsigned int size,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr)
+{
+ u32 reg;
+
+ s3c_gpio_cfgrange_nopull(start, size, cfg);
+
+ for (; size > 0; size--, start++)
+ s5p_gpio_set_drvstr(start, drvstr);
+
+#ifdef CONFIG_FB_S5P_MDNIE
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg &= ~(1<<13);
+ reg &= ~(1<<12);
+ reg &= ~(3<<10);
+ reg |= (1<<0);
+ reg &= ~(1<<1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#else
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg |= (1<<1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#endif
+}
+#endif
+
+#if defined(CONFIG_FB_S5P_WA101S) || defined(CONFIG_FB_S5P_LTE480WV)
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+}
+#elif defined(CONFIG_FB_S5P_AMS369FG06)
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+}
+#elif defined(CONFIG_FB_S5P_LMS501KF03)
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+}
+#elif defined(CONFIG_FB_S5P_HT101HD1)
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+}
+#elif defined(CONFIG_FB_S5P_LD9040) || defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ s3cfb_gpio_setup_24bpp(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+}
+#else
+void s3cfb_cfg_gpio(struct platform_device *pdev)
+{
+ u32 reg;
+
+#ifdef CONFIG_FB_S5P_MDNIE
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg &= ~(1<<13);
+ reg &= ~(1<<12);
+ reg &= ~(3<<10);
+ reg |= (1<<0);
+ reg &= ~(1<<1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#else
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg |= (1<<1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#endif
+
+ return;
+}
+#endif
+#endif
+
+#if defined(CONFIG_FB_S5P_WA101S)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+ return 0;
+}
+#elif defined(CONFIG_FB_S5P_LTE480WV)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+ msleep(100);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ msleep(10);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+ msleep(10);
+
+ gpio_free(EXYNOS4_GPX0(6));
+
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+ return 0;
+}
+#elif defined(CONFIG_FB_S5P_HT101HD1)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ /* Backlight High */
+ err = gpio_request_one(EXYNOS4_GPD0(0), GPIOF_OUT_INIT_HIGH, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(0));
+
+ /* LED_EN (SPI1_MOSI) High */
+ err = gpio_request_one(EXYNOS4_GPB(2), GPIOF_OUT_INIT_HIGH, "GPB");
+ if (err) {
+ printk(KERN_ERR "failed to request GPB for "
+ "lcd LED_EN control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPB(2));
+#endif
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ /* Backlight Low */
+ err = gpio_request_one(EXYNOS4_GPD0(0), GPIOF_OUT_INIT_LOW, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(0));
+
+ /* LED_EN (SPI1_MOSI) Low */
+ err = gpio_request_one(EXYNOS4_GPB(2), GPIOF_OUT_INIT_LOW, "GPB");
+ if (err) {
+ printk(KERN_ERR "failed to request GPB for "
+ "lcd LED_EN control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPB(2));
+#endif
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPH0(1), GPIOF_OUT_INIT_HIGH, "GPH0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPH0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4_GPH0(1), 0);
+ gpio_set_value(EXYNOS4_GPH0(1), 1);
+
+ gpio_free(EXYNOS4_GPH0(1));
+
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+ return 0;
+}
+#elif defined(CONFIG_FB_S5P_AMS369FG06) || defined(CONFIG_FB_S5P_LMS501KF03)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+ int err;
+
+#ifdef CONFIG_MACH_SMDKC210
+ err = gpio_request_one(EXYNOS4_GPX0(6), GPIOF_OUT_INIT_HIGH, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4_GPX0(6), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4_GPX0(6), 1);
+
+ gpio_free(EXYNOS4_GPX0(6));
+#elif defined(CONFIG_MACH_SMDK4X12)
+ if (samsung_board_rev_is_0_1()) {
+ err = gpio_request_one(EXYNOS4212_GPM3(6),
+ GPIOF_OUT_INIT_HIGH, "GPM3");
+ if (err) {
+ printk(KERN_ERR "failed to request GPM3 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4212_GPM3(6), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4212_GPM3(6), 1);
+
+ gpio_free(EXYNOS4212_GPM3(6));
+
+ } else {
+ err = gpio_request_one(EXYNOS4_GPX1(5),
+ GPIOF_OUT_INIT_HIGH, "GPX0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPX0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4_GPX1(5), 0);
+ mdelay(1);
+
+ gpio_set_value(EXYNOS4_GPX1(5), 1);
+
+ gpio_free(EXYNOS4_GPX1(5));
+ }
+#endif
+
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+ return 0;
+}
+
+#elif defined(CONFIG_FB_S5P_S6C1372) && !defined(CONFIG_FB_MDNIE_PWM)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+ gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ gpio_free(EXYNOS4_GPD0(1));
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPC0(1), GPIOF_OUT_INIT_LOW, "GPC0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPC0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4_GPC0(1), GPIO_LEVEL_HIGH);
+ msleep(40);
+
+ /* LVDS_N_SHDN to low */
+ err = gpio_request_one(EXYNOS4212_GPM0(5), GPIOF_OUT_INIT_LOW, "GPM0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPM0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4212_GPM0(5), GPIO_LEVEL_HIGH);
+ msleep(300);
+
+ err = gpio_request_one(EXYNOS4212_GPM0(1), GPIOF_OUT_INIT_LOW, "GPM0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPM0 for "
+ "lcd backlight control\n");
+ return err;
+ }
+
+ gpio_set_value(EXYNOS4212_GPM0(1), GPIO_LEVEL_HIGH);
+ mdelay(2);
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+ gpio_set_value(EXYNOS4212_GPM0(1), GPIO_LEVEL_LOW);
+ mdelay(200);
+
+ /* LVDS_N_SHDN to low */
+ gpio_set_value(EXYNOS4212_GPM0(5), GPIO_LEVEL_LOW);
+ msleep(40);
+
+ gpio_set_value(EXYNOS4_GPC0(1), GPIO_LEVEL_LOW);
+ msleep(400);
+
+ return 0;
+}
+
+#elif defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+#if !defined(CONFIG_FB_MDNIE_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_HIGH, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for lcd reset control\n");
+ return err;
+ }
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ msleep(40);
+ /* LVDS_N_SHDN to high*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_HIGH);
+ msleep(300);
+#if defined(CONFIG_FB_S5P_S6C1372)
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, GPIO_LEVEL_HIGH);
+ mdelay(2);
+#else
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_HIGH);
+ msleep(200);
+#endif
+ gpio_set_value(EXYNOS4_GPD0(1), GPIO_LEVEL_HIGH);
+ gpio_free(EXYNOS4_GPD0(1));
+#endif
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+#if !defined(CONFIG_FB_MDNIE_PWM)
+ int err;
+
+ err = gpio_request_one(EXYNOS4_GPD0(1), GPIOF_OUT_INIT_LOW, "GPD0");
+ if (err) {
+ printk(KERN_ERR "failed to request GPD0 for "
+ "lcd reset control\n");
+ return err;
+ }
+
+ /* LVDS_nSHDN low*/
+ gpio_set_value(EXYNOS4_GPD0(1), GPIO_LEVEL_LOW);
+ gpio_free(EXYNOS4_GPD0(1));
+#if defined(CONFIG_FB_S5P_S6C1372)
+ gpio_set_value(GPIO_LED_BACKLIGHT_RESET, GPIO_LEVEL_LOW);
+ msleep(200);
+#else
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_LOW);
+ msleep(200);
+#endif
+ /* LVDS_nSHDN low*/
+ gpio_set_value(GPIO_LVDS_NSHDN, GPIO_LEVEL_LOW);
+ msleep(40);
+ /* Disable LVDS Panel Power, 1.2, 1.8, display 3.3V */
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+ msleep(400);
+#endif
+ return 0;
+}
+
+#else
+int s3cfb_backlight_on(struct platform_device *pdev)
+{
+ return 0;
+}
+
+int s3cfb_backlight_off(struct platform_device *pdev)
+{
+ return 0;
+}
+
+int s3cfb_lcd_on(struct platform_device *pdev)
+{
+ return 0;
+}
+
+int s3cfb_lcd_off(struct platform_device *pdev)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+int s3cfb_mipi_clk_enable(int enable)
+{
+ struct clk *dsim_clk = NULL;
+
+ dsim_clk = clk_get(NULL, "dsim0");
+ if (IS_ERR(dsim_clk)) {
+ printk(KERN_ERR "failed to get ip clk for dsim0\n");
+ goto err_clk0;
+ }
+
+ if (enable)
+ clk_enable(dsim_clk);
+ else
+ clk_disable(dsim_clk);
+
+ clk_put(dsim_clk);
+
+ return 0;
+
+err_clk0:
+ clk_put(dsim_clk);
+
+ return -EINVAL;
+}
+#endif
+
+int s3cfb_mdnie_clk_on(u32 rate)
+{
+ struct clk *sclk = NULL;
+ struct clk *mout_mpll = NULL;
+ struct clk *mdnie_clk = NULL;
+ int ret = 0;
+
+ mdnie_clk = clk_get(NULL, "mdnie0"); /* CLOCK GATE IP ENABLE */
+ if (IS_ERR(mdnie_clk)) {
+ printk(KERN_ERR "failed to get ip clk for mdnie0\n");
+ goto err_clk0;
+ }
+ clk_enable(mdnie_clk);
+ clk_put(mdnie_clk);
+
+ sclk = clk_get(NULL, "sclk_mdnie");
+ if (IS_ERR(sclk)) {
+ printk(KERN_ERR "failed to get sclk for mdnie\n");
+ goto err_clk1;
+ }
+
+ if (soc_is_exynos4210())
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ else
+ mout_mpll = clk_get(NULL, "mout_mpll_user");
+
+ if (IS_ERR(mout_mpll)) {
+ printk(KERN_ERR "failed to get mout_mpll\n");
+ goto err_clk2;
+ }
+
+ clk_set_parent(sclk, mout_mpll);
+
+ if (!rate)
+ rate = 800 * MHZ;
+
+ ret = clk_set_rate(sclk, rate);
+
+ clk_put(mout_mpll);
+
+ clk_enable(sclk);
+
+ return 0;
+
+err_clk1:
+ clk_put(mout_mpll);
+err_clk2:
+ clk_put(sclk);
+err_clk0:
+ clk_put(mdnie_clk);
+
+ return -EINVAL;
+}
+
+int s3cfb_mdnie_pwm_clk_on(void)
+{
+ struct clk *sclk = NULL;
+ struct clk *sclk_pre = NULL;
+ struct clk *mout_mpll = NULL;
+ u32 rate = 0;
+
+ sclk = clk_get(NULL, "sclk_mdnie_pwm");
+ if (IS_ERR(sclk)) {
+ printk(KERN_ERR "failed to get sclk for mdnie_pwm\n");
+ goto err_clk1;
+ }
+
+ sclk_pre = clk_get(NULL, "sclk_mdnie_pwm_pre");
+ if (IS_ERR(sclk_pre)) {
+ printk(KERN_ERR "failed to get sclk for mdnie_pwm_pre\n");
+ goto err_clk2;
+ }
+#if defined(CONFIG_FB_S5P_S6C1372)
+ mout_mpll = clk_get(NULL, "xusbxti");
+ if (IS_ERR(mout_mpll)) {
+ printk(KERN_ERR "failed to get mout_mpll\n");
+ goto err_clk3;
+ }
+ clk_set_parent(sclk, mout_mpll);
+ rate = clk_round_rate(sclk, 2200000);
+ if (!rate)
+ rate = 2200000;
+ clk_set_rate(sclk, rate);
+ printk(KERN_INFO "set mdnie_pwm sclk rate to %d\n", rate);
+ clk_set_parent(sclk_pre, mout_mpll);
+ rate = clk_round_rate(sclk_pre, 24000000);
+ if (!rate)
+ rate = 24000000;
+ clk_set_rate(sclk_pre, rate);
+#elif defined(CONFIG_FB_S5P_S6F1202A)
+ if (soc_is_exynos4210())
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ else
+ mout_mpll = clk_get(NULL, "mout_mpll_user");
+ if (IS_ERR(mout_mpll)) {
+ printk(KERN_ERR "failed to get mout_mpll\n");
+ goto err_clk3;
+ }
+ clk_set_parent(sclk, mout_mpll);
+ rate = clk_round_rate(sclk, 50000000);
+ if (!rate)
+ rate = 50000000;
+ clk_set_rate(sclk, rate);
+ printk(KERN_INFO "set mdnie_pwm sclk rate to %d\n", rate);
+ clk_set_parent(sclk_pre, mout_mpll);
+ rate = clk_round_rate(sclk_pre, 160000000);
+ if (!rate)
+ rate = 160000000;
+ clk_set_rate(sclk_pre, rate);
+#else
+ if (soc_is_exynos4210())
+ mout_mpll = clk_get(NULL, "mout_mpll");
+ else
+ mout_mpll = clk_get(NULL, "mout_mpll_user");
+
+ if (IS_ERR(mout_mpll)) {
+ printk(KERN_ERR "failed to get mout_mpll\n");
+ goto err_clk3;
+ }
+
+ clk_set_parent(sclk, mout_mpll);
+
+ rate = 57500000;
+ clk_set_rate(sclk, rate);
+#endif
+ printk(KERN_INFO "set mdnie_pwm sclk rate to %d\n", rate);
+
+ clk_put(mout_mpll);
+
+ clk_enable(sclk);
+
+ return 0;
+
+err_clk3:
+ clk_put(mout_mpll);
+err_clk2:
+ clk_put(sclk_pre);
+err_clk1:
+ clk_put(sclk);
+
+ return -EINVAL;
+}
+
+unsigned int get_clk_rate(struct platform_device *pdev, struct clk *sclk)
+{
+ struct s3c_platform_fb *pdata = pdev->dev.platform_data;
+ struct s3cfb_lcd *lcd = (struct s3cfb_lcd *)pdata->lcd;
+ struct s3cfb_lcd_timing *timing = &lcd->timing;
+ u32 src_clk, vclk, div, rate;
+#if defined(CONFIG_MACH_MIDAS) && defined(CONFIG_FB_S5P_S6E8AA0)
+ u32 vclk_limit, div_limit, fimd_div;
+#endif
+
+ src_clk = clk_get_rate(sclk);
+
+ vclk = (lcd->freq *
+ (timing->h_bp + timing->h_fp + timing->h_sw + lcd->width) *
+ (timing->v_bp + timing->v_fp + timing->v_sw + lcd->height));
+
+ if (!vclk)
+ vclk = src_clk;
+
+ div = DIV_ROUND_CLOSEST(src_clk, vclk);
+
+#if defined(CONFIG_MACH_MIDAS) && defined(CONFIG_FB_S5P_S6E8AA0)
+ vclk_limit = (40 *
+ (timing->h_bp + timing->h_fp + timing->h_sw + lcd->width) *
+ (timing->v_bp + timing->v_fp + timing->v_sw + lcd->height));
+
+ div_limit = DIV_ROUND_CLOSEST(src_clk, vclk_limit);
+
+ fimd_div = gcd(div, div_limit);
+
+ div /= fimd_div;
+#endif
+
+ if (!div) {
+ dev_err(&pdev->dev, "div(%d) should be non-zero\n", div);
+ div = 1;
+ } else if (div > 16) {
+ dev_err(&pdev->dev, "div(%d) max should be 16\n", div);
+ div = 16;
+ }
+
+ rate = src_clk / div;
+
+ if ((src_clk % rate) && (div != 1)) {
+ div--;
+ rate = src_clk / div;
+ if (!(src_clk % rate))
+ rate--;
+ }
+
+ dev_info(&pdev->dev, "vclk=%d, div=%d(%d), rate=%d\n",
+ vclk, DIV_ROUND_CLOSEST(src_clk, vclk), div, rate);
+
+ return rate;
+}
+
+int s3cfb_clk_on(struct platform_device *pdev, struct clk **s3cfb_clk)
+{
+ struct clk *sclk = NULL;
+ struct clk *mout_mpll = NULL;
+ struct clk *lcd_clk = NULL;
+ struct clksrc_clk *src_clk = NULL;
+ u32 clkdiv = 0;
+ struct s3c_platform_fb *pdata = pdev->dev.platform_data;
+ struct s3cfb_lcd *lcd = (struct s3cfb_lcd *)pdata->lcd;
+
+ u32 rate = 0;
+ int ret = 0;
+
+ lcd_clk = clk_get(&pdev->dev, "lcd");
+ if (IS_ERR(lcd_clk)) {
+ dev_err(&pdev->dev, "failed to get operation clk for fimd\n");
+ goto err_clk0;
+ }
+
+ ret = clk_enable(lcd_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to clk_enable of lcd clk for fimd\n");
+ goto err_clk0;
+ }
+ clk_put(lcd_clk);
+
+ sclk = clk_get(&pdev->dev, "sclk_fimd");
+ if (IS_ERR(sclk)) {
+ dev_err(&pdev->dev, "failed to get sclk for fimd\n");
+ goto err_clk1;
+ }
+
+ if (soc_is_exynos4210())
+ mout_mpll = clk_get(&pdev->dev, "mout_mpll");
+ else
+ mout_mpll = clk_get(&pdev->dev, "mout_mpll_user");
+
+ if (IS_ERR(mout_mpll)) {
+ dev_err(&pdev->dev, "failed to get mout_mpll for fimd\n");
+ goto err_clk2;
+ }
+
+ ret = clk_set_parent(sclk, mout_mpll);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to clk_set_parent for fimd\n");
+ goto err_clk2;
+ }
+
+ if (!lcd->vclk) {
+ rate = get_clk_rate(pdev, mout_mpll);
+ if (!rate)
+ rate = 800 * MHZ; /* MOUT PLL */
+ lcd->vclk = rate;
+ } else
+ rate = lcd->vclk;
+
+ ret = clk_set_rate(sclk, rate);
+
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to clk_set_rate of sclk for fimd\n");
+ goto err_clk2;
+ }
+ dev_dbg(&pdev->dev, "set fimd sclk rate to %d\n", rate);
+
+ clk_put(mout_mpll);
+
+ ret = clk_enable(sclk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to clk_enable of sclk for fimd\n");
+ goto err_clk2;
+ }
+
+ *s3cfb_clk = sclk;
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+ s3cfb_mipi_clk_enable(1);
+#endif
+#ifdef CONFIG_FB_S5P_MDNIE
+ s3cfb_mdnie_clk_on(rate);
+#ifdef CONFIG_FB_MDNIE_PWM
+ s3cfb_mdnie_pwm_clk_on();
+#endif
+#endif
+
+ src_clk = container_of(sclk, struct clksrc_clk, clk);
+ clkdiv = __raw_readl(src_clk->reg_div.reg);
+
+ dev_info(&pdev->dev, "fimd sclk rate %ld, clkdiv 0x%x\n",
+ clk_get_rate(sclk), clkdiv);
+
+ return 0;
+
+err_clk2:
+ clk_put(mout_mpll);
+err_clk1:
+ clk_put(sclk);
+err_clk0:
+ clk_put(lcd_clk);
+
+ return -EINVAL;
+}
+
+int s3cfb_mdnie_clk_off(void)
+{
+ struct clk *sclk = NULL;
+ struct clk *mdnie_clk = NULL;
+
+ mdnie_clk = clk_get(NULL, "mdnie0"); /* CLOCK GATE IP ENABLE */
+ if (IS_ERR(mdnie_clk)) {
+ printk(KERN_ERR "failed to get ip clk for fimd0\n");
+ goto err_clk0;
+ }
+ clk_disable(mdnie_clk);
+ clk_put(mdnie_clk);
+
+ sclk = clk_get(NULL, "sclk_mdnie");
+ if (IS_ERR(sclk))
+ printk(KERN_ERR "failed to get sclk for mdnie\n");
+
+ clk_disable(sclk);
+ clk_put(sclk);
+
+ return 0;
+
+err_clk0:
+ clk_put(mdnie_clk);
+
+ return -EINVAL;
+}
+
+int s3cfb_mdnie_pwm_clk_off(void)
+{
+ struct clk *sclk = NULL;
+
+ sclk = clk_get(NULL, "sclk_mdnie_pwm");
+ if (IS_ERR(sclk))
+ printk(KERN_ERR "failed to get sclk for mdnie_pwm\n");
+
+ clk_disable(sclk);
+ clk_put(sclk);
+
+ return 0;
+}
+
+int s3cfb_clk_off(struct platform_device *pdev, struct clk **clk)
+{
+ struct clk *lcd_clk = NULL;
+
+ lcd_clk = clk_get(&pdev->dev, "lcd");
+ if (IS_ERR(lcd_clk)) {
+ printk(KERN_ERR "failed to get ip clk for fimd0\n");
+ goto err_clk0;
+ }
+
+ clk_disable(lcd_clk);
+ clk_put(lcd_clk);
+
+ clk_disable(*clk);
+ clk_put(*clk);
+
+ *clk = NULL;
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+ s3cfb_mipi_clk_enable(0);
+#endif
+#ifdef CONFIG_FB_S5P_MDNIE
+ s3cfb_mdnie_clk_off();
+ s3cfb_mdnie_pwm_clk_off();
+#endif
+
+ return 0;
+
+err_clk0:
+ clk_put(lcd_clk);
+
+ return -EINVAL;
+}
+
+void s3cfb_get_clk_name(char *clk_name)
+{
+ strcpy(clk_name, "sclk_fimd");
+}
+
diff --git a/arch/arm/mach-exynos/setup-fimc-is.c b/arch/arm/mach-exynos/setup-fimc-is.c
new file mode 100644
index 0000000..d9d31fd
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-fimc-is.c
@@ -0,0 +1,1111 @@
+/* linux/arch/arm/mach-exynos/setup-fimc-is.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * FIMC-IS gpio and clock configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <plat/map-s5p.h>
+#include <plat/cpu.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <media/exynos_fimc_is.h>
+
+struct platform_device; /* don't need the contents */
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+/*------------------------------------------------------*/
+/* Exynos4 series - FIMC-IS */
+/*------------------------------------------------------*/
+void exynos_fimc_is_cfg_gpio(struct platform_device *pdev)
+{
+ int ret;
+
+#if defined(CONFIG_MACH_SMDK4X12)
+ /* 1. UART setting for FIMC-IS */
+ /* GPM3[5] : TXD_UART_ISP */
+ ret = gpio_request(EXYNOS4212_GPM3(5), "GPM3");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPM3_5 ####\n");
+ s3c_gpio_cfgpin(EXYNOS4212_GPM3(5), (0x3<<20));
+ s3c_gpio_setpull(EXYNOS4212_GPM3(5), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS4212_GPM3(5));
+
+ /* GPM3[7] : RXD_UART_ISP */
+ ret = gpio_request(EXYNOS4212_GPM3(7), "GPM3");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPM3_7 ####\n");
+ s3c_gpio_cfgpin(EXYNOS4212_GPM3(7), (0x3<<28));
+ s3c_gpio_setpull(EXYNOS4212_GPM3(7), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS4212_GPM3(7));
+
+ /* 2. GPIO setting for FIMC-IS */
+ ret = gpio_request(EXYNOS4212_GPM4(0), "GPM4");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPM4_0 ####\n");
+ s3c_gpio_cfgpin(EXYNOS4212_GPM4(0), (0x2<<0));
+ s3c_gpio_setpull(EXYNOS4212_GPM4(0), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS4212_GPM4(0));
+
+ ret = gpio_request(EXYNOS4212_GPM4(1), "GPM4");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPM4_1 ####\n");
+ s3c_gpio_cfgpin(EXYNOS4212_GPM4(1), (0x2<<4));
+ s3c_gpio_setpull(EXYNOS4212_GPM4(1), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS4212_GPM4(1));
+#endif
+
+ ret = gpio_request(EXYNOS4212_GPM4(2), "GPM4");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPM4_2 ####\n");
+ s3c_gpio_cfgpin(EXYNOS4212_GPM4(2), (0x2<<8));
+ s3c_gpio_setpull(EXYNOS4212_GPM4(2), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS4212_GPM4(2));
+
+ ret = gpio_request(EXYNOS4212_GPM4(3), "GPM4");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPM4_3 ####\n");
+ s3c_gpio_cfgpin(EXYNOS4212_GPM4(3), (0x2<<12));
+ s3c_gpio_setpull(EXYNOS4212_GPM4(3), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS4212_GPM4(3));
+}
+
+int exynos_fimc_is_clk_get(struct platform_device *pdev)
+{
+ struct exynos4_platform_fimc_is *pdata;
+ pdata = to_fimc_is_plat(&pdev->dev);
+
+ /* 1. Get clocks for CMU_ISP clock divider setting */
+ /* UART_ISP_SEL - CLK_SRC_ISP (0x1003 C238) , [15:12] */
+ pdata->div_clock[0] = clk_get(&pdev->dev, "mout_mpll_user");
+ if (IS_ERR(pdata->div_clock[0])) {
+ printk(KERN_ERR "failed to get mout_mpll_user\n");
+ goto err_clk1;
+ }
+ /* UART_ISP_RATIO - CLK_DIV_ISP (0x1003 C538) , [31:28] */
+ pdata->div_clock[1] = clk_get(&pdev->dev, "sclk_uart_isp");
+ if (IS_ERR(pdata->div_clock[1])) {
+ printk(KERN_ERR "failed to get sclk_uart_isp\n");
+ goto err_clk2;
+ }
+
+ /* 2. Get clocks for CMU_ISP clock gate setting */
+ /* CLK_MTCADC_ISP - CLK_GATE_IP_ISP0 (0x1004 8800), [27] */
+ pdata->control_clock[0] = clk_get(&pdev->dev, "mtcadc");
+ if (IS_ERR(pdata->control_clock[0])) {
+ printk(KERN_ERR "failed to get mtcadc\n");
+ goto err_clk3;
+ }
+ /* CLK_MPWM_ISP - CLK_GATE_IP_ISP0 (0x1004 8800), [24] */
+ pdata->control_clock[1] = clk_get(&pdev->dev, "mpwm_isp");
+ if (IS_ERR(pdata->control_clock[1])) {
+ printk(KERN_ERR "failed to get mpwm_isp\n");
+ goto err_clk4;
+ }
+ /* CLK_PPMUISPX - CLK_GATE_IP_ISP0 (0x1004 8800), [21] */
+ /* CLK_PPMUISPMX - CLK_GATE_IP_ISP0 (0x1004 8800), [20] */
+ pdata->control_clock[2] = clk_get(&pdev->dev, "ppmuisp");
+ if (IS_ERR(pdata->control_clock[2])) {
+ printk(KERN_ERR "failed to get ppmuisp\n");
+ goto err_clk5;
+ }
+ /* CLK_QE_LITE1 - CLK_GATE_IP_ISP0 (0x1004 8800), [18] */
+ pdata->control_clock[3] = clk_get(&pdev->dev, "qelite1");
+ if (IS_ERR(pdata->control_clock[3])) {
+ printk(KERN_ERR "failed to get qelite1\n");
+ goto err_clk6;
+ }
+ /* CLK_QE_LITE0 - CLK_GATE_IP_ISP0 (0x1004 8800), [17] */
+ pdata->control_clock[4] = clk_get(&pdev->dev, "qelite0");
+ if (IS_ERR(pdata->control_clock[4])) {
+ printk(KERN_ERR "failed to get qelite0\n");
+ goto err_clk7;
+ }
+ /* CLK_QE_FD - CLK_GATE_IP_ISP0 (0x1004 8800), [16] */
+ pdata->control_clock[5] = clk_get(&pdev->dev, "qefd");
+ if (IS_ERR(pdata->control_clock[5])) {
+ printk(KERN_ERR "failed to get qefd\n");
+ goto err_clk8;
+ }
+ /* CLK_QE_DRC - CLK_GATE_IP_ISP0 (0x1004 8800), [15] */
+ pdata->control_clock[6] = clk_get(&pdev->dev, "qedrc");
+ if (IS_ERR(pdata->control_clock[6])) {
+ printk(KERN_ERR "failed to get qedrc\n");
+ goto err_clk9;
+ }
+ /* CLK_QE_ISP - CLK_GATE_IP_ISP0 (0x1004 8800), [14] */
+ pdata->control_clock[7] = clk_get(&pdev->dev, "qeisp");
+ if (IS_ERR(pdata->control_clock[7])) {
+ printk(KERN_ERR "failed to get qeisp\n");
+ goto err_clk10;
+ }
+ /* CLK_SMMU_LITE1 - CLK_GATE_IP_ISP0 (0x1004 8800), [12] */
+ pdata->control_clock[8] = clk_get(&pdev->dev, "sysmmu_lite1");
+ if (IS_ERR(pdata->control_clock[8])) {
+ printk(KERN_ERR "failed to get sysmmu_lite1\n");
+ goto err_clk11;
+ }
+ /* CLK_SMMU_LITE0 - CLK_GATE_IP_ISP0 (0x1004 8800), [11] */
+ pdata->control_clock[9] = clk_get(&pdev->dev, "sysmmu_lite0");
+ if (IS_ERR(pdata->control_clock[9])) {
+ printk(KERN_ERR "failed to get sysmmu_lite0\n");
+ goto err_clk12;
+ }
+ /* CLK_SPI1_ISP - CLK_GATE_IP_ISP0 (0x1004 8804), [13] */
+ pdata->control_clock[10] = clk_get(&pdev->dev, "spi1_isp");
+ if (IS_ERR(pdata->control_clock[10])) {
+ printk(KERN_ERR "failed to get spi1_isp\n");
+ goto err_clk13;
+ }
+ /* CLK_SPI0_ISP - CLK_GATE_IP_ISP0 (0x1004 8804), [12] */
+ pdata->control_clock[11] = clk_get(&pdev->dev, "spi0_isp");
+ if (IS_ERR(pdata->control_clock[11])) {
+ printk(KERN_ERR "failed to get spi0_isp\n");
+ goto err_clk14;
+ }
+ /* CLK_SMMU_FD - CLK_GATE_IP_ISP0 (0x1004 8800), [10] */
+ pdata->control_clock[12] = clk_get(&pdev->dev, "sysmmu_fd");
+ if (IS_ERR(pdata->control_clock[12])) {
+ printk(KERN_ERR "failed to get sysmmu_fd\n");
+ goto err_clk15;
+ }
+ /* CLK_SMMU_DRC - CLK_GATE_IP_ISP0 (0x1004 8800), [9] */
+ pdata->control_clock[13] = clk_get(&pdev->dev, "sysmmu_drc");
+ if (IS_ERR(pdata->control_clock[13])) {
+ printk(KERN_ERR "failed to get sysmmu_drc\n");
+ goto err_clk16;
+ }
+ /* CLK_SMMU_ISP - CLK_GATE_IP_ISP0 (0x1004 8800), [8] */
+ pdata->control_clock[14] = clk_get(&pdev->dev, "sysmmu_isp");
+ if (IS_ERR(pdata->control_clock[14])) {
+ printk(KERN_ERR "failed to get sysmmu_isp\n");
+ goto err_clk17;
+ }
+ /* CLK_SMMU_ISPCX - CLK_GATE_IP_ISP0 (0x1004 8804), [4] */
+ pdata->control_clock[15] = clk_get(&pdev->dev, "sysmmu_ispcx");
+ if (IS_ERR(pdata->control_clock[15])) {
+ printk(KERN_ERR "failed to get sysmmu_ispcx\n");
+ goto err_clk18;
+ }
+ return 0;
+
+err_clk18:
+ clk_put(pdata->control_clock[14]);
+err_clk17:
+ clk_put(pdata->control_clock[13]);
+err_clk16:
+ clk_put(pdata->control_clock[12]);
+err_clk15:
+ clk_put(pdata->control_clock[11]);
+err_clk14:
+ clk_put(pdata->control_clock[10]);
+err_clk13:
+ clk_put(pdata->control_clock[9]);
+err_clk12:
+ clk_put(pdata->control_clock[8]);
+err_clk11:
+ clk_put(pdata->control_clock[7]);
+err_clk10:
+ clk_put(pdata->control_clock[6]);
+err_clk9:
+ clk_put(pdata->control_clock[5]);
+err_clk8:
+ clk_put(pdata->control_clock[4]);
+err_clk7:
+ clk_put(pdata->control_clock[3]);
+err_clk6:
+ clk_put(pdata->control_clock[2]);
+err_clk5:
+ clk_put(pdata->control_clock[1]);
+err_clk4:
+ clk_put(pdata->control_clock[0]);
+err_clk3:
+ clk_put(pdata->div_clock[1]);
+err_clk2:
+ clk_put(pdata->div_clock[0]);
+err_clk1:
+ return -EINVAL;
+}
+
+int exynos_fimc_is_cfg_clk(struct platform_device *pdev)
+{
+ struct exynos4_platform_fimc_is *pdata;
+ unsigned int tmp;
+ pdata = to_fimc_is_plat(&pdev->dev);
+
+ /* 1. MCUISP */
+ __raw_writel(0x00000011, EXYNOS4_CLKDIV_ISP0);
+ /* 2. ACLK_ISP */
+ __raw_writel(0x00000030, EXYNOS4_CLKDIV_ISP1);
+ /* 3. Set mux - CLK_SRC_TOP1(0x1003 C214) [24],[20]*/
+ tmp = __raw_readl(EXYNOS4_CLKSRC_TOP1);
+ tmp |= (0x1 << EXYNOS4_CLKDIV_TOP1_ACLK200_SUB_SHIFT |
+ 0x1 << EXYNOS4_CLKDIV_TOP1_ACLK400_MCUISP_SUB_SHIFT);
+ __raw_writel(tmp, EXYNOS4_CLKSRC_TOP1);
+
+ /* 4. UART-ISP */
+ clk_set_parent(pdata->div_clock[UART_ISP_RATIO],
+ pdata->div_clock[UART_ISP_SEL]);
+ clk_set_rate(pdata->div_clock[UART_ISP_RATIO], 50 * 1000000);
+
+ return 0;
+}
+
+int exynos_fimc_is_clk_on(struct platform_device *pdev)
+{
+ struct exynos4_platform_fimc_is *pdata;
+ int i;
+ pdata = to_fimc_is_plat(&pdev->dev);
+
+ /* 1. CLK_GATE_IP_ISP (0x1003 C938)*/
+#if defined(CONFIG_MACH_SMDK4X12)
+ clk_enable(pdata->div_clock[UART_ISP_RATIO]);
+#endif
+ /* 2. CLK_GATE_IP_ISP0, CLK_GATE_IP_ISP1 (0x1004 8800) (0x1004 8804)*/
+ for (i = 0; i < (EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS - 4); i++)
+ clk_enable(pdata->control_clock[i]);
+#if defined(CONFIG_VIDEOBUF2_CMA_PHYS)
+ /* In case of CMA, clocks related system MMU off */
+ clk_enable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-4]);
+ clk_enable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-3]);
+ clk_enable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-2]);
+ clk_enable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-1]);
+#endif
+ for (i = 0; i < (EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS - 4); i++)
+ clk_disable(pdata->control_clock[i]);
+#if defined(CONFIG_VIDEOBUF2_CMA_PHYS)
+ /* In case of CMA, clocks related system MMU off */
+ clk_disable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-4]);
+ clk_disable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-3]);
+ clk_disable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-2]);
+ clk_disable(pdata->control_clock[EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS-1]);
+#endif
+ return 0;
+}
+
+int exynos_fimc_is_clk_off(struct platform_device *pdev)
+{
+ struct exynos4_platform_fimc_is *pdata;
+ pdata = to_fimc_is_plat(&pdev->dev);
+
+ /* 1. CLK_GATE_IP_ISP (0x1003 C938)*/
+#if defined(CONFIG_MACH_SMDK4X12)
+ clk_disable(pdata->div_clock[UART_ISP_RATIO]);
+#endif
+
+ return 0;
+}
+
+int exynos_fimc_is_clk_put(struct platform_device *pdev)
+{
+ struct exynos4_platform_fimc_is *pdata;
+ int i;
+ pdata = to_fimc_is_plat(&pdev->dev);
+
+ for (i = 0; i < EXYNOS4_FIMC_IS_MAX_DIV_CLOCKS; i++)
+ clk_put(pdata->div_clock[i]);
+ for (i = 0; i < EXYNOS4_FIMC_IS_MAX_CONTROL_CLOCKS; i++)
+ clk_put(pdata->control_clock[i]);
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_ARCH_EXYNOS5)
+/*------------------------------------------------------*/
+/* Exynos5 series - FIMC-IS */
+/*------------------------------------------------------*/
+void exynos5_fimc_is_cfg_gpio(struct platform_device *pdev)
+{
+ int ret;
+
+ /* 1. UART setting for FIMC-IS */
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_5M_nRST, "GPIO_5M_nRST");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_5M_nRST ####\n");
+ s3c_gpio_cfgpin(GPIO_5M_nRST, (0x2<<0));
+ s3c_gpio_setpull(GPIO_5M_nRST, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_5M_nRST);
+#else
+ ret = gpio_request(EXYNOS5_GPE0(0), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_0 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(0), (0x2<<0));
+ s3c_gpio_setpull(EXYNOS5_GPE0(0), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(0));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+#else
+ ret = gpio_request(EXYNOS5_GPE0(1), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_1 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(1), (0x2<<4));
+ s3c_gpio_setpull(EXYNOS5_GPE0(1), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(1));
+
+ ret = gpio_request(EXYNOS5_GPE0(2), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_2 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(2), (0x3<<8));
+ s3c_gpio_setpull(EXYNOS5_GPE0(2), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(2));
+
+ ret = gpio_request(EXYNOS5_GPE0(3), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_3 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(3), (0x3<<12));
+ s3c_gpio_setpull(EXYNOS5_GPE0(3), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(3));
+
+ ret = gpio_request(EXYNOS5_GPE0(4), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_4 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(4), (0x3<<16));
+ s3c_gpio_setpull(EXYNOS5_GPE0(4), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(4));
+
+ ret = gpio_request(EXYNOS5_GPE0(5), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_5 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(5), (0x3<<20));
+ s3c_gpio_setpull(EXYNOS5_GPE0(5), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(5));
+
+ ret = gpio_request(EXYNOS5_GPE0(6), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_6 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(6), (0x3<<24));
+ s3c_gpio_setpull(EXYNOS5_GPE0(6), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(6));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_ISP_TXD, "GPIO_ISP_TXD");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_ISP_TXD ####\n");
+ s3c_gpio_cfgpin(GPIO_ISP_TXD, (0x3<<28));
+ s3c_gpio_setpull(GPIO_ISP_TXD, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_ISP_TXD);
+#else
+ ret = gpio_request(EXYNOS5_GPE0(7), "GPE0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE0_7 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE0(7), (0x3<<28));
+ s3c_gpio_setpull(EXYNOS5_GPE0(7), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE0(7));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+#else
+ ret = gpio_request(EXYNOS5_GPE1(0), "GPE1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE1_0 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE1(0), (0x3<<0));
+ s3c_gpio_setpull(EXYNOS5_GPE1(0), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE1(0));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_ISP_RXD, "GPIO_ISP_RXD");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_ISP_RXD ####\n");
+ s3c_gpio_cfgpin(GPIO_ISP_RXD, (0x3<<4));
+ s3c_gpio_setpull(GPIO_ISP_RXD, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_ISP_RXD);
+#else
+ ret = gpio_request(EXYNOS5_GPE1(1), "GPE1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPE1_1 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPE1(1), (0x3<<4));
+ s3c_gpio_setpull(EXYNOS5_GPE1(1), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPE1(1));
+#endif
+
+ /* 2. GPIO setting for FIMC-IS */
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_5M_CAM_SDA_18V, "GPIO_5M_CAM_SDA_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_5M_CAM_SDA_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_5M_CAM_SDA_18V, (0x2<<0));
+ s3c_gpio_setpull(GPIO_5M_CAM_SDA_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_5M_CAM_SDA_18V);
+#else
+ ret = gpio_request(EXYNOS5_GPF0(0), "GPF0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF0_0 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF0(0), (0x2<<0));
+ s3c_gpio_setpull(EXYNOS5_GPF0(0), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF0(0));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_5M_CAM_SCL_18V, "GPIO_5M_CAM_SCL_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_5M_CAM_SCL_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_5M_CAM_SCL_18V, (0x2<<4));
+ s3c_gpio_setpull(GPIO_5M_CAM_SCL_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_5M_CAM_SCL_18V);
+#else
+ ret = gpio_request(EXYNOS5_GPF0(1), "GPF0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF0_1 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF0(1), (0x2<<4));
+ s3c_gpio_setpull(EXYNOS5_GPF0(1), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF0(1));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_VT_CAM_SDA_18V, "GPIO_VT_CAM_SDA_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_VT_CAM_SDA_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_VT_CAM_SDA_18V, (0x2<<8));
+ s3c_gpio_setpull(GPIO_VT_CAM_SDA_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_VT_CAM_SDA_18V);
+#else
+ ret = gpio_request(EXYNOS5_GPF0(2), "GPF0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF0_2 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF0(2), (0x2<<8));
+ s3c_gpio_setpull(EXYNOS5_GPF0(2), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF0(2));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_VT_CAM_SCL_18V, "GPIO_VT_CAM_SCL_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_5M_CAM_SDA_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_VT_CAM_SCL_18V, (0x2<<12));
+ s3c_gpio_setpull(GPIO_VT_CAM_SCL_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_VT_CAM_SCL_18V);
+#else
+ ret = gpio_request(EXYNOS5_GPF0(0), "GPF0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF0_3 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF0(3), (0x2<<12));
+ s3c_gpio_setpull(EXYNOS5_GPF0(3), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF0(3));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_CMC_CLK_18V, "GPIO_CMC_CLK_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_CMC_CLK_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_CMC_CLK_18V, (0x3<<0));
+ s3c_gpio_setpull(GPIO_CMC_CLK_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_CMC_CLK_18V);
+#else
+ ret = gpio_request(EXYNOS5_GPF1(0), "GPF1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF1_0 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF1(0), (0x3<<0));
+ s3c_gpio_setpull(EXYNOS5_GPF1(0), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF1(0));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_CMC_CS_18V, "GPIO_CMC_CS_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_CMC_CS_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_CMC_CS_18V, (0x3<<4));
+ s3c_gpio_setpull(GPIO_CMC_CS_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_CMC_CS_18V);
+#else
+ ret = gpio_request(EXYNOS5_GPF1(1), "GPF1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF1_0 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF1(1), (0x3<<4));
+ s3c_gpio_setpull(EXYNOS5_GPF1(1), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF1(1));
+#endif
+
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, CLK_OUT */
+#if defined(CONFIG_MACH_P10)
+ s3c_gpio_cfgrange_nopull(GPIO_CAM_MCLK, 1, S3C_GPIO_SFN(2));
+#else
+ s3c_gpio_cfgrange_nopull(EXYNOS5_GPH0(3), 1, S3C_GPIO_SFN(2));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ /* CAM A port : POWER */
+ s3c_gpio_cfgpin(GPIO_CAM_IO_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_CAM_IO_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_CAM_IO_EN, 1);
+
+ /* CAM A reset*/
+ ret = gpio_request(GPIO_5M_nRST, "GPIO_5M_nRST");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_5M_nRST ####\n");
+
+ s3c_gpio_setpull(GPIO_5M_nRST, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_5M_nRST, 0);
+ gpio_direction_output(GPIO_5M_nRST, 1);
+ gpio_free(GPIO_5M_nRST);
+#else
+ /* CAM A port(b0010) : DATA[0-7] */
+ /* s3c_gpio_cfgrange_nopull(EXYNOS5_GPH1(0), 8, S3C_GPIO_SFN(2)); */
+
+ /* Camera A reset*/
+ ret = gpio_request(EXYNOS5_GPX1(2), "GPX1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPX1_2 ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPX1(2), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPX1(2), 0);
+ gpio_direction_output(EXYNOS5_GPX1(2), 1);
+ gpio_free(EXYNOS5_GPX1(2));
+#endif
+
+ /* CAM B port */
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_VTCAM_MCLK, "GPIO_VTCAM_MCLK");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_VTCAM_MCLK ####\n");
+ s3c_gpio_cfgpin(GPIO_VTCAM_MCLK, (0x2<<4));
+ s3c_gpio_setpull(GPIO_VTCAM_MCLK, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_VTCAM_MCLK);
+#else
+ /* CAM B port */
+ ret = gpio_request(EXYNOS5_GPG2(1), "GPG2");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPG2_1 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPG2(1), (0x2<<4));
+ s3c_gpio_setpull(EXYNOS5_GPG2(1), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPG2(1));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_VT_CAM_SDA_18V, "GPIO_VT_CAM_SDA_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_VT_CAM_SDA_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_VT_CAM_SDA_18V, (0x2<<8));
+ s3c_gpio_setpull(GPIO_VT_CAM_SDA_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_VT_CAM_SDA_18V);
+#else
+
+ ret = gpio_request(EXYNOS5_GPF0(2), "GPF0");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF0_2 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF0(2), (0x2<<8));
+ s3c_gpio_setpull(EXYNOS5_GPF0(2), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF0(2));
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_VT_CAM_SCL_18V, "GPIO_VT_CAM_SCL_18V");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_VT_CAM_SCL_18V ####\n");
+ s3c_gpio_cfgpin(GPIO_VT_CAM_SCL_18V, (0x2<<12));
+ s3c_gpio_setpull(GPIO_VT_CAM_SCL_18V, S3C_GPIO_PULL_NONE);
+ gpio_free(GPIO_VT_CAM_SCL_18V);
+#else
+
+ ret = gpio_request(EXYNOS5_GPF0(3), "GPF1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPF0_3 ####\n");
+ s3c_gpio_cfgpin(EXYNOS5_GPF0(3), (0x2<<12));
+ s3c_gpio_setpull(EXYNOS5_GPF0(3), S3C_GPIO_PULL_NONE);
+ gpio_free(EXYNOS5_GPF0(3));
+#endif
+
+ /* Camera B reset*/
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_CAM_VT_nRST, "GPIO_CAM_VT_nRST");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_CAM_VT_nRST ####\n");
+
+ s3c_gpio_setpull(GPIO_CAM_VT_nRST, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_CAM_VT_nRST, 0);
+ gpio_direction_output(GPIO_CAM_VT_nRST, 1);
+ gpio_free(GPIO_CAM_VT_nRST);
+#else
+
+ /* Camera B reset*/
+ ret = gpio_request(EXYNOS5_GPX1(0), "GPX1");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPX1_0 ####\n");
+
+ s3c_gpio_setpull(EXYNOS5_GPX1(0), S3C_GPIO_PULL_NONE);
+ gpio_direction_output(EXYNOS5_GPX1(0), 0);
+ gpio_direction_output(EXYNOS5_GPX1(0), 1);
+ gpio_free(EXYNOS5_GPX1(0));
+#endif
+
+ /* Flash */
+#if defined(CONFIG_MACH_P10)
+ ret = gpio_request(GPIO_CAM_FLASH_SET_T, "GPIO_CAM_FLASH_SET_T");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_CAM_FLASH_SET_T ####\n");
+
+ s3c_gpio_setpull(GPIO_CAM_FLASH_SET_T, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_CAM_FLASH_SET_T, 0);
+ /* turn on */
+ /* gpio_direction_output(GPIO_CAM_FLASH_SET_T, 1); */
+ gpio_free(GPIO_CAM_FLASH_SET_T);
+
+ ret = gpio_request(GPIO_CAM_FLASH_EN_T, "GPIO_CAM_FLASH_EN_T");
+ if (ret)
+ printk(KERN_ERR "#### failed to request GPIO_CAM_FLASH_EN_T ####\n");
+
+ s3c_gpio_setpull(GPIO_CAM_FLASH_EN_T, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_CAM_FLASH_EN_T, 0);
+ /* turn on */
+ /* gpio_direction_output(GPIO_CAM_FLASH_EN_T, 1); */
+ gpio_free(GPIO_CAM_FLASH_EN_T);
+#endif
+
+#if defined(CONFIG_MACH_P10)
+ /* CAM A port : POWER */
+ gpio_set_value(GPIO_CAM_IO_EN, 0);
+#endif
+}
+
+int exynos5_fimc_is_cfg_clk(struct platform_device *pdev)
+{
+ struct clk *aclk_mcuisp = NULL;
+ struct clk *aclk_266 = NULL;
+ struct clk *aclk_mcuisp_div0 = NULL;
+ struct clk *aclk_mcuisp_div1 = NULL;
+ struct clk *aclk_266_div0 = NULL;
+ struct clk *aclk_266_div1 = NULL;
+ struct clk *aclk_266_mpwm = NULL;
+ struct clk *sclk_uart_isp = NULL;
+ struct clk *sclk_uart_isp_div = NULL;
+ struct clk *mout_mpll = NULL;
+ struct clk *sclk_mipi = NULL;
+ struct clk *cam_src = NULL;
+ struct clk *cam_A_clk = NULL;
+ unsigned long mcu_isp_400;
+ unsigned long isp_266;
+ unsigned long isp_uart;
+ unsigned long mipi;
+ unsigned long epll;
+
+ /*
+ * initialize Clocks
+ */
+
+ printk(KERN_DEBUG "exynos5_fimc_is_cfg_clk\n");
+ /* 1. MCUISP */
+ aclk_mcuisp = clk_get(&pdev->dev, "aclk_400_isp");
+ if (IS_ERR(aclk_mcuisp))
+ return PTR_ERR(aclk_mcuisp);
+
+ aclk_mcuisp_div0 = clk_get(&pdev->dev, "aclk_400_isp_div0");
+ if (IS_ERR(aclk_mcuisp_div0))
+ return PTR_ERR(aclk_mcuisp_div0);
+
+ aclk_mcuisp_div1 = clk_get(&pdev->dev, "aclk_400_isp_div1");
+ if (IS_ERR(aclk_mcuisp_div1))
+ return PTR_ERR(aclk_mcuisp_div1);
+
+ clk_set_rate(aclk_mcuisp_div0, 400 * 1000000);
+ clk_set_rate(aclk_mcuisp_div1, 400 * 1000000);
+
+ mcu_isp_400 = clk_get_rate(aclk_mcuisp);
+ printk(KERN_DEBUG "mcu_isp_400 : %ld\n", mcu_isp_400);
+
+ mcu_isp_400 = clk_get_rate(aclk_mcuisp_div0);
+ printk(KERN_DEBUG "mcu_isp_400_div0 : %ld\n", mcu_isp_400);
+
+ mcu_isp_400 = clk_get_rate(aclk_mcuisp_div1);
+ printk(KERN_DEBUG "aclk_mcuisp_div1 : %ld\n", mcu_isp_400);
+
+ clk_put(aclk_mcuisp);
+ clk_put(aclk_mcuisp_div0);
+ clk_put(aclk_mcuisp_div1);
+
+ /* 2. ACLK_ISP */
+ aclk_266 = clk_get(&pdev->dev, "aclk_266_isp");
+ if (IS_ERR(aclk_266))
+ return PTR_ERR(aclk_266);
+ aclk_266_div0 = clk_get(&pdev->dev, "aclk_266_isp_div0");
+ if (IS_ERR(aclk_266_div0))
+ return PTR_ERR(aclk_266_div0);
+ aclk_266_div1 = clk_get(&pdev->dev, "aclk_266_isp_div1");
+ if (IS_ERR(aclk_266_div1))
+ return PTR_ERR(aclk_266_div1);
+ aclk_266_mpwm = clk_get(&pdev->dev, "aclk_266_isp_divmpwm");
+ if (IS_ERR(aclk_266_mpwm))
+ return PTR_ERR(aclk_266_mpwm);
+
+ clk_set_rate(aclk_266_div0, 134 * 1000000);
+ clk_set_rate(aclk_266_div1, 68 * 1000000);
+
+ isp_266 = clk_get_rate(aclk_266);
+ printk(KERN_DEBUG "isp_266 : %ld\n", isp_266);
+
+ isp_266 = clk_get_rate(aclk_266_div0);
+ printk(KERN_DEBUG "isp_266_div0 : %ld\n", isp_266);
+
+ isp_266 = clk_get_rate(aclk_266_div1);
+ printk(KERN_DEBUG "isp_266_div1 : %ld\n", isp_266);
+
+ isp_266 = clk_get_rate(aclk_266_mpwm);
+ printk(KERN_DEBUG "isp_266_mpwm : %ld\n", isp_266);
+
+ clk_put(aclk_266);
+ clk_put(aclk_266_div0);
+ clk_put(aclk_266_div1);
+ clk_put(aclk_266_mpwm);
+
+ /* 3. UART-ISP */
+ sclk_uart_isp = clk_get(&pdev->dev, "sclk_uart_src_isp");
+ if (IS_ERR(sclk_uart_isp))
+ return PTR_ERR(sclk_uart_isp);
+
+ sclk_uart_isp_div = clk_get(&pdev->dev, "sclk_uart_isp");
+ if (IS_ERR(sclk_uart_isp_div))
+ return PTR_ERR(sclk_uart_isp_div);
+
+ clk_set_parent(sclk_uart_isp_div, sclk_uart_isp);
+ clk_set_rate(sclk_uart_isp_div, 50 * 1000000);
+
+ isp_uart = clk_get_rate(sclk_uart_isp);
+ printk(KERN_DEBUG "isp_uart : %ld\n", isp_uart);
+ isp_uart = clk_get_rate(sclk_uart_isp_div);
+ printk(KERN_DEBUG "isp_uart_div : %ld\n", isp_uart);
+
+ clk_put(sclk_uart_isp);
+ clk_put(sclk_uart_isp_div);
+
+ /* MIPI-CSI */
+ mout_mpll = clk_get(&pdev->dev, "mout_mpll_user");
+ if (IS_ERR(mout_mpll))
+ return PTR_ERR(mout_mpll);
+ sclk_mipi = clk_get(&pdev->dev, "sclk_gscl_wrap0");
+ if (IS_ERR(sclk_mipi))
+ return PTR_ERR(sclk_mipi);
+
+ clk_set_parent(sclk_mipi, mout_mpll);
+ clk_set_rate(sclk_mipi, 267 * 1000000);
+
+ mout_mpll = clk_get(&pdev->dev, "mout_mpll_user");
+ if (IS_ERR(mout_mpll))
+ return PTR_ERR(mout_mpll);
+ sclk_mipi = clk_get(&pdev->dev, "sclk_gscl_wrap1");
+ if (IS_ERR(sclk_mipi))
+ return PTR_ERR(sclk_mipi);
+
+ clk_set_parent(sclk_mipi, mout_mpll);
+ clk_set_rate(sclk_mipi, 267 * 1000000);
+ mipi = clk_get_rate(mout_mpll);
+ printk(KERN_DEBUG "mipi_src : %ld\n", mipi);
+ mipi = clk_get_rate(sclk_mipi);
+ printk(KERN_DEBUG "mipi_div : %ld\n", mipi);
+
+ clk_put(mout_mpll);
+ clk_put(sclk_mipi);
+
+ /* camera A */
+ cam_src = clk_get(&pdev->dev, "xxti");
+ if (IS_ERR(cam_src))
+ return PTR_ERR(cam_src);
+ cam_A_clk = clk_get(&pdev->dev, "sclk_cam0");
+ if (IS_ERR(cam_A_clk))
+ return PTR_ERR(cam_A_clk);
+
+ epll = clk_get_rate(cam_src);
+ printk(KERN_DEBUG "epll : %ld\n", epll);
+
+ clk_set_parent(cam_A_clk, cam_src);
+ clk_set_rate(cam_A_clk, 24 * 1000000);
+
+ clk_put(cam_src);
+ clk_put(cam_A_clk);
+
+ /* camera B */
+ cam_src = clk_get(&pdev->dev, "xxti");
+ if (IS_ERR(cam_src))
+ return PTR_ERR(cam_src);
+ cam_A_clk = clk_get(&pdev->dev, "sclk_cam1");
+ if (IS_ERR(cam_A_clk))
+ return PTR_ERR(cam_A_clk);
+
+ epll = clk_get_rate(cam_src);
+ printk(KERN_DEBUG "epll : %ld\n", epll);
+
+ clk_set_parent(cam_A_clk, cam_src);
+ clk_set_rate(cam_A_clk, 24 * 1000000);
+
+ clk_put(cam_src);
+ clk_put(cam_A_clk);
+ return 0;
+}
+
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+
+int exynos5_fimc_is_clk_on(struct platform_device *pdev)
+{
+ struct clk *gsc_ctrl = NULL;
+ struct clk *isp_ctrl = NULL;
+ struct clk *mipi_ctrl = NULL;
+ struct clk *cam_if_top = NULL;
+ struct clk *cam_A_clk = NULL;
+ struct regulator *regulator = NULL;
+
+ printk(KERN_DEBUG "exynos5_fimc_is_clk_on\n");
+
+#if defined(CONFIG_MACH_P10)
+ /* CAM A port : POWER */
+ gpio_set_value(GPIO_CAM_IO_EN, 1);
+
+ /* ISP */
+ regulator = regulator_get(NULL, "cam_core_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ /* ldo18 */
+ regulator = regulator_get(NULL, "cam_io_from_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ /* ldo24 */
+ regulator = regulator_get(NULL, "cam_af_2.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ regulator_enable(regulator);
+ regulator_put(regulator);
+
+ /* ldo19 */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ regulator_enable(regulator);
+ regulator_put(regulator);
+#endif
+
+ gsc_ctrl = clk_get(&pdev->dev, "gscl");
+ if (IS_ERR(gsc_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(gscl) failed\n", __func__);
+ return PTR_ERR(gsc_ctrl);
+ }
+
+ clk_enable(gsc_ctrl);
+ clk_put(gsc_ctrl);
+
+ isp_ctrl = clk_get(&pdev->dev, "isp0");
+ if (IS_ERR(isp_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(isp0) failed\n", __func__);
+ return PTR_ERR(isp_ctrl);
+ }
+
+ clk_enable(isp_ctrl);
+ clk_put(isp_ctrl);
+
+ isp_ctrl = clk_get(&pdev->dev, "isp1");
+ if (IS_ERR(isp_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(isp1) failed\n", __func__);
+ return PTR_ERR(isp_ctrl);
+ }
+
+ clk_enable(isp_ctrl);
+ clk_put(isp_ctrl);
+
+ mipi_ctrl = clk_get(&pdev->dev, "gscl_wrap0");
+ if (IS_ERR(mipi_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(gscl_wrap0) failed\n", __func__);
+ return PTR_ERR(mipi_ctrl);
+ }
+
+ clk_enable(mipi_ctrl);
+ clk_put(mipi_ctrl);
+
+ mipi_ctrl = clk_get(&pdev->dev, "gscl_wrap1");
+ if (IS_ERR(mipi_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(gscl_wrap1) failed\n", __func__);
+ return PTR_ERR(mipi_ctrl);
+ }
+
+ clk_enable(mipi_ctrl);
+ clk_put(mipi_ctrl);
+
+ cam_if_top = clk_get(&pdev->dev, "camif_top");
+ if (IS_ERR(cam_if_top)) {
+ printk(KERN_ERR "%s : clk_get(camif_top) failed\n", __func__);
+ return PTR_ERR(cam_if_top);
+ }
+
+ clk_enable(cam_if_top);
+ clk_put(cam_if_top);
+
+ cam_A_clk = clk_get(&pdev->dev, "sclk_cam0");
+ if (IS_ERR(cam_A_clk)) {
+ printk(KERN_ERR "%s : clk_get(sclk_cam0) failed\n", __func__);
+ return PTR_ERR(cam_A_clk);
+ }
+
+ clk_enable(cam_A_clk);
+ clk_put(cam_A_clk);
+
+ cam_A_clk = clk_get(&pdev->dev, "sclk_cam1");
+ if (IS_ERR(cam_A_clk)) {
+ printk(KERN_ERR "%s : clk_get(sclk_cam1) failed\n", __func__);
+ return PTR_ERR(cam_A_clk);
+ }
+
+ clk_enable(cam_A_clk);
+ clk_put(cam_A_clk);
+
+ return 0;
+}
+
+int exynos5_fimc_is_clk_off(struct platform_device *pdev)
+{
+ struct clk *gsc_ctrl = NULL;
+ struct clk *isp_ctrl = NULL;
+ struct clk *mipi_ctrl = NULL;
+ struct clk *cam_if_top = NULL;
+ struct clk *cam_A_clk = NULL;
+ struct regulator *regulator = NULL;
+
+ printk(KERN_DEBUG "exynos5_fimc_is_clk_on\n");
+
+ cam_A_clk = clk_get(&pdev->dev, "sclk_cam1");
+ if (IS_ERR(cam_A_clk)) {
+ printk(KERN_ERR "%s : clk_get(sclk_cam1) failed\n", __func__);
+ return PTR_ERR(cam_A_clk);
+ }
+
+ clk_disable(cam_A_clk);
+ clk_put(cam_A_clk);
+
+ cam_A_clk = clk_get(&pdev->dev, "sclk_cam0");
+ if (IS_ERR(cam_A_clk)) {
+ printk(KERN_ERR "%s : clk_get(sclk_cam0) failed\n", __func__);
+ return PTR_ERR(cam_A_clk);
+ }
+
+ clk_disable(cam_A_clk);
+ clk_put(cam_A_clk);
+
+ cam_if_top = clk_get(&pdev->dev, "camif_top");
+ if (IS_ERR(cam_if_top)) {
+ printk(KERN_ERR "%s : clk_get(camif_top) failed\n", __func__);
+ return PTR_ERR(cam_if_top);
+ }
+
+ clk_disable(cam_if_top);
+ clk_put(cam_if_top);
+
+ mipi_ctrl = clk_get(&pdev->dev, "gscl_wrap1");
+ if (IS_ERR(mipi_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(gscl_wrap1) failed\n", __func__);
+ return PTR_ERR(mipi_ctrl);
+ }
+
+ clk_disable(mipi_ctrl);
+ clk_put(mipi_ctrl);
+
+ mipi_ctrl = clk_get(&pdev->dev, "gscl_wrap0");
+ if (IS_ERR(mipi_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(gscl_wrap0) failed\n", __func__);
+ return PTR_ERR(mipi_ctrl);
+ }
+
+ clk_disable(mipi_ctrl);
+ clk_put(mipi_ctrl);
+
+ isp_ctrl = clk_get(&pdev->dev, "isp1");
+ if (IS_ERR(isp_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(isp1) failed\n", __func__);
+ return PTR_ERR(isp_ctrl);
+ }
+
+ clk_disable(isp_ctrl);
+ clk_put(isp_ctrl);
+
+ isp_ctrl = clk_get(&pdev->dev, "isp0");
+ if (IS_ERR(isp_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(isp0) failed\n", __func__);
+ return PTR_ERR(isp_ctrl);
+ }
+
+ clk_disable(isp_ctrl);
+ clk_put(isp_ctrl);
+
+ gsc_ctrl = clk_get(&pdev->dev, "gscl");
+ if (IS_ERR(gsc_ctrl)) {
+ printk(KERN_ERR "%s : clk_get(gscl) failed\n", __func__);
+ return PTR_ERR(gsc_ctrl);
+ }
+
+ clk_disable(gsc_ctrl);
+ clk_put(gsc_ctrl);
+
+#if defined(CONFIG_MACH_P10)
+ /* ldo19 */
+ regulator = regulator_get(NULL, "vt_cam_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ /* ldo24 */
+ regulator = regulator_get(NULL, "cam_af_2.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ /* ldo18 */
+ regulator = regulator_get(NULL, "cam_io_from_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ /* ISP */
+ regulator = regulator_get(NULL, "cam_core_1.8v");
+ if (IS_ERR(regulator)) {
+ printk(KERN_ERR "%s : regulator_get failed\n", __func__);
+ return PTR_ERR(regulator);
+ }
+ if (regulator_is_enabled(regulator))
+ regulator_force_disable(regulator);
+ regulator_put(regulator);
+
+ /* CAM A port : POWER */
+ gpio_set_value(GPIO_CAM_IO_EN, 0);
+#endif
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-exynos4/setup-fimc.c b/arch/arm/mach-exynos/setup-fimc.c
index 6a45078..4323429 100644
--- a/arch/arm/mach-exynos4/setup-fimc.c
+++ b/arch/arm/mach-exynos/setup-fimc.c
@@ -20,14 +20,14 @@ int exynos4_fimc_setup_gpio(enum s5p_camport_id id)
switch (id) {
case S5P_CAMPORT_A:
- gpio8 = EXYNOS4_GPJ0(0); /* PCLK, VSYNC, HREF, DATA[0:4] */
- gpio5 = EXYNOS4_GPJ1(0); /* DATA[5:7], CLKOUT, FIELD */
+ gpio8 = EXYNOS4210_GPJ0(0); /* PCLK, VSYNC, HREF, DATA[0:4] */
+ gpio5 = EXYNOS4210_GPJ1(0); /* DATA[5:7], CLKOUT, FIELD */
sfn = S3C_GPIO_SFN(2);
break;
case S5P_CAMPORT_B:
- gpio8 = EXYNOS4_GPE0(0); /* DATA[0:7] */
- gpio5 = EXYNOS4_GPE1(0); /* PCLK, VSYNC, HREF, CLKOUT, FIELD */
+ gpio8 = EXYNOS4210_GPE0(0); /* DATA[0:7] */
+ gpio5 = EXYNOS4210_GPE1(0); /* PCLK, VSYNC, HREF, CLKOUT, FIELD */
sfn = S3C_GPIO_SFN(3);
break;
diff --git a/arch/arm/mach-exynos/setup-fimc0.c b/arch/arm/mach-exynos/setup-fimc0.c
new file mode 100644
index 0000000..e95adcb
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-fimc0.c
@@ -0,0 +1,107 @@
+/* linux/arch/arm/mach-s5pv310/setup-fimc0.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMC 0 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <plat/map-s5p.h>
+#include <plat/cpu.h>
+#include <mach/map.h>
+
+struct platform_device; /* don't need the contents */
+
+void s3c_fimc0_cfg_gpio(struct platform_device *pdev)
+{
+#if defined(CONFIG_MACH_SMDK4212) || defined(CONFIG_MACH_SMDK4210)
+ if (soc_is_exynos4210()) {
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPJ0(0), 8, S3C_GPIO_SFN(2));
+ /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPJ1(0), 5, S3C_GPIO_SFN(2));
+ /* CAM B port(b0011) : DATA[0-7] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPE1(0), 8, S3C_GPIO_SFN(3));
+ /* CAM B port(b0011) : PCLK, VSYNC, HREF, FIELD, CLKOUT */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPE0(0), 5, S3C_GPIO_SFN(3));
+ } else {
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPJ0(0), 8, S3C_GPIO_SFN(2));
+ /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPJ1(0), 5, S3C_GPIO_SFN(2));
+ /* CAM B port(b0011) : PCLK, DATA[0-6] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM0(0), 8, S3C_GPIO_SFN(3));
+ /* CAM B port(b0011) : FIELD, DATA[7]*/
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM1(0), 2, S3C_GPIO_SFN(3));
+ /* CAM B port(b0011) : VSYNC, HREF, CLKOUT*/
+ s3c_gpio_cfgrange_nopull(EXYNOS4212_GPM2(0), 3, S3C_GPIO_SFN(3));
+ }
+ /* note : driver strength to max is unnecessary */
+#elif defined(CONFIG_MACH_PX)
+ /* CAM A port(b0010) : PCLK, VSYNC, HREF, DATA[0-4] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPJ0(0), 8, S3C_GPIO_SFN(2));
+ /* CAM A port(b0010) : DATA[5-7], CLKOUT(MIPI CAM also), FIELD */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPJ1(0), 5, S3C_GPIO_SFN(2));
+ /* Disable Mclk */
+ s3c_gpio_cfgpin(EXYNOS4210_GPJ1(3), S3C_GPIO_INPUT);
+ s3c_gpio_setpull(EXYNOS4210_GPJ1(3), S3C_GPIO_PULL_DOWN);
+
+ /* CAM B port(b0011) : DATA[0-7] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPE1(0), 8, S3C_GPIO_SFN(3));
+ /* CAM B port(b0011) : PCLK, VSYNC, HREF, FIELD, CLKOUT */
+ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPE0(0), 5, S3C_GPIO_SFN(3));
+#endif
+}
+
+int s3c_fimc_clk_on(struct platform_device *pdev, struct clk **clk)
+{
+ struct clk *sclk_fimc_lclk = NULL;
+
+ sclk_fimc_lclk = clk_get(&pdev->dev, "sclk_fimc");
+ if (IS_ERR(sclk_fimc_lclk)) {
+ dev_err(&pdev->dev, "failed to get sclk_fimc_lclk\n");
+ goto err_clk1;
+ }
+
+ /* be able to handle clock on/off only with this clock */
+ *clk = clk_get(&pdev->dev, "fimc");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get interface clock\n");
+ goto err_clk2;
+ }
+
+ clk_enable(*clk);
+ clk_enable(sclk_fimc_lclk);
+
+ return 0;
+
+err_clk2:
+ clk_put(sclk_fimc_lclk);
+err_clk1:
+ return -EINVAL;
+}
+
+int s3c_fimc_clk_off(struct platform_device *pdev, struct clk **clk)
+{
+ if (*clk != NULL) {
+ clk_disable(*clk);
+ clk_put(*clk);
+ *clk = NULL;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c4.c b/arch/arm/mach-exynos/setup-fimc1.c
index 9f3c048..76a1e97 100644
--- a/arch/arm/mach-exynos4/setup-i2c4.c
+++ b/arch/arm/mach-exynos/setup-fimc1.c
@@ -1,23 +1,21 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c4.c
+/* linux/arch/arm/mach-s5pv310/setup-fimc1.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
*
- * I2C4 GPIO configuration.
+ * Base FIMC 1 gpio configuration
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
+#include <linux/types.h>
+
struct platform_device; /* don't need the contents */
-#include <linux/gpio.h>
-#include <plat/iic.h>
+#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
-void s3c_i2c4_cfg_gpio(struct platform_device *dev)
-{
- s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
- S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
+void s3c_fimc1_cfg_gpio(struct platform_device *pdev) { }
diff --git a/arch/arm/mach-exynos4/setup-i2c5.c b/arch/arm/mach-exynos/setup-fimc2.c
index 77e1a1e..a0d7fa3 100644
--- a/arch/arm/mach-exynos4/setup-i2c5.c
+++ b/arch/arm/mach-exynos/setup-fimc2.c
@@ -1,23 +1,21 @@
-/*
- * linux/arch/arm/mach-exynos4/setup-i2c5.c
+/* linux/arch/arm/mach-s5pv310/setup-fimc2.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
*
- * I2C5 GPIO configuration.
+ * Base FIMC 2 gpio configuration
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/kernel.h>
+#include <linux/types.h>
+
struct platform_device; /* don't need the contents */
-#include <linux/gpio.h>
-#include <plat/iic.h>
+#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
-void s3c_i2c5_cfg_gpio(struct platform_device *dev)
-{
- s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
- S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
-}
+void s3c_fimc2_cfg_gpio(struct platform_device *pdev) { }
diff --git a/arch/arm/mach-exynos/setup-fimc3.c b/arch/arm/mach-exynos/setup-fimc3.c
new file mode 100644
index 0000000..ee4182f
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-fimc3.c
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-s5pv310/setup-fimc3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base FIMC 3 gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_fimc3_cfg_gpio(struct platform_device *pdev) { }
diff --git a/arch/arm/mach-exynos/setup-fimd.c b/arch/arm/mach-exynos/setup-fimd.c
new file mode 100644
index 0000000..91bad86
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-fimd.c
@@ -0,0 +1,73 @@
+/* linux/arch/arm/mach-exynos/setup-fimd.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos4 FIMD configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+
+#include <mach/regs-clock.h>
+#include <mach/map.h>
+
+void exynos4_fimd_cfg_gpios(unsigned int base, unsigned int nr,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, cfg);
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, drvstr);
+}
+
+int __init exynos4_fimd_setup_clock(struct device *dev, const char *bus_clk,
+ const char *parent, unsigned long clk_rate)
+{
+ struct clk *clk_parent;
+ struct clk *sclk;
+
+ sclk = clk_get(dev, bus_clk);
+ if (IS_ERR(sclk))
+ return PTR_ERR(sclk);
+
+ clk_parent = clk_get(NULL, parent);
+ if (IS_ERR(clk_parent)) {
+ clk_put(sclk);
+ return PTR_ERR(clk_parent);
+ }
+
+ if (clk_set_parent(sclk, clk_parent)) {
+ pr_err("Unable to set parent %s of clock %s.\n",
+ clk_parent->name, sclk->name);
+ clk_put(sclk);
+ clk_put(clk_parent);
+ return PTR_ERR(sclk);
+ }
+
+ if (!clk_rate)
+ clk_rate = 87000000UL;
+
+ if (clk_set_rate(sclk, clk_rate)) {
+ pr_err("%s rate change failed: %lu\n", sclk->name, clk_rate);
+ clk_put(sclk);
+ clk_put(clk_parent);
+ return PTR_ERR(sclk);
+ }
+
+ clk_put(sclk);
+ clk_put(clk_parent);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/setup-fimd0.c b/arch/arm/mach-exynos/setup-fimd0.c
new file mode 100644
index 0000000..b763682
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-fimd0.c
@@ -0,0 +1,119 @@
+/* linux/arch/arm/mach-exynos/setup-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos4 FIMD 0 configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+
+#include <mach/regs-clock.h>
+#include <mach/map.h>
+
+#ifdef CONFIG_FB_S3C
+static void exynos4_fimd0_cfg_gpios(unsigned int base, unsigned int nr,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, cfg);
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, drvstr);
+}
+
+void exynos4_fimd0_gpio_setup_24bpp(void)
+{
+ unsigned int reg = 0;
+#if defined(CONFIG_LCD_WA101S) || defined(CONFIG_LCD_LTE480WV)
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+#elif defined(CONFIG_LCD_AMS369FG06)
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+#elif defined(CONFIG_LCD_LMS501KF03)
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF0(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV4);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF1(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF2(0), 8, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+ exynos4_fimd0_cfg_gpios(EXYNOS4_GPF3(0), 4, S3C_GPIO_SFN(2), S5P_GPIO_DRVSTR_LV1);
+#endif
+ /*
+ * Set DISPLAY_CONTROL register for Display path selection.
+ *
+ * DISPLAY_CONTROL[1:0]
+ * ---------------------
+ * 00 | MIE
+ * 01 | MDINE
+ * 10 | FIMD : selected
+ * 11 | FIMD
+ */
+#ifdef CONFIG_FB_S5P_MDNIE
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg &= ~(1<<13);
+ reg &= ~(1<<12);
+ reg &= ~(3<<10);
+ reg |= (1<<0);
+ reg &= ~(1<<1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#else
+ reg = __raw_readl(S3C_VA_SYS + 0x0210);
+ reg |= (1 << 1);
+ __raw_writel(reg, S3C_VA_SYS + 0x0210);
+#endif
+}
+#endif
+
+int __init exynos4_fimd0_setup_clock(struct device *dev, const char *parent,
+ unsigned long clk_rate)
+{
+ struct clk *clk_parent;
+ struct clk *sclk;
+
+ sclk = clk_get(dev, "sclk_fimd");
+ if (IS_ERR(sclk))
+ return PTR_ERR(sclk);
+
+ clk_parent = clk_get(NULL, parent);
+ if (IS_ERR(clk_parent)) {
+ clk_put(sclk);
+ return PTR_ERR(clk_parent);
+ }
+
+ if (clk_set_parent(sclk, clk_parent)) {
+ pr_err("Unable to set parent %s of clock %s.\n",
+ clk_parent->name, sclk->name);
+ clk_put(sclk);
+ clk_put(clk_parent);
+ return PTR_ERR(sclk);
+ }
+
+ if (!clk_rate)
+ clk_rate = 134000000UL;
+
+ if (clk_set_rate(sclk, clk_rate)) {
+ pr_err("%s rate change failed: %lu\n", sclk->name, clk_rate);
+ clk_put(sclk);
+ clk_put(clk_parent);
+ return PTR_ERR(sclk);
+ }
+
+ clk_put(sclk);
+ clk_put(clk_parent);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/setup-gsc.c b/arch/arm/mach-exynos/setup-gsc.c
new file mode 100644
index 0000000..493d756
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-gsc.c
@@ -0,0 +1,95 @@
+/* linux/arch/arm/mach-exynos/setup-gsc.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos5 G-Scaler clock configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <mach/regs-clock.h>
+#include <mach/map.h>
+#include <media/exynos_gscaler.h>
+
+void __init exynos5_gsc_set_pdev_name(int id, char *name)
+{
+ switch (id) {
+ case 0:
+ exynos5_device_gsc0.name = name;
+ break;
+ case 1:
+ exynos5_device_gsc1.name = name;
+ break;
+ case 2:
+ exynos5_device_gsc2.name = name;
+ break;
+ case 3:
+ exynos5_device_gsc3.name = name;
+ break;
+ }
+}
+
+int __init exynos5_gsc_set_parent_clock(const char *child, const char *parent)
+{
+ struct clk *clk_parent;
+ struct clk *clk_child;
+
+ clk_child = clk_get(NULL, child);
+ if (IS_ERR(clk_child)) {
+ pr_err("failed to get %s clock.\n", child);
+ return PTR_ERR(clk_child);
+ }
+
+ clk_parent = clk_get(NULL, parent);
+ if (IS_ERR(clk_parent)) {
+ clk_put(clk_child);
+ pr_err("failed to get %s clock.\n", parent);
+ return PTR_ERR(clk_parent);
+ }
+
+ if (clk_set_parent(clk_child, clk_parent)) {
+ pr_err("Unable to set parent %s of clock %s.\n",
+ clk_parent->name, clk_child->name);
+ clk_put(clk_child);
+ clk_put(clk_parent);
+ return PTR_ERR(clk_child);
+ }
+
+ clk_put(clk_child);
+ clk_put(clk_parent);
+
+ return 0;
+}
+
+int __init exynos5_gsc_set_clock_rate(const char *clk, unsigned long clk_rate)
+{
+ struct clk *gsc_clk;
+
+ gsc_clk = clk_get(NULL, clk);
+ if (IS_ERR(gsc_clk)) {
+ pr_err("failed to get %s clock.\n", clk);
+ return PTR_ERR(gsc_clk);
+ }
+
+ if (!clk_rate)
+ clk_rate = 310000000UL;
+
+ if (clk_set_rate(gsc_clk, clk_rate)) {
+ pr_err("%s rate change failed: %lu\n", gsc_clk->name, clk_rate);
+ clk_put(gsc_clk);
+ return PTR_ERR(gsc_clk);
+ }
+
+ clk_put(gsc_clk);
+
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/setup-hdmi.c b/arch/arm/mach-exynos/setup-hdmi.c
new file mode 100644
index 0000000..b3ce85b
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-hdmi.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s5p_hdmi_cfg_hpd(bool enable)
+{
+ if (enable)
+ s3c_gpio_cfgpin(GPIO_HDMI_HPD, S3C_GPIO_SFN(3));
+ else
+ s3c_gpio_cfgpin(GPIO_HDMI_HPD, S3C_GPIO_SFN(0xf));
+
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_DOWN);
+}
+
+int s5p_hdmi_get_hpd(void)
+{
+ return !!gpio_get_value(GPIO_HDMI_HPD);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c0.c b/arch/arm/mach-exynos/setup-i2c0.c
index d395bd1..e6ae115 100644
--- a/arch/arm/mach-exynos4/setup-i2c0.c
+++ b/arch/arm/mach-exynos/setup-i2c0.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/setup-i2c0.c
+ * linux/arch/arm/mach-exynos/setup-i2c0.c
*
* Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
@@ -18,9 +18,14 @@ struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgall_range(EXYNOS5_GPB3(0), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS4_GPD1(0), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-exynos4/setup-i2c1.c b/arch/arm/mach-exynos/setup-i2c1.c
index fd7235a..4cf6d92 100644
--- a/arch/arm/mach-exynos4/setup-i2c1.c
+++ b/arch/arm/mach-exynos/setup-i2c1.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/setup-i2c1.c
+ * linux/arch/arm/mach-exynos/setup-i2c1.c
*
* Copyright (C) 2010 Samsung Electronics Co., Ltd.
*
@@ -15,9 +15,14 @@ struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgall_range(EXYNOS4_GPD1(2), 2,
- S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgall_range(EXYNOS5_GPB3(2), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS4_GPD1(2), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-exynos4/setup-i2c2.c b/arch/arm/mach-exynos/setup-i2c2.c
index 2694b19..d85d6ee 100644
--- a/arch/arm/mach-exynos4/setup-i2c2.c
+++ b/arch/arm/mach-exynos/setup-i2c2.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/setup-i2c2.c
+ * linux/arch/arm/mach-exynos/setup-i2c2.c
*
* Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
*
@@ -15,9 +15,14 @@ struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgall_range(EXYNOS4_GPA0(6), 2,
- S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgall_range(EXYNOS5_GPA0(6), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS4_GPA0(6), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-exynos4/setup-i2c3.c b/arch/arm/mach-exynos/setup-i2c3.c
index 379bd30..e0ee9b7 100644
--- a/arch/arm/mach-exynos4/setup-i2c3.c
+++ b/arch/arm/mach-exynos/setup-i2c3.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/setup-i2c3.c
+ * linux/arch/arm/mach-exynos/setup-i2c3.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
@@ -15,9 +15,14 @@ struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
void s3c_i2c3_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
- S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgall_range(EXYNOS5_GPA1(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-exynos/setup-i2c4.c b/arch/arm/mach-exynos/setup-i2c4.c
new file mode 100644
index 0000000..5e81e78
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-i2c4.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-exynos/setup-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C4 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+void s3c_i2c4_cfg_gpio(struct platform_device *dev)
+{
+ if (soc_is_exynos4210())
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ else if (soc_is_exynos4212())
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(0), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS5_GPA2(0), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos/setup-i2c5.c b/arch/arm/mach-exynos/setup-i2c5.c
new file mode 100644
index 0000000..8253fc1
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-i2c5.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-exynos/setup-i2c5.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C5 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+void s3c_i2c5_cfg_gpio(struct platform_device *dev)
+{
+ if (soc_is_exynos4210())
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ else if (soc_is_exynos4212())
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_NONE);
+ else
+ s3c_gpio_cfgall_range(EXYNOS5_GPA2(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c6.c b/arch/arm/mach-exynos/setup-i2c6.c
index 284d12b..8d4fce9 100644
--- a/arch/arm/mach-exynos4/setup-i2c6.c
+++ b/arch/arm/mach-exynos/setup-i2c6.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/setup-i2c6.c
+ * linux/arch/arm/mach-exynos/setup-i2c6.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
@@ -15,9 +15,14 @@ struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
void s3c_i2c6_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
- S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgall_range(EXYNOS5_GPB1(3), 2,
+ S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS4_GPC1(3), 2,
+ S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-exynos4/setup-i2c7.c b/arch/arm/mach-exynos/setup-i2c7.c
index b7611ee..8122381 100644
--- a/arch/arm/mach-exynos4/setup-i2c7.c
+++ b/arch/arm/mach-exynos/setup-i2c7.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-exynos4/setup-i2c7.c
+ * linux/arch/arm/mach-exynos/setup-i2c7.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
@@ -15,9 +15,14 @@ struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
void s3c_i2c7_cfg_gpio(struct platform_device *dev)
{
- s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
- S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ if (soc_is_exynos5210() || soc_is_exynos5250())
+ s3c_gpio_cfgall_range(EXYNOS5_GPB2(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ else
+ s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
diff --git a/arch/arm/mach-exynos/setup-jpeg.c b/arch/arm/mach-exynos/setup-jpeg.c
new file mode 100644
index 0000000..dc50398
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-jpeg.c
@@ -0,0 +1,133 @@
+/* linux/arch/arm/mach-exynos/setup-jpeg.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos4 JPEG configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#include <mach/regs-clock.h>
+#include <mach/map.h>
+
+int __init exynos4_jpeg_setup_clock(struct device *dev,
+ unsigned long clk_rate)
+{
+ struct clk *sclk = NULL;
+ struct clk *mout_jpeg = NULL;
+ struct clk *mout_mpll = NULL;
+ int ret;
+
+ sclk = clk_get(dev, "aclk_clk_jpeg");
+ if (IS_ERR(sclk)) {
+ dev_err(dev, "failed to get aclk for jpeg\n");
+ goto err_clk1;
+ }
+
+ mout_jpeg = clk_get(dev, "mout_jpeg0");
+
+ if (IS_ERR(mout_jpeg)) {
+ dev_err(dev, "failed to get mout_jpeg0 for jpeg\n");
+ goto err_clk2;
+ }
+
+ ret = clk_set_parent(sclk, mout_jpeg);
+ if (ret < 0) {
+ dev_err(dev, "failed to clk_set_parent for jpeg\n");
+ goto err_clk2;
+ }
+
+ mout_mpll = clk_get(dev, "mout_mpll_user");
+
+ if (IS_ERR(mout_mpll)) {
+ dev_err(dev, "failed to get mout_mpll for jpeg\n");
+ goto err_clk2;
+ }
+
+ ret = clk_set_parent(mout_jpeg, mout_mpll);
+ if (ret < 0) {
+ dev_err(dev, "failed to clk_set_parent for jpeg\n");
+ goto err_clk2;
+ }
+
+ ret = clk_set_rate(sclk, clk_rate);
+ if (ret < 0) {
+ dev_err(dev, "failed to clk_set_rate of sclk for jpeg\n");
+ goto err_clk2;
+ }
+ dev_dbg(dev, "set jpeg aclk rate\n");
+
+ clk_put(mout_jpeg);
+ clk_put(mout_mpll);
+
+ ret = clk_enable(sclk);
+ if (ret < 0) {
+ dev_err(dev, "failed to clk_enable of aclk for jpeg\n");
+ goto err_clk2;
+ }
+
+ return 0;
+
+err_clk2:
+ clk_put(mout_mpll);
+err_clk1:
+ clk_put(sclk);
+
+ return -EINVAL;
+}
+
+int __init exynos5_jpeg_setup_clock(struct device *dev,
+ unsigned long clk_rate)
+{
+ struct clk *sclk;
+ struct clk *mout_user = NULL;
+ int ret;
+
+ sclk = clk_get(dev, "sclk_jpeg");
+ if (IS_ERR(sclk))
+ return PTR_ERR(sclk);
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+ mout_user = clk_get(dev, "mout_mpll_user");
+ if (IS_ERR(sclk))
+ return PTR_ERR(sclk);
+
+ ret = clk_set_parent(sclk, mout_user);
+ if (ret < 0) {
+ dev_err(dev, "failed to clk_set_parent for jpeg\n");
+ goto err_clk;
+ }
+ }
+ if (!clk_rate)
+ clk_rate = 150000000UL;
+
+ if (clk_set_rate(sclk, clk_rate)) {
+ pr_err("%s rate change failed: %lu\n", sclk->name, clk_rate);
+ clk_put(sclk);
+ return PTR_ERR(sclk);
+ }
+
+ clk_put(sclk);
+ if (samsung_rev() >= EXYNOS5250_REV_1_0)
+ clk_put(mout_user);
+
+ return 0;
+ if (samsung_rev() >= EXYNOS5250_REV_1_0) {
+err_clk:
+ clk_put(mout_user);
+
+ return -EINVAL;
+ }
+}
diff --git a/arch/arm/mach-exynos4/setup-keypad.c b/arch/arm/mach-exynos/setup-keypad.c
index 1ee0ebf..2163904 100644
--- a/arch/arm/mach-exynos4/setup-keypad.c
+++ b/arch/arm/mach-exynos/setup-keypad.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/setup-keypad.c
+/* linux/arch/arm/mach-exynos/setup-keypad.c
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -19,15 +19,16 @@ void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
if (rows > 8) {
/* Set all the necessary GPX2 pins: KP_ROW[0~7] */
- s3c_gpio_cfgrange_nopull(EXYNOS4_GPX2(0), 8, S3C_GPIO_SFN(3));
+ s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), 8,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
/* Set all the necessary GPX3 pins: KP_ROW[8~] */
- s3c_gpio_cfgrange_nopull(EXYNOS4_GPX3(0), (rows - 8),
- S3C_GPIO_SFN(3));
+ s3c_gpio_cfgall_range(EXYNOS4_GPX3(0), (rows - 8),
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
} else {
/* Set all the necessary GPX2 pins: KP_ROW[x] */
- s3c_gpio_cfgrange_nopull(EXYNOS4_GPX2(0), rows,
- S3C_GPIO_SFN(3));
+ s3c_gpio_cfgall_range(EXYNOS4_GPX2(0), rows,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
/* Set all the necessary GPX1 pins to special-function 3: KP_COL[x] */
diff --git a/arch/arm/mach-exynos/setup-mfc.c b/arch/arm/mach-exynos/setup-mfc.c
new file mode 100644
index 0000000..0fc2f28
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-mfc.c
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-exynos/setup-mfc.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base Exynos4 MFC configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/s5p-mfc.h>
+#include <plat/devs.h>
+
+#include <mach/regs-clock.h>
+#include <mach/map.h>
+
+unsigned int mfc_clk_rate;
+int exynos4_mfc_setup_clock(struct device *dev,
+ unsigned long clock_rate)
+{
+ mfc_clk_rate = clock_rate;
+
+ return 0;
+}
+
+static struct s5p_mfc_platdata default_mfc_pd __initdata = {
+ .clock_rate = 200 * MHZ,
+};
+
+void __init s5p_mfc_set_platdata(struct s5p_mfc_platdata *pd)
+{
+ if (!pd)
+ pd = &default_mfc_pd;
+
+ s3c_set_platdata(pd, sizeof(struct s5p_mfc_platdata),
+ &s5p_device_mfc);
+}
+
+void s5p_mfc_setname(struct platform_device *pdev, char *name)
+{
+ pdev->name = name;
+}
diff --git a/arch/arm/mach-exynos/setup-mipidsim.c b/arch/arm/mach-exynos/setup-mipidsim.c
new file mode 100644
index 0000000..e85e1e0
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-mipidsim.c
@@ -0,0 +1,93 @@
+/* linux/arch/arm/mach-exynos/setup-mipidsim.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * ERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * A 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/dsim.h>
+#include <plat/clock.h>
+#include <plat/regs-mipidsim.h>
+
+#define S5P_MIPI_M_RESETN 4
+
+static int s5p_dsim_enable_d_phy(struct mipi_dsim_device *dsim,
+ unsigned int enable)
+{
+ unsigned int reg;
+#if defined(CONFIG_ARCH_EXYNOS5)
+ reg = readl(S5P_MIPI_DPHY_CONTROL(1)) & ~(1 << 0);
+ reg |= (enable << 0);
+ writel(reg, S5P_MIPI_DPHY_CONTROL(1));
+#else
+ reg = readl(S5P_MIPI_DPHY_CONTROL(0)) & ~(1 << 0);
+ reg |= (enable << 0);
+ writel(reg, S5P_MIPI_DPHY_CONTROL(0));
+#endif
+ return 0;
+}
+
+static int s5p_dsim_enable_dsi_master(struct mipi_dsim_device *dsim,
+ unsigned int enable)
+{
+ unsigned int reg;
+#if defined(CONFIG_ARCH_EXYNOS5)
+ reg = readl(S5P_MIPI_DPHY_CONTROL(1)) & ~(1 << 2);
+ reg |= (enable << 2);
+ writel(reg, S5P_MIPI_DPHY_CONTROL(1));
+#else
+ reg = readl(S5P_MIPI_DPHY_CONTROL(0)) & ~(1 << 2);
+ reg |= (enable << 2);
+ writel(reg, S5P_MIPI_DPHY_CONTROL(0));
+#endif
+ return 0;
+}
+
+int s5p_dsim_part_reset(struct mipi_dsim_device *dsim)
+{
+#if defined(CONFIG_ARCH_EXYNOS5)
+ if (dsim->id == 0)
+ writel(S5P_MIPI_M_RESETN, S5P_MIPI_DPHY_CONTROL(1));
+#else
+ if (dsim->id == 0)
+ writel(S5P_MIPI_M_RESETN, S5P_MIPI_DPHY_CONTROL(0));
+#endif
+ return 0;
+}
+
+int s5p_dsim_init_d_phy(struct mipi_dsim_device *dsim, unsigned int enable)
+{
+ /**
+ * DPHY and aster block must be enabled at the system initialization
+ * step before data access from/to DPHY begins.
+ */
+ s5p_dsim_enable_d_phy(dsim, enable);
+
+ s5p_dsim_enable_dsi_master(dsim, enable);
+ return 0;
+}
diff --git a/arch/arm/mach-exynos/setup-mshci-gpio.c b/arch/arm/mach-exynos/setup-mshci-gpio.c
new file mode 100644
index 0000000..4c73310
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-mshci-gpio.c
@@ -0,0 +1,220 @@
+/* linux/arch/arm/mach-exynos/setup-mshci-gpio.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Helper functions for setting up MSHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/delay.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <plat/gpio-cfg.h>
+#include <plat/mshci.h>
+#include <plat/cpu.h>
+
+#define GPK0DRV (S5P_VA_GPIO2 + 0x4C)
+#define GPK1DRV (S5P_VA_GPIO2 + 0x6C)
+#define GPK2DRV (S5P_VA_GPIO2 + 0x8C)
+#define GPK3DRV (S5P_VA_GPIO2 + 0xAC)
+
+#define DIV_FSYS3 (S5P_VA_CMU + 0x0C54C)
+
+#if defined(CONFIG_MACH_M0) && defined(CONFIG_TARGET_LOCALE_EUR)
+#define EPLL_CON0_F (S5P_VA_CMU + 0x0C110)
+
+void print_epll_con0(void)
+{
+ pr_info("EPLL_CON0 : 0x%x\n",__raw_readl(EPLL_CON0_F));
+}
+#endif
+
+void exynos4_setup_mshci_cfg_gpio(struct platform_device *dev, int width)
+{
+ unsigned int gpio;
+ struct s3c_mshci_platdata *pdata = dev->dev.platform_data;
+
+ /* early_printk("exynos4_setup_mshci_cfg_gpio\n"); */
+
+ /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
+ for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ /* if CDn pin is used as eMMC_EN pin, it might make a problem
+ So, a built-in type eMMC is embedded, it dose not set CDn pin */
+ if (pdata->cd_type != S3C_MSHCI_CD_PERMANENT) {
+ s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_NONE);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ __raw_writel(0x2AAA, GPK1DRV);
+ case 4:
+ /* GPK[3:6] special-funtion 2 */
+ for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ __raw_writel(0x2AAA, GPK0DRV);
+ break;
+ case 1:
+ /* GPK[3] special-funtion 2 */
+ for (gpio = EXYNOS4_GPK0(3); gpio < EXYNOS4_GPK0(4); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ __raw_writel(0xAA, GPK0DRV);
+ default:
+ break;
+ }
+}
+
+void exynos4_setup_mshci_cfg_ddr(struct platform_device *dev, int ddr)
+{
+ if (ddr) {
+#ifdef CONFIG_EXYNOS4_MSHC_EPLL_45MHZ
+ __raw_writel(0x00, DIV_FSYS3);
+#elif defined(CONFIG_EXYNOS4_MSHC_VPLL_46MHZ)
+ __raw_writel(0x01, DIV_FSYS3);
+#else
+ if ((soc_is_exynos4412() || soc_is_exynos4212()) &&
+ samsung_rev() >= EXYNOS4412_REV_1_0) {
+ __raw_writel(0x1, DIV_FSYS3);
+ } else
+ __raw_writel(0x05, DIV_FSYS3);
+#endif
+ } else {
+#ifdef CONFIG_EXYNOS4_MSHC_EPLL_45MHZ
+ __raw_writel(0x01, DIV_FSYS3);
+#elif defined(CONFIG_EXYNOS4_MSHC_VPLL_46MHZ)
+ __raw_writel(0x03, DIV_FSYS3);
+#else
+ if ((soc_is_exynos4412() || soc_is_exynos4212()) &&
+ samsung_rev() >= EXYNOS4412_REV_1_0)
+ __raw_writel(0x3, DIV_FSYS3);
+ else
+ __raw_writel(0xb, DIV_FSYS3);
+#endif
+ }
+}
+
+void exynos4_setup_mshci_init_card(struct platform_device *dev)
+{
+ /*
+ * Reset moviNAND for re-init.
+ * output/low for eMMC_EN and input/pull-none for others
+ * and then wait 10ms.
+ */
+ __raw_writel(0x100, S5P_VA_GPIO2 + 0x40);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x44);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x48);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x60);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x64);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x68);
+ mdelay(100);
+
+ /* set data buswidth 8 */
+ exynos4_setup_mshci_cfg_gpio(dev, 8);
+
+ /* power to moviNAND on */
+ gpio_set_value(EXYNOS4_GPK0(2), 1);
+
+ /* to wait a pull-up resistance ready */
+ mdelay(10);
+}
+
+void exynos4_setup_mshci_set_power(struct platform_device *dev, int en)
+{
+ struct s3c_mshci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio = 0;
+
+ if (pdata->int_power_gpio) {
+ if (en) {
+#ifdef CONFIG_MACH_Q1_BD
+ mdelay(20);
+#endif
+ /*CMD/CLK*/
+ for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2);
+ gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ /*DAT[0]~[3]*/
+ for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6);
+ gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+ /*DAT[4]~[7]*/
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6);
+ gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ gpio_set_value(pdata->int_power_gpio, 1);
+ pr_info("%s : internal MMC Card ON samsung-mshc.\n",
+ __func__);
+ } else {
+#if defined(CONFIG_MACH_M0_CTC)
+ s3c_gpio_cfgpin(pdata->int_power_gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(pdata->int_power_gpio,
+ S3C_GPIO_PULL_NONE);
+#endif
+ gpio_set_value(pdata->int_power_gpio, 0);
+
+ /*CMD/CLK*/
+ for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2);
+ gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ }
+ /*DAT[0]~[3]*/
+ for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6);
+ gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ }
+ /*DAT[4]~[7]*/
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6);
+ gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ }
+ pr_info("%s : internal MMC Card OFF samsung-mshc.\n",
+ __func__);
+ mdelay(50);
+ }
+ }
+}
+
+void exynos4_setup_mshci_shutdown()
+{
+ /* to reset eMMC card, VDD of eMMC should be off over 1ms */
+ __raw_writel(0x100, S5P_VA_GPIO2 + 0x40);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x44);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x48);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x60);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x64);
+ __raw_writel(0, S5P_VA_GPIO2 + 0x68);
+ mdelay(10);
+}
diff --git a/arch/arm/mach-exynos/setup-mshci.c b/arch/arm/mach-exynos/setup-mshci.c
new file mode 100644
index 0000000..caaf0ec
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-mshci.c
@@ -0,0 +1,37 @@
+/* linux/arch/arm/mach-exynos/setup-mshci.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS4 - Helper functions for settign up MSHCI device(s)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/mshci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *exynos4_mshci_clksrcs[1] = {
+ [0] = "sclk_dwmci", /* sclk for mshc */
+};
+
+void exynos4_setup_mshci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ /* still now, It dose not have something to do on booting time*/
+}
+
diff --git a/arch/arm/mach-exynos/setup-sdhci-gpio.c b/arch/arm/mach-exynos/setup-sdhci-gpio.c
new file mode 100644
index 0000000..1973e79
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-sdhci-gpio.c
@@ -0,0 +1,336 @@
+/* linux/arch/arm/mach-exynos/setup-sdhci-gpio.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK0[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+ /* Data pin GPK1[3:6] to special-function 3 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case 4:
+ for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
+ /* Data pin GPK0[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK1[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS4_GPK1(0); gpio < EXYNOS4_GPK1(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
+ /* Data pin GPK1[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS4_GPK1(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPK1(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK2[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS4_GPK2(0); gpio < EXYNOS4_GPK2(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+#ifdef CONFIG_MACH_U1
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+#elif defined(CONFIG_MACH_MIDAS)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#else
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#endif
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
+ /* Data pin GPK3[3:6] to special-function 3 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+#ifdef CONFIG_MACH_U1
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+#elif defined(CONFIG_MACH_MIDAS)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#else
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#endif
+ }
+ case 4:
+ for (gpio = EXYNOS4_GPK2(3); gpio <= EXYNOS4_GPK2(6); gpio++) {
+ /* Data pin GPK2[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+#ifdef CONFIG_MACH_U1
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV3);
+#elif defined(CONFIG_MACH_MIDAS)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#else
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#endif
+ }
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS4_GPK2(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPK2(2), S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+}
+
+void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK3[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+#ifdef CONFIG_MACH_U1
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+#elif defined(CONFIG_MACH_MIDAS)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#elif defined(CONFIG_MACH_PX)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#else
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#endif
+ }
+
+#if defined(CONFIG_MACH_PX)
+ s3c_gpio_setpull(EXYNOS4_GPK3(1), S3C_GPIO_PULL_UP);
+#endif
+
+ for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
+ /* Data pin GPK3[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+#ifdef CONFIG_MACH_U1
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+#elif defined(CONFIG_MACH_MIDAS)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#elif defined(CONFIG_MACH_PX)
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#else
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+#endif
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS4_GPK3(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2);
+ }
+}
+
+#endif /* CONFIG_ARCH_EXYNOS4 */
+
+#if defined(CONFIG_ARCH_EXYNOS5)
+void exynos5_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPC0[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS5_GPC0(0); gpio < EXYNOS5_GPC0(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = EXYNOS5_GPC1(3); gpio <= EXYNOS5_GPC1(6); gpio++) {
+ /* Data pin GPK1[3:6] to special-function 3 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case 4:
+ for (gpio = EXYNOS5_GPC0(3); gpio <= EXYNOS5_GPC0(6); gpio++) {
+ /* Data pin GPK0[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS5_GPC0(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPC0(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void exynos5_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK1[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS5_GPC1(0); gpio < EXYNOS5_GPC1(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = EXYNOS5_GPC1(3); gpio <= EXYNOS5_GPC1(6); gpio++) {
+ /* Data pin GPK1[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS5_GPC1(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPC1(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void exynos5_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK2[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS5_GPC2(0); gpio < EXYNOS5_GPC2(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ switch (width) {
+ case 8:
+ for (gpio = EXYNOS5_GPC3(3); gpio <= EXYNOS5_GPC3(6); gpio++) {
+ /* Data pin GPK3[3:6] to special-function 3 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ case 4:
+ for (gpio = EXYNOS5_GPC2(3); gpio <= EXYNOS5_GPC2(6); gpio++) {
+ /* Data pin GPK2[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS5_GPC2(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPC2(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+void exynos5_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int gpio;
+
+ /* Set all the necessary GPK3[0:1] pins to special-function 2 */
+ for (gpio = EXYNOS5_GPC3(0); gpio < EXYNOS5_GPC3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = EXYNOS5_GPC3(3); gpio <= EXYNOS5_GPC3(6); gpio++) {
+ /* Data pin GPK3[3:6] to special-function 2 */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_cfgpin(EXYNOS5_GPC3(2), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(EXYNOS5_GPC3(2), S3C_GPIO_PULL_UP);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
+
+#endif /* CONFIG_ARCH_EXYNOS5 */
diff --git a/arch/arm/mach-exynos4/setup-sdhci.c b/arch/arm/mach-exynos/setup-sdhci.c
index 1e83f8c..7c6ea0f 100644
--- a/arch/arm/mach-exynos4/setup-sdhci.c
+++ b/arch/arm/mach-exynos/setup-sdhci.c
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/setup-sdhci.c
+/* linux/arch/arm/mach-exynos/setup-sdhci.c
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
diff --git a/arch/arm/mach-exynos/setup-tvout.c b/arch/arm/mach-exynos/setup-tvout.c
new file mode 100644
index 0000000..7e487f8
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-tvout.c
@@ -0,0 +1,118 @@
+/* linux/arch/arm/mach-exynos/setup-tvout.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base TVOUT gpio configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <linux/io.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <plat/tvout.h>
+#include <plat/cpu.h>
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+#define HDMI_GPX(_nr) EXYNOS4_GPX3(_nr)
+#elif defined(CONFIG_ARCH_EXYNOS5)
+#define HDMI_GPX(_nr) EXYNOS5_GPX3(_nr)
+#endif
+
+struct platform_device; /* don't need the contents */
+
+void s5p_int_src_hdmi_hpd(struct platform_device *pdev)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+ s3c_gpio_cfgpin(GPIO_HDMI_HPD, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_NONE);
+}
+
+void s5p_int_src_ext_hpd(struct platform_device *pdev)
+{
+ printk(KERN_INFO "%s()\n", __func__);
+ s3c_gpio_cfgpin(GPIO_HDMI_HPD, S3C_GPIO_SFN(0xf));
+ /* To avoid floating state of the HPD pin *
+ * in the absence of external pull-up */
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_DOWN);
+#else
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_NONE);
+#endif
+}
+
+int s5p_hpd_read_gpio(struct platform_device *pdev)
+{
+ int ret;
+ ret = gpio_get_value(GPIO_HDMI_HPD);
+ printk(KERN_INFO "%s(%d)\n", __func__, ret);
+ return ret;
+}
+
+int s5p_v4l2_hpd_read_gpio(void)
+{
+ return gpio_get_value(HDMI_GPX(7));
+}
+
+void s5p_v4l2_int_src_hdmi_hpd(void)
+{
+ s3c_gpio_cfgpin(HDMI_GPX(7), S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(HDMI_GPX(7), S3C_GPIO_PULL_DOWN);
+}
+
+void s5p_v4l2_int_src_ext_hpd(void)
+{
+ s3c_gpio_cfgpin(HDMI_GPX(7), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(HDMI_GPX(7), S3C_GPIO_PULL_DOWN);
+}
+
+void s5p_cec_cfg_gpio(struct platform_device *pdev)
+{
+#ifdef CONFIG_HDMI_CEC
+ s3c_gpio_cfgpin(GPIO_HDMI_CEC, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_HDMI_CEC, S3C_GPIO_PULL_NONE);
+#endif
+}
+
+#ifdef CONFIG_VIDEO_EXYNOS_TV
+void s5p_tv_setup(void)
+{
+ int ret;
+
+ /* direct HPD to HDMI chip */
+ if (soc_is_exynos4412()) {
+ gpio_request(GPIO_HDMI_HPD, "hpd-plug");
+
+ gpio_direction_input(GPIO_HDMI_HPD);
+ s3c_gpio_cfgpin(GPIO_HDMI_HPD, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_NONE);
+ } else if (soc_is_exynos5250()) {
+ gpio_request(GPIO_HDMI_HPD, "hpd-plug");
+ gpio_direction_input(GPIO_HDMI_HPD);
+ s3c_gpio_cfgpin(GPIO_HDMI_HPD, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_HDMI_HPD, S3C_GPIO_PULL_NONE);
+
+ /* HDMI CEC */
+ gpio_request(GPIO_HDMI_CEC, "hdmi-cec");
+ gpio_direction_input(GPIO_HDMI_CEC);
+ s3c_gpio_cfgpin(GPIO_HDMI_CEC, S3C_GPIO_SFN(0x3));
+ s3c_gpio_setpull(GPIO_HDMI_CEC, S3C_GPIO_PULL_NONE);
+ } else {
+ printk(KERN_ERR "HPD GPIOs are not defined!\n");
+ }
+}
+#endif
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
new file mode 100644
index 0000000..bae906f
--- /dev/null
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -0,0 +1,1407 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Yulgon Kim <yulgon.kim@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-pmu5.h>
+#include <mach/regs-usb-phy.h>
+#include <plat/cpu.h>
+#include <plat/usb-phy.h>
+#include <plat/regs-usb3-exynos-drd-phy.h>
+#include <linux/interrupt.h>
+#include <plat/usbgadget.h>
+#include <mach/sec_modem.h>
+
+#ifdef CONFIG_USB_OHCI_S5P
+ #include <plat/devs.h>
+ #include <linux/usb.h>
+ #include <linux/usb/otg.h>
+ #include <linux/usb/hcd.h>
+#endif
+
+#ifdef CONFIG_USB_OHCI_S5P
+ #include <plat/devs.h>
+ #include <linux/usb.h>
+ #include <linux/usb/otg.h>
+ #include <linux/usb/hcd.h>
+#endif
+
+#define ETC6PUD (S5P_VA_GPIO2 + 0x228)
+#define EXYNOS4_USB_CFG (S3C_VA_SYS + 0x21C)
+#define EXYNOS5_USB_CFG (S3C_VA_SYS + 0x230)
+
+#define PHY_ENABLE (1 << 0)
+#define PHY_DISABLE (0)
+
+#ifdef CONFIG_USB_OHCI_S5P
+struct s5p_ohci_hcd {
+ struct device *dev;
+ struct usb_hcd *hcd;
+ struct clk *clk;
+ int power_on;
+};
+#endif
+
+enum usb_host_type {
+ HOST_PHY_EHCI = (0x1 << 0),
+ HOST_PHY_OHCI = (0x1 << 1),
+ HOST_PHY_DEVICE = (0x1 << 2),
+};
+
+enum usb_phy_type {
+ USB_PHY = (0x1 << 0),
+ USB_PHY0 = (0x1 << 0),
+ USB_PHY1 = (0x1 << 1),
+ USB_PHY_HSIC0 = (0x1 << 1),
+ USB_PHY_HSIC1 = (0x1 << 2),
+};
+
+struct exynos_usb_phy {
+ u8 lpa_entered;
+ unsigned long flags;
+ unsigned long usage;
+};
+
+static struct exynos_usb_phy usb_phy_control;
+
+static atomic_t host_usage;
+static DEFINE_MUTEX(phy_lock);
+static struct clk *phy_clk = NULL;
+
+static void exynos_usb_mux_change(struct platform_device *pdev, int val)
+{
+ u32 is_host;
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ is_host = readl(EXYNOS4_USB_CFG);
+ writel(val, EXYNOS4_USB_CFG);
+ } else {
+ is_host = readl(EXYNOS5_USB_CFG);
+ writel(val, EXYNOS5_USB_CFG);
+ }
+
+ if (is_host != val)
+ dev_dbg(&pdev->dev, "Change USB MUX from %s to %s",
+ is_host ? "Host" : "Device",
+ val ? "Host" : "Device");
+}
+
+static int exynos4_usb_host_phy_is_on(void)
+{
+ return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
+}
+
+static int exynos_usb_device_phy_is_on(void)
+{
+ int ret;
+
+ if (soc_is_exynos4210())
+ ret = (readl(EXYNOS4_PHYPWR) & PHY0_ANALOG_POWERDOWN) ? 0 : 1;
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ ret = readl(EXYNOS4_USB_CFG) ? 0 : 1;
+ else
+ ret = readl(EXYNOS5_USB_CFG) ? 0 : 1;
+
+ return ret;
+}
+
+static int exynos4_usb_phy20_is_on(void)
+{
+ return exynos4_usb_host_phy_is_on();
+}
+
+static int exynos5_usb_host_phy20_is_on(void)
+{
+ return (readl(EXYNOS5_PHY_HOST_CTRL0) & HOST_CTRL0_SIDDQ) ? 0 : 1;
+}
+
+static int exynos5_usb_phy30_is_on(void)
+{
+ return readl(EXYNOS5_USBDEV_PHY_CONTROL) ? 1 : 0;
+}
+
+static int exynos_usb_phy_clock_enable(struct platform_device *pdev)
+{
+ int err;
+
+ if (!phy_clk) {
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ phy_clk = clk_get(&pdev->dev, "usbotg");
+ else
+ phy_clk = clk_get(&pdev->dev, "usbhost");
+
+ if (IS_ERR(phy_clk)) {
+ dev_err(&pdev->dev, "Failed to get phy clock\n");
+ return PTR_ERR(phy_clk);
+ }
+ }
+
+ err = clk_enable(phy_clk);
+
+ return err;
+}
+
+static int exynos_usb_phy_clock_disable(struct platform_device *pdev)
+{
+ if (!phy_clk) {
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ phy_clk = clk_get(&pdev->dev, "usbotg");
+ else
+ phy_clk = clk_get(&pdev->dev, "usbhost");
+ if (IS_ERR(phy_clk)) {
+ dev_err(&pdev->dev, "Failed to get phy clock\n");
+ return PTR_ERR(phy_clk);
+ }
+ }
+
+ clk_disable(phy_clk);
+
+ return 0;
+}
+
+static u32 exynos_usb_phy_set_clock(struct platform_device *pdev)
+{
+ struct clk *ref_clk;
+ u32 refclk_freq = 0;
+
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412())
+ ref_clk = clk_get(&pdev->dev, "xusbxti");
+ else
+ ref_clk = clk_get(&pdev->dev, "ext_xtal");
+
+ if (IS_ERR(ref_clk)) {
+ dev_err(&pdev->dev, "Failed to get reference clock\n");
+ return PTR_ERR(ref_clk);
+ }
+
+ if (soc_is_exynos4210()) {
+ switch (clk_get_rate(ref_clk)) {
+ case 12 * MHZ:
+ refclk_freq = EXYNOS4210_CLKSEL_12M;
+ break;
+ case 48 * MHZ:
+ refclk_freq = EXYNOS4210_CLKSEL_48M;
+ break;
+ case 24 * MHZ:
+ default:
+ /* default reference clock */
+ refclk_freq = EXYNOS4210_CLKSEL_24M;
+ break;
+ }
+ } else if (soc_is_exynos4212() | soc_is_exynos4412()) {
+ switch (clk_get_rate(ref_clk)) {
+ case 96 * 100000:
+ refclk_freq = EXYNOS4212_CLKSEL_9600K;
+ break;
+ case 10 * MHZ:
+ refclk_freq = EXYNOS4212_CLKSEL_10M;
+ break;
+ case 12 * MHZ:
+ refclk_freq = EXYNOS4212_CLKSEL_12M;
+ break;
+ case 192 * 100000:
+ refclk_freq = EXYNOS4212_CLKSEL_19200K;
+ break;
+ case 20 * MHZ:
+ refclk_freq = EXYNOS4212_CLKSEL_20M;
+ break;
+ case 24 * MHZ:
+ default:
+ /* default reference clock */
+ refclk_freq = EXYNOS4212_CLKSEL_24M;
+ break;
+ }
+ } else {
+ switch (clk_get_rate(ref_clk)) {
+ case 96 * 100000:
+ refclk_freq = EXYNOS5_CLKSEL_9600K;
+ break;
+ case 10 * MHZ:
+ refclk_freq = EXYNOS5_CLKSEL_10M;
+ break;
+ case 12 * MHZ:
+ refclk_freq = EXYNOS5_CLKSEL_12M;
+ break;
+ case 192 * 100000:
+ refclk_freq = EXYNOS5_CLKSEL_19200K;
+ break;
+ case 20 * MHZ:
+ refclk_freq = EXYNOS5_CLKSEL_20M;
+ break;
+ case 50 * MHZ:
+ refclk_freq = EXYNOS5_CLKSEL_50M;
+ break;
+ case 24 * MHZ:
+ default:
+ /* default reference clock */
+ refclk_freq = EXYNOS5_CLKSEL_24M;
+ break;
+ }
+ }
+ clk_put(ref_clk);
+
+ return refclk_freq;
+}
+
+static void exynos_usb_phy_control(enum usb_phy_type phy_type , int on)
+{
+ if (soc_is_exynos4210()) {
+ if (phy_type & USB_PHY0)
+ writel(on, S5P_USBOTG_PHY_CONTROL);
+ if (phy_type & USB_PHY1)
+ writel(on, S5P_USBHOST_PHY_CONTROL);
+ } else if (soc_is_exynos4212() | soc_is_exynos4412()) {
+ if (phy_type & USB_PHY)
+ writel(on, S5P_USB_PHY_CONTROL);
+#ifdef CONFIG_USB_S5P_HSIC0
+ if (phy_type & USB_PHY_HSIC0)
+ writel(on, S5P_HSIC_1_PHY_CONTROL);
+#endif
+#ifdef CONFIG_USB_S5P_HSIC1
+ if (phy_type & USB_PHY_HSIC1)
+ writel(on, S5P_HSIC_2_PHY_CONTROL);
+#endif
+ } else {
+ if (phy_type & USB_PHY0)
+ writel(on, EXYNOS5_USBDEV_PHY_CONTROL);
+ if (phy_type & USB_PHY1)
+ writel(on, EXYNOS5_USBHOST_PHY_CONTROL);
+ }
+}
+
+static int exynos4_usb_phy0_init(struct platform_device *pdev)
+{
+ u32 phypwr;
+ u32 phyclk;
+ u32 rstcon;
+
+ exynos_usb_phy_control(USB_PHY0, PHY_ENABLE);
+
+ /* set clock frequency for PLL */
+ phyclk = readl(EXYNOS4_PHYCLK) & ~(EXYNOS4210_CLKSEL_MASK);
+ phyclk |= exynos_usb_phy_set_clock(pdev);
+ phyclk &= ~(PHY0_COMMON_ON_N);
+ writel(phyclk, EXYNOS4_PHYCLK);
+
+ /* set to normal of PHY0 */
+ phypwr = readl(EXYNOS4_PHYPWR) & ~PHY0_NORMAL_MASK;
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* reset all ports of both PHY and Link */
+ rstcon = readl(EXYNOS4_RSTCON) | PHY0_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+ rstcon &= ~PHY0_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+
+ return 0;
+}
+
+static int exynos4_usb_phy0_exit(struct platform_device *pdev)
+{
+ /* unset to normal of PHY0 */
+ writel((readl(EXYNOS4_PHYPWR) | PHY0_NORMAL_MASK),
+ EXYNOS4_PHYPWR);
+
+ exynos_usb_phy_control(USB_PHY0, PHY_DISABLE);
+
+ return 0;
+}
+
+static int exynos4_usb_phy1_suspend(struct platform_device *pdev)
+{
+ u32 phypwr;
+
+ /* set to suspend HSIC 0 and 1 and standard of PHY1 */
+ phypwr = readl(EXYNOS4_PHYPWR);
+ if (soc_is_exynos4210()) {
+ phypwr |= (PHY1_STD_FORCE_SUSPEND
+ | EXYNOS4210_HSIC0_FORCE_SUSPEND
+ | EXYNOS4210_HSIC1_FORCE_SUSPEND);
+ } else {
+ phypwr = readl(EXYNOS4_PHYPWR);
+ phypwr |= (PHY1_STD_FORCE_SUSPEND
+ | EXYNOS4212_HSIC0_FORCE_SUSPEND
+ | EXYNOS4212_HSIC1_FORCE_SUSPEND);
+ }
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ return 0;
+}
+
+static int exynos4_usb_phy1_resume(struct platform_device *pdev)
+{
+ u32 rstcon;
+ u32 phypwr;
+ int err;
+
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+ /* HSIC LPA: reset-resume, let cp know pda active from LPA */
+ /* slave wake at lpa wake ??? */
+ /* 12.04.27 Move start of phy1_resume, If usb cable power on the
+ * host phy, EHCI resume miss the PDA_ACTVIE, then CP can't send Host
+ * wakeup Irq */
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ set_hsic_lpa_states(STATE_HSIC_LPA_WAKE);
+#endif
+
+ if (exynos4_usb_host_phy_is_on()) {
+ /* set to resume HSIC 0 and 1 and standard of PHY1 */
+ phypwr = readl(EXYNOS4_PHYPWR);
+ if (soc_is_exynos4210()) {
+ phypwr &= ~(PHY1_STD_FORCE_SUSPEND
+ | EXYNOS4210_HSIC0_FORCE_SUSPEND
+ | EXYNOS4210_HSIC1_FORCE_SUSPEND);
+ } else {
+ phypwr = readl(EXYNOS4_PHYPWR);
+ phypwr &= ~(PHY1_STD_FORCE_SUSPEND
+ | EXYNOS4212_HSIC0_FORCE_SUSPEND
+ | EXYNOS4212_HSIC1_FORCE_SUSPEND);
+ }
+ writel(phypwr, EXYNOS4_PHYPWR);
+ if (usb_phy_control.lpa_entered) {
+ usb_phy_control.lpa_entered = 0;
+ err = 1;
+ } else
+ err = 0;
+ } else {
+ phypwr = readl(EXYNOS4_PHYPWR);
+ /* set to normal HSIC 0 and 1 of PHY1 */
+ if (soc_is_exynos4210()) {
+ writel(PHY_ENABLE, S5P_USBHOST_PHY_CONTROL);
+
+ phypwr &= ~(PHY1_STD_NORMAL_MASK
+ | EXYNOS4210_HSIC0_NORMAL_MASK
+ | EXYNOS4210_HSIC1_NORMAL_MASK);
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* reset all ports of both PHY and Link */
+ rstcon = readl(EXYNOS4_RSTCON)
+ | EXYNOS4210_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4210_PHY1_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+
+ rstcon &= ~(EXYNOS4210_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4210_PHY1_SWRST_MASK);
+ writel(rstcon, EXYNOS4_RSTCON);
+ } else {
+ exynos_usb_phy_control(USB_PHY
+ | USB_PHY_HSIC0
+ | USB_PHY_HSIC1,
+ PHY_ENABLE);
+
+ /* set to normal of Device */
+ phypwr = readl(EXYNOS4_PHYPWR) & ~PHY0_NORMAL_MASK;
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* reset both PHY and Link of Device */
+ rstcon = readl(EXYNOS4_RSTCON) | PHY0_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+ rstcon &= ~PHY0_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+
+ /* set to normal of Host */
+ phypwr &= ~(PHY1_STD_NORMAL_MASK
+ | EXYNOS4212_HSIC0_NORMAL_MASK
+ | EXYNOS4212_HSIC1_NORMAL_MASK);
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* reset all ports of both PHY and Link */
+ rstcon = readl(EXYNOS4_RSTCON)
+ | EXYNOS4212_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4212_PHY1_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+
+ rstcon &= ~(EXYNOS4212_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4212_PHY1_SWRST_MASK);
+ writel(rstcon, EXYNOS4_RSTCON);
+ }
+ usb_phy_control.lpa_entered = 0;
+ err = 1;
+ }
+ udelay(80);
+
+ return err;
+}
+
+static int exynos4_usb_phy1_init(struct platform_device *pdev)
+{
+ u32 phypwr;
+ u32 phyclk;
+ u32 rstcon;
+
+
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ set_bit(HOST_PHY_EHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ set_bit(HOST_PHY_OHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s3c-usbgadget"))
+ set_bit(HOST_PHY_DEVICE, &usb_phy_control.usage);
+
+ dev_info(&pdev->dev, "usb phy usage(%ld)\n",usb_phy_control.usage);
+
+ if (exynos4_usb_host_phy_is_on()) {
+ dev_err(&pdev->dev, "Already power on PHY\n");
+ return 0;
+ }
+
+ /*
+ * set XuhostOVERCUR to in-active by controlling ET6PUD[15:14]
+ * 0x0 : pull-up/down disabled
+ * 0x1 : pull-down enabled
+ * 0x2 : reserved
+ * 0x3 : pull-up enabled
+ */
+ writel((__raw_readl(ETC6PUD) & ~(0x3 << 14)) | (0x3 << 14),
+ ETC6PUD);
+
+ exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);
+
+ /* set clock frequency for PLL */
+ phyclk = readl(EXYNOS4_PHYCLK) & ~(EXYNOS4210_CLKSEL_MASK);
+ phyclk |= exynos_usb_phy_set_clock(pdev);
+#ifdef CONFIG_USB_OHCI_S5P
+ phyclk |= PHY1_COMMON_ON_N;
+#else
+ phyclk &= ~(PHY1_COMMON_ON_N);
+#endif
+ writel(phyclk, EXYNOS4_PHYCLK);
+
+ /* set to normal HSIC 0 and 1 of PHY1 */
+ phypwr = readl(EXYNOS4_PHYPWR);
+ phypwr &= ~(PHY1_STD_NORMAL_MASK
+ | EXYNOS4210_HSIC0_NORMAL_MASK
+ | EXYNOS4210_HSIC1_NORMAL_MASK);
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* floating prevention logic: disable */
+ writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
+
+ /* reset all ports of both PHY and Link */
+ rstcon = readl(EXYNOS4_RSTCON)
+ | EXYNOS4210_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4210_PHY1_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+
+ rstcon &= ~(EXYNOS4210_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4210_PHY1_SWRST_MASK);
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(80);
+
+ return 0;
+}
+
+static int exynos4_usb_phy1_exit(struct platform_device *pdev)
+{
+ u32 phypwr;
+
+
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ clear_bit(HOST_PHY_EHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ clear_bit(HOST_PHY_OHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s3c-usbgadget"))
+ clear_bit(HOST_PHY_DEVICE, &usb_phy_control.usage);
+
+ if (usb_phy_control.usage) {
+ dev_info(&pdev->dev, "still being used(%ld)\n",usb_phy_control.usage);
+ return -EBUSY;
+ }
+
+ phypwr = readl(EXYNOS4_PHYPWR)
+ | PHY1_STD_NORMAL_MASK
+ | EXYNOS4210_HSIC0_NORMAL_MASK
+ | EXYNOS4210_HSIC1_NORMAL_MASK;
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ exynos_usb_phy_control(USB_PHY1, PHY_DISABLE);
+
+ return 0;
+}
+
+static int exynos4_usb_phy20_init(struct platform_device *pdev)
+{
+ u32 phypwr, phyclk, rstcon;
+
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ set_bit(HOST_PHY_EHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ set_bit(HOST_PHY_OHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s3c-usbgadget"))
+ set_bit(HOST_PHY_DEVICE, &usb_phy_control.usage);
+
+ dev_info(&pdev->dev, "usb phy usage(%ld)\n", usb_phy_control.usage);
+
+ if (exynos4_usb_phy20_is_on()) {
+ dev_err(&pdev->dev, "Already power on PHY\n");
+ return 0;
+ }
+
+ /*
+ * set XuhostOVERCUR to in-active by controlling ET6PUD[15:14]
+ * 0x0 : pull-up/down disabled
+ * 0x1 : pull-down enabled
+ * 0x2 : reserved
+ * 0x3 : pull-up enabled
+ */
+ writel((__raw_readl(ETC6PUD) & ~(0x3 << 14)) | (0x3 << 14),
+ ETC6PUD);
+
+ exynos_usb_phy_control(USB_PHY
+ | USB_PHY_HSIC0
+ | USB_PHY_HSIC1,
+ PHY_ENABLE);
+
+ /* USB MUX change from Device to Host */
+ exynos_usb_mux_change(pdev, 1);
+
+ /* set clock frequency for PLL */
+ phyclk = exynos_usb_phy_set_clock(pdev);
+ /* COMMON Block configuration during suspend */
+ phyclk &= ~(PHY0_COMMON_ON_N);
+#ifdef CONFIG_USB_OHCI_S5P
+ phyclk |= PHY1_COMMON_ON_N;
+#else
+ phyclk &= ~(PHY1_COMMON_ON_N);
+#endif
+ writel(phyclk, EXYNOS4_PHYCLK);
+
+ /* set to normal of Device */
+ phypwr = readl(EXYNOS4_PHYPWR) & ~PHY0_NORMAL_MASK;
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* set to normal of Host */
+ phypwr = readl(EXYNOS4_PHYPWR);
+ phypwr &= ~(PHY1_STD_NORMAL_MASK
+ | EXYNOS4212_HSIC0_NORMAL_MASK
+ | EXYNOS4212_HSIC1_NORMAL_MASK);
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ /* reset both PHY and Link of Device */
+ rstcon = readl(EXYNOS4_RSTCON) | PHY0_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+ rstcon &= ~PHY0_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+
+ /* reset both PHY and Link of Host */
+ rstcon = readl(EXYNOS4_RSTCON)
+ | EXYNOS4212_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4212_PHY1_SWRST_MASK;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+
+ rstcon &= ~(EXYNOS4212_HOST_LINK_PORT_SWRST_MASK
+ | EXYNOS4212_PHY1_SWRST_MASK);
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(80);
+
+ return 0;
+}
+
+static int exynos4_usb_phy20_exit(struct platform_device *pdev)
+{
+ u32 phypwr;
+
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ clear_bit(HOST_PHY_EHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ clear_bit(HOST_PHY_OHCI, &usb_phy_control.usage);
+ else if (!strcmp(pdev->name, "s3c-usbgadget"))
+ clear_bit(HOST_PHY_DEVICE, &usb_phy_control.usage);
+
+ if (usb_phy_control.usage) {
+ dev_info(&pdev->dev, "still being used(%ld)\n",
+ usb_phy_control.usage);
+ return -EBUSY;
+ } else
+ dev_info(&pdev->dev, "usb host phy off\n");
+
+ /* unset to normal of Device */
+ writel((readl(EXYNOS4_PHYPWR) | PHY0_NORMAL_MASK),
+ EXYNOS4_PHYPWR);
+
+ /* unset to normal of Host */
+ phypwr = readl(EXYNOS4_PHYPWR)
+ | PHY1_STD_NORMAL_MASK
+ | EXYNOS4212_HSIC0_NORMAL_MASK
+ | EXYNOS4212_HSIC1_NORMAL_MASK;
+ writel(phypwr, EXYNOS4_PHYPWR);
+
+ exynos_usb_phy_control(USB_PHY
+ | USB_PHY_HSIC0
+ | USB_PHY_HSIC1,
+ PHY_DISABLE);
+
+ usb_phy_control.lpa_entered = 0;
+
+ return 0;
+}
+
+static int exynos5_usb_phy_host_suspend(struct platform_device *pdev)
+{
+ u32 hostphy_ctrl0;
+
+ /* set to suspend HSIC 1 and 2 */
+ writel(readl(EXYNOS5_PHY_HSIC_CTRL1) | HSIC_CTRL_FORCESUSPEND,
+ EXYNOS5_PHY_HSIC_CTRL1);
+ writel(readl(EXYNOS5_PHY_HSIC_CTRL2) | HSIC_CTRL_FORCESUSPEND,
+ EXYNOS5_PHY_HSIC_CTRL2);
+
+ hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
+ /* set to suspend standard of PHY20 */
+ hostphy_ctrl0 |= HOST_CTRL0_FORCESUSPEND;
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+
+ return 0;
+}
+
+static int exynos5_usb_phy_host_resume(struct platform_device *pdev)
+{
+ u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl;
+ int err;
+
+ if (exynos5_usb_host_phy20_is_on()) {
+ /* set to suspend HSIC 0 and 1 and standard of PHY1 */
+ hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+
+ /* set common_on_n of PHY1 for power consumption */
+ hsic_ctrl = readl(EXYNOS5_PHY_HSIC_CTRL1);
+ hsic_ctrl &= ~(HSIC_CTRL_FORCESUSPEND);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+ if (usb_phy_control.lpa_entered) {
+ usb_phy_control.lpa_entered = 0;
+ err = 1;
+ } else
+ err = 0;
+ } else {
+ exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);
+
+ /* otg phy reset */
+ otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
+ otgphy_sys &= ~(OTG_SYS_SIDDQ_UOTG);
+ otgphy_sys |= (OTG_SYS_PHY0_SW_RST |
+ OTG_SYS_LINK_SW_RST_UOTG |
+ OTG_SYS_PHYLINK_SW_RESET);
+ writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
+ udelay(10);
+ otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST |
+ OTG_SYS_LINK_SW_RST_UOTG |
+ OTG_SYS_PHYLINK_SW_RESET);
+ writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
+
+ /* reset all ports of both PHY and Link */
+ hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_SIDDQ | HOST_CTRL0_FORCESUSPEND);
+ hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+ udelay(10);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+
+ /* HSIC phy reset */
+ hsic_ctrl = readl(EXYNOS5_PHY_HSIC_CTRL1);
+ hsic_ctrl &= ~(HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESUSPEND);
+ hsic_ctrl |= (HSIC_CTRL_PHYSWRST | HSIC_CTRL_UTMISWRST);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+ udelay(10);
+ hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST | HSIC_CTRL_UTMISWRST);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+
+ usb_phy_control.lpa_entered = 0;
+ err = 1;
+ }
+ udelay(80);
+
+ return err;
+}
+
+static int exynos5_usb_phy20_init(struct platform_device *pdev)
+{
+ u32 refclk_freq;
+ u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl, ehcictrl, ohcictrl;
+
+ atomic_inc(&host_usage);
+
+ if (exynos5_usb_host_phy20_is_on()) {
+ dev_err(&pdev->dev, "Already power on PHY\n");
+ return 0;
+ }
+
+ exynos_usb_mux_change(pdev, 1);
+
+ exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);
+
+ /* Host and Device should be set at the same time */
+ hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
+ otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
+ otgphy_sys &= ~(OTG_SYS_CTRL0_FSEL_MASK);
+
+ /* 2.0 phy reference clock configuration */
+ refclk_freq = exynos_usb_phy_set_clock(pdev);
+ hostphy_ctrl0 |= (refclk_freq << HOST_CTRL0_CLKSEL_SHIFT);
+ otgphy_sys |= (refclk_freq << OTG_SYS_CLKSEL_SHIFT);
+
+ /* COMMON Block configuration during suspend */
+ hostphy_ctrl0 |= HOST_CTRL0_COMMONON_N;
+ otgphy_sys &= ~(OTG_SYS_COMMON_ON);
+
+ /* otg phy reset */
+ otgphy_sys &= ~(OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG | OTG_SYS_FORCE_SLEEP);
+ otgphy_sys &= ~(OTG_SYS_REF_CLK_SEL_MASK);
+ otgphy_sys |= (OTG_SYS_REF_CLK_SEL(0x2) | OTG_SYS_OTGDISABLE);
+ otgphy_sys |= (OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG | OTG_SYS_PHYLINK_SW_RESET);
+ writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
+ udelay(10);
+ otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG | OTG_SYS_PHYLINK_SW_RESET);
+ writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
+
+ /* host phy reset */
+ hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL | HOST_CTRL0_SIDDQ);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
+ hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+ udelay(10);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+
+ /* HSIC phy reset */
+ hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |
+ HSIC_CTRL_PHYSWRST);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+ udelay(10);
+ hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+
+ udelay(80);
+ /* enable EHCI DMA burst */
+ ehcictrl = readl(EXYNOS5_PHY_HOST_EHCICTRL);
+ ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4 |
+ EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
+ writel(ehcictrl, EXYNOS5_PHY_HOST_EHCICTRL);
+ /* set ohci_suspend_on_n */
+ ohcictrl = readl(EXYNOS5_PHY_HOST_OHCICTRL);
+ ohcictrl |= OHCICTRL_SUSPLGCY;
+ writel(ohcictrl, EXYNOS5_PHY_HOST_OHCICTRL);
+ return 0;
+}
+
+static int exynos5_usb_phy20_exit(struct platform_device *pdev)
+{
+ u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl;
+
+ if (atomic_dec_return(&host_usage) > 0) {
+ dev_info(&pdev->dev, "still being used\n");
+ return -EBUSY;
+ }
+
+ hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |
+ HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESLEEP | HSIC_CTRL_FORCESUSPEND);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+
+ hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
+ hostphy_ctrl0 |= (HOST_CTRL0_SIDDQ);
+ hostphy_ctrl0 |= (HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
+ hostphy_ctrl0 |= (HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+
+ otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
+ otgphy_sys |= (OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG | OTG_SYS_FORCE_SLEEP);
+ writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
+
+ exynos_usb_phy_control(USB_PHY1, PHY_DISABLE);
+
+ return 0;
+}
+
+static int exynos_usb_dev_phy20_init(struct platform_device *pdev)
+{
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ exynos4_usb_phy20_init(pdev);
+ if (usb_phy_control.lpa_entered)
+ exynos4_usb_phy1_suspend(pdev);
+ } else {
+ exynos5_usb_phy20_init(pdev);
+ if (usb_phy_control.lpa_entered)
+ exynos5_usb_phy_host_suspend(pdev);
+ }
+
+ exynos_usb_mux_change(pdev, 0);
+
+ return 0;
+}
+
+static int exynos_usb_dev_phy20_exit(struct platform_device *pdev)
+{
+ if (soc_is_exynos4212() || soc_is_exynos4412())
+ exynos4_usb_phy20_exit(pdev);
+ else
+ exynos5_usb_phy20_exit(pdev);
+
+ exynos_usb_mux_change(pdev, 1);
+
+ return 0;
+}
+
+static int __maybe_unused exynos_usb_hsic_init(struct platform_device *pdev)
+{
+ u32 rstcon, hsic_ctrl;
+
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ exynos_usb_phy_control(USB_PHY_HSIC0
+ | USB_PHY_HSIC1,
+ PHY_ENABLE);
+
+ /* reset both PHY and Link of Host */
+ rstcon = readl(EXYNOS4_RSTCON)
+ | EXYNOS4212_PHY1_HSIC0_SWRST
+ | EXYNOS4212_PHY1_HSIC1_SWRST;
+ writel(rstcon, EXYNOS4_RSTCON);
+ udelay(10);
+
+ rstcon &= ~(EXYNOS4212_PHY1_HSIC0_SWRST
+ | EXYNOS4212_PHY1_HSIC1_SWRST);
+ writel(rstcon, EXYNOS4_RSTCON);
+ } else {
+ /* HSIC phy reset */
+ hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |
+ HSIC_CTRL_PHYSWRST);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+ udelay(10);
+ hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+ }
+
+ return 0;
+}
+
+static int __maybe_unused exynos_usb_hsic_exit(struct platform_device *pdev)
+{
+ u32 hsic_ctrl;
+
+ if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ exynos_usb_phy_control(USB_PHY_HSIC0
+ | USB_PHY_HSIC1,
+ PHY_DISABLE);
+ } else {
+ hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |
+ HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESLEEP | HSIC_CTRL_FORCESUSPEND);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
+ writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
+ }
+
+ return 0;
+}
+
+static int exynos5_usb_phy30_init(struct platform_device *pdev)
+{
+ u32 reg;
+ bool use_ext_clk = true;
+
+ exynos_usb_phy_control(USB_PHY0, PHY_ENABLE);
+
+ /* Reset USB 3.0 PHY */
+ writel(0x00000000, EXYNOS_USB3_PHYREG0);
+ writel(0x24d4e6e4, EXYNOS_USB3_PHYPARAM0);
+ writel(0x03fff820, EXYNOS_USB3_PHYPARAM1);
+ writel(0x00000000, EXYNOS_USB3_PHYRESUME);
+
+ if (soc_is_exynos5250() && samsung_rev() < EXYNOS5250_REV_1_0) {
+ writel(0x087fffc0, EXYNOS_USB3_LINKSYSTEM);
+ writel(0x00000000, EXYNOS_USB3_PHYBATCHG);
+ /* Over-current pin is inactive on SMDK5250 rev 0.0 */
+ writel((readl(EXYNOS_USB3_LINKPORT) & ~(0x3<<4)) |
+ (0x3<<2), EXYNOS_USB3_LINKPORT);
+ } else {
+ writel(0x08000000, EXYNOS_USB3_LINKSYSTEM);
+ writel(0x00000004, EXYNOS_USB3_PHYBATCHG);
+#ifdef CONFIG_USB_EXYNOS_SWITCH
+ writel(readl(EXYNOS_USB3_LINKPORT) |
+ (0xf<<2), EXYNOS_USB3_LINKPORT);
+#endif
+ /* REVISIT :use externel clock 100MHz */
+ if (use_ext_clk)
+ writel(readl(EXYNOS_USB3_PHYPARAM0) | (0x1<<31),
+ EXYNOS_USB3_PHYPARAM0);
+ else
+ writel(readl(EXYNOS_USB3_PHYPARAM0) & ~(0x1<<31),
+ EXYNOS_USB3_PHYPARAM0);
+ }
+
+ /* UTMI Power Control */
+ writel(EXYNOS_USB3_PHYUTMI_OTGDISABLE, EXYNOS_USB3_PHYUTMI);
+
+ /* Set 100MHz external clock */
+ reg = EXYNOS_USB3_PHYCLKRST_PORTRESET |
+ /* HS PLL uses ref_pad_clk{p,m} or ref_alt_clk_{p,m}
+ * as reference */
+ EXYNOS_USB3_PHYCLKRST_REFCLKSEL(2) |
+ /* Digital power supply in normal operating mode */
+ EXYNOS_USB3_PHYCLKRST_RETENABLEN |
+ /* 0x27-100MHz, 0x2a-24MHz, 0x31-20MHz, 0x38-19.2MHz */
+ EXYNOS_USB3_PHYCLKRST_FSEL(0x27) |
+ /* 0x19-100MHz, 0x68-24MHz, 0x7d-20Mhz */
+ EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(0x19) |
+ /* Enable ref clock for SS function */
+ EXYNOS_USB3_PHYCLKRST_REF_SSP_EN |
+ /* Enable spread spectrum */
+ EXYNOS_USB3_PHYCLKRST_SSC_EN;
+
+ if (!(soc_is_exynos5250() && samsung_rev() < EXYNOS5250_REV_1_0))
+ reg |= EXYNOS_USB3_PHYCLKRST_COMMONONN;
+
+ writel(reg, EXYNOS_USB3_PHYCLKRST);
+
+ udelay(10);
+
+ reg &= ~(EXYNOS_USB3_PHYCLKRST_PORTRESET);
+ writel(reg, EXYNOS_USB3_PHYCLKRST);
+
+ return 0;
+}
+
+static int exynos5_usb_phy30_exit(struct platform_device *pdev)
+{
+ u32 reg;
+
+ reg = EXYNOS_USB3_PHYUTMI_OTGDISABLE |
+ EXYNOS_USB3_PHYUTMI_FORCESUSPEND |
+ EXYNOS_USB3_PHYUTMI_FORCESLEEP;
+ writel(reg, EXYNOS_USB3_PHYUTMI);
+
+ exynos_usb_phy_control(USB_PHY0, PHY_DISABLE);
+
+ return 0;
+}
+
+int exynos4_check_usb_op(void)
+{
+ u32 phypwr;
+ u32 op = 1;
+ unsigned long flags;
+ int ret;
+
+ ret = clk_enable(phy_clk);
+ if (ret)
+ return 0;
+
+ local_irq_save(flags);
+ phypwr = readl(EXYNOS4_PHYPWR);
+
+ /*If USB Device is power on, */
+ if (exynos_usb_device_phy_is_on()) {
+ op = 1;
+ goto done;
+ } else if (!exynos4_usb_host_phy_is_on()) {
+ op = 0;
+ goto done;
+ }
+
+ /*If USB Device & Host is suspended, */
+ if (soc_is_exynos4210()) {
+ if (phypwr & (PHY1_STD_FORCE_SUSPEND
+ | EXYNOS4210_HSIC0_FORCE_SUSPEND
+ | EXYNOS4210_HSIC1_FORCE_SUSPEND)) {
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+ /* HSIC LPA: LPA USB phy retention reume call the usb
+ * reset resume, so we should let CP to HSIC L3 mode. */
+ set_hsic_lpa_states(STATE_HSIC_LPA_ENTER);
+#endif
+ writel(readl(EXYNOS4_PHYPWR)
+ | PHY1_STD_ANALOG_POWERDOWN,
+ EXYNOS4_PHYPWR);
+ writel(PHY_DISABLE, S5P_USBHOST_PHY_CONTROL);
+
+ op = 0;
+ }
+ } else {
+ if (phypwr & (PHY1_STD_FORCE_SUSPEND
+ | EXYNOS4212_HSIC0_FORCE_SUSPEND
+ | EXYNOS4212_HSIC1_FORCE_SUSPEND)) {
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+ /* HSIC LPA: LPA USB phy retention reume call the usb
+ * reset resume, so we should let CP to HSIC L3 mode. */
+ set_hsic_lpa_states(STATE_HSIC_LPA_ENTER);
+#endif
+ /* unset to normal of Host */
+ writel(readl(EXYNOS4_PHYPWR)
+ | PHY1_STD_ANALOG_POWERDOWN
+ | EXYNOS4212_HSIC0_ANALOG_POWERDOWN
+ | EXYNOS4212_HSIC1_ANALOG_POWERDOWN,
+ EXYNOS4_PHYPWR);
+ /* unset to normal of Device */
+ writel((readl(EXYNOS4_PHYPWR) | PHY0_NORMAL_MASK),
+ EXYNOS4_PHYPWR);
+
+ exynos_usb_phy_control(USB_PHY
+ | USB_PHY_HSIC0
+ | USB_PHY_HSIC1,
+ PHY_DISABLE);
+
+ op = 0;
+ usb_phy_control.lpa_entered = 1;
+ }
+ }
+done:
+ local_irq_restore(flags);
+ clk_disable(phy_clk);
+
+ return op;
+}
+
+static int exynos5_check_usb_op(void)
+{
+ u32 hostphy_ctrl0, otgphy_sys;
+ u32 op = 1;
+ unsigned long flags;
+ int ret;
+
+ ret = clk_enable(phy_clk);
+ if (ret)
+ return 0;
+
+ local_irq_save(flags);
+ /* Check USB 3.0 DRD power */
+ if (exynos5_usb_phy30_is_on()) {
+ op = 1;
+ goto done;
+ }
+ /*If USB Device is power on, */
+ if (exynos_usb_device_phy_is_on()) {
+ op = 1;
+ goto done;
+ } else if (!exynos5_usb_host_phy20_is_on()) {
+ op = 0;
+ goto done;
+ }
+
+ hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
+
+ if (hostphy_ctrl0 & HOST_CTRL0_FORCESUSPEND) {
+ /* unset to normal of Host */
+ hostphy_ctrl0 |= (HOST_CTRL0_SIDDQ);
+ writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
+
+ /* unset to normal of Device */
+ otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
+ otgphy_sys |= OTG_SYS_SIDDQ_UOTG;
+ writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
+
+ exynos_usb_phy_control(USB_PHY1,
+ PHY_DISABLE);
+
+ op = 0;
+ usb_phy_control.lpa_entered = 1;
+ }
+done:
+ local_irq_restore(flags);
+ clk_disable(phy_clk);
+
+ return op;
+}
+
+/**
+ * exynos_check_usb_op - Check usb operation
+ *
+ * USB operation is checked for AP Power mode.
+ * NOTE: Should be checked before Entering AP power mode.
+ * exynos4 - USB Host & Device
+ * exynos5 - USB Host & Device & DRD
+ *
+ * return 1 : operation, 0 : stop.
+ */
+int exynos_check_usb_op(void)
+{
+ if (soc_is_exynos4210() ||
+ soc_is_exynos4212() ||
+ soc_is_exynos4412())
+ return exynos4_check_usb_op();
+ else
+ return exynos5_check_usb_op();
+}
+
+int s5p_usb_phy_suspend(struct platform_device *pdev, int type)
+{
+ int ret = 0;
+#ifdef CONFIG_USB_OHCI_S5P
+ struct s5p_ohci_hcd *s5p_ohci = platform_get_drvdata(&s5p_device_ohci);
+ struct usb_hcd *ohci_hcd = s5p_ohci->hcd;
+ u32 phyclk;
+#endif
+
+ if (exynos_usb_phy_clock_enable(pdev))
+ return 0;
+
+ mutex_lock(&phy_lock);
+
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ clear_bit(HOST_PHY_EHCI, &usb_phy_control.flags);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ clear_bit(HOST_PHY_OHCI, &usb_phy_control.flags);
+
+ if (usb_phy_control.flags)
+ goto done;
+
+ if (type == S5P_USB_PHY_HOST) {
+ if (soc_is_exynos4210() ||
+ soc_is_exynos4212() ||
+ soc_is_exynos4412()) {
+#ifdef CONFIG_USB_OHCI_S5P
+ /* Set OHCI clock off when ohci_hcd is suspended */
+ if (ohci_hcd->state == HC_STATE_SUSPENDED) {
+ phyclk = readl(EXYNOS4_PHYCLK);
+ phyclk &= ~(PHY1_COMMON_ON_N);
+ writel(phyclk, EXYNOS4_PHYCLK);
+ }
+ dev_info(&pdev->dev, "host_phy_susp:%d\n",
+ ohci_hcd->state);
+#endif
+ ret = exynos4_usb_phy1_suspend(pdev);
+ } else
+ ret = exynos5_usb_phy_host_suspend(pdev);
+ }
+done:
+ mutex_unlock(&phy_lock);
+ exynos_usb_phy_clock_disable(pdev);
+
+ return ret;
+}
+
+int s5p_usb_phy_resume(struct platform_device *pdev, int type)
+{
+ int ret = 0;
+ u32 phyclk;
+
+ if (exynos_usb_phy_clock_enable(pdev))
+ return 0;
+
+ mutex_lock(&phy_lock);
+
+ if (usb_phy_control.flags)
+ goto done;
+
+ if (type == S5P_USB_PHY_HOST) {
+ if (soc_is_exynos4210() ||
+ soc_is_exynos4212() ||
+ soc_is_exynos4412()) {
+ dev_info(&pdev->dev, "host_phy_resume\n");
+#ifdef CONFIG_USB_OHCI_S5P
+ phyclk = readl(EXYNOS4_PHYCLK);
+ phyclk |= PHY1_COMMON_ON_N;
+ writel(phyclk, EXYNOS4_PHYCLK);
+#endif
+ ret = exynos4_usb_phy1_resume(pdev);
+ } else
+ ret = exynos5_usb_phy_host_resume(pdev);
+ }
+done:
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ set_bit(HOST_PHY_EHCI, &usb_phy_control.flags);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ set_bit(HOST_PHY_OHCI, &usb_phy_control.flags);
+
+ mutex_unlock(&phy_lock);
+ exynos_usb_phy_clock_disable(pdev);
+
+ return ret;
+}
+
+int s5p_usb_phy0_tune(struct s5p_usbgadget_platdata *pdata, int def_mode)
+{
+ u32 phytune;
+ static u32 def_phytune;
+
+ if (!pdata)
+ return -1;
+
+ printk(KERN_DEBUG "usb: %s read original tune\n", __func__);
+ phytune = readl(PHY0_PHYTUNE);
+ if (!def_phytune) {
+ def_phytune = phytune;
+ printk(KERN_DEBUG "usb: %s save default phytune (0x%x)\n",
+ __func__, def_phytune);
+ }
+
+ printk(KERN_DEBUG "usb: %s original tune=0x%x\n",
+ __func__, phytune);
+ printk(KERN_DEBUG "usb: %s tune_mask=0x%x, tune=0x%x\n",
+ __func__, pdata->phy_tune_mask, pdata->phy_tune);
+
+ if (pdata->phy_tune_mask) {
+ phytune &= ~(pdata->phy_tune_mask);
+ phytune |= pdata->phy_tune;
+ udelay(10);
+ if (def_mode) {
+ printk(KERN_DEBUG "usb: %s set defult tune=0x%x\n",
+ __func__, def_phytune);
+ writel(def_phytune, PHY0_PHYTUNE);
+
+ } else {
+ printk(KERN_DEBUG "usb: %s custom tune=0x%x\n",
+ __func__, phytune);
+ writel(phytune, PHY0_PHYTUNE);
+ }
+ phytune = readl(PHY0_PHYTUNE);
+ printk(KERN_DEBUG "usb: %s modified tune=0x%x\n",
+ __func__, phytune);
+ } else
+ printk(KERN_DEBUG "usb: %s default tune\n", __func__);
+
+ return 0;
+}
+
+void set_exynos_usb_phy_tune(int type)
+{
+ u32 phytune;
+ if (soc_is_exynos4412()) {
+ if (type == S5P_USB_PHY_DEVICE) {
+ phytune = readl(PHY0_PHYTUNE);
+ printk(KERN_DEBUG "usb: %s old phy0 tune=0x%x t=%d\n",
+ __func__, phytune, type);
+ /* sqrxtune [13:11] 3b110 : -15% */
+ phytune &= ~(0x7 << 11);
+ phytune |= (0x6 << 11);
+ udelay(10);
+ writel(phytune, PHY0_PHYTUNE);
+ phytune = readl(PHY0_PHYTUNE);
+ printk(KERN_DEBUG "usb: %s new phy0 tune=0x%x\n",
+ __func__, phytune);
+ } else if (type == S5P_USB_PHY_HOST) {
+ phytune = readl(PHY1_PHYTUNE);
+ printk(KERN_DEBUG "usb: %s old phy1 tune=0x%x t=%d\n",
+ __func__, phytune, type);
+ /* sqrxtune [13:11] 3b110 : -15% */
+ phytune &= ~(0x7 << 11);
+ phytune |= (0x6 << 11);
+ udelay(10);
+ writel(phytune, PHY1_PHYTUNE);
+ phytune = readl(PHY1_PHYTUNE);
+ printk(KERN_DEBUG "usb: %s new phy1 tune=0x%x\n",
+ __func__, phytune);
+ }
+ } else
+ printk(KERN_DEBUG "usb: %s it is not exynos4412.(t=%d)\n",
+ __func__, type);
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+ int ret = -EINVAL;
+
+ if (exynos_usb_phy_clock_enable(pdev))
+ return ret;
+
+ mutex_lock(&phy_lock);
+
+ if (type == S5P_USB_PHY_HOST) {
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ set_bit(HOST_PHY_EHCI, &usb_phy_control.flags);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ set_bit(HOST_PHY_OHCI, &usb_phy_control.flags);
+
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+ /* HSIC LPA: Let CP know the slave wakeup from LPA wakeup */
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ set_hsic_lpa_states(STATE_HSIC_LPA_PHY_INIT);
+#endif
+ if (soc_is_exynos4210())
+ ret = exynos4_usb_phy1_init(pdev);
+ else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ ret = exynos4_usb_phy20_init(pdev);
+ set_exynos_usb_phy_tune(type);
+ } else
+ ret = exynos5_usb_phy20_init(pdev);
+ } else if (type == S5P_USB_PHY_DEVICE) {
+ if (soc_is_exynos4210())
+ ret = exynos4_usb_phy0_init(pdev);
+ else {
+ ret = exynos_usb_dev_phy20_init(pdev);
+ set_exynos_usb_phy_tune(type);
+ }
+ /* set custom usb phy tune */
+ if (pdev->dev.platform_data)
+ ret = s5p_usb_phy0_tune(pdev->dev.platform_data, 0);
+ } else if (type == S5P_USB_PHY_OTGHOST) {
+ if (soc_is_exynos4210())
+ ret = exynos4_usb_phy0_init(pdev);
+ else
+ ret = exynos_usb_dev_phy20_init(pdev);
+ } else if (type == S5P_USB_PHY_DRD)
+ ret = exynos5_usb_phy30_init(pdev);
+
+ mutex_unlock(&phy_lock);
+ exynos_usb_phy_clock_disable(pdev);
+
+ return ret;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+ int ret = -EINVAL;
+
+ if (exynos_usb_phy_clock_enable(pdev))
+ return ret;
+
+ mutex_lock(&phy_lock);
+
+ if (type == S5P_USB_PHY_HOST) {
+ if (soc_is_exynos4210())
+ ret = exynos4_usb_phy1_exit(pdev);
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ ret = exynos4_usb_phy20_exit(pdev);
+ else
+ ret = exynos5_usb_phy20_exit(pdev);
+
+ if (!strcmp(pdev->name, "s5p-ehci"))
+ clear_bit(HOST_PHY_EHCI, &usb_phy_control.flags);
+ else if (!strcmp(pdev->name, "s5p-ohci"))
+ clear_bit(HOST_PHY_OHCI, &usb_phy_control.flags);
+ } else if (type == S5P_USB_PHY_DEVICE) {
+ /* set default usb phy tune */
+ if (pdev->dev.platform_data && soc_is_exynos4210())
+ ret = s5p_usb_phy0_tune(pdev->dev.platform_data, 1);
+ if (soc_is_exynos4210())
+ ret = exynos4_usb_phy0_exit(pdev);
+ else
+ ret = exynos_usb_dev_phy20_exit(pdev);
+ } else if (type == S5P_USB_PHY_DRD)
+ ret = exynos5_usb_phy30_exit(pdev);
+ else if (type == S5P_USB_PHY_OTGHOST) {
+ if (soc_is_exynos4210())
+ ret = exynos4_usb_phy0_exit(pdev);
+ else
+ ret = exynos_usb_dev_phy20_exit(pdev);
+ }
+
+ mutex_unlock(&phy_lock);
+ exynos_usb_phy_clock_disable(pdev);
+
+ return ret;
+}
diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos/sleep-exynos4.S
index 6b62425..d5c2aa0 100644
--- a/arch/arm/mach-exynos4/sleep.S
+++ b/arch/arm/mach-exynos/sleep-exynos4.S
@@ -1,4 +1,4 @@
-/* linux/arch/arm/mach-exynos4/sleep.S
+/* linux/arch/arm/mach-exynos/sleep-exynos4.S
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
@@ -29,6 +29,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/memory.h>
+#include <mach/smc.h>
.text
@@ -42,14 +43,53 @@
ENTRY(s3c_cpu_save)
stmfd sp!, { r3 - r12, lr }
+
+ adr r0, sleep_save_misc
+
+ mrc p15, 0, r2, c15, c0, 0 @ read power control register
+ str r2, [r0], #4
+
+ mrc p15, 0, r2, c15, c0, 1 @ read diagnostic register
+ str r2, [r0], #4
+
ldr r3, =resume_with_mmu
bl cpu_suspend
- ldr r0, =pm_cpu_sleep
- ldr r0, [ r0 ]
- mov pc, r0
+ bl exynos4_cpu_suspend
+
+ /* Restore original sp */
+ mov r0, sp
+ add r0, r0, #4
+ ldr sp, [r0]
+
+ mov r0, #0
+ b early_wakeup
resume_with_mmu:
+
+ adr r0, sleep_save_misc
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldr r1, [r0], #4
+ ldr r2, [r0], #4
+
+ ldr r0, =SMC_CMD_C15RESUME
+ mov r3, #0
+#ifdef REQUIRES_SEC
+ .arch_extension sec
+#endif
+ smc 0
+#else
+ ldr r1, [r0], #4
+ mcr p15, 0, r1, c15, c0, 0 @ write power control register
+
+ ldr r1, [r0], #4
+ mcr p15, 0, r1, c15, c0, 1 @ write diagnostic register
+#endif
+
+ mov r0, #1
+early_wakeup:
+
ldmfd sp!, { r3 - r12, pc }
.ltorg
@@ -62,6 +102,10 @@ resume_with_mmu:
.word 0x2bedf00d
+sleep_save_misc:
+ .long 0
+ .long 0
+
/*
* s3c_cpu_resume
*
diff --git a/arch/arm/mach-exynos/sleep-exynos5.S b/arch/arm/mach-exynos/sleep-exynos5.S
new file mode 100644
index 0000000..36b50c1
--- /dev/null
+++ b/arch/arm/mach-exynos/sleep-exynos5.S
@@ -0,0 +1,137 @@
+/* linux/arch/arm/mach-exynos/sleep-exynos5.S
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS5 power Manager (Suspend-To-RAM) support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+#include <mach/smc.h>
+
+ .text
+
+ /*
+ * s3c_cpu_save
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(s3c_cpu_save)
+
+ stmfd sp!, { r3 - r12, lr }
+
+ adr r0, sleep_save_misc
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ mrc p15, 0, r2, c1, c0, 1 @ read aux control register
+ str r2, [r0], #4
+#endif
+ mrc p15, 1, r2, c9, c0, 2 @ read l2 control register
+ str r2, [r0], #4
+ mrc p15, 1, r2, c15, c0, 3 @ read l2 prefetch register
+ str r2, [r0], #4
+
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ bl exynos5_cpu_suspend
+
+ /* Restore original sp */
+ mov r0, sp
+ add r0, r0, #4
+ ldr sp, [r0]
+
+ mov r0, #0
+ b early_wakeup
+
+resume_with_mmu:
+
+ adr r4, sleep_save_misc
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ mov r3, #0
+
+ ldr r0, =SMC_CMD_REG
+ ldr r1, =SMC_REG_ID_CP15(1, 0, 0, 1) @ aux control register
+ ldr r2, [r4], #4
+ smc 0
+ ldr r0, =SMC_CMD_REG
+ ldr r1, =SMC_REG_ID_CP15(9, 1, 0, 2) @ L2 control register
+ ldr r2, [r4], #4
+ smc 0
+ ldr r0, =SMC_CMD_REG
+ ldr r1, =SMC_REG_ID_CP15(15, 1, 0, 3) @ L2 prefetch register
+ ldr r2, [r4], #4
+ smc 0
+#else
+ ldr r2, [r4], #4
+ mcr p15, 1, r2, c9, c0, 2 @ L2 control register
+ ldr r2, [r4], #4
+ mcr p15, 1, r2, c15, c0, 3 @ L2 prefetch register
+#endif
+ mov r0, #1
+early_wakeup:
+
+ ldmfd sp!, { r3 - r12, pc }
+
+ .ltorg
+
+ /*
+ * sleep magic, to allow the bootloader to check for an valid
+ * image to resume to. Must be the first word before the
+ * s3c_cpu_resume entry.
+ */
+
+ .word 0x2bedf00d
+
+sleep_save_misc:
+ .long 0
+ .long 0
+ .long 0
+
+ /*
+ * s3c_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ *
+ * we must put this code here in the data segment as we have no
+ * other way of restoring the stack pointer after sleep, and we
+ * must not write to the code segment (code is read-only)
+ */
+
+ENTRY(s3c_cpu_resume)
+ /*
+ * Set for L2 Cache latency
+ */
+ mcr p15, 1, r0, c9, c0, 2
+ ldr r1, =0x3ff
+ bic r0, r0, r1
+ ldr r1, =0x2a2
+ orr r0, r0, r1
+ mrc p15, 1, r0, c9, c0, 2
+
+ b cpu_resume
diff --git a/arch/arm/mach-exynos/stand-hotplug.c b/arch/arm/mach-exynos/stand-hotplug.c
new file mode 100644
index 0000000..2a83c72
--- /dev/null
+++ b/arch/arm/mach-exynos/stand-hotplug.c
@@ -0,0 +1,414 @@
+/* linux/arch/arm/mach-exynos/stand-hotplug.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * EXYNOS - Dynamic CPU hotpluging
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/percpu.h>
+#include <linux/ktime.h>
+#include <linux/tick.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/gpio.h>
+#include <linux/cpufreq.h>
+
+#include <plat/map-base.h>
+#include <plat/gpio-cfg.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+
+#if defined(CONFIG_MACH_P10)
+#define TRANS_LOAD_H0 5
+#define TRANS_LOAD_L1 2
+#define TRANS_LOAD_H1 100
+
+#define BOOT_DELAY 30
+#define CHECK_DELAY_ON (.5*HZ * 8)
+#define CHECK_DELAY_OFF (.5*HZ)
+
+#endif
+
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_PX)
+#define TRANS_LOAD_H0 30
+#define TRANS_LOAD_L1 20
+#define TRANS_LOAD_H1 100
+
+#define BOOT_DELAY 60
+#define CHECK_DELAY_ON (.5*HZ * 4)
+#define CHECK_DELAY_OFF (.5*HZ)
+#endif
+
+#if defined(CONFIG_MACH_MIDAS) || defined(CONFIG_MACH_SMDK4X12)
+#ifdef CONFIG_MACH_S2PLUS
+#define TRANS_LOAD_H0 30
+#define TRANS_LOAD_L1 20
+#define TRANS_LOAD_H1 100
+#else
+#define TRANS_LOAD_H0 20
+#define TRANS_LOAD_L1 10
+#define TRANS_LOAD_H1 35
+#endif
+#define TRANS_LOAD_L2 15
+#define TRANS_LOAD_H2 45
+#define TRANS_LOAD_L3 20
+
+#define BOOT_DELAY 60
+#define CHECK_DELAY_ON (.5*HZ * 4)
+#define CHECK_DELAY_OFF (.5*HZ)
+#endif
+
+#define TRANS_RQ 2
+#define TRANS_LOAD_RQ 20
+
+#define CPU_OFF 0
+#define CPU_ON 1
+
+#define HOTPLUG_UNLOCKED 0
+#define HOTPLUG_LOCKED 1
+#define PM_HOTPLUG_DEBUG 1
+#define NUM_CPUS num_possible_cpus()
+#define CPULOAD_TABLE (NR_CPUS + 1)
+
+#define DBG_PRINT(fmt, ...)\
+ if(PM_HOTPLUG_DEBUG) \
+ printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
+
+static struct workqueue_struct *hotplug_wq;
+static struct delayed_work hotplug_work;
+
+static unsigned int max_performance;
+static unsigned int freq_min = -1UL;
+
+static unsigned int hotpluging_rate = CHECK_DELAY_OFF;
+module_param_named(rate, hotpluging_rate, uint, 0644);
+static unsigned int user_lock;
+module_param_named(lock, user_lock, uint, 0644);
+static unsigned int trans_rq= TRANS_RQ;
+module_param_named(min_rq, trans_rq, uint, 0644);
+static unsigned int trans_load_rq = TRANS_LOAD_RQ;
+module_param_named(load_rq, trans_load_rq, uint, 0644);
+
+static unsigned int trans_load_h0 = TRANS_LOAD_H0;
+module_param_named(load_h0, trans_load_h0, uint, 0644);
+static unsigned int trans_load_l1 = TRANS_LOAD_L1;
+module_param_named(load_l1, trans_load_l1, uint, 0644);
+static unsigned int trans_load_h1 = TRANS_LOAD_H1;
+module_param_named(load_h1, trans_load_h1, uint, 0644);
+
+#if (NR_CPUS > 2)
+static unsigned int trans_load_l2 = TRANS_LOAD_L2;
+module_param_named(load_l2, trans_load_l2, uint, 0644);
+static unsigned int trans_load_h2 = TRANS_LOAD_H2;
+module_param_named(load_h2, trans_load_h2, uint, 0644);
+static unsigned int trans_load_l3 = TRANS_LOAD_L3;
+module_param_named(load_l3, trans_load_l3, uint, 0644);
+#endif
+
+enum flag{
+ HOTPLUG_NOP,
+ HOTPLUG_IN,
+ HOTPLUG_OUT
+};
+
+struct cpu_time_info {
+ cputime64_t prev_cpu_idle;
+ cputime64_t prev_cpu_wall;
+ unsigned int load;
+};
+
+struct cpu_hotplug_info {
+ unsigned long nr_running;
+ pid_t tgid;
+};
+
+
+static DEFINE_PER_CPU(struct cpu_time_info, hotplug_cpu_time);
+
+/* mutex can be used since hotplug_timer does not run in
+ timer(softirq) context but in process context */
+static DEFINE_MUTEX(hotplug_lock);
+
+bool hotplug_out_chk(unsigned int nr_online_cpu, unsigned int threshold_up,
+ unsigned int avg_load, unsigned int cur_freq)
+{
+#if defined(CONFIG_MACH_P10)
+ return ((nr_online_cpu > 1) &&
+ (avg_load < threshold_up &&
+ cur_freq <= freq_min));
+#else
+ return ((nr_online_cpu > 1) &&
+ (avg_load < threshold_up ||
+ cur_freq <= freq_min));
+#endif
+}
+
+static inline enum flag
+standalone_hotplug(unsigned int load, unsigned long nr_rq_min, unsigned int cpu_rq_min)
+{
+ unsigned int cur_freq;
+ unsigned int nr_online_cpu;
+ unsigned int avg_load;
+ /*load threshold*/
+ unsigned int threshold[CPULOAD_TABLE][2] = {
+ {0, trans_load_h0},
+ {trans_load_l1, trans_load_h1},
+#if (NR_CPUS > 2)
+ {trans_load_l2, trans_load_h2},
+ {trans_load_l3, 100},
+#endif
+ {0, 0}
+ };
+
+ static void __iomem *clk_fimc;
+ unsigned char fimc_stat;
+
+ cur_freq = clk_get_rate(clk_get(NULL, "armclk")) / 1000;
+
+ nr_online_cpu = num_online_cpus();
+
+ avg_load = (unsigned int)((cur_freq * load) / max_performance);
+
+ clk_fimc = ioremap(0x10020000, SZ_4K);
+ fimc_stat = __raw_readl(clk_fimc + 0x0920);
+ iounmap(clk_fimc);
+
+ if ((fimc_stat>>4 & 0x1) == 1)
+ return HOTPLUG_IN;
+
+ if (hotplug_out_chk(nr_online_cpu, threshold[nr_online_cpu - 1][0],
+ avg_load, cur_freq)) {
+ return HOTPLUG_OUT;
+ /* If total nr_running is less than cpu(on-state) number, hotplug do not hotplug-in */
+ } else if (nr_running() > nr_online_cpu &&
+ avg_load > threshold[nr_online_cpu - 1][1] && cur_freq > freq_min) {
+
+ return HOTPLUG_IN;
+#if defined(CONFIG_MACH_P10)
+#else
+ } else if (nr_online_cpu > 1 && nr_rq_min < trans_rq) {
+
+ struct cpu_time_info *tmp_info;
+
+ tmp_info = &per_cpu(hotplug_cpu_time, cpu_rq_min);
+ /*If CPU(cpu_rq_min) load is less than trans_load_rq, hotplug-out*/
+ if (tmp_info->load < trans_load_rq)
+ return HOTPLUG_OUT;
+#endif
+ }
+
+ return HOTPLUG_NOP;
+}
+
+static void hotplug_timer(struct work_struct *work)
+{
+ struct cpu_hotplug_info tmp_hotplug_info[4];
+ int i;
+ unsigned int load = 0;
+ unsigned int cpu_rq_min=0;
+ unsigned long nr_rq_min = -1UL;
+ unsigned int select_off_cpu = 0;
+ enum flag flag_hotplug;
+
+ mutex_lock(&hotplug_lock);
+
+ if (user_lock == 1)
+ goto no_hotplug;
+
+ for_each_online_cpu(i) {
+ struct cpu_time_info *tmp_info;
+ cputime64_t cur_wall_time, cur_idle_time;
+ unsigned int idle_time, wall_time;
+
+ tmp_info = &per_cpu(hotplug_cpu_time, i);
+
+ cur_idle_time = get_cpu_idle_time_us(i, &cur_wall_time);
+
+ idle_time = (unsigned int)cputime64_sub(cur_idle_time,
+ tmp_info->prev_cpu_idle);
+ tmp_info->prev_cpu_idle = cur_idle_time;
+
+ wall_time = (unsigned int)cputime64_sub(cur_wall_time,
+ tmp_info->prev_cpu_wall);
+ tmp_info->prev_cpu_wall = cur_wall_time;
+
+ if (wall_time < idle_time)
+ goto no_hotplug;
+
+#ifdef CONFIG_TARGET_LOCALE_P2TMO_TEMP
+ /*For once Divide-by-Zero issue*/
+ if (wall_time == 0)
+ wall_time++;
+#endif
+ tmp_info->load = 100 * (wall_time - idle_time) / wall_time;
+
+ load += tmp_info->load;
+ /*find minimum runqueue length*/
+ tmp_hotplug_info[i].nr_running = get_cpu_nr_running(i);
+
+ if (i && nr_rq_min > tmp_hotplug_info[i].nr_running) {
+ nr_rq_min = tmp_hotplug_info[i].nr_running;
+
+ cpu_rq_min = i;
+ }
+ }
+
+ for (i = NUM_CPUS - 1; i > 0; --i) {
+ if (cpu_online(i) == 0) {
+ select_off_cpu = i;
+ break;
+ }
+ }
+
+ /*standallone hotplug*/
+ flag_hotplug = standalone_hotplug(load, nr_rq_min, cpu_rq_min);
+
+ /*cpu hotplug*/
+ if (flag_hotplug == HOTPLUG_IN && cpu_online(select_off_cpu) == CPU_OFF) {
+ DBG_PRINT("cpu%d turning on!\n", select_off_cpu);
+ cpu_up(select_off_cpu);
+ DBG_PRINT("cpu%d on\n", select_off_cpu);
+ hotpluging_rate = CHECK_DELAY_ON;
+ } else if (flag_hotplug == HOTPLUG_OUT && cpu_online(cpu_rq_min) == CPU_ON) {
+ DBG_PRINT("cpu%d turnning off!\n", cpu_rq_min);
+ cpu_down(cpu_rq_min);
+ DBG_PRINT("cpu%d off!\n", cpu_rq_min);
+ hotpluging_rate = CHECK_DELAY_OFF;
+ }
+
+no_hotplug:
+
+ queue_delayed_work_on(0, hotplug_wq, &hotplug_work, hotpluging_rate);
+
+ mutex_unlock(&hotplug_lock);
+}
+
+static int exynos4_pm_hotplug_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ static unsigned user_lock_saved;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ mutex_lock(&hotplug_lock);
+ user_lock_saved = user_lock;
+ user_lock = 1;
+ pr_info("%s: saving pm_hotplug lock %x\n",
+ __func__, user_lock_saved);
+ mutex_unlock(&hotplug_lock);
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ mutex_lock(&hotplug_lock);
+ pr_info("%s: restoring pm_hotplug lock %x\n",
+ __func__, user_lock_saved);
+ user_lock = user_lock_saved;
+ mutex_unlock(&hotplug_lock);
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block exynos4_pm_hotplug_notifier = {
+ .notifier_call = exynos4_pm_hotplug_notifier_event,
+};
+
+static int hotplug_reboot_notifier_call(struct notifier_block *this,
+ unsigned long code, void *_cmd)
+{
+ mutex_lock(&hotplug_lock);
+ pr_err("%s: disabling pm hotplug\n", __func__);
+ user_lock = 1;
+ mutex_unlock(&hotplug_lock);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block hotplug_reboot_notifier = {
+ .notifier_call = hotplug_reboot_notifier_call,
+};
+
+static int __init exynos4_pm_hotplug_init(void)
+{
+ unsigned int i;
+ unsigned int freq;
+ unsigned int freq_max = 0;
+ struct cpufreq_frequency_table *table;
+
+ printk(KERN_INFO "EXYNOS4 PM-hotplug init function\n");
+ //hotplug_wq = create_workqueue("dynamic hotplug");
+ hotplug_wq = alloc_workqueue("dynamic hotplug", 0, 0);
+ if (!hotplug_wq) {
+ printk(KERN_ERR "Creation of hotplug work failed\n");
+ return -EFAULT;
+ }
+
+ INIT_DELAYED_WORK(&hotplug_work, hotplug_timer);
+
+ queue_delayed_work_on(0, hotplug_wq, &hotplug_work, BOOT_DELAY * HZ);
+#ifdef CONFIG_CPU_FREQ
+ table = cpufreq_frequency_get_table(0);
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq != CPUFREQ_ENTRY_INVALID && freq > freq_max)
+ freq_max = freq;
+ else if (freq != CPUFREQ_ENTRY_INVALID && freq_min > freq)
+ freq_min = freq;
+ }
+ /*get max frequence*/
+ max_performance = freq_max * NUM_CPUS;
+#else
+ max_performance = clk_get_rate(clk_get(NULL, "armclk")) / 1000 * NUM_CPUS;
+ freq_min = clk_get_rate(clk_get(NULL, "armclk")) / 1000;
+#endif
+ register_pm_notifier(&exynos4_pm_hotplug_notifier);
+ register_reboot_notifier(&hotplug_reboot_notifier);
+
+ return 0;
+}
+
+late_initcall(exynos4_pm_hotplug_init);
+
+static struct platform_device exynos4_pm_hotplug_device = {
+ .name = "exynos4-dynamic-cpu-hotplug",
+ .id = -1,
+};
+
+static int __init exynos4_pm_hotplug_device_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&exynos4_pm_hotplug_device);
+
+ if (ret) {
+ printk(KERN_ERR "failed at(%d)\n", __LINE__);
+ return ret;
+ }
+
+ printk(KERN_INFO "exynos4_pm_hotplug_device_init: %d\n", ret);
+
+ return ret;
+}
+
+late_initcall(exynos4_pm_hotplug_device_init);
diff --git a/arch/arm/mach-exynos/subsystem_notif.c b/arch/arm/mach-exynos/subsystem_notif.c
new file mode 100644
index 0000000..f7db54c
--- /dev/null
+++ b/arch/arm/mach-exynos/subsystem_notif.c
@@ -0,0 +1,222 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * Subsystem Notifier -- Provides notifications
+ * of subsys events.
+ *
+ * Use subsys_notif_register_notifier to register for notifications
+ * and subsys_notif_queue_notification to send notifications.
+ *
+ */
+
+#include <linux/notifier.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/stringify.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include <mach/subsystem_notif.h>
+
+struct subsys_notif_info {
+ char name[50];
+ struct srcu_notifier_head subsys_notif_rcvr_list;
+ struct list_head list;
+};
+
+static LIST_HEAD(subsystem_list);
+static DEFINE_MUTEX(notif_lock);
+static DEFINE_MUTEX(notif_add_lock);
+
+#if defined(SUBSYS_RESTART_DEBUG)
+static void subsys_notif_reg_test_notifier(const char *);
+#endif
+
+static struct subsys_notif_info *_notif_find_subsys(const char *subsys_name)
+{
+ struct subsys_notif_info *subsys;
+
+ mutex_lock(&notif_lock);
+ list_for_each_entry(subsys, &subsystem_list, list)
+ if (!strncmp(subsys->name, subsys_name,
+ ARRAY_SIZE(subsys->name))) {
+ mutex_unlock(&notif_lock);
+ return subsys;
+ }
+ mutex_unlock(&notif_lock);
+
+ return NULL;
+}
+
+void *subsys_notif_register_notifier(
+ const char *subsys_name, struct notifier_block *nb)
+{
+ int ret;
+ struct subsys_notif_info *subsys = _notif_find_subsys(subsys_name);
+
+ if (!subsys) {
+
+ /* Possible first time reference to this subsystem. Add it. */
+ subsys = (struct subsys_notif_info *)
+ subsys_notif_add_subsys(subsys_name);
+
+ if (!subsys)
+ return ERR_PTR(-EINVAL);
+ }
+
+ ret = srcu_notifier_chain_register(
+ &subsys->subsys_notif_rcvr_list, nb);
+
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ return subsys;
+}
+EXPORT_SYMBOL(subsys_notif_register_notifier);
+
+int subsys_notif_unregister_notifier(void *subsys_handle,
+ struct notifier_block *nb)
+{
+ int ret;
+ struct subsys_notif_info *subsys =
+ (struct subsys_notif_info *)subsys_handle;
+
+ if (!subsys)
+ return -EINVAL;
+
+ ret = srcu_notifier_chain_unregister(
+ &subsys->subsys_notif_rcvr_list, nb);
+
+ return ret;
+}
+EXPORT_SYMBOL(subsys_notif_unregister_notifier);
+
+void *subsys_notif_add_subsys(const char *subsys_name)
+{
+ struct subsys_notif_info *subsys = NULL;
+
+ if (!subsys_name)
+ goto done;
+
+ mutex_lock(&notif_add_lock);
+
+ subsys = _notif_find_subsys(subsys_name);
+
+ if (subsys) {
+ mutex_unlock(&notif_add_lock);
+ goto done;
+ }
+
+ subsys = kmalloc(sizeof(struct subsys_notif_info), GFP_KERNEL);
+
+ if (!subsys) {
+ mutex_unlock(&notif_add_lock);
+ return ERR_PTR(-EINVAL);
+ }
+
+ strlcpy(subsys->name, subsys_name, ARRAY_SIZE(subsys->name));
+
+ srcu_init_notifier_head(&subsys->subsys_notif_rcvr_list);
+
+ INIT_LIST_HEAD(&subsys->list);
+
+ mutex_lock(&notif_lock);
+ list_add_tail(&subsys->list, &subsystem_list);
+ mutex_unlock(&notif_lock);
+
+ #if defined(SUBSYS_RESTART_DEBUG)
+ subsys_notif_reg_test_notifier(subsys->name);
+ #endif
+
+ mutex_unlock(&notif_add_lock);
+
+done:
+ return subsys;
+}
+EXPORT_SYMBOL(subsys_notif_add_subsys);
+
+int subsys_notif_queue_notification(void *subsys_handle,
+ enum subsys_notif_type notif_type)
+{
+ int ret = 0;
+ struct subsys_notif_info *subsys =
+ (struct subsys_notif_info *) subsys_handle;
+
+ if (!subsys)
+ return -EINVAL;
+
+ if (notif_type < 0 || notif_type >= SUBSYS_NOTIF_TYPE_COUNT)
+ return -EINVAL;
+
+ ret = srcu_notifier_call_chain(
+ &subsys->subsys_notif_rcvr_list, notif_type,
+ (void *)subsys);
+
+ return ret;
+}
+EXPORT_SYMBOL(subsys_notif_queue_notification);
+
+#if defined(SUBSYS_RESTART_DEBUG)
+static const char *notif_to_string(enum subsys_notif_type notif_type)
+{
+ switch (notif_type) {
+
+ case SUBSYS_BEFORE_SHUTDOWN:
+ return __stringify(SUBSYS_BEFORE_SHUTDOWN);
+
+ case SUBSYS_AFTER_SHUTDOWN:
+ return __stringify(SUBSYS_AFTER_SHUTDOWN);
+
+ case SUBSYS_BEFORE_POWERUP:
+ return __stringify(SUBSYS_BEFORE_POWERUP);
+
+ case SUBSYS_AFTER_POWERUP:
+ return __stringify(SUBSYS_AFTER_POWERUP);
+
+ default:
+ return "unknown";
+ }
+}
+
+static int subsys_notifier_test_call(struct notifier_block *this,
+ unsigned long code,
+ void *data)
+{
+ switch (code) {
+
+ default:
+ printk(KERN_WARNING "%s: Notification %s from subsystem %p\n",
+ __func__, notif_to_string(code), data);
+ break;
+
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block nb = {
+ .notifier_call = subsys_notifier_test_call,
+};
+
+static void subsys_notif_reg_test_notifier(const char *subsys_name)
+{
+ void *handle = subsys_notif_register_notifier(subsys_name, &nb);
+ printk(KERN_WARNING "%s: Registered test notifier, handle=%p",
+ __func__, handle);
+}
+#endif
+
+MODULE_DESCRIPTION("Subsystem Restart Notifier");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-exynos/subsystem_restart.c b/arch/arm/mach-exynos/subsystem_restart.c
new file mode 100644
index 0000000..0a76ab3
--- /dev/null
+++ b/arch/arm/mach-exynos/subsystem_restart.c
@@ -0,0 +1,680 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "subsys-restart: %s(): " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/kthread.h>
+#include <linux/time.h>
+#include <linux/wakelock.h>
+#include <linux/suspend.h>
+
+#include <asm/current.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include <mach/peripheral-loader.h>
+#include <mach/scm.h>
+#include <mach/socinfo.h>
+#endif
+#include <mach/subsystem_notif.h>
+#include <mach/subsystem_restart.h>
+
+#ifndef CONFIG_ARCH_EXYNOS
+#include "smd_private.h"
+#endif
+
+struct subsys_soc_restart_order {
+ const char * const *subsystem_list;
+ int count;
+
+ struct mutex shutdown_lock;
+ struct mutex powerup_lock;
+ struct subsys_data *subsys_ptrs[];
+};
+
+struct restart_wq_data {
+ struct subsys_data *subsys;
+ struct wake_lock ssr_wake_lock;
+ char wakelockname[64];
+ int coupled;
+ struct work_struct work;
+};
+
+struct restart_log {
+ struct timeval time;
+ struct subsys_data *subsys;
+ struct list_head list;
+};
+
+static int restart_level;
+static int enable_ramdumps = 1;
+struct workqueue_struct *ssr_wq;
+
+static LIST_HEAD(restart_log_list);
+static LIST_HEAD(subsystem_list);
+static DEFINE_MUTEX(subsystem_list_lock);
+static DEFINE_MUTEX(soc_order_reg_lock);
+static DEFINE_MUTEX(restart_log_mutex);
+
+/* SOC specific restart orders go here */
+
+#define DEFINE_SINGLE_RESTART_ORDER(name, order) \
+ static struct subsys_soc_restart_order __##name = { \
+ .subsystem_list = order, \
+ .count = ARRAY_SIZE(order), \
+ .subsys_ptrs = {[ARRAY_SIZE(order)] = NULL} \
+ }; \
+ static struct subsys_soc_restart_order *name[] = { \
+ &__##name, \
+ }
+
+#ifndef CONFIG_ARCH_EXYNOS
+/* MSM 8x60 restart ordering info */
+static const char * const _order_8x60_all[] = {
+ "external_modem", "modem", "lpass"
+};
+DEFINE_SINGLE_RESTART_ORDER(orders_8x60_all, _order_8x60_all);
+
+static const char * const _order_8x60_modems[] = {"external_modem", "modem"};
+DEFINE_SINGLE_RESTART_ORDER(orders_8x60_modems, _order_8x60_modems);
+#else /* CONFIG_ARCH_EXYNOS */
+/* MSM 8x60 restart ordering info */
+static const char * const _order_8x60_all[] = {
+ "external_modem",
+};
+DEFINE_SINGLE_RESTART_ORDER(orders_8x60_all, _order_8x60_all);
+
+static const char * const _order_8x60_modems[] = {"external_modem"};
+DEFINE_SINGLE_RESTART_ORDER(orders_8x60_modems, _order_8x60_modems);
+#endif
+
+/* MSM 8960 restart ordering info */
+static const char * const order_8960[] = {"modem", "lpass"};
+
+static struct subsys_soc_restart_order restart_orders_8960_one = {
+ .subsystem_list = order_8960,
+ .count = ARRAY_SIZE(order_8960),
+ .subsys_ptrs = {[ARRAY_SIZE(order_8960)] = NULL}
+ };
+
+static struct subsys_soc_restart_order *restart_orders_8960[] = {
+ &restart_orders_8960_one,
+};
+/* These will be assigned to one of the sets above after
+ * runtime SoC identification.
+ */
+static struct subsys_soc_restart_order **restart_orders;
+static int n_restart_orders;
+
+module_param(enable_ramdumps, int, S_IRUGO | S_IWUSR);
+
+static struct subsys_soc_restart_order *_update_restart_order(
+ struct subsys_data *subsys);
+
+#ifndef CONFIG_ARCH_EXYNOS
+int get_restart_level()
+{
+ return restart_level;
+}
+EXPORT_SYMBOL(get_restart_level);
+
+static void restart_level_changed(void)
+{
+ struct subsys_data *subsys;
+
+ if (cpu_is_msm8x60() && restart_level == RESET_SUBSYS_COUPLED) {
+ restart_orders = orders_8x60_all;
+ n_restart_orders = ARRAY_SIZE(orders_8x60_all);
+ }
+
+ if (cpu_is_msm8x60() && restart_level == RESET_SUBSYS_MIXED) {
+ restart_orders = orders_8x60_modems;
+ n_restart_orders = ARRAY_SIZE(orders_8x60_modems);
+ }
+
+ mutex_lock(&subsystem_list_lock);
+ list_for_each_entry(subsys, &subsystem_list, list)
+ subsys->restart_order = _update_restart_order(subsys);
+ mutex_unlock(&subsystem_list_lock);
+}
+
+static int restart_level_set(const char *val, struct kernel_param *kp)
+{
+ int ret;
+ int old_val = restart_level;
+
+ if (cpu_is_msm9615()) {
+ pr_err("Only Phase 1 subsystem restart is supported\n");
+ return -EINVAL;
+ }
+
+ ret = param_set_int(val, kp);
+ if (ret)
+ return ret;
+
+ switch (restart_level) {
+
+ case RESET_SOC:
+ case RESET_SUBSYS_COUPLED:
+ case RESET_SUBSYS_INDEPENDENT:
+ pr_info("Phase %d behavior activated.\n", restart_level);
+ break;
+
+ case RESET_SUBSYS_MIXED:
+ pr_info("Phase 2+ behavior activated.\n");
+ break;
+
+ default:
+ restart_level = old_val;
+ return -EINVAL;
+ break;
+
+ }
+
+ if (restart_level != old_val)
+ restart_level_changed();
+
+ return 0;
+}
+
+module_param_call(restart_level, restart_level_set, param_get_int,
+ &restart_level, 0644);
+#endif
+static struct subsys_data *_find_subsystem(const char *subsys_name)
+{
+ struct subsys_data *subsys;
+
+ mutex_lock(&subsystem_list_lock);
+ list_for_each_entry(subsys, &subsystem_list, list)
+ if (!strncmp(subsys->name, subsys_name,
+ SUBSYS_NAME_MAX_LENGTH)) {
+ mutex_unlock(&subsystem_list_lock);
+ return subsys;
+ }
+ mutex_unlock(&subsystem_list_lock);
+
+ return NULL;
+}
+
+static struct subsys_soc_restart_order *_update_restart_order(
+ struct subsys_data *subsys)
+{
+ int i, j;
+
+ if (!subsys)
+ return NULL;
+
+ if (!subsys->name)
+ return NULL;
+
+ mutex_lock(&soc_order_reg_lock);
+ for (j = 0; j < n_restart_orders; j++) {
+ for (i = 0; i < restart_orders[j]->count; i++)
+ if (!strncmp(restart_orders[j]->subsystem_list[i],
+ subsys->name, SUBSYS_NAME_MAX_LENGTH)) {
+
+ restart_orders[j]->subsys_ptrs[i] =
+ subsys;
+ mutex_unlock(&soc_order_reg_lock);
+ return restart_orders[j];
+ }
+ }
+
+ mutex_unlock(&soc_order_reg_lock);
+
+ return NULL;
+}
+
+static void _send_notification_to_order(struct subsys_data
+ **restart_list, int count,
+ enum subsys_notif_type notif_type)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (restart_list[i])
+ subsys_notif_queue_notification(
+ restart_list[i]->notif_handle, notif_type);
+}
+
+static int max_restarts;
+module_param(max_restarts, int, 0644);
+
+static long max_history_time = 3600;
+module_param(max_history_time, long, 0644);
+
+static void do_epoch_check(struct subsys_data *subsys)
+{
+ int n = 0;
+ struct timeval *time_first = NULL, *curr_time;
+ struct restart_log *r_log, *temp;
+ static int max_restarts_check;
+ static long max_history_time_check;
+
+ mutex_lock(&restart_log_mutex);
+
+ max_restarts_check = max_restarts;
+ max_history_time_check = max_history_time;
+
+ /* Check if epoch checking is enabled */
+ if (!max_restarts_check)
+ goto out;
+
+ r_log = kmalloc(sizeof(struct restart_log), GFP_KERNEL);
+ if (!r_log)
+ goto out;
+ r_log->subsys = subsys;
+ do_gettimeofday(&r_log->time);
+ curr_time = &r_log->time;
+ INIT_LIST_HEAD(&r_log->list);
+
+ list_add_tail(&r_log->list, &restart_log_list);
+
+ list_for_each_entry_safe(r_log, temp, &restart_log_list, list) {
+
+ if ((curr_time->tv_sec - r_log->time.tv_sec) >
+ max_history_time_check) {
+
+ pr_debug("Deleted node with restart_time = %ld\n",
+ r_log->time.tv_sec);
+ list_del(&r_log->list);
+ kfree(r_log);
+ continue;
+ }
+ if (!n) {
+ time_first = &r_log->time;
+ pr_debug("Time_first: %ld\n", time_first->tv_sec);
+ }
+ n++;
+ pr_debug("Restart_time: %ld\n", r_log->time.tv_sec);
+ }
+
+ if (time_first && n >= max_restarts_check) {
+ if ((curr_time->tv_sec - time_first->tv_sec) <
+ max_history_time_check)
+ panic("Subsystems have crashed %d times in less than "
+ "%ld seconds!", max_restarts_check,
+ max_history_time_check);
+ }
+
+out:
+ mutex_unlock(&restart_log_mutex);
+}
+
+static void subsystem_restart_wq_func(struct work_struct *work)
+{
+ struct restart_wq_data *r_work = container_of(work,
+ struct restart_wq_data, work);
+ struct subsys_data **restart_list;
+ struct subsys_data *subsys = r_work->subsys;
+ struct subsys_soc_restart_order *soc_restart_order = NULL;
+
+ struct mutex *powerup_lock;
+ struct mutex *shutdown_lock;
+
+ int i;
+ int restart_list_count = 0;
+
+ if (r_work->coupled)
+ soc_restart_order = subsys->restart_order;
+
+ /* It's OK to not take the registration lock at this point.
+ * This is because the subsystem list inside the relevant
+ * restart order is not being traversed.
+ */
+ if (!soc_restart_order) {
+ pr_info("i am here\n");
+ restart_list = subsys->single_restart_list;
+ restart_list_count = 1;
+ powerup_lock = &subsys->powerup_lock;
+ shutdown_lock = &subsys->shutdown_lock;
+ } else {
+ pr_info("i am here, 2nd\n");
+ restart_list = soc_restart_order->subsys_ptrs;
+ restart_list_count = soc_restart_order->count;
+ powerup_lock = &soc_restart_order->powerup_lock;
+ shutdown_lock = &soc_restart_order->shutdown_lock;
+ }
+ pr_info("subsys[%p], powerup lock[%p], shutdown_lock[%p]\n", subsys,
+ powerup_lock, shutdown_lock);
+
+ pr_info("[%p]: Attempting to get shutdown lock!\n", current);
+
+ /* Try to acquire shutdown_lock. If this fails, these subsystems are
+ * already being restarted - return.
+ */
+ if (!mutex_trylock(shutdown_lock))
+ goto out;
+
+ pr_info("[%p]: Attempting to get powerup lock!\n", current);
+
+ /* Now that we've acquired the shutdown lock, either we're the first to
+ * restart these subsystems or some other thread is doing the powerup
+ * sequence for these subsystems. In the latter case, panic and bail
+ * out, since a subsystem died in its powerup sequence.
+ */
+ if (!mutex_trylock(powerup_lock))
+ panic("%s[%p]: Subsystem died during powerup!",
+ __func__, current);
+
+ do_epoch_check(subsys);
+
+ /* Now it is necessary to take the registration lock. This is because
+ * the subsystem list in the SoC restart order will be traversed
+ * and it shouldn't be changed until _this_ restart sequence completes.
+ */
+ mutex_lock(&soc_order_reg_lock);
+
+ pr_info("[%p]: Starting restart sequence for %s\n", current,
+ r_work->subsys->name);
+
+ _send_notification_to_order(restart_list,
+ restart_list_count,
+ SUBSYS_BEFORE_SHUTDOWN);
+
+ for (i = 0; i < restart_list_count; i++) {
+
+ if (!restart_list[i])
+ continue;
+
+ pr_info("[%p]: Shutting down %s\n", current,
+ restart_list[i]->name);
+
+ if (restart_list[i]->shutdown(subsys) < 0)
+ panic("subsys-restart: %s[%p]: Failed to shutdown %s!",
+ __func__, current, restart_list[i]->name);
+ }
+
+ _send_notification_to_order(restart_list, restart_list_count,
+ SUBSYS_AFTER_SHUTDOWN);
+
+ /* Now that we've finished shutting down these subsystems, release the
+ * shutdown lock. If a subsystem restart request comes in for a
+ * subsystem in _this_ restart order after the unlock below, and
+ * before the powerup lock is released, panic and bail out.
+ */
+ mutex_unlock(shutdown_lock);
+
+ /* Collect ram dumps for all subsystems in order here */
+ for (i = 0; i < restart_list_count; i++) {
+ if (!restart_list[i])
+ continue;
+
+ if (restart_list[i]->ramdump)
+ if (restart_list[i]->ramdump(enable_ramdumps,
+ subsys) < 0)
+ pr_warn("%s[%p]: Ramdump failed.\n",
+ restart_list[i]->name, current);
+ }
+
+ _send_notification_to_order(restart_list,
+ restart_list_count,
+ SUBSYS_BEFORE_POWERUP);
+
+ for (i = restart_list_count - 1; i >= 0; i--) {
+
+ if (!restart_list[i])
+ continue;
+
+ pr_info("[%p]: Powering up %s\n", current,
+ restart_list[i]->name);
+
+ if (restart_list[i]->powerup(subsys) < 0)
+ panic("%s[%p]: Failed to powerup %s!", __func__,
+ current, restart_list[i]->name);
+ }
+
+ _send_notification_to_order(restart_list,
+ restart_list_count,
+ SUBSYS_AFTER_POWERUP);
+
+ pr_info("[%p]: Restart sequence for %s completed.\n",
+ current, r_work->subsys->name);
+
+ mutex_unlock(powerup_lock);
+
+ mutex_unlock(&soc_order_reg_lock);
+
+ pr_info("[%p]: Released powerup lock!\n", current);
+
+out:
+ wake_unlock(&r_work->ssr_wake_lock);
+ wake_lock_destroy(&r_work->ssr_wake_lock);
+ kfree(r_work);
+}
+
+int subsystem_restart(const char *subsys_name)
+{
+ struct subsys_data *subsys;
+ struct restart_wq_data *data = NULL;
+ int rc;
+
+ if (!subsys_name) {
+ pr_err("Invalid subsystem name.\n");
+ return -EINVAL;
+ }
+
+ pr_info("Restart sequence requested for %s, restart_level = %d.\n",
+ subsys_name, restart_level);
+
+ /* List of subsystems is protected by a lock. New subsystems can
+ * still come in.
+ */
+ subsys = _find_subsystem(subsys_name);
+
+ if (!subsys) {
+ pr_warn("Unregistered subsystem %s!\n", subsys_name);
+ return -EINVAL;
+ }
+
+#ifndef CONFIG_ARCH_EXYNOS
+ if (restart_level != RESET_SOC) {
+ data = kzalloc(sizeof(struct restart_wq_data), GFP_KERNEL);
+ if (!data) {
+ restart_level = RESET_SOC;
+ pr_warn("Failed to alloc restart data. Resetting.\n");
+ } else {
+ if (restart_level == RESET_SUBSYS_COUPLED ||
+ restart_level == RESET_SUBSYS_MIXED)
+ data->coupled = 1;
+ else
+ data->coupled = 0;
+
+ data->subsys = subsys;
+ }
+ }
+
+ switch (restart_level) {
+
+ case RESET_SUBSYS_COUPLED:
+ case RESET_SUBSYS_MIXED:
+ case RESET_SUBSYS_INDEPENDENT:
+ pr_debug("Restarting %s [level=%d]!\n", subsys_name,
+ restart_level);
+
+ snprintf(data->wakelockname, sizeof(data->wakelockname),
+ "ssr(%s)", subsys_name);
+ wake_lock_init(&data->ssr_wake_lock, WAKE_LOCK_SUSPEND,
+ data->wakelockname);
+ wake_lock(&data->ssr_wake_lock);
+
+ INIT_WORK(&data->work, subsystem_restart_wq_func);
+ rc = schedule_work(&data->work);
+
+ if (rc < 0)
+ panic("%s: Unable to schedule work to restart %s",
+ __func__, subsys->name);
+ break;
+
+ case RESET_SOC:
+ panic("subsys-restart: Resetting the SoC - %s crashed.",
+ subsys->name);
+ break;
+
+ default:
+ panic("subsys-restart: Unknown restart level!\n");
+ break;
+
+ }
+#else /* CONFIG_ARCH_EXYNOS */
+ data = kzalloc(sizeof(struct restart_wq_data), GFP_KERNEL);
+ if (!data) {
+ restart_level = RESET_SOC;
+ pr_warn("Failed to alloc restart data. Resetting.\n");
+ panic("subsys-restart: Resetting the SoC - %s crashed.",
+ subsys->name);
+ } else {
+ data->coupled = 0;
+ data->subsys = subsys;
+ }
+ pr_debug("Restarting %s [level=%d]!\n", subsys_name, restart_level);
+
+ snprintf(data->wakelockname, sizeof(data->wakelockname),
+ "ssr(%s)", subsys_name);
+ wake_lock_init(&data->ssr_wake_lock, WAKE_LOCK_SUSPEND,
+ data->wakelockname);
+ wake_lock(&data->ssr_wake_lock);
+
+ INIT_WORK(&data->work, subsystem_restart_wq_func);
+ rc = schedule_work(&data->work);
+
+ if (rc < 0)
+ panic("%s: Unable to schedule work to restart %s",
+ __func__, subsys->name);
+#endif
+ return 0;
+}
+EXPORT_SYMBOL(subsystem_restart);
+
+int ssr_register_subsystem(struct subsys_data *subsys)
+{
+ pr_info("%s\n", __func__);
+ if (!subsys)
+ goto err;
+
+ if (!subsys->name)
+ goto err;
+
+ if (!subsys->powerup || !subsys->shutdown)
+ goto err;
+
+ subsys->notif_handle = subsys_notif_add_subsys(subsys->name);
+ subsys->restart_order = _update_restart_order(subsys);
+ subsys->single_restart_list[0] = subsys;
+
+ mutex_init(&subsys->shutdown_lock);
+ mutex_init(&subsys->powerup_lock);
+
+ mutex_lock(&subsystem_list_lock);
+ list_add(&subsys->list, &subsystem_list);
+ mutex_unlock(&subsystem_list_lock);
+
+ return 0;
+
+err:
+ return -EINVAL;
+}
+EXPORT_SYMBOL(ssr_register_subsystem);
+
+static int ssr_panic_handler(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct subsys_data *subsys;
+
+ list_for_each_entry(subsys, &subsystem_list, list)
+ if (subsys->crash_shutdown)
+ subsys->crash_shutdown(subsys);
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_nb = {
+ .notifier_call = ssr_panic_handler,
+};
+
+static int __init ssr_init_soc_restart_orders(void)
+{
+ int i;
+
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &panic_nb);
+#ifndef CONFIG_ARCH_EXYNOS
+ if (cpu_is_msm8x60()) {
+ for (i = 0; i < ARRAY_SIZE(orders_8x60_all); i++) {
+ mutex_init(&orders_8x60_all[i]->powerup_lock);
+ mutex_init(&orders_8x60_all[i]->shutdown_lock);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(orders_8x60_modems); i++) {
+ mutex_init(&orders_8x60_modems[i]->powerup_lock);
+ mutex_init(&orders_8x60_modems[i]->shutdown_lock);
+ }
+
+ restart_orders = orders_8x60_all;
+ n_restart_orders = ARRAY_SIZE(orders_8x60_all);
+ }
+
+ if (cpu_is_msm8960() || cpu_is_msm8930() || cpu_is_msm9615() ||
+ cpu_is_apq8064()) {
+ restart_orders = restart_orders_8960;
+ n_restart_orders = ARRAY_SIZE(restart_orders_8960);
+ }
+#else
+ for (i = 0; i < ARRAY_SIZE(orders_8x60_all); i++) {
+ mutex_init(&orders_8x60_all[i]->powerup_lock);
+ mutex_init(&orders_8x60_all[i]->shutdown_lock);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(orders_8x60_modems); i++) {
+ mutex_init(&orders_8x60_modems[i]->powerup_lock);
+ mutex_init(&orders_8x60_modems[i]->shutdown_lock);
+ }
+
+ restart_orders = orders_8x60_all;
+ n_restart_orders = ARRAY_SIZE(orders_8x60_all);
+#endif
+ if (restart_orders == NULL || n_restart_orders < 1) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __init subsys_restart_init(void)
+{
+ int ret = 0;
+
+ pr_info("%s\n", __func__);
+
+ restart_level = RESET_SOC;
+
+ ssr_wq = alloc_workqueue("ssr_wq", 0, 0);
+
+ if (!ssr_wq)
+ panic("Couldn't allocate workqueue for subsystem restart.\n");
+
+ ret = ssr_init_soc_restart_orders();
+
+ return ret;
+}
+
+arch_initcall(subsys_restart_init);
+
+MODULE_DESCRIPTION("Subsystem Restart Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-exynos/sysreg.c b/arch/arm/mach-exynos/sysreg.c
new file mode 100644
index 0000000..9711934
--- /dev/null
+++ b/arch/arm/mach-exynos/sysreg.c
@@ -0,0 +1,78 @@
+/* linux/arch/arm/mach-exynos/sysreg.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ * MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * EXYNOS - System Register PM Support Driver
+ *
+ * Currently support Exynos4210, 4212, 4412.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/syscore_ops.h>
+
+#include <plat/cpu.h>
+#include <plat/map-base.h>
+#include <plat/pm.h>
+
+#ifdef CONFIG_PM_SLEEP
+static struct sleep_save exynos4210_sysreg_save[] = {
+ SAVE_ITEM(S3C_VA_SYS + 0x210),
+ SAVE_ITEM(S3C_VA_SYS + 0x214),
+ SAVE_ITEM(S3C_VA_SYS + 0x218),
+ SAVE_ITEM(S3C_VA_SYS + 0x220),
+ SAVE_ITEM(S3C_VA_SYS + 0x230),
+};
+
+static struct sleep_save exynos4x12_sysreg_save[] = {
+ SAVE_ITEM(S3C_VA_SYS + 0x10C),
+ SAVE_ITEM(S3C_VA_SYS + 0x110),
+ SAVE_ITEM(S3C_VA_SYS + 0x114),
+ SAVE_ITEM(S3C_VA_SYS + 0x20C),
+ SAVE_ITEM(S3C_VA_SYS + 0x210),
+ SAVE_ITEM(S3C_VA_SYS + 0x214),
+ SAVE_ITEM(S3C_VA_SYS + 0x218),
+ SAVE_ITEM(S3C_VA_SYS + 0x21C),
+ SAVE_ITEM(S3C_VA_SYS + 0x320),
+ SAVE_ITEM(S3C_VA_SYS + 0x330),
+};
+
+static int exynos4_sysreg_suspend(void)
+{
+ if (soc_is_exynos4210()) {
+ s3c_pm_do_save(exynos4210_sysreg_save,
+ ARRAY_SIZE(exynos4210_sysreg_save));
+ } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ s3c_pm_do_save(exynos4x12_sysreg_save,
+ ARRAY_SIZE(exynos4x12_sysreg_save));
+ }
+ return 0;
+}
+
+static void exynos4_sysreg_resume(void)
+{
+ if (soc_is_exynos4210()) {
+ s3c_pm_do_restore_core(exynos4210_sysreg_save,
+ ARRAY_SIZE(exynos4210_sysreg_save));
+ } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
+ s3c_pm_do_restore_core(exynos4x12_sysreg_save,
+ ARRAY_SIZE(exynos4x12_sysreg_save));
+ }
+}
+
+static struct syscore_ops exynos4_syscore_ops = {
+ .suspend = exynos4_sysreg_suspend,
+ .resume = exynos4_sysreg_resume,
+};
+
+static int __init exynos4_register_sysreg_pm(void)
+{
+ register_syscore_ops(&exynos4_syscore_ops);
+ return 0;
+}
+arch_initcall(exynos4_register_sysreg_pm);
+#endif
diff --git a/arch/arm/mach-exynos/tmu.c b/arch/arm/mach-exynos/tmu.c
new file mode 100644
index 0000000..c39ff65
--- /dev/null
+++ b/arch/arm/mach-exynos/tmu.c
@@ -0,0 +1,1432 @@
+/* linux/arch/arm/mach-exynos/tmu.c
+*
+* Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+*
+ * EXYNOS4 - Thermal Management support
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/kobject.h>
+
+#include <asm/irq.h>
+
+#include <mach/regs-tmu.h>
+#include <mach/cpufreq.h>
+#include <mach/map.h>
+#include <mach/smc.h>
+#include <plat/s5p-tmu.h>
+#include <plat/map-s5p.h>
+#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+#include <mach/asv.h>
+#ifdef CONFIG_BUSFREQ_OPP
+#include <mach/busfreq_exynos4.h>
+#include <mach/dev.h>
+#endif
+
+static enum {
+ENABLE_TEMP_MON = 0x1,
+ENABLE_TEST_MODE = 0x2,
+} enable_mask = ENABLE_TEMP_MON | ENABLE_TEST_MODE;
+module_param_named(enable_mask, enable_mask, uint, 0644);
+#define ENABLE_DBGMASK (ENABLE_TEMP_MON | ENABLE_TEST_MODE)
+
+/* for factory mode */
+#define CONFIG_TMU_SYSFS
+
+/* flags that throttling or trippint is treated */
+#define THROTTLE_FLAG (0x1 << 0)
+#define WARNING_FLAG (0x1 << 1)
+#define TRIPPING_FLAG (0x1 << 2)
+#define MEM_THROTTLE_FLAG (0x1 << 4)
+
+#define TIMING_AREF_OFFSET 0x30
+
+static struct workqueue_struct *tmu_monitor_wq;
+
+static DEFINE_MUTEX(tmu_lock);
+
+
+#if (defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)) \
+ && defined(CONFIG_VIDEO_MALI400MP)
+extern int mali_voltage_lock_init(void);
+extern int mali_voltage_lock_push(int lock_vol);
+extern int mali_voltage_lock_pop(void);
+#define CONFIG_TC_VOLTAGE /* Temperature compensated voltage */
+#endif
+
+static unsigned int get_curr_temp(struct s5p_tmu_info *info)
+{
+ unsigned char curr_temp_code;
+ int temperature;
+
+ if (!info)
+ return -EAGAIN;
+
+ /* After reading temperature code from register, compensating
+ * its value and calculating celsius temperatue,
+ * get current temperatue.
+ */
+ curr_temp_code =
+ __raw_readl(info->tmu_base + EXYNOS4_TMU_CURRENT_TEMP) & 0xff;
+
+ /* Check range of temprature code with curr_temp_code & efusing info */
+ pr_debug("CURRENT_TEMP = 0x%02x\n", curr_temp_code);
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ /* temperature code range are between min 10 and 125 */
+ if ((info->te1 - curr_temp_code) > 15
+ || (curr_temp_code - info->te1) > 100)
+#else
+ /* temperature code range are between min 25 and 125 */
+ if ((curr_temp_code - info->te1) < 0
+ || (curr_temp_code - info->te1) > 100)
+#endif
+ pr_warning("temperature code is in inaccurate -->"
+ "check if vdd_18_ts is on\n"
+ "or surrounding temp is low.\n");
+
+ /* compensate and calculate current temperature */
+ temperature = curr_temp_code - info->te1 + TMU_DC_VALUE;
+ if (temperature < 0) {
+ /* if temperature lower than 0 degree, set 0 degree */
+ pr_info("current temp is %d celsius degree.\n"
+ "so, set to 0 celsius degree!\n", temperature);
+ temperature = 0;
+ }
+ return (unsigned int)temperature;
+}
+
+static ssize_t show_temperature(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct s5p_tmu_info *info = dev_get_drvdata(dev);
+ unsigned int temperature;
+
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&tmu_lock);
+
+ temperature = get_curr_temp(info);
+
+ mutex_unlock(&tmu_lock);
+
+ return sprintf(buf, "%u\n", temperature);
+}
+
+static ssize_t show_tmu_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct s5p_tmu_info *info = dev_get_drvdata(dev);
+
+ if (!dev)
+ return -ENODEV;
+
+ return sprintf(buf, "%d\n", info->tmu_state);
+}
+
+static ssize_t show_lot_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u32 id1 = 0;
+ u32 id2 = 0;
+ id1 = __raw_readl(S5P_VA_CHIPID + 0x14);
+ id2 = __raw_readl(S5P_VA_CHIPID + 0x18);
+
+ return sprintf(buf, "%08x-%08x\n", id1, id2);
+}
+static DEVICE_ATTR(temperature, 0444, show_temperature, NULL);
+static DEVICE_ATTR(tmu_state, 0444, show_tmu_state, NULL);
+static DEVICE_ATTR(lot_id, 0444, show_lot_id, NULL);
+
+static void print_temperature_params(struct s5p_tmu_info *info)
+{
+ struct s5p_platform_tmu *pdata = info->dev->platform_data;
+
+ pr_info("** temperature set value **\n"
+ "1st throttling stop_temp = %u, start_temp = %u\n"
+ "2nd throttling stop_temp = %u, start_tmep = %u\n"
+ "tripping temp = %u, s/w emergency temp = %u\n"
+ "mem throttling stop_temp = %u, start_temp = %u\n",
+ pdata->ts.stop_1st_throttle,
+ pdata->ts.start_1st_throttle,
+ pdata->ts.stop_2nd_throttle,
+ pdata->ts.start_2nd_throttle,
+ pdata->ts.start_tripping,
+ pdata->ts.start_emergency,
+ pdata->ts.stop_mem_throttle,
+ pdata->ts.start_mem_throttle);
+#if defined(CONFIG_TC_VOLTAGE)
+ pr_info("tc_voltage stop_temp = %u, start_temp = %u\n",
+ pdata->ts.stop_tc, pdata->ts.start_tc);
+#endif
+}
+
+unsigned int get_refresh_interval(unsigned int freq_ref,
+ unsigned int refresh_nsec)
+{
+ unsigned int uRlk, refresh = 0;
+
+ /*
+ * uRlk = FIN / 100000;
+ * refresh_usec = (unsigned int)(fMicrosec * 10);
+ * uRegVal = ((unsigned int)(uRlk * uMicroSec / 100)) - 1;
+ * refresh =
+ * (unsigned int)(freq_ref * (unsigned int)(refresh_usec * 10) / 100) - 1;
+ */
+ uRlk = freq_ref / 1000000;
+ refresh = ((unsigned int)(uRlk * refresh_nsec / 1000));
+
+ pr_info("@@@ get_refresh_interval = 0x%02x\n", refresh);
+ return refresh;
+}
+
+struct tmu_early_param {
+ int set_ts;
+ struct temperature_params ts;
+ int set_lock;
+ unsigned cpufreq_level_1st_throttle;
+ unsigned cpufreq_level_2nd_throttle;
+ int set_rate;
+ unsigned int sampling_rate;
+ unsigned int monitor_rate;
+};
+static struct tmu_early_param tmu_in;
+
+static int tmu_print_temp_on_off;
+
+static int __init get_temperature_params(char *str)
+{
+ int ints[11];
+
+ unsigned int mask = (enable_mask & ENABLE_DBGMASK);
+
+ if (!(mask & ENABLE_TEST_MODE))
+ return -EPERM;
+
+ get_options(str, ARRAY_SIZE(ints), ints);
+
+ /* output the input value */
+ pr_info("tmu_test=%s\n", str);
+
+ if (ints[0])
+ tmu_in.set_ts = 1;
+ if (ints[0] > 0)
+ tmu_in.ts.stop_1st_throttle = (unsigned int)ints[1];
+ if (ints[0] > 1)
+ tmu_in.ts.start_1st_throttle = (unsigned int)ints[2];
+ if (ints[0] > 2)
+ tmu_in.ts.stop_2nd_throttle = (unsigned int)ints[3];
+ if (ints[0] > 3)
+ tmu_in.ts.start_2nd_throttle = (unsigned int)ints[4];
+ if (ints[0] > 4)
+ tmu_in.ts.start_tripping = (unsigned int)ints[5];
+ if (ints[0] > 5)
+ tmu_in.ts.start_emergency = (unsigned int)ints[6];
+ if (ints[0] > 6)
+ tmu_in.ts.stop_mem_throttle = (unsigned int)ints[7];
+ if (ints[0] > 7)
+ tmu_in.ts.start_mem_throttle = (unsigned int)ints[8];
+
+ /* output the input value */
+ pr_info("-->1st throttling temp: start[%u], stop[%u]\n"
+ "-->2nd throttling temp: start[%u], stop[%u]\n"
+ "-->trpping temp[%u], emergency temp[%u]\n"
+ "-->mem throttling temp: start[%u], stop[%u]\n",
+ tmu_in.ts.start_1st_throttle, tmu_in.ts.stop_1st_throttle,
+ tmu_in.ts.start_2nd_throttle, tmu_in.ts.stop_2nd_throttle,
+ tmu_in.ts.start_tripping, tmu_in.ts.start_emergency,
+ tmu_in.ts.start_mem_throttle, tmu_in.ts.stop_mem_throttle);
+#ifdef CONFIG_TC_VOLTAGE
+ if (ints[0] > 8)
+ tmu_in.ts.stop_tc = (unsigned int)ints[9];
+ if (ints[0] > 9)
+ tmu_in.ts.start_tc = (unsigned int)ints[10];
+ pr_info("-->temp compensate : start[%u], stop[%u]\n",
+ tmu_in.ts.start_tc, tmu_in.ts.stop_tc);
+#endif
+ return 0;
+}
+early_param("tmu_test", get_temperature_params);
+
+static int __init get_cpufreq_limit_param(char *str)
+{
+ int ints[3];
+ unsigned int mask = (enable_mask & ENABLE_DBGMASK);
+
+ if (!(mask & ENABLE_TEST_MODE))
+ return -EPERM;
+
+ get_options(str, ARRAY_SIZE(ints), ints);
+ /* output the input value */
+ pr_info("cpu_level=%s\n", str);
+
+ if (ints[0])
+ tmu_in.set_lock = 1;
+ if (ints[0] > 0)
+ tmu_in.cpufreq_level_1st_throttle = (unsigned int)ints[1];
+ if (ints[0] > 1)
+ tmu_in.cpufreq_level_2nd_throttle = (unsigned int)ints[2];
+
+ pr_info("--> cpufreq_limit: 1st cpu_level = %u, 2nd cpu_level = %u\n",
+ tmu_in.cpufreq_level_1st_throttle,
+ tmu_in.cpufreq_level_2nd_throttle);
+
+ return 0;
+}
+early_param("cpu_level", get_cpufreq_limit_param);
+
+static int __init get_sampling_rate_param(char *str)
+{
+ int ints[3];
+ unsigned int mask = (enable_mask & ENABLE_DBGMASK);
+
+ if (!(mask & ENABLE_TEST_MODE))
+ return -EPERM;
+
+ get_options(str, ARRAY_SIZE(ints), ints);
+ /* output the input value */
+ pr_info("tmu_sampling_rate=%s\n", str);
+
+ if (ints[0])
+ tmu_in.set_rate = 1;
+ if (ints[0] > 0)
+ tmu_in.sampling_rate = (unsigned int)ints[1];
+ if (ints[0] > 1)
+ tmu_in.monitor_rate = (unsigned int)ints[2];
+
+ pr_info("--> sampling_rate = %u ms, monitor_rate = %u ms\n",
+ tmu_in.sampling_rate, tmu_in.monitor_rate);
+
+ return 0;
+}
+early_param("tmu_sampling_rate", get_sampling_rate_param);
+
+static void exynos4_poll_cur_temp(struct work_struct *work)
+{
+ unsigned int cur_temp;
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct s5p_tmu_info *info =
+ container_of(delayed_work, struct s5p_tmu_info, monitor);
+ unsigned int mask = (enable_mask & ENABLE_DBGMASK);
+
+ mutex_lock(&tmu_lock);
+
+ if (mask & ENABLE_TEMP_MON) {
+ cur_temp = get_curr_temp(info);
+
+ if (tmu_print_temp_on_off)
+ pr_info("curr temp in polling_interval = %u state = %d\n",
+ cur_temp, info->tmu_state);
+ else
+ pr_debug("curr temp in polling_interval = %u\n", cur_temp);
+ }
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->monitor,
+ info->monitor_period);
+
+ mutex_unlock(&tmu_lock);
+}
+
+static ssize_t tmu_show_print_state(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+
+ ret = sprintf(buf, "[TMU] tmu_print_temp_on_off=%d\n"
+ , tmu_print_temp_on_off);
+
+ return ret;
+}
+
+static ssize_t tmu_store_print_state(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret = 0;
+
+ if (!strncmp(buf, "0", 1)) {
+ tmu_print_temp_on_off = 0;
+ ret = 0;
+ } else if (!strncmp(buf, "1", 1)) {
+ tmu_print_temp_on_off = 1;
+ ret = 1;
+ } else {
+ dev_err(dev, "Invalid cmd !!\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+static DEVICE_ATTR(print_state, S_IRUGO | S_IWUSR,\
+ tmu_show_print_state, tmu_store_print_state);
+
+void set_refresh_rate(unsigned int auto_refresh)
+{
+ /*
+ * uRlk = FIN / 100000;
+ * refresh_usec = (unsigned int)(fMicrosec * 10);
+ * uRegVal = ((unsigned int)(uRlk * uMicroSec / 100)) - 1;
+ */
+ pr_debug("set_auto_refresh = 0x%02x\n", auto_refresh);
+
+#ifdef CONFIG_ARCH_EXYNOS4
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_REG,
+ SMC_REG_ID_SFR_W((EXYNOS4_PA_DMC0_4212 + TIMING_AREF_OFFSET)),
+ auto_refresh, 0);
+ exynos_smc(SMC_CMD_REG,
+ SMC_REG_ID_SFR_W((EXYNOS4_PA_DMC1_4212 + TIMING_AREF_OFFSET)),
+ auto_refresh, 0);
+#else
+ /* change auto refresh period in TIMING_AREF register of dmc0 */
+ __raw_writel(auto_refresh, S5P_VA_DMC0 + TIMING_AREF_OFFSET);
+
+ /* change auto refresh period in TIMING_AREF regisger of dmc1 */
+ __raw_writel(auto_refresh, S5P_VA_DMC1 + TIMING_AREF_OFFSET);
+#endif
+#else /* CONFIG_ARCH_EXYNOS4 */
+#ifdef CONFIG_ARM_TRUSTZONE
+ exynos_smc(SMC_CMD_REG,
+ SMC_REG_ID_SFR_W((EXYNOS5_PA_DMC + TIMING_AREF_OFFSET)),
+ auto_refresh, 0);
+#else
+ /* change auto refresh period in TIMING_AREF register of dmc */
+ __raw_writel(auto_refresh, S5P_VA_DMC0 + TIMING_AREF_OFFSET);
+#endif
+#endif /* CONFIG_ARCH_EXYNOS4 */
+}
+
+static void set_temperature_params(struct s5p_tmu_info *info)
+{
+ struct s5p_platform_tmu *data = info->dev->platform_data;
+
+ /* In the tmu_test mode, change temperature_params value
+ * input data.
+ */
+ if (tmu_in.set_ts)
+ data->ts = tmu_in.ts;
+ if (tmu_in.set_lock) {
+ info->cpufreq_level_1st_throttle =
+ tmu_in.cpufreq_level_1st_throttle;
+ info->cpufreq_level_2nd_throttle =
+ tmu_in.cpufreq_level_2nd_throttle;
+ }
+ if (tmu_in.set_rate) {
+ info->sampling_rate =
+ usecs_to_jiffies(tmu_in.sampling_rate * 1000);
+ info->monitor_period =
+ usecs_to_jiffies(tmu_in.monitor_rate * 1000);
+ }
+ print_temperature_params(info);
+}
+
+static int notify_change_of_tmu_state(struct s5p_tmu_info *info)
+{
+ char temp_buf[20];
+ char *envp[2];
+ int env_offset = 0;
+
+ snprintf(temp_buf, sizeof(temp_buf), "TMUSTATE=%d", info->tmu_state);
+ envp[env_offset++] = temp_buf;
+ envp[env_offset] = NULL;
+
+ pr_info("%s: uevent: %d, name = %s\n",
+ __func__, info->tmu_state, temp_buf);
+
+ return kobject_uevent_env(&info->dev->kobj, KOBJ_CHANGE, envp);
+}
+
+static void exynos_interrupt_enable(struct s5p_tmu_info *info, int enable)
+{
+ static unsigned int save;
+
+ if (!save)
+ save = __raw_readl(info->tmu_base + EXYNOS4_TMU_INTEN);
+
+ if (enable)
+ __raw_writel(save, info->tmu_base + EXYNOS4_TMU_INTEN);
+ else
+ __raw_writel(0x0, info->tmu_base + EXYNOS4_TMU_INTEN);
+}
+
+/**
+ * exynos_tc_volt - locks or frees vdd_arm, vdd_mif/int and vdd_g3d for
+ * temperature compensation.
+ *
+ * This function limits or free voltage of cpufreq, busfreq, and mali driver
+ * according to 2nd arguments.
+ */
+static int exynos_tc_volt(struct s5p_tmu_info *info, int enable)
+{
+ struct s5p_platform_tmu *data = info->dev->platform_data;
+ static int usage;
+ int ret = 0;
+
+ if (!info)
+ return -EPERM;
+
+ if (enable == usage) {
+ pr_debug("TMU: already is %s.\n",
+ enable ? "locked" : "unlocked");
+ return 0;
+ }
+
+ if (enable) {
+ ret = exynos_cpufreq_lock(DVFS_LOCK_ID_TMU, info->cpulevel_tc);
+ if (ret)
+ goto err_lock;
+#ifdef CONFIG_BUSFREQ_OPP
+ ret = dev_lock(info->bus_dev, info->dev, info->busfreq_tc);
+ if (ret)
+ goto err_lock;
+#endif
+ ret = mali_voltage_lock_push(data->temp_compensate.g3d_volt);
+ if (ret < 0) {
+ pr_err("TMU: g3d_push error: %u uV\n",
+ data->temp_compensate.g3d_volt);
+ goto err_lock;
+ }
+ } else {
+ exynos_cpufreq_lock_free(DVFS_LOCK_ID_TMU);
+#ifdef CONFIG_BUSFREQ_OPP
+ ret = dev_unlock(info->bus_dev, info->dev);
+ if (ret)
+ goto err_unlock;
+#endif
+ ret = mali_voltage_lock_pop();
+ if (ret < 0) {
+ pr_err("TMU: g3d_pop error\n");
+ goto err_unlock;
+ }
+ }
+ usage = enable;
+ pr_info("TMU: %s is ok!\n", enable ? "lock" : "unlock");
+ return ret;
+
+err_lock:
+err_unlock:
+ pr_err("TMU: %s is fail.\n", enable ? "lock" : "unlock");
+ return ret;
+}
+
+static void exynos4_handler_tmu_state(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct s5p_tmu_info *info =
+ container_of(delayed_work, struct s5p_tmu_info, polling);
+ struct s5p_platform_tmu *data = info->dev->platform_data;
+ unsigned int cur_temp;
+ static int auto_refresh_changed;
+ static int check_handle;
+ int trend = 0;
+
+ mutex_lock(&tmu_lock);
+
+ cur_temp = get_curr_temp(info);
+ trend = cur_temp - info->last_temperature;
+ pr_debug("curr_temp = %u, temp_diff = %d\n", cur_temp, trend);
+
+ switch (info->tmu_state) {
+#if defined(CONFIG_TC_VOLTAGE)
+ case TMU_STATUS_TC:
+ /* lock has priority than unlock */
+ if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ } else if (cur_temp >= data->ts.stop_tc) {
+ if (exynos_tc_volt(info, 0) < 0) {
+ pr_err("TMU: unlock error!\n");
+ } else {
+ info->tmu_state = TMU_STATUS_NORMAL;
+ pr_info("change state: tc -> normal.\n");
+ }
+ }
+ /* free if upper limit is locked */
+ if (check_handle) {
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_TMU);
+ check_handle = 0;
+ }
+ break;
+#endif
+ case TMU_STATUS_NORMAL:
+ /* 1. change state: 1st-throttling */
+ if (cur_temp >= data->ts.start_1st_throttle) {
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ pr_info("change state: normal->throttle.\n");
+#if defined(CONFIG_TC_VOLTAGE)
+ /* check whether temp compesation need or not */
+ } else if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0) {
+ pr_err("TMU: lock error!\n");
+ } else {
+ info->tmu_state = TMU_STATUS_TC;
+ pr_info("change state: normal->tc.\n");
+ }
+#endif
+ /* 2. polling end and uevent */
+ } else if ((cur_temp <= data->ts.stop_1st_throttle)
+ && (cur_temp <= data->ts.stop_mem_throttle)) {
+ if (check_handle & THROTTLE_FLAG) {
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_TMU);
+ check_handle &= ~(THROTTLE_FLAG);
+ }
+ pr_debug("check_handle = %d\n", check_handle);
+ notify_change_of_tmu_state(info);
+ pr_info("normal: free cpufreq_limit & interrupt enable.\n");
+
+ /* clear to prevent from interfupt by peindig bit */
+ __raw_writel(INTCLEARALL,
+ info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ exynos_interrupt_enable(info, 1);
+ enable_irq(info->irq);
+ mutex_unlock(&tmu_lock);
+ return;
+ }
+ break;
+
+ case TMU_STATUS_THROTTLED:
+ /* 1. change state: 2nd-throttling or warning */
+ if (cur_temp >= data->ts.start_2nd_throttle) {
+ info->tmu_state = TMU_STATUS_WARNING;
+ pr_info("change state: 1st throttle->2nd throttle.\n");
+#if defined(CONFIG_TC_VOLTAGE)
+ /* check whether temp compesation need or not */
+ } else if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ else
+ info->tmu_state = TMU_STATUS_TC;
+#endif
+ /* 2. cpufreq limitation and uevent */
+ } else if ((cur_temp >= data->ts.start_1st_throttle) &&
+ !(check_handle & THROTTLE_FLAG)) {
+ if (check_handle & WARNING_FLAG) {
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_TMU);
+ check_handle &= ~(WARNING_FLAG);
+ }
+ exynos_cpufreq_upper_limit(DVFS_LOCK_ID_TMU,
+ info->cpufreq_level_1st_throttle);
+ check_handle |= THROTTLE_FLAG;
+ pr_debug("check_handle = %d\n", check_handle);
+ notify_change_of_tmu_state(info);
+ pr_info("throttling: set cpufreq upper limit.\n");
+ /* 3. change state: normal */
+ } else if ((cur_temp <= data->ts.stop_1st_throttle)
+ && (trend < 0)) {
+ info->tmu_state = TMU_STATUS_NORMAL;
+ pr_info("change state: 1st throttle->normal.\n");
+ }
+ break;
+
+ case TMU_STATUS_WARNING:
+ /* 1. change state: tripping */
+ if (cur_temp >= data->ts.start_tripping) {
+ info->tmu_state = TMU_STATUS_TRIPPED;
+ pr_info("change state: 2nd throttle->trip\n");
+#if defined(CONFIG_TC_VOLTAGE)
+ /* check whether temp compesation need or not */
+ } else if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ else
+ info->tmu_state = TMU_STATUS_TC;
+#endif
+ /* 2. cpufreq limitation and uevent */
+ } else if ((cur_temp >= data->ts.start_2nd_throttle) &&
+ !(check_handle & WARNING_FLAG)) {
+ if (check_handle & THROTTLE_FLAG) {
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_TMU);
+ check_handle &= ~(THROTTLE_FLAG);
+ }
+ exynos_cpufreq_upper_limit(DVFS_LOCK_ID_TMU,
+ info->cpufreq_level_2nd_throttle);
+
+ check_handle |= WARNING_FLAG;
+ pr_debug("check_handle = %d\n", check_handle);
+ notify_change_of_tmu_state(info);
+ pr_info("2nd throttle: cpufreq is limited.\n");
+ /* 3. change state: 1st-throttling */
+ } else if ((cur_temp <= data->ts.stop_2nd_throttle)
+ && (trend < 0)) {
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ pr_info("change state: 2nd throttle->1st throttle, "
+ "and release cpufreq upper limit.\n");
+ }
+ break;
+
+ case TMU_STATUS_TRIPPED:
+ /* 1. call uevent to shut-down */
+ if ((cur_temp >= data->ts.start_tripping) &&
+ (trend > 0) && !(check_handle & TRIPPING_FLAG)) {
+ notify_change_of_tmu_state(info);
+ pr_info("tripping: on waiting shutdown.\n");
+ check_handle |= TRIPPING_FLAG;
+ pr_debug("check_handle = %d\n", check_handle);
+#if defined(CONFIG_TC_VOLTAGE)
+ /* check whether temp compesation need or not */
+ } else if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ else
+ info->tmu_state = TMU_STATUS_TC;
+#endif
+ /* 2. change state: 2nd-throttling or warning */
+ } else if ((cur_temp <= data->ts.stop_2nd_throttle)
+ && (trend < 0)) {
+ info->tmu_state = TMU_STATUS_WARNING;
+ pr_info("change state: trip->2nd throttle, "
+ "Check! occured only test mode.\n");
+ }
+ /* 3. chip protection: kernel panic as SW workaround */
+ if ((cur_temp >= data->ts.start_emergency) && (trend > 0)) {
+ panic("Emergency!!!! tripping is not treated!\n");
+ /* clear to prevent from interfupt by peindig bit */
+ __raw_writel(INTCLEARALL,
+ info->tmu_state + EXYNOS4_TMU_INTCLEAR);
+ enable_irq(info->irq);
+ mutex_unlock(&tmu_lock);
+ return;
+ }
+ break;
+
+ case TMU_STATUS_INIT:
+ /* sned tmu initial status to platform */
+ disable_irq(info->irq);
+ if (cur_temp >= data->ts.start_tripping)
+ info->tmu_state = TMU_STATUS_TRIPPED;
+#if defined(CONFIG_TC_VOLTAGE)
+ /* check whether temp compesation need or not */
+ else if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ else
+ info->tmu_state = TMU_STATUS_TC;
+ }
+#endif
+ else if (cur_temp >= data->ts.start_2nd_throttle)
+ info->tmu_state = TMU_STATUS_WARNING;
+ else if (cur_temp >= data->ts.start_1st_throttle)
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ else if (cur_temp <= data->ts.stop_1st_throttle)
+ info->tmu_state = TMU_STATUS_NORMAL;
+
+ notify_change_of_tmu_state(info);
+ pr_info("%s: inform to init state to platform.\n", __func__);
+ break;
+
+ default:
+ pr_warn("Bug: checked tmu_state.\n");
+ if (cur_temp >= data->ts.start_tripping)
+ info->tmu_state = TMU_STATUS_TRIPPED;
+#if defined(CONFIG_TC_VOLTAGE)
+ /* check whether temp compesation need or not */
+ else if (cur_temp <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ else
+ info->tmu_state = TMU_STATUS_TC;
+ }
+#endif
+ else
+ info->tmu_state = TMU_STATUS_WARNING;
+ break;
+ } /* end */
+
+ /* memory throttling */
+ if (cur_temp >= data->ts.start_mem_throttle) {
+ if (!(auto_refresh_changed) && (trend > 0)) {
+ pr_info("set auto_refresh 1.95us\n");
+ set_refresh_rate(info->auto_refresh_tq0);
+ auto_refresh_changed = 1;
+ }
+ } else if (cur_temp <= (data->ts.stop_mem_throttle)) {
+ if ((auto_refresh_changed) && (trend < 0)) {
+ pr_info("set auto_refresh 3.9us\n");
+ set_refresh_rate(info->auto_refresh_normal);
+ auto_refresh_changed = 0;
+ }
+ }
+
+ info->last_temperature = cur_temp;
+
+ /* reschedule the next work */
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->polling,
+ info->sampling_rate);
+
+ mutex_unlock(&tmu_lock);
+
+ return;
+}
+
+static int exynos4210_tmu_init(struct s5p_tmu_info *info)
+{
+ struct s5p_platform_tmu *data = info->dev->platform_data;
+ unsigned int tmp;
+ unsigned int temp_code_threshold;
+ unsigned int temp_code_throttle, temp_code_warning, temp_code_trip;
+
+ /* To compensate temperature sensor
+ * get trim informatoin and save to struct tmu_info
+ */
+ tmp = __raw_readl(info->tmu_base + EXYNOS4_TMU_TRIMINFO);
+ info->te1 = tmp & TMU_TRIMINFO_MASK;
+ info->te2 = ((tmp >> 8) & TMU_TRIMINFO_MASK);
+
+ /* check boundary the triminfo */
+ if ((EFUSE_MIN_VALUE > info->te1)
+ || (info->te1 > EFUSE_MAX_VALUE) || (info->te2 != 0))
+ info->te1 = EFUSE_AVG_VALUE;
+
+ pr_info("%s: triminfo = 0x%08x, low 8bit = 0x%02x, high 24 bit = 0x%06x\n",
+ __func__, tmp, info->te1, info->te2);
+
+ /* Need to initial regsiter setting after getting parameter info */
+ /* [28:23] vref [11:8] slope - Tunning parameter */
+ __raw_writel(VREF_SLOPE, info->tmu_base + EXYNOS4_TMU_CONTROL);
+
+ /* Convert celsius temperature value to temperature code value
+ * such as threshold_level, 1st throttle, 2nd throttle,
+ * tripping temperature.
+ */
+ temp_code_threshold = data->ts.stop_1st_throttle
+ + info->te1 - TMU_DC_VALUE;
+ temp_code_throttle = data->ts.start_1st_throttle
+ - data->ts.stop_1st_throttle;
+ temp_code_warning = data->ts.start_2nd_throttle
+ - data->ts.stop_1st_throttle;
+ temp_code_trip = data->ts.start_tripping
+ - data->ts.stop_1st_throttle;
+
+ /* Set interrupt trigger level */
+ __raw_writel(temp_code_threshold, info->tmu_base + EXYNOS4210_TMU_THRESHOLD_TEMP);
+ __raw_writel(temp_code_throttle, info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL0);
+ __raw_writel(temp_code_warning, info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL1);
+ __raw_writel(temp_code_trip, info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL2);
+ __raw_writel(TRIGGER_LEV_MAX, info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL3);
+
+ pr_info("THD_TEMP:0x%02x: TRIG_LEV0: 0x%02x\n"
+ "TRIG_LEV1: 0x%02x TRIG_LEV2: 0x%02x, TRIG_LEV3: 0x%02x\n",
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_THRESHOLD_TEMP),
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL0),
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL1),
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL2),
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL3));
+
+ mdelay(50);
+
+ /* Need to initial regsiter setting after getting parameter info */
+ /* [28:23] vref [11:8] slope - Tunning parameter */
+ __raw_writel(VREF_SLOPE, info->tmu_base + EXYNOS4_TMU_CONTROL);
+ /* TMU core enable */
+ tmp = __raw_readl(info->tmu_base + EXYNOS4_TMU_CONTROL);
+ tmp |= TMUCORE_ENABLE;
+ __raw_writel(tmp, info->tmu_base + EXYNOS4_TMU_CONTROL);
+
+ /* check interrupt status register */
+ pr_debug("tmu interrupt status: 0x%02x\n",
+ __raw_readl(info->tmu_base + EXYNOS4_TMU_INTSTAT));
+
+ /* LEV0 LEV1 LEV2 interrupt enable */
+ __raw_writel(INTEN0 | INTEN1 | INTEN2, info->tmu_base + EXYNOS4_TMU_INTEN);
+ return 0;
+}
+
+static int exynos4x12_tmu_init(struct s5p_tmu_info *info)
+{
+ struct s5p_platform_tmu *data = info->dev->platform_data;
+ unsigned int tmp;
+ unsigned char temp_code_throttle, temp_code_warning, temp_code_trip;
+
+ /* To compensate temperature sensor,
+ * set triminfo control register & get trim informatoin
+ * and save to struct tmu_info
+ */
+ tmp = __raw_readl(info->tmu_base + EXYNOS4x12_TMU_TRIMINFO_CONROL);
+ tmp |= TMU_RELOAD;
+ __raw_writel(tmp, info->tmu_base + EXYNOS4x12_TMU_TRIMINFO_CONROL);
+
+ mdelay(1);
+
+ tmp = __raw_readl(info->tmu_base + EXYNOS4_TMU_TRIMINFO);
+ info->te1 = tmp & TMU_TRIMINFO_MASK;
+
+ /* In case of non e-fusing chip, s/w workaround */
+ if (tmp == 0)
+ info->te1 = 0x37;
+
+ pr_debug("%s: triminfo reg = 0x%08x, value = %u\n", __func__,
+ tmp, info->te1);
+
+ /* Convert celsius temperature value to temperature code value
+ * such as 1st throttle, 2nd throttle, tripping temperature.
+ * its ranges are between 25 cesius(0x32) to 125 cesius4(0x96)
+ */
+ temp_code_throttle = data->ts.start_1st_throttle
+ + info->te1 - TMU_DC_VALUE;
+ temp_code_warning = data->ts.start_2nd_throttle
+ + info->te1 - TMU_DC_VALUE;
+ temp_code_trip = data->ts.start_tripping
+ + info->te1 - TMU_DC_VALUE;
+
+ pr_debug("temp_code_throttle: %u, temp_code_warning: %u\n"
+ "temp_code_trip: %u, info->te1 = %u\n",
+ temp_code_throttle, temp_code_warning,
+ temp_code_trip, info->te1);
+
+ /* Set interrupt trigger level */
+ tmp = ((0xFF << 24) | (temp_code_trip << 16) |
+ (temp_code_warning << 8) | (temp_code_throttle << 0));
+ __raw_writel(tmp, info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_RISE);
+
+ pr_debug("THD_TEMP_RISE: 0x%08x\n",
+ __raw_readl(info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_RISE));
+
+#if defined(CONFIG_TC_VOLTAGE)
+ /* Get set temperature for tc_voltage and set falling interrupt
+ * trigger level
+ */
+ tmp = (data->ts.start_tc + info->te1 - TMU_DC_VALUE) << 0;
+ __raw_writel(tmp, info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_FALL);
+ pr_debug("THD_TEMP_FALL: 0x%08x\n",
+ __raw_readl(info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_FALL));
+#endif
+
+ /* TMU core enable */
+ tmp = __raw_readl(info->tmu_base + EXYNOS4_TMU_CONTROL);
+ tmp |= (TMUCORE_ENABLE | (0x6 << 20)); /* MUX_ADDR : 110b */
+ __raw_writel(tmp, info->tmu_base + EXYNOS4_TMU_CONTROL);
+
+ /* Because temperature sensing time is appro 940us,
+ * tmu is enabled and 1st valid sample can get 1ms after.
+ */
+ mdelay(1);
+ /* check interrupt status register */
+ pr_debug("tmu interrupt status: 0x%08x\n",
+ __raw_readl(info->tmu_base + EXYNOS4_TMU_INTSTAT));
+
+ /* THRESHOLD_TEMP_RISE0, RISE1, RISE2 interrupt enable */
+ __raw_writel(INTEN_RISE0 | INTEN_RISE1 | INTEN_RISE2,
+ info->tmu_base + EXYNOS4_TMU_INTEN);
+
+#if defined(CONFIG_TC_VOLTAGE)
+ tmp = __raw_readl(info->tmu_base + EXYNOS4_TMU_INTEN);
+ tmp |= INTEN_FALL0;
+ __raw_writel(tmp, info->tmu_base + EXYNOS4_TMU_INTEN);
+#endif
+
+ return 0;
+}
+
+static int tmu_initialize(struct platform_device *pdev)
+{
+ struct s5p_tmu_info *info = platform_get_drvdata(pdev);
+ unsigned int tmp;
+ unsigned ret;
+
+ /* check if sensing is idle */
+ tmp = (__raw_readl(info->tmu_base + EXYNOS4_TMU_STATUS) & 0x1);
+ if (!tmp) {
+ pr_err("failed to start tmu driver\n");
+ return -ENOENT;
+ }
+
+ if (soc_is_exynos4210())
+ ret = exynos4210_tmu_init(info);
+ else
+ ret = exynos4x12_tmu_init(info);
+
+ return ret;
+}
+
+static irqreturn_t exynos4x12_tmu_irq_handler(int irq, void *id)
+{
+ struct s5p_tmu_info *info = id;
+ unsigned int status;
+
+ disable_irq_nosync(irq);
+
+ status = __raw_readl(info->tmu_base + EXYNOS4_TMU_INTSTAT) & 0x1FFFF;
+ pr_info("EXYNOS4x12_tmu interrupt: INTSTAT = 0x%08x\n", status);
+
+ /* To handle multiple interrupt pending,
+ * interrupt by high temperature are serviced with priority.
+ */
+#if defined(CONFIG_TC_VOLTAGE)
+ if (status & INTSTAT_FALL0) {
+ info->tmu_state = TMU_STATUS_TC;
+
+ __raw_writel(INTCLEARALL, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ exynos_interrupt_enable(info, 0);
+ } else if (status & INTSTAT_RISE2) {
+ info->tmu_state = TMU_STATUS_TRIPPED;
+ __raw_writel(INTCLEAR_RISE2, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+#else
+ if (status & INTSTAT_RISE2) {
+ info->tmu_state = TMU_STATUS_TRIPPED;
+ __raw_writel(INTCLEAR_RISE2, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+#endif
+ } else if (status & INTSTAT_RISE1) {
+ info->tmu_state = TMU_STATUS_WARNING;
+ __raw_writel(INTCLEAR_RISE1, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ } else if (status & INTSTAT_RISE0) {
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ __raw_writel(INTCLEAR_RISE0, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ } else {
+ pr_err("%s: interrupt error\n", __func__);
+ __raw_writel(INTCLEARALL, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, info->sampling_rate / 2);
+ return -ENODEV;
+ }
+
+ /* read current temperature & save */
+ info->last_temperature = get_curr_temp(info);
+
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->polling,
+ info->sampling_rate);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t exynos4210_tmu_irq_handler(int irq, void *id)
+{
+ struct s5p_tmu_info *info = id;
+ unsigned int status;
+
+ disable_irq_nosync(irq);
+
+ status = __raw_readl(info->tmu_base + EXYNOS4_TMU_INTSTAT);
+ pr_info("EXYNOS4212_tmu interrupt: INTSTAT = 0x%08x\n", status);
+
+ /* To handle multiple interrupt pending,
+ * interrupt by high temperature are serviced with priority.
+ */
+ if (status & TMU_INTSTAT2) {
+ info->tmu_state = TMU_STATUS_TRIPPED;
+ __raw_writel(INTCLEAR2, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ } else if (status & TMU_INTSTAT1) {
+ info->tmu_state = TMU_STATUS_WARNING;
+ __raw_writel(INTCLEAR1, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ } else if (status & TMU_INTSTAT0) {
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ __raw_writel(INTCLEAR0, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ } else {
+ pr_err("%s: interrupt error\n", __func__);
+ __raw_writel(INTCLEARALL, info->tmu_base + EXYNOS4_TMU_INTCLEAR);
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, info->sampling_rate / 2);
+ return -ENODEV;
+ }
+
+ /* read current temperature & save */
+ info->last_temperature = get_curr_temp(info);
+
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->polling,
+ info->sampling_rate);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_TMU_SYSFS
+static ssize_t s5p_tmu_show_curr_temp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct s5p_tmu_info *info = dev_get_drvdata(dev);
+ unsigned int curr_temp;
+
+ curr_temp = get_curr_temp(info);
+ curr_temp *= 10;
+ pr_info("curr temp = %d\n", curr_temp);
+
+ return sprintf(buf, "%d\n", curr_temp);
+}
+static DEVICE_ATTR(curr_temp, S_IRUGO, s5p_tmu_show_curr_temp, NULL);
+#endif
+
+static int __devinit s5p_tmu_probe(struct platform_device *pdev)
+{
+ struct s5p_tmu_info *info;
+ struct s5p_platform_tmu *pdata;
+ struct resource *res;
+ unsigned int mask = (enable_mask & ENABLE_DBGMASK);
+ int ret = 0;
+
+ pr_debug("%s: probe=%p\n", __func__, pdev);
+
+ info = kzalloc(sizeof(struct s5p_tmu_info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "failed to alloc memory!\n");
+ ret = -ENOMEM;
+ goto err_nomem;
+ }
+ platform_set_drvdata(pdev, info);
+
+ info->dev = &pdev->dev;
+ info->tmu_state = TMU_STATUS_INIT;
+
+ /* set cpufreq limit level at 1st_throttle & 2nd throttle */
+ pdata = info->dev->platform_data;
+ if (pdata->cpufreq.limit_1st_throttle)
+ exynos_cpufreq_get_level(pdata->cpufreq.limit_1st_throttle,
+ &info->cpufreq_level_1st_throttle);
+
+ if (pdata->cpufreq.limit_2nd_throttle)
+ exynos_cpufreq_get_level(pdata->cpufreq.limit_2nd_throttle,
+ &info->cpufreq_level_2nd_throttle);
+
+ pr_info("@@@ %s: cpufreq_limit: 1st_throttle: %u, 2nd_throttle = %u\n",
+ __func__, info->cpufreq_level_1st_throttle,
+ info->cpufreq_level_2nd_throttle);
+
+#if defined(CONFIG_TC_VOLTAGE) /* Temperature compensated voltage */
+ if (exynos_find_cpufreq_level_by_volt(pdata->temp_compensate.arm_volt,
+ &info->cpulevel_tc) < 0) {
+ dev_err(&pdev->dev, "cpufreq_get_level error\n");
+ ret = -EINVAL;
+ goto err_nomem;
+ }
+#ifdef CONFIG_BUSFREQ_OPP
+ /* To lock bus frequency in OPP mode */
+ info->bus_dev = dev_get("exynos-busfreq");
+ if (info->bus_dev < 0) {
+ dev_err(&pdev->dev, "Failed to get_dev\n");
+ ret = -EINVAL;
+ goto err_nomem;
+ }
+ if (exynos4x12_find_busfreq_by_volt(pdata->temp_compensate.bus_volt,
+ &info->busfreq_tc)) {
+ dev_err(&pdev->dev, "get_busfreq_value error\n");
+ ret = -EINVAL;
+ goto err_nomem;
+ }
+#endif
+ pr_info("%s: cpufreq_level[%u], busfreq_value[%u]\n",
+ __func__, info->cpulevel_tc, info->busfreq_tc);
+#endif
+ /* Map auto_refresh_rate of normal & tq0 mode */
+ info->auto_refresh_tq0 =
+ get_refresh_interval(FREQ_IN_PLL, AUTO_REFRESH_PERIOD_TQ0);
+ info->auto_refresh_normal =
+ get_refresh_interval(FREQ_IN_PLL, AUTO_REFRESH_PERIOD_NORMAL);
+
+ /* To poll current temp, set sampling rate to ONE second sampling */
+ info->sampling_rate = usecs_to_jiffies(1000 * 1000);
+ /* 10sec monitroing */
+ info->monitor_period = usecs_to_jiffies(10000 * 1000);
+
+ /* support test mode */
+ if (mask & ENABLE_TEST_MODE)
+ set_temperature_params(info);
+ else
+ print_temperature_params(info);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get memory region resource\n");
+ ret = -ENODEV;
+ goto err_nores;
+ }
+
+ info->ioarea = request_mem_region(res->start,
+ res->end-res->start + 1, pdev->name);
+ if (!(info->ioarea)) {
+ dev_err(&pdev->dev, "failed to reserve memory region\n");
+ ret = -EBUSY;
+ goto err_nores;
+ }
+
+ info->tmu_base = ioremap(res->start, (res->end - res->start) + 1);
+ if (!(info->tmu_base)) {
+ dev_err(&pdev->dev, "failed ioremap()\n");
+ ret = -ENOMEM;
+ goto err_nomap;
+ }
+ tmu_monitor_wq = create_freezable_workqueue(dev_name(&pdev->dev));
+ if (!tmu_monitor_wq) {
+ pr_info("Creation of tmu_monitor_wq failed\n");
+ ret = -ENOMEM;
+ goto err_wq;
+ }
+
+ /* To support periodic temprature monitoring */
+ if (mask & ENABLE_TEMP_MON) {
+ INIT_DELAYED_WORK_DEFERRABLE(&info->monitor,
+ exynos4_poll_cur_temp);
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->monitor,
+ info->monitor_period);
+ }
+ INIT_DELAYED_WORK_DEFERRABLE(&info->polling, exynos4_handler_tmu_state);
+
+ info->irq = platform_get_irq(pdev, 0);
+ if (info->irq < 0) {
+ dev_err(&pdev->dev, "no irq for thermal %d\n", info->irq);
+ ret = -EINVAL;
+ goto err_irq;
+ }
+
+ if (soc_is_exynos4210())
+ ret = request_irq(info->irq, exynos4210_tmu_irq_handler,
+ IRQF_DISABLED, "s5p-tmu interrupt", info);
+ else
+ ret = request_irq(info->irq, exynos4x12_tmu_irq_handler,
+ IRQF_DISABLED, "s5p-tmu interrupt", info);
+
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq is failed. %d\n", ret);
+ goto err_irq;
+ }
+
+ ret = device_create_file(&pdev->dev, &dev_attr_temperature);
+ if (ret != 0) {
+ pr_err("Failed to create temperatue file: %d\n", ret);
+ goto err_sysfs_file1;
+ }
+
+ ret = device_create_file(&pdev->dev, &dev_attr_tmu_state);
+ if (ret != 0) {
+ pr_err("Failed to create tmu_state file: %d\n", ret);
+ goto err_sysfs_file2;
+ }
+ ret = device_create_file(&pdev->dev, &dev_attr_lot_id);
+ if (ret != 0) {
+ pr_err("Failed to create lot id file: %d\n", ret);
+ goto err_sysfs_file3;
+ }
+
+ ret = tmu_initialize(pdev);
+ if (ret)
+ goto err_init;
+
+#ifdef CONFIG_TMU_SYSFS
+ ret = device_create_file(&pdev->dev, &dev_attr_curr_temp);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to create sysfs group\n");
+ goto err_init;
+ }
+#endif
+
+#ifdef CONFIG_TMU_DEBUG
+ ret = device_create_file(&pdev->dev, &dev_attr_print_state);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to create tmu sysfs group\n\n");
+ return ret;
+ }
+#endif
+
+#if defined(CONFIG_TC_VOLTAGE)
+ /* s/w workaround for fast service when interrupt is not occured,
+ * such as current temp is lower than tc interrupt temperature
+ * or current temp is continuosly increased.
+ */
+ if (get_curr_temp(info) <= pdata->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ }
+ if (mali_voltage_lock_init())
+ pr_err("Failed to initialize mail voltage lock.\n");
+#endif
+
+ /* initialize tmu_state */
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->polling,
+ info->sampling_rate);
+
+ return ret;
+
+err_init:
+ device_remove_file(&pdev->dev, &dev_attr_lot_id);
+
+err_sysfs_file3:
+ device_remove_file(&pdev->dev, &dev_attr_tmu_state);
+
+err_sysfs_file2:
+ device_remove_file(&pdev->dev, &dev_attr_temperature);
+
+err_sysfs_file1:
+ if (info->irq >= 0)
+ free_irq(info->irq, info);
+
+err_irq:
+ destroy_workqueue(tmu_monitor_wq);
+
+err_wq:
+ iounmap(info->tmu_base);
+
+err_nomap:
+ release_resource(info->ioarea);
+ kfree(info->ioarea);
+
+err_nores:
+ kfree(info);
+ info = NULL;
+
+err_nomem:
+ dev_err(&pdev->dev, "initialization failed.\n");
+
+ return ret;
+}
+
+static int __devinit s5p_tmu_remove(struct platform_device *pdev)
+{
+ struct s5p_tmu_info *info = platform_get_drvdata(pdev);
+
+ cancel_delayed_work(&info->polling);
+ destroy_workqueue(tmu_monitor_wq);
+
+ device_remove_file(&pdev->dev, &dev_attr_temperature);
+ device_remove_file(&pdev->dev, &dev_attr_tmu_state);
+
+ if (info->irq >= 0)
+ free_irq(info->irq, info);
+
+ iounmap(info->tmu_base);
+
+ release_resource(info->ioarea);
+ kfree(info->ioarea);
+
+ kfree(info);
+ info = NULL;
+
+ pr_info("%s is removed\n", dev_name(&pdev->dev));
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s5p_tmu_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct s5p_tmu_info *info = platform_get_drvdata(pdev);
+
+ if (!info)
+ return -EAGAIN;
+
+ /* save register value */
+ info->reg_save[0] = __raw_readl(info->tmu_base + EXYNOS4_TMU_CONTROL);
+ info->reg_save[1] = __raw_readl(info->tmu_base + EXYNOS4_TMU_SAMPLING_INTERNAL);
+ info->reg_save[2] = __raw_readl(info->tmu_base + EXYNOS4_TMU_COUNTER_VALUE0);
+ info->reg_save[3] = __raw_readl(info->tmu_base + EXYNOS4_TMU_COUNTER_VALUE1);
+ info->reg_save[4] = __raw_readl(info->tmu_base + EXYNOS4_TMU_INTEN);
+
+ if (soc_is_exynos4210()) {
+ info->reg_save[5] =
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_THRESHOLD_TEMP);
+ info->reg_save[6] =
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL0);
+ info->reg_save[7] =
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL1);
+ info->reg_save[8] =
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL2);
+ info->reg_save[9] =
+ __raw_readl(info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL3);
+ } else {
+ info->reg_save[5] =
+ __raw_readl(info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_RISE);
+#if defined(CONFIG_TC_VOLTAGE)
+ info->reg_save[6] = __raw_readl(info->tmu_base
+ + EXYNOS4x12_TMU_TRESHOLD_TEMP_FALL);
+#endif
+ }
+ disable_irq(info->irq);
+
+ return 0;
+}
+
+static int s5p_tmu_resume(struct platform_device *pdev)
+{
+ struct s5p_tmu_info *info = platform_get_drvdata(pdev);
+ struct s5p_platform_tmu *data = info->dev->platform_data;
+
+ if (!info)
+ return -EAGAIN;
+
+ /* restore tmu register value */
+ __raw_writel(info->reg_save[0], info->tmu_base + EXYNOS4_TMU_CONTROL);
+ __raw_writel(info->reg_save[1],
+ info->tmu_base + EXYNOS4_TMU_SAMPLING_INTERNAL);
+ __raw_writel(info->reg_save[2],
+ info->tmu_base + EXYNOS4_TMU_COUNTER_VALUE0);
+ __raw_writel(info->reg_save[3],
+ info->tmu_base + EXYNOS4_TMU_COUNTER_VALUE1);
+
+ if (soc_is_exynos4210()) {
+ __raw_writel(info->reg_save[5],
+ info->tmu_base + EXYNOS4210_TMU_THRESHOLD_TEMP);
+ __raw_writel(info->reg_save[6],
+ info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL0);
+ __raw_writel(info->reg_save[7],
+ info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL1);
+ __raw_writel(info->reg_save[8],
+ info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL2);
+ __raw_writel(info->reg_save[9],
+ info->tmu_base + EXYNOS4210_TMU_TRIG_LEVEL3);
+ } else {
+ __raw_writel(info->reg_save[5],
+ info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_RISE);
+#if defined(CONFIG_TC_VOLTAGE)
+ __raw_writel(info->reg_save[6],
+ info->tmu_base + EXYNOS4x12_TMU_TRESHOLD_TEMP_FALL);
+#endif
+ }
+ __raw_writel(info->reg_save[4],
+ info->tmu_base + EXYNOS4_TMU_INTEN);
+
+#if defined(CONFIG_TC_VOLTAGE)
+ /* s/w workaround for fast service when interrupt is not occured,
+ * such as current temp is lower than tc interrupt temperature
+ * or current temp is continuosly increased..
+ */
+ mdelay(1);
+ if (get_curr_temp(info) <= data->ts.start_tc) {
+ if (exynos_tc_volt(info, 1) < 0)
+ pr_err("TMU: lock error!\n");
+ }
+#endif
+ /* Find out tmu_state after wakeup */
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->polling, 0);
+
+ return 0;
+}
+#else
+#define s5p_tmu_suspend NULL
+#define s5p_tmu_resume NULL
+#endif
+
+static struct platform_driver s5p_tmu_driver = {
+ .probe = s5p_tmu_probe,
+ .remove = s5p_tmu_remove,
+ .suspend = s5p_tmu_suspend,
+ .resume = s5p_tmu_resume,
+ .driver = {
+ .name = "s5p-tmu",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s5p_tmu_driver_init(void)
+{
+ return platform_driver_register(&s5p_tmu_driver);
+}
+
+static void __exit s5p_tmu_driver_exit(void)
+{
+ platform_driver_unregister(&s5p_tmu_driver);
+}
+late_initcall(s5p_tmu_driver_init);
+module_exit(s5p_tmu_driver_exit);
diff --git a/arch/arm/mach-exynos/tmu_exynos.c b/arch/arm/mach-exynos/tmu_exynos.c
new file mode 100644
index 0000000..47f580d
--- /dev/null
+++ b/arch/arm/mach-exynos/tmu_exynos.c
@@ -0,0 +1,423 @@
+/* linux/arch/arm/mach-exynos/tmu_exynos.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS - Thermal Management support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+
+#include <linux/irq.h>
+
+#include <mach/regs-tmu.h>
+#include <mach/cpufreq.h>
+#include <plat/s5p-tmu.h>
+
+#define MUX_ADDR_VALUE 6
+
+enum tmu_status_t {
+ TMU_STATUS_INIT = 0,
+ TMU_STATUS_NORMAL,
+ TMU_STATUS_THROTTLED,
+ TMU_STATUS_WARNING,
+ TMU_STATUS_TRIPPED,
+};
+
+static struct workqueue_struct *tmu_monitor_wq;
+
+static int tmu_tripped_cb(void)
+{
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+
+ if (!psy) {
+ pr_err("%s:fail to get batter ps\n", __func__);
+ return -ENODEV;
+ }
+
+ value.intval = TMU_STATUS_TRIPPED;
+
+ return psy->set_property(psy, POWER_SUPPLY_PROP_TEMP_AMBIENT, &value);
+}
+
+static unsigned char get_cur_temp(struct tmu_info *info)
+{
+ unsigned char curr_temp;
+ unsigned char temperature;
+
+ /* After reading temperature code from register, compensating
+ * its value and calculating celsius temperatue,
+ * get current temperatue.
+ */
+ curr_temp = __raw_readl(info->tmu_base + CURRENT_TEMP) & 0xff;
+
+ /* compensate and calculate current temperature */
+ temperature = curr_temp - info->te1 + TMU_DC_VALUE;
+ if (temperature < 0) {
+ /* temperature code range are between min 25 and 125 */
+ pr_err("%s: Current temperature is unreasonable value\n", __func__);
+ }
+
+ return temperature;
+}
+
+#ifdef CONFIG_TMU_DEBUG
+static void cur_temp_monitor(struct work_struct *work)
+{
+ unsigned char cur_temp;
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct tmu_info *info =
+ container_of(delayed_work, struct tmu_info, monitor);
+
+ cur_temp = get_cur_temp(info);
+ pr_info("current temp = %d\n", cur_temp);
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->monitor,
+ usecs_to_jiffies(1000 * 1000));
+}
+#endif
+
+static void tmu_monitor(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct tmu_info *info =
+ container_of(delayed_work, struct tmu_info, polling);
+ struct tmu_data *data = info->dev->platform_data;
+ unsigned char cur_temp;
+
+#ifdef CONFIG_TMU_DEBUG
+ cancel_delayed_work(&info->monitor);
+#endif
+ cur_temp = get_cur_temp(info);
+ pr_info("Current: %dc, FLAG=%d\n",
+ cur_temp, info->tmu_state);
+
+ switch (info->tmu_state) {
+ case TMU_STATUS_NORMAL:
+#ifdef CONFIG_TMU_DEBUG
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->monitor,
+ usecs_to_jiffies(1000 * 1000));
+#endif
+ cancel_delayed_work(&info->polling);
+ enable_irq(info->irq);
+ break;
+ case TMU_STATUS_THROTTLED:
+ if (cur_temp >= data->ts.start_warning)
+ info->tmu_state = TMU_STATUS_WARNING;
+ else if (cur_temp > data->ts.stop_throttle &&
+ cur_temp < data->ts.start_warning)
+ exynos_cpufreq_upper_limit(DVFS_LOCK_ID_TMU,
+ data->cpulimit.throttle_freq);
+ else if (cur_temp <= data->ts.stop_throttle) {
+ info->tmu_state = TMU_STATUS_NORMAL;
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_TMU);
+ }
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, usecs_to_jiffies(500 * 1000));
+ break;
+ case TMU_STATUS_WARNING:
+ if (cur_temp >= data->ts.start_tripping)
+ info->tmu_state = TMU_STATUS_TRIPPED;
+ else if (cur_temp > data->ts.stop_warning && \
+ cur_temp < data->ts.start_tripping)
+ exynos_cpufreq_upper_limit(DVFS_LOCK_ID_TMU,
+ data->cpulimit.warning_freq);
+ else if (cur_temp <= data->ts.stop_warning) {
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ exynos_cpufreq_upper_limit_free(DVFS_LOCK_ID_TMU);
+ }
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, usecs_to_jiffies(500 * 1000));
+ break;
+ case TMU_STATUS_TRIPPED:
+ tmu_tripped_cb();
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, usecs_to_jiffies(5000 * 1000));
+ default:
+ break;
+ }
+ return;
+}
+
+static void s5p_pm_tmu_save(struct tmu_info *info)
+{
+ info->reg_save[0] = __raw_readl(info->tmu_base + TMU_CON);
+ info->reg_save[1] = __raw_readl(info->tmu_base + SAMPLING_INTERNAL);
+ info->reg_save[2] = __raw_readl(info->tmu_base + CNT_VALUE0);
+ info->reg_save[3] = __raw_readl(info->tmu_base + CNT_VALUE1);
+ info->reg_save[4] = __raw_readl(info->tmu_base + THD_TEMP_RISE);
+ info->reg_save[5] = __raw_readl(info->tmu_base + THD_TEMP_FALL);
+ info->reg_save[6] = __raw_readl(info->tmu_base + INTEN);
+}
+
+static void s5p_pm_tmu_restore(struct tmu_info *info)
+{
+ __raw_writel(info->reg_save[0], info->tmu_base + TMU_CON);
+ __raw_writel(info->reg_save[1], info->tmu_base + SAMPLING_INTERNAL);
+ __raw_writel(info->reg_save[2], info->tmu_base + CNT_VALUE0);
+ __raw_writel(info->reg_save[3], info->tmu_base + CNT_VALUE1);
+ __raw_writel(info->reg_save[4], info->tmu_base + THD_TEMP_RISE);
+ __raw_writel(info->reg_save[5], info->tmu_base + THD_TEMP_FALL);
+ __raw_writel(info->reg_save[6], info->tmu_base + INTEN);
+}
+
+static int tmu_start(struct tmu_info *info)
+{
+ struct tmu_data *data = info->dev->platform_data;
+ unsigned int te_temp, con;
+ unsigned int throttle_temp, waring_temp, trip_temp;
+ unsigned int cooling_temp;
+ unsigned int rising_value;
+ unsigned int reg_info; /* debugging */
+
+ /* must reload for using efuse value at EXYNOS4212 */
+ __raw_writel(TRIMINFO_RELOAD, info->tmu_base + TRIMINFO_CON);
+
+ /* get the compensation parameter */
+ te_temp = __raw_readl(info->tmu_base + TRIMINFO);
+ info->te1 = te_temp & TRIM_INFO_MASK;
+ info->te2 = ((te_temp >> 8) & TRIM_INFO_MASK);
+
+ if ((EFUSE_MIN_VALUE > info->te1) || (info->te1 > EFUSE_MAX_VALUE)
+ || (info->te2 != 0))
+ info->te1 = data->efuse_value;
+
+ /*Get RISING & FALLING Threshold value */
+ throttle_temp = data->ts.start_throttle
+ + info->te1 - TMU_DC_VALUE;
+ waring_temp = data->ts.start_warning
+ + info->te1 - TMU_DC_VALUE;
+ trip_temp = data->ts.start_tripping
+ + info->te1 - TMU_DC_VALUE;
+ cooling_temp = 0;
+
+ rising_value = (throttle_temp | (waring_temp<<8) | \
+ (trip_temp<<16));
+
+ /* Set interrupt level */
+ __raw_writel(rising_value, info->tmu_base + THD_TEMP_RISE);
+ __raw_writel(cooling_temp, info->tmu_base + THD_TEMP_FALL);
+
+ /* Set frequecny level */
+ exynos_cpufreq_get_level(800000, &data->cpulimit.throttle_freq);
+ exynos_cpufreq_get_level(200000, &data->cpulimit.warning_freq);
+
+ /* Need to initail regsiter setting after getting parameter info */
+ /* [28:23] vref [11:8] slope - Tunning parameter */
+ __raw_writel(data->slope, info->tmu_base + TMU_CON);
+
+ pr_info("TMU initialization is successful!!");
+ reg_info = __raw_readl(info->tmu_base + THD_TEMP_RISE);
+ pr_info("RISING THRESHOLD = %x", reg_info);
+
+ __raw_writel(INTCLEARALL, info->tmu_base + INTCLEAR);
+ /* TMU core enable */
+ con = __raw_readl(info->tmu_base + TMU_CON);
+ con |= (MUX_ADDR_VALUE<<20 | CORE_EN);
+
+ __raw_writel(con, info->tmu_base + TMU_CON);
+
+ /*LEV0 LEV1 LEV2 interrupt enable */
+ __raw_writel(INTEN_RISE0 | INTEN_RISE1 | INTEN_RISE2, \
+ info->tmu_base + INTEN);
+ return 0;
+}
+
+static int tmu_initialize(struct platform_device *pdev)
+{
+ struct tmu_info *info = platform_get_drvdata(pdev);
+ unsigned int en;
+
+ en = (__raw_readl(info->tmu_base + TMU_STATUS) & 0x1);
+
+ if (!en) {
+ dev_err(&pdev->dev, "failed to start tmu drvier\n");
+ return -ENOENT;
+ }
+
+ return tmu_start(info);
+}
+
+static irqreturn_t tmu_irq(int irq, void *id)
+{
+ struct tmu_info *info = id;
+ unsigned int status;
+
+ disable_irq_nosync(irq);
+
+ status = __raw_readl(info->tmu_base + INTSTAT);
+
+ if (status & INTSTAT_RISE0) {
+ pr_info("Throttling interrupt occured!!!!\n");
+ __raw_writel(INTCLEAR_RISE0, info->tmu_base + INTCLEAR);
+ info->tmu_state = TMU_STATUS_THROTTLED;
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, usecs_to_jiffies(500 * 1000));
+ } else if (status & INTSTAT_RISE1) {
+ pr_info("Warning interrupt occured!!!!\n");
+ __raw_writel(INTCLEAR_RISE1, info->tmu_base + INTCLEAR);
+ info->tmu_state = TMU_STATUS_WARNING;
+ queue_delayed_work_on(0, tmu_monitor_wq,
+ &info->polling, usecs_to_jiffies(500 * 1000));
+ } else if (status & INTSTAT_RISE2) {
+ pr_info("Tripping interrupt occured!!!!\n");
+ info->tmu_state = TMU_STATUS_TRIPPED;
+ __raw_writel(INTCLEAR_RISE2, info->tmu_base + INTCLEAR);
+ tmu_tripped_cb();
+ } else {
+ pr_err("%s: TMU interrupt error\n", __func__);
+ return -ENODEV;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit tmu_probe(struct platform_device *pdev)
+{
+ struct tmu_info *info;
+ struct resource *res;
+ int ret = 0;
+
+ pr_debug("%s: probe=%p\n", __func__, pdev);
+
+ info = kzalloc(sizeof(struct tmu_info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "failed to alloc memory!\n");
+ ret = -ENOMEM;
+ goto err_nores;
+ }
+ platform_set_drvdata(pdev, info);
+
+ info->dev = &pdev->dev;
+ info->tmu_state = TMU_STATUS_INIT;
+
+ info->irq = platform_get_irq(pdev, 0);
+ if (info->irq < 0) {
+ dev_err(&pdev->dev, "no irq for thermal\n");
+ return -ENOENT;
+ }
+
+ ret = request_irq(info->irq, tmu_irq,
+ IRQF_DISABLED, "tmu interrupt", info);
+ if (ret) {
+ dev_err(&pdev->dev, "IRQ%d error %d\n", info->irq, ret);
+ goto err_noirq;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "failed to get memory region resource\n");
+ return -ENOENT;
+ }
+
+ info->ioarea = request_mem_region(res->start,
+ res->end-res->start+1, pdev->name);
+ if (!(info->ioarea)) {
+ dev_err(&pdev->dev, "failed to reserve memory region\n");
+ ret = -ENOENT;
+ goto err_nores;
+ }
+
+ info->tmu_base = ioremap(res->start, (res->end - res->start) + 1);
+ if (!(info->tmu_base)) {
+ dev_err(&pdev->dev, "failed ioremap()\n");
+ ret = -EINVAL;
+ goto err_nomap;
+ }
+
+ tmu_monitor_wq = create_freezable_workqueue("tmu");
+ if (!tmu_monitor_wq) {
+ pr_info("Creation of tmu_monitor_wq failed\n");
+ return -EFAULT;
+ }
+
+#ifdef CONFIG_TMU_DEBUG
+ INIT_DELAYED_WORK_DEFERRABLE(&info->monitor, cur_temp_monitor);
+ queue_delayed_work_on(0, tmu_monitor_wq, &info->monitor,
+ usecs_to_jiffies(1000 * 1000));
+#endif
+ INIT_DELAYED_WORK_DEFERRABLE(&info->polling, tmu_monitor);
+
+ ret = tmu_initialize(pdev);
+ if (ret)
+ goto err_noinit;
+
+ return ret;
+
+err_noinit:
+ free_irq(info->irq, info);
+err_noirq:
+ iounmap(info->tmu_base);
+err_nomap:
+ release_resource(info->ioarea);
+err_nores:
+ return ret;
+}
+
+static int __devinit tmu_remove(struct platform_device *pdev)
+{
+ struct tmu_info *info = platform_get_drvdata(pdev);
+
+ free_irq(info->irq, (void *)pdev);
+ iounmap(info->tmu_base);
+
+ pr_info("%s is removed\n", dev_name(&pdev->dev));
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int tmu_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct tmu_info *info = platform_get_drvdata(pdev);
+ s5p_pm_tmu_save(info);
+
+ return 0;
+}
+
+static int tmu_resume(struct platform_device *pdev)
+{
+ struct tmu_info *info = platform_get_drvdata(pdev);
+ s5p_pm_tmu_restore(info);
+
+ return 0;
+}
+
+#else
+#define s5p_tmu_suspend NULL
+#define s5p_tmu_resume NULL
+#endif
+
+static struct platform_driver tmu_driver = {
+ .probe = tmu_probe,
+ .remove = tmu_remove,
+ .suspend = tmu_suspend,
+ .resume = tmu_resume,
+ .driver = {
+ .name = "s5p-tmu",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init tmu_driver_init(void)
+{
+ return platform_driver_register(&tmu_driver);
+}
+
+late_initcall(tmu_driver_init);
diff --git a/arch/arm/mach-exynos/u1-gpio.c b/arch/arm/mach-exynos/u1-gpio.c
new file mode 100644
index 0000000..434ccd2
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-gpio.c
@@ -0,0 +1,678 @@
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio.h>
+#include "u1.h"
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data u1_init_gpios[] = {
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPA0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPA0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPC0(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {EXYNOS4_GPB(4), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* TDMB_INT */
+ {EXYNOS4_GPB(5), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* TDMB_RST_N */
+ {EXYNOS4_GPC0(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* TDMB_EN */
+#endif
+#if defined(CONFIG_ISDBT_FC8100)
+ {EXYNOS4210_GPE1(5), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ISDBT_RST_N */
+ {EXYNOS4_GPC0(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* ISDBT_EN */
+#endif
+ {EXYNOS4_GPC1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SDA_1.8V */
+ {EXYNOS4_GPC1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SCL_1.8V */
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPD0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MHL_SDA_2.8V */
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MHL_SCL_2.8V */
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* 8M_CAM_SDA_2.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* 8M_CAM_SCL_2.8V */
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SENSE_SDA_2.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SENSE_SCL_2.8V */
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE1(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* MHL_SCL_1.8V */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* MHL_SDA_1.8V */
+ {EXYNOS4210_GPE3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE3(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPE4(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+
+ {EXYNOS4_GPK1(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPK2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_SDA_2.8V */
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* PS_ALS_SCL_2.8V */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPL0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+ {EXYNOS4_GPL1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1}, /* NC */
+#endif
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_UP */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_DOWN */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_BOOT_MODE */
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_FUEL_ALERT */
+ {EXYNOS4_GPX3(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX3(2), S3C_GPIO_SFN(GPIO_DET_35_AF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_DET_35 */
+ {EXYNOS4_GPX3(3), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+#if defined(CONFIG_TARGET_LOCALE_NTT)
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+#endif
+ {EXYNOS4_GPY0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1,},
+ {EXYNOS4_GPY2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY4(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+};
+
+/* this table only for u1 board */
+static unsigned int u1_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#elif defined(CONFIG_TARGET_LOCALE_NTT)
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_TARGET_LOCALE_NTT)
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#elif defined(CONFIG_TARGET_LOCALE_NTT)
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_TDMB) || defined(CONFIG_TDMB_MODULE)
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#elif defined(CONFIG_ISDBT_FC8100)
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if !defined(CONFIG_VIDEO_TSI)
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#else
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#endif
+#endif /*end CONFIG_VIDEO_TSI*/
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#if !defined(CONFIG_VIDEO_TSI)
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+#endif /* end CONFIG_VIDEO_TSI */
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#if defined(CONFIG_PN544) && (defined(CONFIG_TARGET_LOCALE_KOR) \
+ || defined(CONFIG_TARGET_LOCALE_EUR_U1_NFC))
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+#elif defined(CONFIG_TARGET_LOCALE_NTT)
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+#endif
+
+#if defined(CONFIG_PN544) && defined(CONFIG_TARGET_LOCALE_KOR)
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#endif
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+#else
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+#else
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+#if defined(CONFIG_MACH_U1_KOR_LGT)
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE}, /* NC */
+#else
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+#endif
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+void u1_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ for (i = 0; i < ARRAY_SIZE(u1_init_gpios); i++) {
+ gpio = u1_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, u1_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, u1_init_gpios[i].pud);
+
+ if (u1_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, u1_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, u1_init_gpios[i].drv);
+ }
+}
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void u1_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(u1_sleep_gpio_table),
+ u1_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos/u1-otg.c b/arch/arm/mach-exynos/u1-otg.c
new file mode 100644
index 0000000..a70c69d
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-otg.c
@@ -0,0 +1,218 @@
+
+#include <mach/regs-usb-phy.h>
+#include "../../../drivers/usb/gadget/s3c_udc.h"
+#include <plat/s5p-otghost.h>
+#include <plat/usb-phy.h>
+
+#define PHY_ENABLE (1 << 0)
+#define PHY_DISABLE (0)
+
+static int usb_status;
+static u64 s3c_device_usb_otghcd_dmamask = 0xffffffffUL;
+
+#ifdef USE_S3C_OTG_PHY
+static int c210_otg_host_phy_init(int mode)
+{
+ struct clk *otg_clk;
+ u32 value;
+ int err;
+
+ otg_clk = clk_get(NULL, "usbotg");
+ if (IS_ERR(otg_clk)) {
+ pr_err("otg: Failed to get otg clock\n");
+ return PTR_ERR(otg_clk);
+ }
+
+ err = clk_enable(otg_clk);
+ if (err) {
+ pr_err("otg: Failed to enable otg clock\n");
+ clk_put(otg_clk);
+ return err;
+ }
+
+ writel(PHY_ENABLE, S5P_USBOTG_PHY_CONTROL);
+
+ value = readl(EXYNOS4_PHYCLK) & (~(1<<4) | (7<<0));
+ pr_info("otg : phy clk 0x%x\n", value);
+ writel(value, EXYNOS4_PHYCLK);
+
+ value = readl(EXYNOS4_PHYPWR) & (~(7<<3) & ~(1<<0));
+ pr_info("otg : phy pwr 0x%x\n", value);
+ writel(value, EXYNOS4_PHYPWR);
+
+ value = readl(EXYNOS4_RSTCON) & (~(3<<1) | (1<<0));
+ writel(value, EXYNOS4_RSTCON);
+ udelay(10);
+ value &= ~(7<<0);
+ writel(value, EXYNOS4_RSTCON);
+
+ clk_put(otg_clk);
+
+ return 0;
+}
+
+static int c210_otg_host_phy_exit(int mode)
+{
+ struct clk *otg_clk;
+
+ otg_clk = clk_get(NULL, "usbotg");
+ if (IS_ERR(otg_clk)) {
+ pr_err("otg: Failed to get otg clock\n");
+ return PTR_ERR(otg_clk);
+ }
+
+ writel((readl(EXYNOS4_PHYPWR) | PHY0_NORMAL_MASK),
+ EXYNOS4_PHYPWR);
+
+ writel(PHY_DISABLE, S5P_USBOTG_PHY_CONTROL);
+
+ clk_disable(otg_clk);
+ clk_put(otg_clk);
+
+ return 0;
+}
+#else
+static int c210_otg_host_phy_init(int mode)
+{
+ s5p_usb_phy_init(&s3c_device_usbgadget, S5P_USB_PHY_OTGHOST);
+ return 0;
+}
+static int c210_otg_host_phy_exit(int mode)
+{
+ s5p_usb_phy_exit(&s3c_device_usbgadget, S5P_USB_PHY_OTGHOST);
+ return 0;
+}
+#endif
+
+static void c210_host_notify_cb(int mode)
+{
+ pr_info("otg host_notify : %d\n", mode);
+ host_state_notify(&host_notifier_pdata.ndev, mode);
+}
+
+static struct sec_otghost_data otghost_data = {
+ .clk_usage = 0,
+ .set_pwr_cb = usb_otg_accessory_power,
+ .sec_whlist_table_num = 1,
+ .start = 0,
+ .stop = 0,
+
+ .phy_init = c210_otg_host_phy_init,
+ .phy_exit = c210_otg_host_phy_exit,
+ .host_notify_cb = c210_host_notify_cb,
+};
+
+static struct resource s3c_usb_otghcd_resource[] = {
+ [0] = {
+ .start = S5P_PA_HSOTG,
+ .end = S5P_PA_HSOTG + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB_HSOTG,
+ .end = IRQ_USB_HSOTG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device s3c_device_usb_otghcd = {
+ .name = "s3c_otghcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb_otghcd_resource),
+ .resource = s3c_usb_otghcd_resource,
+ .dev = {
+ .platform_data = &otghost_data,
+ .dma_mask = &s3c_device_usb_otghcd_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ }
+};
+
+static char *get_usb_cable_string(int mode)
+{
+ switch (mode) {
+ case USB_CABLE_DETACHED: return "USB Cable Detached";
+ case USB_CABLE_ATTACHED: return "USB Cable Attached";
+ case USB_OTGHOST_ATTACHED: return "Host Attached";
+ case USB_OTGHOST_DETACHED: return "Host Detached";
+ case USB_CABLE_DETACHED_WITHOUT_NOTI:
+ return "USB Cable Detached without noti";
+ default: return "Unknown cable state";
+ }
+}
+
+
+static void c210_otghost_start(struct s3c_udc *dev)
+{
+ host_notifier_pdata.ndev.mode = NOTIFY_HOST_MODE;
+ host_state_notify(&host_notifier_pdata.ndev, NOTIFY_HOST_ADD);
+
+ pr_info("otg start: udc %p, regs %p\n", dev, dev->regs);
+ free_irq(IRQ_USB_HSOTG, dev);
+
+ if (otghost_data.start)
+ otghost_data.start((u32)dev->regs);
+}
+
+static int c210_otghost_stop(struct s3c_udc *dev)
+{
+ struct s5p_usbgadget_platdata *pdata;
+ int ret = 0;
+
+ host_notifier_pdata.ndev.mode = NOTIFY_NONE_MODE;
+ host_state_notify(&host_notifier_pdata.ndev, NOTIFY_HOST_REMOVE);
+
+ if (otghost_data.stop)
+ otghost_data.stop();
+
+ pdata = (struct s5p_usbgadget_platdata *)
+ s3c_device_usbgadget.dev.platform_data;
+
+ pr_info("otg pdata %p, irq_cb %p, irq %p\n",
+ pdata, &pdata->udc_irq, pdata->udc_irq);
+
+ if (pdata && pdata->udc_irq) {
+ pr_info("otg request_irq irq %p, dev %p\n",
+ pdata->udc_irq, dev);
+
+ ret = request_irq(IRQ_USB_HSOTG,
+ pdata->udc_irq, 0, "s3c-udc", dev);
+ if (ret != 0) {
+ pr_info("otg host - can't get irq %i, err %d\n",
+ IRQ_USB_HSOTG, ret);
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+static int c210_change_usb_mode(struct s3c_udc *dev, int mode)
+{
+ pr_info("otg change mode : %s --> %s (%d --> %d) %s\n",
+ get_usb_cable_string(usb_status),
+ get_usb_cable_string(mode),
+ usb_status, mode,
+ dev->udc_enabled ? "enabled" : "disabled"
+ );
+
+ switch (mode) {
+ case USB_CABLE_DETACHED:
+ if (dev->udc_enabled)
+ usb_gadget_vbus_disconnect(&dev->gadget);
+ break;
+ case USB_CABLE_ATTACHED:
+ if (!dev->udc_enabled)
+ usb_gadget_vbus_connect(&dev->gadget);
+ break;
+ case USB_OTGHOST_ATTACHED:
+ c210_otghost_start(dev);
+ break;
+
+ case USB_OTGHOST_DETACHED:
+ c210_otghost_stop(dev);
+ break;
+ }
+ usb_status = mode;
+ return 0;
+}
+
diff --git a/arch/arm/mach-exynos/u1-panel.c b/arch/arm/mach-exynos/u1-panel.c
new file mode 100644
index 0000000..2da82ab
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-panel.c
@@ -0,0 +1,1665 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ld9040.h>
+#include "u1-panel.h"
+
+
+static const unsigned short SEQ_SM2_ELVSS_44[] = {
+ 0xB2, 0x15,
+ DATA_ONLY, 0x15,
+ DATA_ONLY, 0x15,
+ DATA_ONLY, 0x15,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_37[] = {
+ 0xB2, 0x1C,
+ DATA_ONLY, 0x1C,
+ DATA_ONLY, 0x1C,
+ DATA_ONLY, 0x1C,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_34[] = {
+ 0xB2, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_30[] = {
+ 0xB2, 0x23,
+ DATA_ONLY, 0x23,
+ DATA_ONLY, 0x23,
+ DATA_ONLY, 0x23,
+ ENDDEF, 0x00
+};
+
+static const unsigned short *SEQ_SM2_ELVSS_set[] = {
+ SEQ_SM2_ELVSS_30,
+ SEQ_SM2_ELVSS_34,
+ SEQ_SM2_ELVSS_37,
+ SEQ_SM2_ELVSS_44,
+};
+
+
+static const unsigned short SEQ_PWR_CTRL[] = {
+ 0xF4, 0x0A,
+
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x25,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x44,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", SM2 A1 Panel Gamma Data */
+static const unsigned short ld9040_sm2_a1_22_300[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_290[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_280[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_270[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_260[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_250[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9A,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_240[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_230[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x94,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_220[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_210[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB4,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_200[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_190[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_180[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_170[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_160[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9D,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_150[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9D,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_140[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_130[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9A,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_120[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x90,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_110[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6D,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_100[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x93,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x79,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x87,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_90[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x65,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x92,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+
+static const unsigned short ld9040_sm2_a1_22_80[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_70[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5B,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x76,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_22_60[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x63,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_50[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x50,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x68,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_40[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x49,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_22_30_dimming[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x41,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x80,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short ld9040_sm2_a1_19_300[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_290[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_280[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_270[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_260[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_250[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_240[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_230[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x94,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_220[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_210[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_200[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_190[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_180[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_170[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_160[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_150[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9D,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_140[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x79,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_130[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_120[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x90,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_110[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_100[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x87,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_90[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x66,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_80[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x61,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_70[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5C,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_60[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x63,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_50[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4F,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5D,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x67,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_40[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x48,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a1_19_30_dimming[] = {
+ 0xF9, 0x2E,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x40,
+ DATA_ONLY, 0x36,
+ DATA_ONLY, 0x93,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4C,
+ DATA_ONLY, 0x2E,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", SM2 A1 Panel Gamma Table */
+static const unsigned short *psm2_a1_22Gamma_set[] = {
+ ld9040_sm2_a1_22_30_dimming,
+ ld9040_sm2_a1_22_40,
+ ld9040_sm2_a1_22_70,
+ ld9040_sm2_a1_22_90,
+ ld9040_sm2_a1_22_100,
+ ld9040_sm2_a1_22_110,
+ ld9040_sm2_a1_22_120,
+ ld9040_sm2_a1_22_130,
+ ld9040_sm2_a1_22_140,
+ ld9040_sm2_a1_22_150,
+ ld9040_sm2_a1_22_160,
+ ld9040_sm2_a1_22_170,
+ ld9040_sm2_a1_22_180,
+ ld9040_sm2_a1_22_190,
+ ld9040_sm2_a1_22_200,
+ ld9040_sm2_a1_22_210,
+ ld9040_sm2_a1_22_220,
+ ld9040_sm2_a1_22_230,
+ ld9040_sm2_a1_22_240,
+ ld9040_sm2_a1_22_250,
+ ld9040_sm2_a1_22_300,
+};
+
+static const unsigned short *psm2_a1_19Gamma_set[] = {
+ ld9040_sm2_a1_19_30_dimming,
+ ld9040_sm2_a1_19_40,
+ ld9040_sm2_a1_19_70,
+ ld9040_sm2_a1_19_90,
+ ld9040_sm2_a1_19_100,
+ ld9040_sm2_a1_19_110,
+ ld9040_sm2_a1_19_120,
+ ld9040_sm2_a1_19_130,
+ ld9040_sm2_a1_19_140,
+ ld9040_sm2_a1_19_150,
+ ld9040_sm2_a1_19_160,
+ ld9040_sm2_a1_19_170,
+ ld9040_sm2_a1_19_180,
+ ld9040_sm2_a1_19_190,
+ ld9040_sm2_a1_19_200,
+ ld9040_sm2_a1_19_210,
+ ld9040_sm2_a1_19_220,
+ ld9040_sm2_a1_19_230,
+ ld9040_sm2_a1_19_240,
+ ld9040_sm2_a1_19_250,
+ ld9040_sm2_a1_19_300,
+};
+
+
+struct ld9040_panel_data u1_panel_data = {
+ .seq_user_set = SEQ_USER_SETTING,
+ .seq_displayctl_set = SEQ_DISPCTL,
+ .seq_gtcon_set = SEQ_GTCON,
+ .seq_panelcondition_set = SEQ_PANEL_CONDITION,
+ .seq_pwrctl_set = SEQ_PWR_CTRL,
+ .display_on = SEQ_DISPON,
+ .display_off = SEQ_DISPOFF,
+ .sleep_in = SEQ_SLPIN,
+ .sleep_out = SEQ_SLPOUT,
+ .acl_on = SEQ_ACL_ON,
+ .acl_table = ACL_cutoff_set,
+ .elvss_on = SEQ_ELVSS_ON,
+ .elvss_table = SEQ_SM2_ELVSS_set,
+ .gamma19_table = psm2_a1_19Gamma_set,
+ .gamma22_table = psm2_a1_22Gamma_set,
+ .lcdtype = LCDTYPE_SM2_A1,
+};
+
diff --git a/arch/arm/mach-exynos/u1-panel.h b/arch/arm/mach-exynos/u1-panel.h
new file mode 100644
index 0000000..6a367cb
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-panel.h
@@ -0,0 +1,146 @@
+/*
+ * arch/arm/mach-exynos/u1-panel.h
+ */
+
+#ifndef __C1_PANEL_H__
+#define __C1_PANEL_H__
+
+#define SLEEPMSEC 0x1000
+#define ENDDEF 0x2000
+#define DEFMASK 0xFF00
+#define COMMAND_ONLY 0xFE
+#define DATA_ONLY 0xFF
+
+
+static const unsigned short SEQ_USER_SETTING[] = {
+ 0xF0, 0x5A,
+
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPCTL[] = {
+ 0xF2, 0x02,
+
+ DATA_ONLY, 0x06,
+ DATA_ONLY, 0x0A,
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_GTCON[] = {
+ 0xF7, 0x09,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_PANEL_CONDITION[] = {
+ 0xF8, 0x05,
+ DATA_ONLY, 0x5E,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x7D,
+ DATA_ONLY, 0x0D,
+ DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x32,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x07,
+ DATA_ONLY, 0x05,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SLPOUT[] = {
+ 0x11, COMMAND_ONLY,
+ SLEEPMSEC, 120,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SLPIN[] = {
+ 0x10, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPON[] = {
+ 0x29, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_DISPOFF[] = {
+ 0x28, COMMAND_ONLY,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_ON[] = {
+ 0xB1, 0x0F,
+
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x16,
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_ON[] = {
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ACL_40P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x06, DATA_ONLY, 0x11, DATA_ONLY, 0x1A, DATA_ONLY, 0x20,
+ DATA_ONLY, 0x25, DATA_ONLY, 0x29, DATA_ONLY, 0x2D, DATA_ONLY, 0x30,
+ DATA_ONLY, 0x33, DATA_ONLY, 0x35,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+
+static const unsigned short SEQ_ACL_50P[] = {
+ 0xC1, 0x4D,
+
+ DATA_ONLY, 0x96, DATA_ONLY, 0x1D, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x01, DATA_ONLY, 0xDF, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x03, DATA_ONLY, 0x1F, DATA_ONLY, 0x00, DATA_ONLY, 0x00,
+ DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x00, DATA_ONLY, 0x01,
+ DATA_ONLY, 0x08, DATA_ONLY, 0x16, DATA_ONLY, 0x22, DATA_ONLY, 0x2B,
+ DATA_ONLY, 0x31, DATA_ONLY, 0x37, DATA_ONLY, 0x3B, DATA_ONLY, 0x3F,
+ DATA_ONLY, 0x43, DATA_ONLY, 0x46,
+
+ 0xC0, 0x01,
+
+ ENDDEF, 0x00
+};
+
+static const unsigned short *ACL_cutoff_set[] = {
+ SEQ_ACL_OFF,
+ SEQ_ACL_40P,
+ SEQ_ACL_50P,
+};
+
+#endif
diff --git a/arch/arm/mach-exynos/u1-panel_a2.c b/arch/arm/mach-exynos/u1-panel_a2.c
new file mode 100644
index 0000000..d36ff8a
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-panel_a2.c
@@ -0,0 +1,1668 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ld9040.h>
+#include "u1-panel.h"
+
+
+static const unsigned short SEQ_SM2_ELVSS_44[] = {
+ 0xB2, 0x15,
+
+ DATA_ONLY, 0x15,
+ DATA_ONLY, 0x15,
+ DATA_ONLY, 0x15,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_37[] = {
+ 0xB2, 0x1C,
+
+ DATA_ONLY, 0x1C,
+ DATA_ONLY, 0x1C,
+ DATA_ONLY, 0x1C,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_34[] = {
+ 0xB2, 0x1F,
+
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ DATA_ONLY, 0x1F,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_SM2_ELVSS_30[] = {
+ 0xB2, 0x23,
+
+ DATA_ONLY, 0x23,
+ DATA_ONLY, 0x23,
+ DATA_ONLY, 0x23,
+ ENDDEF, 0x00
+};
+
+static const unsigned short *SEQ_SM2_ELVSS_set[] = {
+ SEQ_SM2_ELVSS_30,
+ SEQ_SM2_ELVSS_34,
+ SEQ_SM2_ELVSS_37,
+ SEQ_SM2_ELVSS_44,
+};
+
+
+static const unsigned short SEQ_PWR_CTRL_SM2_A2[] = {
+ 0xF4, 0x0A,
+
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0x25,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x44,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", SM2 A2 Panel Gamma Data */
+static const unsigned short ld9040_sm2_a2_22_300[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_290[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_280[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_270[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC4,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_260[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_250[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_240[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_230[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_220[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB4,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_210[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x94,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_200[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_190[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_180[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_170[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_160[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9D,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_150[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA1,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9B,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_140[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x97,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_130[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x93,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_120[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x77,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x9D,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_110[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x73,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_100[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x70,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_90[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x80,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_80[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x67,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7A,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7B,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_70[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x62,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x94,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x75,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_60[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5C,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_50[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x57,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x68,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x68,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_40[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0x9D,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x50,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_22_30_dimming[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x48,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x7A,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x57,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_300[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_290[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_280[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_270[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA6,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_260[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9D,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_250[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9A,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBD,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_240[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA8,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_230[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_220[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB3,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_210[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8E,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_200[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_190[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_180[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA4,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_170[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_160[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_150[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x93,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x97,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_140[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x77,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8F,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x92,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_130[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x73,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8D,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_120[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_110[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x84,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_100[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x66,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAD,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_90[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x61,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x77,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_80[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x72,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_70[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6B,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_60[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x50,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x64,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x65,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_50[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4A,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5C,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5D,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_40[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x42,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xA4,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x53,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x53,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_sm2_a2_19_30_dimming[] = {
+ 0xF9, 0x0C,
+ DATA_ONLY, 0xB0,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x38,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x49,
+ DATA_ONLY, 0x0C,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x48,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+/* LD9040, 4.27", SM2 A2 Panel Gamma Table */
+static const unsigned short *psm2_a2_22Gamma_set[] = {
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
+ ld9040_sm2_a2_22_50,
+ ld9040_sm2_a2_22_60,
+#else
+ ld9040_sm2_a2_22_30_dimming,
+ ld9040_sm2_a2_22_40,
+#endif
+ ld9040_sm2_a2_22_70,
+ ld9040_sm2_a2_22_90,
+ ld9040_sm2_a2_22_100,
+ ld9040_sm2_a2_22_110,
+ ld9040_sm2_a2_22_120,
+ ld9040_sm2_a2_22_130,
+ ld9040_sm2_a2_22_140,
+ ld9040_sm2_a2_22_150,
+ ld9040_sm2_a2_22_160,
+ ld9040_sm2_a2_22_170,
+ ld9040_sm2_a2_22_180,
+ ld9040_sm2_a2_22_190,
+ ld9040_sm2_a2_22_200,
+ ld9040_sm2_a2_22_210,
+ ld9040_sm2_a2_22_220,
+ ld9040_sm2_a2_22_230,
+ ld9040_sm2_a2_22_240,
+ ld9040_sm2_a2_22_250,
+ ld9040_sm2_a2_22_300,
+};
+
+static const unsigned short *psm2_a2_19Gamma_set[] = {
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
+ ld9040_sm2_a2_19_50,
+ ld9040_sm2_a2_19_60,
+#else
+ ld9040_sm2_a2_19_30_dimming,
+ ld9040_sm2_a2_19_40,
+#endif
+ ld9040_sm2_a2_19_70,
+ ld9040_sm2_a2_19_90,
+ ld9040_sm2_a2_19_100,
+ ld9040_sm2_a2_19_110,
+ ld9040_sm2_a2_19_120,
+ ld9040_sm2_a2_19_130,
+ ld9040_sm2_a2_19_140,
+ ld9040_sm2_a2_19_150,
+ ld9040_sm2_a2_19_160,
+ ld9040_sm2_a2_19_170,
+ ld9040_sm2_a2_19_180,
+ ld9040_sm2_a2_19_190,
+ ld9040_sm2_a2_19_200,
+ ld9040_sm2_a2_19_210,
+ ld9040_sm2_a2_19_220,
+ ld9040_sm2_a2_19_230,
+ ld9040_sm2_a2_19_240,
+ ld9040_sm2_a2_19_250,
+ ld9040_sm2_a2_19_300,
+};
+
+struct ld9040_panel_data u1_panel_data_a2 = {
+ .seq_user_set = SEQ_USER_SETTING,
+ .seq_displayctl_set = SEQ_DISPCTL,
+ .seq_gtcon_set = SEQ_GTCON,
+ .seq_panelcondition_set = SEQ_PANEL_CONDITION,
+ .seq_pwrctl_set = SEQ_PWR_CTRL_SM2_A2,
+ .display_on = SEQ_DISPON,
+ .display_off = SEQ_DISPOFF,
+ .sleep_in = SEQ_SLPIN,
+ .sleep_out = SEQ_SLPOUT,
+ .acl_on = SEQ_ACL_ON,
+ .acl_table = ACL_cutoff_set,
+ .elvss_on = SEQ_ELVSS_ON,
+ .elvss_table = SEQ_SM2_ELVSS_set,
+ .gamma19_table = psm2_a2_19Gamma_set,
+ .gamma22_table = psm2_a2_22Gamma_set,
+ .lcdtype = LCDTYPE_SM2_A2,
+};
+
diff --git a/arch/arm/mach-exynos/u1-panel_m2.c b/arch/arm/mach-exynos/u1-panel_m2.c
new file mode 100644
index 0000000..954c5a6
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-panel_m2.c
@@ -0,0 +1,1660 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ld9040.h>
+#include "u1-panel.h"
+
+
+static const unsigned short SEQ_ELVSS_49[] = {
+ 0xB2, 0x10,
+
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ DATA_ONLY, 0x10,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_41[] = {
+ 0xB2, 0x17,
+
+ DATA_ONLY, 0x17,
+ DATA_ONLY, 0x17,
+ DATA_ONLY, 0x17,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_39[] = {
+ 0xB2, 0x1A,
+
+ DATA_ONLY, 0x1A,
+ DATA_ONLY, 0x1A,
+ DATA_ONLY, 0x1A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short SEQ_ELVSS_35[] = {
+ 0xB2, 0x1E,
+
+ DATA_ONLY, 0x1E,
+ DATA_ONLY, 0x1E,
+ DATA_ONLY, 0x1E,
+ ENDDEF, 0x00
+};
+
+static const unsigned short *SEQ_ELVSS_set[] = {
+ SEQ_ELVSS_35,
+ SEQ_ELVSS_39,
+ SEQ_ELVSS_41,
+ SEQ_ELVSS_49,
+};
+
+
+static const unsigned short SEQ_PWR_CTRL[] = {
+ 0xF4, 0x0A,
+
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x25,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x44,
+ DATA_ONLY, 0x02,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", M2 Panel Gamma Data : Useless - too old */
+static const unsigned short ld9040_22_300[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xDF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_290[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xDE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_280[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xDA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_270[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD6,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_260[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xB4,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_250[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD2,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_240[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9E,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_230[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_220[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x98,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_210[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x95,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_200[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x92,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC0,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_190[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBC,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_180[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB8,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_170[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB3,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_160[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_150[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_140[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA6,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_130[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x97,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_120[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x77,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x92,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_110[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8D,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x98,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_100[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x88,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x92,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_90[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_80[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x65,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x85,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_70[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x60,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x76,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_60[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_50[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x55,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x71,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_40[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD9,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB5,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x61,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_22_30_dimming[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD9,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x46,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB1,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xD9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x58,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_300[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xDE,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_290[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xB8,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xDF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_280[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xB9,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xDC,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_270[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD9,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_260[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD6,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_250[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD2,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_240[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_230[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9C,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xBC,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_220[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xBF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC6,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_210[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xBD,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_200[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x93,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xBE,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_190[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x90,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xBB,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_180[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8D,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB7,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_170[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x89,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xB2,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_160[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC2,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xC0,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAF,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_150[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x82,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xAA,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_140[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7E,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC4,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x99,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xC1,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA5,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_130[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7B,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x96,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xA1,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_120[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x77,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x9B,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_110[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x74,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8C,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x97,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_100[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x87,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x91,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_90[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x6A,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC8,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x81,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xC5,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x8B,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_80[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x66,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7C,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xC7,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x86,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_70[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD7,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x61,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x77,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xC9,
+ DATA_ONLY, 0xD6,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x7F,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_60[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD9,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCD,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5D,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xCB,
+ DATA_ONLY, 0xD9,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x70,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xD0,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x78,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_50[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xD8,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xDB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x56,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xCA,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xDB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x69,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xCC,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x70,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_40[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xDA,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xD1,
+ DATA_ONLY, 0xDC,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x4F,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC6,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xDB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x61,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCE,
+ DATA_ONLY, 0xDB,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x68,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+static const unsigned short ld9040_19_30_dimming[] = {
+ 0xF9, 0x00,
+ DATA_ONLY, 0xDC,
+ DATA_ONLY, 0xD5,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xDE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x46,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xC3,
+ DATA_ONLY, 0xD2,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xDE,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x58,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0xD3,
+ DATA_ONLY, 0xD4,
+ DATA_ONLY, 0xCF,
+ DATA_ONLY, 0xDD,
+ DATA_ONLY, 0x00,
+ DATA_ONLY, 0x5E,
+ 0xFB, 0x02,
+ DATA_ONLY, 0x5A,
+ ENDDEF, 0x00
+};
+
+
+/* LD9040, 4.27", SM2 M2 Panel Gamma Table : Useless - too old */
+static const unsigned short *p22Gamma_set[] = {
+ ld9040_22_30_dimming,
+ ld9040_22_40,
+ ld9040_22_70,
+ ld9040_22_90,
+ ld9040_22_100,
+ ld9040_22_110,
+ ld9040_22_120,
+ ld9040_22_130,
+ ld9040_22_140,
+ ld9040_22_150,
+ ld9040_22_160,
+ ld9040_22_170,
+ ld9040_22_180,
+ ld9040_22_190,
+ ld9040_22_200,
+ ld9040_22_210,
+ ld9040_22_220,
+ ld9040_22_230,
+ ld9040_22_240,
+ ld9040_22_250,
+ ld9040_22_300,
+};
+
+static const unsigned short *p19Gamma_set[] = {
+ ld9040_19_30_dimming,
+ ld9040_19_40,
+ ld9040_19_70,
+ ld9040_19_90,
+ ld9040_19_100,
+ ld9040_19_110,
+ ld9040_19_120,
+ ld9040_19_130,
+ ld9040_19_140,
+ ld9040_19_150,
+ ld9040_19_160,
+ ld9040_19_170,
+ ld9040_19_180,
+ ld9040_19_190,
+ ld9040_19_200,
+ ld9040_19_210,
+ ld9040_19_220,
+ ld9040_19_230,
+ ld9040_19_240,
+ ld9040_19_250,
+ ld9040_19_300,
+};
+
+
+struct ld9040_panel_data u1_panel_data_m2 = {
+ .seq_user_set = SEQ_USER_SETTING,
+ .seq_displayctl_set = SEQ_DISPCTL,
+ .seq_gtcon_set = SEQ_GTCON,
+ .seq_panelcondition_set = SEQ_PANEL_CONDITION,
+ .seq_pwrctl_set = SEQ_PWR_CTRL,
+ .display_on = SEQ_DISPON,
+ .display_off = SEQ_DISPOFF,
+ .sleep_in = SEQ_SLPIN,
+ .sleep_out = SEQ_SLPOUT,
+ .acl_on = SEQ_ACL_ON,
+ .acl_table = ACL_cutoff_set,
+ .elvss_on = SEQ_ELVSS_ON,
+ .elvss_table = SEQ_ELVSS_set,
+ .gamma19_table = p19Gamma_set,
+ .gamma22_table = p22Gamma_set,
+ .lcdtype = LCDTYPE_M2,
+};
+
diff --git a/arch/arm/mach-exynos/u1-wlan.c b/arch/arm/mach-exynos/u1-wlan.c
new file mode 100644
index 0000000..c570fc8
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-wlan.c
@@ -0,0 +1,329 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/skbuff.h>
+#include <linux/wlan_plat.h>
+
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+
+#define WLAN_STATIC_SCAN_BUF0 5
+#define WLAN_STATIC_SCAN_BUF1 6
+#define PREALLOC_WLAN_SEC_NUM 4
+#define PREALLOC_WLAN_BUF_NUM 160
+#define PREALLOC_WLAN_SECTION_HEADER 24
+
+#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512)
+#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024)
+
+#define DHD_SKB_HDRSIZE 336
+#define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
+
+#define WLAN_SKB_BUF_NUM 17
+
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
+
+struct wlan_mem_prealloc {
+ void *mem_ptr;
+ unsigned long size;
+};
+
+static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
+ {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
+ {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
+};
+
+void *wlan_static_scan_buf0;
+void *wlan_static_scan_buf1;
+static void *brcm_wlan_mem_prealloc(int section, unsigned long size)
+{
+ if (section == PREALLOC_WLAN_SEC_NUM)
+ return wlan_static_skb;
+ if (section == WLAN_STATIC_SCAN_BUF0)
+ return wlan_static_scan_buf0;
+ if (section == WLAN_STATIC_SCAN_BUF1)
+ return wlan_static_scan_buf1;
+ if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM))
+ return NULL;
+
+ if (wlan_mem_array[section].size < size)
+ return NULL;
+
+ return wlan_mem_array[section].mem_ptr;
+}
+
+static int brcm_init_wlan_mem(void)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 8; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ for (; i < 16; i++) {
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+ }
+
+ wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE);
+ if (!wlan_static_skb[i])
+ goto err_skb_alloc;
+
+ for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) {
+ wlan_mem_array[i].mem_ptr =
+ kmalloc(wlan_mem_array[i].size, GFP_KERNEL);
+
+ if (!wlan_mem_array[i].mem_ptr)
+ goto err_mem_alloc;
+ }
+ wlan_static_scan_buf0 = kmalloc(65536, GFP_KERNEL);
+ if (!wlan_static_scan_buf0)
+ goto err_mem_alloc;
+ wlan_static_scan_buf1 = kmalloc(65536, GFP_KERNEL);
+ if (!wlan_static_scan_buf1)
+ goto err_mem_alloc;
+ printk(KERN_INFO"%s: WIFI MEM Allocated\n", __func__);
+ return 0;
+
+ err_mem_alloc:
+ pr_err("Failed to mem_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ kfree(wlan_mem_array[j].mem_ptr);
+
+ i = WLAN_SKB_BUF_NUM;
+
+ err_skb_alloc:
+ pr_err("Failed to skb_alloc for WLAN\n");
+ for (j = 0 ; j < i ; j++)
+ dev_kfree_skb(wlan_static_skb[j]);
+
+ return -ENOMEM;
+}
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+
+static unsigned int wlan_on_gpio_table[][4] = {
+ {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_HIGH, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_HOST_WAKE, GPIO_WLAN_HOST_WAKE_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int wlan_off_gpio_table[][4] = {
+ {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_HOST_WAKE, 0 , GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN},
+};
+
+static unsigned int wlan_sdio_on_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, GPIO_WLAN_SDIO_CLK_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, GPIO_WLAN_SDIO_CMD_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, GPIO_WLAN_SDIO_D0_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, GPIO_WLAN_SDIO_D1_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, GPIO_WLAN_SDIO_D2_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, GPIO_WLAN_SDIO_D3_AF,
+ GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static unsigned int wlan_sdio_off_table[][4] = {
+ {GPIO_WLAN_SDIO_CLK, 1, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+ {GPIO_WLAN_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE},
+};
+
+static void s3c_config_gpio_alive_table
+(int array_size, unsigned int
+(*gpio_table)[4])
+{
+ u32 i, gpio;
+ printk(KERN_INFO"gpio_table = [%d] \r\n" , array_size);
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1]));
+ s3c_gpio_setpull(gpio, gpio_table[i][3]);
+ if (gpio_table[i][2] != GPIO_LEVEL_NONE)
+ gpio_set_value(gpio, gpio_table[i][2]);
+ }
+}
+
+static int brcm_wlan_power(int onoff)
+{
+ printk(KERN_INFO"------------------------------------------------");
+ printk(KERN_INFO"------------------------------------------------\n");
+ printk(KERN_INFO"%s Enter: power %s\n", __func__, onoff ? "on" : "off");
+ if (onoff) {
+ s3c_config_gpio_alive_table
+ (ARRAY_SIZE(wlan_on_gpio_table), wlan_on_gpio_table);
+ udelay(200);
+ gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_HIGH);
+ printk(KERN_DEBUG"WLAN: GPIO_WLAN_EN = %d\n",
+ gpio_get_value(GPIO_WLAN_EN));
+ } else {
+ gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_LOW);
+ s3c_config_gpio_alive_table
+ (ARRAY_SIZE(wlan_off_gpio_table), wlan_off_gpio_table);
+ printk(KERN_DEBUG"WLAN: GPIO_WLAN_EN = %d\n",
+ gpio_get_value(GPIO_WLAN_EN));
+ }
+
+ return 0;
+}
+
+static int brcm_wlan_reset(int onoff)
+{
+ gpio_set_value(GPIO_WLAN_EN,
+ onoff ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW);
+ return 0;
+}
+
+static int brcm_wlan_set_carddetect(int onoff)
+{
+ if (onoff) {
+ s3c_config_gpio_alive_table(
+ARRAY_SIZE(wlan_sdio_on_table), wlan_sdio_on_table);
+ } else {
+ s3c_config_gpio_alive_table(
+ARRAY_SIZE(wlan_sdio_off_table), wlan_sdio_off_table); }
+
+ udelay(200);
+
+ mmc_force_presence_change(&s3c_device_hsmmc3);
+ msleep(500); /* wait for carddetect */
+ return 0;
+}
+
+/* Customized Locale table : OPTIONAL feature */
+#define WLC_CNTRY_BUF_SZ 4
+struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ];
+ char custom_locale[WLC_CNTRY_BUF_SZ];
+ int custom_locale_rev;
+};
+
+static struct cntry_locales_custom brcm_wlan_translate_custom_table[] = {
+ /* Table should be filled out based
+ on custom platform regulatory requirement */
+ {"", "XY", 4}, /* universal */
+ {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
+ {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
+ {"EU", "EU", 5}, /* European union countries */
+ {"AT", "EU", 5},
+ {"BE", "EU", 5},
+ {"BG", "EU", 5},
+ {"CY", "EU", 5},
+ {"CZ", "EU", 5},
+ {"DK", "EU", 5},
+ {"EE", "EU", 5},
+ {"FI", "EU", 5},
+ {"FR", "EU", 5},
+ {"DE", "EU", 5},
+ {"GR", "EU", 5},
+ {"HU", "EU", 5},
+ {"IE", "EU", 5},
+ {"IT", "EU", 5},
+ {"LV", "EU", 5},
+ {"LI", "EU", 5},
+ {"LT", "EU", 5},
+ {"LU", "EU", 5},
+ {"MT", "EU", 5},
+ {"NL", "EU", 5},
+ {"PL", "EU", 5},
+ {"PT", "EU", 5},
+ {"RO", "EU", 5},
+ {"SK", "EU", 5},
+ {"SI", "EU", 5},
+ {"ES", "EU", 5},
+ {"SE", "EU", 5},
+ {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */
+ {"IL", "IL", 0},
+ {"CH", "CH", 0},
+ {"TR", "TR", 0},
+ {"NO", "NO", 0},
+ {"KR", "XY", 3},
+ {"AU", "XY", 3},
+ {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
+ {"TW", "XY", 3},
+ {"AR", "XY", 3},
+ {"MX", "XY", 3}
+};
+
+static void *brcm_wlan_get_country_code(char *ccode)
+{
+ int size = ARRAY_SIZE(brcm_wlan_translate_custom_table);
+ int i;
+
+ if (!ccode)
+ return NULL;
+
+ for (i = 0; i < size; i++)
+ if (strcmp(ccode,
+ brcm_wlan_translate_custom_table[i].iso_abbrev) == 0)
+ return &brcm_wlan_translate_custom_table[i];
+ return &brcm_wlan_translate_custom_table[0];
+}
+
+static struct resource brcm_wlan_resources[] = {
+ [0] = {
+ .name = "bcmdhd_wlan_irq",
+ .start = IRQ_EINT(21),
+ .end = IRQ_EINT(21),
+#ifdef CONFIG_MACH_Q1_BD
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
+#else
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+#endif
+ },
+};
+
+static struct wifi_platform_data brcm_wlan_control = {
+ .set_power = brcm_wlan_power,
+ .set_reset = brcm_wlan_reset,
+ .set_carddetect = brcm_wlan_set_carddetect,
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+ .mem_prealloc = brcm_wlan_mem_prealloc,
+#endif
+ .get_country_code = brcm_wlan_get_country_code,
+};
+
+static struct platform_device brcm_device_wlan = {
+ .name = "bcmdhd_wlan",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(brcm_wlan_resources),
+ .resource = brcm_wlan_resources,
+ .dev = {
+ .platform_data = &brcm_wlan_control,
+ },
+};
+
+int __init brcm_wlan_init(void)
+{
+ printk(KERN_INFO"%s: start\n", __func__);
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+ brcm_init_wlan_mem();
+#endif
+
+ return platform_device_register(&brcm_device_wlan);
+}
diff --git a/arch/arm/mach-exynos/u1.h b/arch/arm/mach-exynos/u1.h
new file mode 100644
index 0000000..d77e440
--- /dev/null
+++ b/arch/arm/mach-exynos/u1.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-s5pv210/u1.h
+ */
+
+#ifndef __U1_H__
+#define __U1_H__
+
+extern struct ld9040_panel_data u1_panel_data;
+extern struct ld9040_panel_data u1_panel_data_a2;
+extern struct ld9040_panel_data u1_panel_data_m2;
+
+extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config);
+extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config);
+
+extern void u1_config_gpio_table(void);
+extern void u1_config_sleep_gpio_table(void);
+
+extern int brcm_wlan_init(void);
+extern void set_gps_uart_op(int onoff);
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+extern int u1_switch_get_usb_lock_state(void);
+#endif
+
+#endif
diff --git a/arch/arm/mach-exynos/u1_regulator_consumer.c b/arch/arm/mach-exynos/u1_regulator_consumer.c
new file mode 100644
index 0000000..e142235
--- /dev/null
+++ b/arch/arm/mach-exynos/u1_regulator_consumer.c
@@ -0,0 +1,147 @@
+/* u1-regulator-consumer.c
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+
+static int u1_enable_regulator_for_usb_mipi(bool enable)
+{
+ struct regulator *mipi11_regulator;
+ struct regulator *mipi18_regulator;
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ struct regulator *hsic12_regulator;
+#endif
+ struct regulator *usb33_regulator;
+ int ret = 0;
+
+ mipi11_regulator = regulator_get(NULL, "vmipi_1.1v");
+ if (IS_ERR(mipi11_regulator)) {
+ pr_err("%s: failed to get %s\n", __func__, "vmipi_1.1v");
+ ret = -ENODEV;
+ goto out4;
+ }
+
+ mipi18_regulator = regulator_get(NULL, "vmipi_1.8v");
+ if (IS_ERR(mipi18_regulator)) {
+ pr_err("%s: failed to get %s\n", __func__, "vmipi_1.8v");
+ ret = -ENODEV;
+ goto out3;
+ }
+
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ hsic12_regulator = regulator_get(NULL, "vhsic");
+ if (IS_ERR(hsic12_regulator)) {
+ pr_err("%s: failed to get %s\n", __func__, "vhsic 1.2v");
+ ret = -ENODEV;
+ goto out2;
+ }
+#endif
+
+ usb33_regulator = regulator_get(NULL, "vusb_3.3v");
+ if (IS_ERR(usb33_regulator)) {
+ pr_err("%s: failed to get %s\n", __func__, "vusb_3.3v");
+ ret = -ENODEV;
+ goto out1;
+ }
+
+ if (enable) {
+ /* Power On Sequence
+ * MIPI 1.1V -> HSIC 1.2V -> MIPI 1.8V -> USB 3.3V
+ */
+ pr_info("%s: enable LDOs\n", __func__);
+ if (!regulator_is_enabled(mipi11_regulator))
+ regulator_enable(mipi11_regulator);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ if (!regulator_is_enabled(hsic12_regulator))
+ regulator_enable(hsic12_regulator);
+#endif
+ if (!regulator_is_enabled(mipi18_regulator))
+ regulator_enable(mipi18_regulator);
+ if (!regulator_is_enabled(usb33_regulator))
+ regulator_enable(usb33_regulator);
+ } else {
+ /* Power Off Sequence
+ * USB 3.3V -> MIPI 18V -> HSIC 1.2V -> MIPI 1.1V
+ */
+ pr_info("%s: disable LDOs\n", __func__);
+ regulator_force_disable(usb33_regulator);
+ regulator_force_disable(mipi18_regulator);
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ regulator_force_disable(hsic12_regulator);
+#endif
+ regulator_force_disable(mipi11_regulator);
+ }
+
+ regulator_put(usb33_regulator);
+out1:
+#ifndef CONFIG_MACH_U1_KOR_LGT
+ regulator_put(hsic12_regulator);
+#endif
+out2:
+ regulator_put(mipi18_regulator);
+out3:
+ regulator_put(mipi11_regulator);
+out4:
+ return ret;
+}
+
+
+static int regulator_consumer_probe(struct platform_device *pdev)
+{
+ pr_info("%s: loading u1-regulator-consumer\n", __func__);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int regulator_consumer_suspend(struct device *dev)
+{
+ u1_enable_regulator_for_usb_mipi(false);
+ return 0;
+}
+
+static int regulator_consumer_resume(struct device *dev)
+{
+ u1_enable_regulator_for_usb_mipi(true);
+ return 0;
+}
+#else
+#define regulator_consumer_suspend NULL
+#define regulator_consumer_resume NULL
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops regulator_consumer_pm_ops = {
+ .suspend = regulator_consumer_suspend,
+ .resume = regulator_consumer_resume,
+};
+
+static struct platform_driver regulator_consumer_driver = {
+ .probe = regulator_consumer_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "u1-regulator-consumer",
+ .pm = &regulator_consumer_pm_ops,
+ },
+};
+
+static int __init regulator_consumer_init(void)
+{
+ return platform_driver_register(&regulator_consumer_driver);
+}
+module_init(regulator_consumer_init);
+
+MODULE_DESCRIPTION("U1 regulator consumer driver");
+MODULE_AUTHOR("ms925.kim@samsung.com");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos/u1camera-gpio.c b/arch/arm/mach-exynos/u1camera-gpio.c
new file mode 100644
index 0000000..b00b6c5
--- /dev/null
+++ b/arch/arm/mach-exynos/u1camera-gpio.c
@@ -0,0 +1,439 @@
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <mach/gpio.h>
+#include "u1.h"
+
+struct gpio_init_data {
+ uint num;
+ uint cfg;
+ uint val;
+ uint pud;
+ uint drv;
+};
+
+static struct gpio_init_data u1_init_gpios[] = {
+ {EXYNOS4_GPC1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SDA_1.8V */
+ {EXYNOS4_GPC1(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* CODEC_SCL_1.8V */
+
+ {EXYNOS4_GPD0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MHL_SDA_2.8V */
+ {EXYNOS4_GPD0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* MHL_SCL_2.8V */
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* 8M_CAM_SDA_2.8V */
+ {EXYNOS4_GPD1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* 8M_CAM_SCL_2.8V */
+ {EXYNOS4_GPD1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SENSE_SDA_2.8V */
+ {EXYNOS4_GPD1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* SENSE_SCL_2.8V */
+
+ {EXYNOS4_GPK3(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_CMD */
+ {EXYNOS4_GPK3(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(0) */
+ {EXYNOS4_GPK3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(1) */
+ {EXYNOS4_GPK3(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(2) */
+ {EXYNOS4_GPK3(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* WLAN_SDIO_D(3) */
+
+ {EXYNOS4_GPX0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_UP */
+ {EXYNOS4_GPX0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* VOL_DOWN */
+ {EXYNOS4_GPX0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_BOOT_MODE */
+
+ {EXYNOS4_GPX2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_FUEL_ALERT */
+
+ {EXYNOS4_GPX3(1), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX3(2), S3C_GPIO_SFN(GPIO_DET_35_AF), S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1}, /* GPIO_DET_35 */
+ {EXYNOS4_GPX3(3), S3C_GPIO_OUTPUT, S3C_GPIO_SETPIN_ZERO,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPX3(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_NONE, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY0(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY1(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1,},
+ {EXYNOS4_GPY2(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY2(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY3(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY4(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY4(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY4(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY4(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY5(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(1), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(2), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(3), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(4), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(5), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(6), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+ {EXYNOS4_GPY6(7), S3C_GPIO_INPUT, S3C_GPIO_SETPIN_NONE,
+ S3C_GPIO_PULL_DOWN, S5P_GPIO_DRVSTR_LV1},
+};
+
+/* this table only for GC1 board */
+static unsigned int u1_sleep_gpio_table[][3] = {
+ {EXYNOS4_GPA0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPA1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPA1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPA1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPA1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPB(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPB(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPB(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPC0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPC1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPD1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE0(4), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE1(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPE2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPE2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4210_GPE4(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPE4(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF0(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF1(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF1(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF2(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPF3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPF3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPF3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPJ0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ0(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4210_GPJ1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4210_GPJ1(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4210_GPJ1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPK0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPK2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+
+ {EXYNOS4_GPK3(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPK3(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPK3(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL0(6), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL0(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL1(2), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPL2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPL2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPL2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPL2(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(1), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY3(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ {EXYNOS4_GPY3(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(6), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY3(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+
+ {EXYNOS4_GPY4(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(5), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPY4(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY4(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY5(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* TP */
+ {EXYNOS4_GPY5(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY5(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPY6(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPY6(7), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+
+ {EXYNOS4_GPZ(0), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(2), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(3), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(4), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
+ {EXYNOS4_GPZ(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+ {EXYNOS4_GPZ(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN}, /* NC */
+};
+
+void u1_config_gpio_table(void)
+{
+ u32 i, gpio;
+
+ for (i = 0; i < ARRAY_SIZE(u1_init_gpios); i++) {
+ gpio = u1_init_gpios[i].num;
+ s3c_gpio_cfgpin(gpio, u1_init_gpios[i].cfg);
+ s3c_gpio_setpull(gpio, u1_init_gpios[i].pud);
+
+ if (u1_init_gpios[i].val != S3C_GPIO_SETPIN_NONE)
+ gpio_set_value(gpio, u1_init_gpios[i].val);
+
+ s5p_gpio_set_drvstr(gpio, u1_init_gpios[i].drv);
+ }
+}
+
+static void config_sleep_gpio_table(int array_size,
+ unsigned int (*gpio_table)[3])
+{
+ u32 i, gpio;
+
+ for (i = 0; i < array_size; i++) {
+ gpio = gpio_table[i][0];
+ s3c_gpio_slp_cfgpin(gpio, gpio_table[i][1]);
+ s3c_gpio_slp_setpull_updown(gpio, gpio_table[i][2]);
+ }
+}
+
+void u1_config_sleep_gpio_table(void)
+{
+ config_sleep_gpio_table(ARRAY_SIZE(u1_sleep_gpio_table),
+ u1_sleep_gpio_table);
+}
diff --git a/arch/arm/mach-exynos/wakeup_assist.c b/arch/arm/mach-exynos/wakeup_assist.c
new file mode 100644
index 0000000..fe6d9d7
--- /dev/null
+++ b/arch/arm/mach-exynos/wakeup_assist.c
@@ -0,0 +1,110 @@
+/*
+ * Wakeup assist driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/regs-pmu.h>
+
+#define DEV_NAME "wakeup_assist"
+
+static int wakeup_assist_keycode[] = { KEY_POWER };
+
+static int __devinit wakeup_assist_probe(struct platform_device *pdev)
+{
+ int error;
+ struct input_dev *input_dev;
+
+ input_dev = input_allocate_device();
+
+ if (!input_dev)
+ return -ENOMEM;
+
+ input_dev->name = DEV_NAME;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->dev.parent = &pdev->dev;
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ input_dev->keycode = wakeup_assist_keycode;
+ input_dev->keycodesize = sizeof(wakeup_assist_keycode[0]);
+ input_dev->keycodemax = ARRAY_SIZE(wakeup_assist_keycode);
+
+ __set_bit(wakeup_assist_keycode[0], input_dev->keybit);
+ __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+ error = input_register_device(input_dev);
+ if (error) {
+ input_free_device(input_dev);
+ return error;
+ }
+
+ platform_set_drvdata(pdev, input_dev);
+
+ return 0;
+}
+
+static int __devexit wakeup_assist_remove(struct platform_device *pdev)
+{
+ struct input_dev *input_dev = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ input_unregister_device(input_dev);
+ input_free_device(input_dev);
+
+ return 0;
+}
+
+static int wakeup_assist_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct input_dev *input_dev = platform_get_drvdata(pdev);
+
+ if (readl(S5P_WAKEUP_STAT) & 0x1) {
+ input_report_key(input_dev, wakeup_assist_keycode[0], 0x2);
+ input_sync(input_dev);
+ input_report_key(input_dev, wakeup_assist_keycode[0], 0x0);
+ input_sync(input_dev);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops wakeup_assist_pm_ops = {
+ .resume = wakeup_assist_resume,
+};
+
+static struct platform_driver wakeup_assist_driver = {
+ .probe = wakeup_assist_probe,
+ .remove = __devexit_p(wakeup_assist_remove),
+ .driver = {
+ .name = DEV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &wakeup_assist_pm_ops,
+ },
+};
+
+static int __init wakeup_assist_init(void)
+{
+ return platform_driver_register(&wakeup_assist_driver);
+}
+module_init(wakeup_assist_init);
+
+static void __exit wakeup_assist_exit(void)
+{
+ platform_driver_unregister(&wakeup_assist_driver);
+}
+module_exit(wakeup_assist_exit);
+
+MODULE_DESCRIPTION("Wakeup assist driver");
+MODULE_AUTHOR("Eunki Kim <eunki_kim@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
deleted file mode 100644
index 1435fc3..0000000
--- a/arch/arm/mach-exynos4/Kconfig
+++ /dev/null
@@ -1,209 +0,0 @@
-# arch/arm/mach-exynos4/Kconfig
-#
-# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-# Configuration options for the EXYNOS4
-
-if ARCH_EXYNOS4
-
-config CPU_EXYNOS4210
- bool
- select S3C_PL330_DMA
- help
- Enable EXYNOS4210 CPU support
-
-config EXYNOS4_MCT
- bool "Kernel timer support by MCT"
- help
- Use MCT (Multi Core Timer) as kernel timers
-
-config EXYNOS4_DEV_AHCI
- bool
- help
- Compile in platform device definitions for AHCI
-
-config EXYNOS4_DEV_PD
- bool
- help
- Compile in platform device definitions for Power Domain
-
-config EXYNOS4_DEV_SYSMMU
- bool
- help
- Common setup code for SYSTEM MMU in EXYNOS4
-
-config EXYNOS4_SETUP_I2C1
- bool
- help
- Common setup code for i2c bus 1.
-
-config EXYNOS4_SETUP_I2C2
- bool
- help
- Common setup code for i2c bus 2.
-
-config EXYNOS4_SETUP_I2C3
- bool
- help
- Common setup code for i2c bus 3.
-
-config EXYNOS4_SETUP_I2C4
- bool
- help
- Common setup code for i2c bus 4.
-
-config EXYNOS4_SETUP_I2C5
- bool
- help
- Common setup code for i2c bus 5.
-
-config EXYNOS4_SETUP_I2C6
- bool
- help
- Common setup code for i2c bus 6.
-
-config EXYNOS4_SETUP_I2C7
- bool
- help
- Common setup code for i2c bus 7.
-
-config EXYNOS4_SETUP_KEYPAD
- bool
- help
- Common setup code for keypad.
-
-config EXYNOS4_SETUP_SDHCI
- bool
- select EXYNOS4_SETUP_SDHCI_GPIO
- help
- Internal helper functions for EXYNOS4 based SDHCI systems.
-
-config EXYNOS4_SETUP_SDHCI_GPIO
- bool
- help
- Common setup code for SDHCI gpio.
-
-config EXYNOS4_SETUP_FIMC
- bool
- help
- Common setup code for the camera interfaces.
-
-config EXYNOS4_SETUP_USB_PHY
- bool
- help
- Common setup code for USB PHY controller
-
-# machine support
-
-menu "EXYNOS4 Machines"
-
-config MACH_SMDKC210
- bool "SMDKC210"
- select CPU_EXYNOS4210
- select S3C_DEV_RTC
- select S3C_DEV_WDT
- select S3C_DEV_I2C1
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC1
- select S3C_DEV_HSMMC2
- select S3C_DEV_HSMMC3
- select EXYNOS4_DEV_PD
- select EXYNOS4_DEV_SYSMMU
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_SDHCI
- help
- Machine support for Samsung SMDKC210
-
-config MACH_SMDKV310
- bool "SMDKV310"
- select CPU_EXYNOS4210
- select S3C_DEV_RTC
- select S3C_DEV_WDT
- select S3C_DEV_I2C1
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC1
- select S3C_DEV_HSMMC2
- select S3C_DEV_HSMMC3
- select SAMSUNG_DEV_KEYPAD
- select EXYNOS4_DEV_PD
- select EXYNOS4_DEV_SYSMMU
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_KEYPAD
- select EXYNOS4_SETUP_SDHCI
- help
- Machine support for Samsung SMDKV310
-
-config MACH_ARMLEX4210
- bool "ARMLEX4210"
- select CPU_EXYNOS4210
- select S3C_DEV_RTC
- select S3C_DEV_WDT
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC2
- select S3C_DEV_HSMMC3
- select EXYNOS4_DEV_AHCI
- select EXYNOS4_DEV_SYSMMU
- select EXYNOS4_SETUP_SDHCI
- help
- Machine support for Samsung ARMLEX4210 based on EXYNOS4210
-
-config MACH_UNIVERSAL_C210
- bool "Mobile UNIVERSAL_C210 Board"
- select CPU_EXYNOS4210
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC2
- select S3C_DEV_HSMMC3
- select S3C_DEV_I2C1
- select S3C_DEV_I2C5
- select S5P_DEV_ONENAND
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_I2C5
- select EXYNOS4_SETUP_SDHCI
- help
- Machine support for Samsung Mobile Universal S5PC210 Reference
- Board.
-
-config MACH_NURI
- bool "Mobile NURI Board"
- select CPU_EXYNOS4210
- select S3C_DEV_WDT
- select S3C_DEV_HSMMC
- select S3C_DEV_HSMMC2
- select S3C_DEV_HSMMC3
- select S3C_DEV_I2C1
- select S3C_DEV_I2C3
- select S3C_DEV_I2C5
- select S5P_DEV_USB_EHCI
- select EXYNOS4_SETUP_I2C1
- select EXYNOS4_SETUP_I2C3
- select EXYNOS4_SETUP_I2C5
- select EXYNOS4_SETUP_SDHCI
- select EXYNOS4_SETUP_USB_PHY
- select SAMSUNG_DEV_PWM
- help
- Machine support for Samsung Mobile NURI Board.
-
-endmenu
-
-comment "Configuration for HSMMC bus width"
-
-menu "Use 8-bit bus width"
-
-config EXYNOS4_SDHCI_CH0_8BIT
- bool "Channel 0 with 8-bit bus"
- help
- Support HSMMC Channel 0 8-bit bus.
- If selected, Channel 1 is disabled.
-
-config EXYNOS4_SDHCI_CH2_8BIT
- bool "Channel 2 with 8-bit bus"
- help
- Support HSMMC Channel 2 8-bit bus.
- If selected, Channel 3 is disabled.
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
deleted file mode 100644
index 60fe5ec..0000000
--- a/arch/arm/mach-exynos4/Makefile
+++ /dev/null
@@ -1,59 +0,0 @@
-# arch/arm/mach-exynos4/Makefile
-#
-# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
-# http://www.samsung.com/
-#
-# Licensed under GPLv2
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-
-# Core support for EXYNOS4 system
-
-obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o irq-eint.o dma.o
-obj-$(CONFIG_PM) += pm.o sleep.o
-obj-$(CONFIG_CPU_FREQ) += cpufreq.o
-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
-
-obj-$(CONFIG_SMP) += platsmp.o headsmp.o
-
-ifeq ($(CONFIG_EXYNOS4_MCT),y)
-obj-y += mct.o
-else
-obj-y += time.o
-obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
-endif
-
-obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-
-# machine support
-
-obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
-obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
-obj-$(CONFIG_MACH_ARMLEX4210) += mach-armlex4210.o
-obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
-obj-$(CONFIG_MACH_NURI) += mach-nuri.o
-
-# device support
-
-obj-y += dev-audio.o
-obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
-obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
-obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
-
-obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C1) += setup-i2c1.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C2) += setup-i2c2.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C3) += setup-i2c3.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C4) += setup-i2c4.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C5) += setup-i2c5.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C6) += setup-i2c6.o
-obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
-obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
-obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
-obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
-
-obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY) += setup-usb-phy.o
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
deleted file mode 100644
index 871f9d5..0000000
--- a/arch/arm/mach-exynos4/clock.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-/* linux/arch/arm/mach-exynos4/clock.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/sysmmu.h>
-
-static struct clk clk_sclk_hdmi27m = {
- .name = "sclk_hdmi27m",
- .id = -1,
- .rate = 27000000,
-};
-
-static struct clk clk_sclk_hdmiphy = {
- .name = "sclk_hdmiphy",
- .id = -1,
-};
-
-static struct clk clk_sclk_usbphy0 = {
- .name = "sclk_usbphy0",
- .id = -1,
- .rate = 27000000,
-};
-
-static struct clk clk_sclk_usbphy1 = {
- .name = "sclk_usbphy1",
- .id = -1,
-};
-
-static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
-}
-
-static int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
-}
-
-static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
-}
-
-static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
-}
-
-static int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
-}
-
-static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
-{
- return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk clk_mout_apll = {
- .clk = {
- .name = "mout_apll",
- .id = -1,
- },
- .sources = &clk_src_apll,
- .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk clk_sclk_apll = {
- .clk = {
- .name = "sclk_apll",
- .id = -1,
- .parent = &clk_mout_apll.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 24, .size = 3 },
-};
-
-static struct clksrc_clk clk_mout_epll = {
- .clk = {
- .name = "mout_epll",
- .id = -1,
- },
- .sources = &clk_src_epll,
- .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk clk_mout_mpll = {
- .clk = {
- .name = "mout_mpll",
- .id = -1,
- },
- .sources = &clk_src_mpll,
- .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 8, .size = 1 },
-};
-
-static struct clk *clkset_moutcore_list[] = {
- [0] = &clk_mout_apll.clk,
- [1] = &clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clkset_moutcore = {
- .sources = clkset_moutcore_list,
- .nr_sources = ARRAY_SIZE(clkset_moutcore_list),
-};
-
-static struct clksrc_clk clk_moutcore = {
- .clk = {
- .name = "moutcore",
- .id = -1,
- },
- .sources = &clkset_moutcore,
- .reg_src = { .reg = S5P_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk clk_coreclk = {
- .clk = {
- .name = "core_clk",
- .id = -1,
- .parent = &clk_moutcore.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_armclk = {
- .clk = {
- .name = "armclk",
- .id = -1,
- .parent = &clk_coreclk.clk,
- },
-};
-
-static struct clksrc_clk clk_aclk_corem0 = {
- .clk = {
- .name = "aclk_corem0",
- .id = -1,
- .parent = &clk_coreclk.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_cores = {
- .clk = {
- .name = "aclk_cores",
- .id = -1,
- .parent = &clk_coreclk.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_corem1 = {
- .clk = {
- .name = "aclk_corem1",
- .id = -1,
- .parent = &clk_coreclk.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk clk_periphclk = {
- .clk = {
- .name = "periphclk",
- .id = -1,
- .parent = &clk_coreclk.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
-};
-
-/* Core list of CMU_CORE side */
-
-static struct clk *clkset_corebus_list[] = {
- [0] = &clk_mout_mpll.clk,
- [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_mout_corebus = {
- .sources = clkset_corebus_list,
- .nr_sources = ARRAY_SIZE(clkset_corebus_list),
-};
-
-static struct clksrc_clk clk_mout_corebus = {
- .clk = {
- .name = "mout_corebus",
- .id = -1,
- },
- .sources = &clkset_mout_corebus,
- .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk clk_sclk_dmc = {
- .clk = {
- .name = "sclk_dmc",
- .id = -1,
- .parent = &clk_mout_corebus.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_cored = {
- .clk = {
- .name = "aclk_cored",
- .id = -1,
- .parent = &clk_sclk_dmc.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_corep = {
- .clk = {
- .name = "aclk_corep",
- .id = -1,
- .parent = &clk_aclk_cored.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_acp = {
- .clk = {
- .name = "aclk_acp",
- .id = -1,
- .parent = &clk_mout_corebus.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_pclk_acp = {
- .clk = {
- .name = "pclk_acp",
- .id = -1,
- .parent = &clk_aclk_acp.clk,
- },
- .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-static struct clk *clkset_aclk_top_list[] = {
- [0] = &clk_mout_mpll.clk,
- [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_aclk = {
- .sources = clkset_aclk_top_list,
- .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
-};
-
-static struct clksrc_clk clk_aclk_200 = {
- .clk = {
- .name = "aclk_200",
- .id = -1,
- },
- .sources = &clkset_aclk,
- .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
- .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_100 = {
- .clk = {
- .name = "aclk_100",
- .id = -1,
- },
- .sources = &clkset_aclk,
- .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
- .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk clk_aclk_160 = {
- .clk = {
- .name = "aclk_160",
- .id = -1,
- },
- .sources = &clkset_aclk,
- .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
- .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk clk_aclk_133 = {
- .clk = {
- .name = "aclk_133",
- .id = -1,
- },
- .sources = &clkset_aclk,
- .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
- .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
-};
-
-static struct clk *clkset_vpllsrc_list[] = {
- [0] = &clk_fin_vpll,
- [1] = &clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources clkset_vpllsrc = {
- .sources = clkset_vpllsrc_list,
- .nr_sources = ARRAY_SIZE(clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk clk_vpllsrc = {
- .clk = {
- .name = "vpll_src",
- .id = -1,
- .enable = exynos4_clksrc_mask_top_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &clkset_vpllsrc,
- .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_sclk_vpll_list[] = {
- [0] = &clk_vpllsrc.clk,
- [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources clkset_sclk_vpll = {
- .sources = clkset_sclk_vpll_list,
- .nr_sources = ARRAY_SIZE(clkset_sclk_vpll_list),
-};
-
-static struct clksrc_clk clk_sclk_vpll = {
- .clk = {
- .name = "sclk_vpll",
- .id = -1,
- },
- .sources = &clkset_sclk_vpll,
- .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 8, .size = 1 },
-};
-
-static struct clk init_clocks_off[] = {
- {
- .name = "timers",
- .id = -1,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1<<24),
- }, {
- .name = "csis",
- .id = 0,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "csis",
- .id = 1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "fimc",
- .id = 0,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "fimc",
- .id = 1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "fimc",
- .id = 2,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "fimc",
- .id = 3,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "fimd",
- .id = 0,
- .enable = exynos4_clk_ip_lcd0_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "fimd",
- .id = 1,
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "sataphy",
- .id = -1,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "hsmmc",
- .id = 0,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "hsmmc",
- .id = 1,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "hsmmc",
- .id = 2,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "hsmmc",
- .id = 3,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "hsmmc",
- .id = 4,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "sata",
- .id = -1,
- .parent = &clk_aclk_133.clk,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "pdma",
- .id = 0,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "pdma",
- .id = 1,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "adc",
- .id = -1,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "keypad",
- .id = -1,
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "rtc",
- .id = -1,
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 15),
- }, {
- .name = "watchdog",
- .id = -1,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_perir_ctrl,
- .ctrlbit = (1 << 14),
- }, {
- .name = "usbhost",
- .id = -1,
- .enable = exynos4_clk_ip_fsys_ctrl ,
- .ctrlbit = (1 << 12),
- }, {
- .name = "otg",
- .id = -1,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 13),
- }, {
- .name = "spi",
- .id = 0,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 16),
- }, {
- .name = "spi",
- .id = 1,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 17),
- }, {
- .name = "spi",
- .id = 2,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 18),
- }, {
- .name = "iis",
- .id = 0,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 19),
- }, {
- .name = "iis",
- .id = 1,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 20),
- }, {
- .name = "iis",
- .id = 2,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 21),
- }, {
- .name = "ac97",
- .id = -1,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 27),
- }, {
- .name = "fimg2d",
- .id = -1,
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "i2c",
- .id = 0,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 6),
- }, {
- .name = "i2c",
- .id = 1,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "i2c",
- .id = 2,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "i2c",
- .id = 3,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "i2c",
- .id = 4,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "i2c",
- .id = 5,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = "i2c",
- .id = 6,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 12),
- }, {
- .name = "i2c",
- .id = 7,
- .parent = &clk_aclk_100.clk,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 13),
- }, {
- .name = "SYSMMU_MDMA",
- .id = -1,
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 5),
- }, {
- .name = "SYSMMU_FIMC0",
- .id = -1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 7),
- }, {
- .name = "SYSMMU_FIMC1",
- .id = -1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 8),
- }, {
- .name = "SYSMMU_FIMC2",
- .id = -1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 9),
- }, {
- .name = "SYSMMU_FIMC3",
- .id = -1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 10),
- }, {
- .name = "SYSMMU_JPEG",
- .id = -1,
- .enable = exynos4_clk_ip_cam_ctrl,
- .ctrlbit = (1 << 11),
- }, {
- .name = "SYSMMU_FIMD0",
- .id = -1,
- .enable = exynos4_clk_ip_lcd0_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_FIMD1",
- .id = -1,
- .enable = exynos4_clk_ip_lcd1_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_PCIe",
- .id = -1,
- .enable = exynos4_clk_ip_fsys_ctrl,
- .ctrlbit = (1 << 18),
- }, {
- .name = "SYSMMU_G2D",
- .id = -1,
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "SYSMMU_ROTATOR",
- .id = -1,
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_TV",
- .id = -1,
- .enable = exynos4_clk_ip_tv_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "SYSMMU_MFC_L",
- .id = -1,
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "SYSMMU_MFC_R",
- .id = -1,
- .enable = exynos4_clk_ip_mfc_ctrl,
- .ctrlbit = (1 << 2),
- }
-};
-
-static struct clk init_clocks[] = {
- {
- .name = "uart",
- .id = 0,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 0),
- }, {
- .name = "uart",
- .id = 1,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 1),
- }, {
- .name = "uart",
- .id = 2,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 2),
- }, {
- .name = "uart",
- .id = 3,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "uart",
- .id = 4,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 4),
- }, {
- .name = "uart",
- .id = 5,
- .enable = exynos4_clk_ip_peril_ctrl,
- .ctrlbit = (1 << 5),
- }
-};
-
-static struct clk *clkset_group_list[] = {
- [0] = &clk_ext_xtal_mux,
- [1] = &clk_xusbxti,
- [2] = &clk_sclk_hdmi27m,
- [3] = &clk_sclk_usbphy0,
- [4] = &clk_sclk_usbphy1,
- [5] = &clk_sclk_hdmiphy,
- [6] = &clk_mout_mpll.clk,
- [7] = &clk_mout_epll.clk,
- [8] = &clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources clkset_group = {
- .sources = clkset_group_list,
- .nr_sources = ARRAY_SIZE(clkset_group_list),
-};
-
-static struct clk *clkset_mout_g2d0_list[] = {
- [0] = &clk_mout_mpll.clk,
- [1] = &clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d0 = {
- .sources = clkset_mout_g2d0_list,
- .nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
-};
-
-static struct clksrc_clk clk_mout_g2d0 = {
- .clk = {
- .name = "mout_g2d0",
- .id = -1,
- },
- .sources = &clkset_mout_g2d0,
- .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
-static struct clk *clkset_mout_g2d1_list[] = {
- [0] = &clk_mout_epll.clk,
- [1] = &clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d1 = {
- .sources = clkset_mout_g2d1_list,
- .nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
-};
-
-static struct clksrc_clk clk_mout_g2d1 = {
- .clk = {
- .name = "mout_g2d1",
- .id = -1,
- },
- .sources = &clkset_mout_g2d1,
- .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *clkset_mout_g2d_list[] = {
- [0] = &clk_mout_g2d0.clk,
- [1] = &clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources clkset_mout_g2d = {
- .sources = clkset_mout_g2d_list,
- .nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
-};
-
-static struct clksrc_clk clk_dout_mmc0 = {
- .clk = {
- .name = "dout_mmc0",
- .id = -1,
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc1 = {
- .clk = {
- .name = "dout_mmc1",
- .id = -1,
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc2 = {
- .clk = {
- .name = "dout_mmc2",
- .id = -1,
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc3 = {
- .clk = {
- .name = "dout_mmc3",
- .id = -1,
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk clk_dout_mmc4 = {
- .clk = {
- .name = "dout_mmc4",
- .id = -1,
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk clksrcs[] = {
- {
- .clk = {
- .name = "uclk1",
- .id = 0,
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .id = 1,
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .id = 2,
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "uclk1",
- .id = 3,
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_pwm",
- .id = -1,
- .enable = exynos4_clksrc_mask_peril0_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_csis",
- .id = 0,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_csis",
- .id = 1,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 28),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_cam",
- .id = 0,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 16),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_cam",
- .id = 1,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 20),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .id = 0,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .id = 1,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 4),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .id = 2,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 8),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimc",
- .id = 3,
- .enable = exynos4_clksrc_mask_cam_ctrl,
- .ctrlbit = (1 << 12),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimd",
- .id = 0,
- .enable = exynos4_clksrc_mask_lcd0_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimd",
- .id = 1,
- .enable = exynos4_clksrc_mask_lcd1_ctrl,
- .ctrlbit = (1 << 0),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_sata",
- .id = -1,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &clkset_mout_corebus,
- .reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
- .reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .id = 0,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 16),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .id = 1,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 20),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_spi",
- .id = 2,
- .enable = exynos4_clksrc_mask_peril1_ctrl,
- .ctrlbit = (1 << 24),
- },
- .sources = &clkset_group,
- .reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
- .reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_fimg2d",
- .id = -1,
- },
- .sources = &clkset_mout_g2d,
- .reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
- .reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .id = 0,
- .parent = &clk_dout_mmc0.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 0),
- },
- .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .id = 1,
- .parent = &clk_dout_mmc1.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 4),
- },
- .reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .id = 2,
- .parent = &clk_dout_mmc2.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 8),
- },
- .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .id = 3,
- .parent = &clk_dout_mmc3.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 12),
- },
- .reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
- }, {
- .clk = {
- .name = "sclk_mmc",
- .id = 4,
- .parent = &clk_dout_mmc4.clk,
- .enable = exynos4_clksrc_mask_fsys_ctrl,
- .ctrlbit = (1 << 16),
- },
- .reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
- }
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *sysclks[] = {
- &clk_mout_apll,
- &clk_sclk_apll,
- &clk_mout_epll,
- &clk_mout_mpll,
- &clk_moutcore,
- &clk_coreclk,
- &clk_armclk,
- &clk_aclk_corem0,
- &clk_aclk_cores,
- &clk_aclk_corem1,
- &clk_periphclk,
- &clk_mout_corebus,
- &clk_sclk_dmc,
- &clk_aclk_cored,
- &clk_aclk_corep,
- &clk_aclk_acp,
- &clk_pclk_acp,
- &clk_vpllsrc,
- &clk_sclk_vpll,
- &clk_aclk_200,
- &clk_aclk_100,
- &clk_aclk_160,
- &clk_aclk_133,
- &clk_dout_mmc0,
- &clk_dout_mmc1,
- &clk_dout_mmc2,
- &clk_dout_mmc3,
- &clk_dout_mmc4,
-};
-
-static int xtal_rate;
-
-static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
-{
- return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508);
-}
-
-static struct clk_ops exynos4_fout_apll_ops = {
- .get_rate = exynos4_fout_apll_get_rate,
-};
-
-void __init_or_cpufreq exynos4_setup_clocks(void)
-{
- struct clk *xtal_clk;
- unsigned long apll;
- unsigned long mpll;
- unsigned long epll;
- unsigned long vpll;
- unsigned long vpllsrc;
- unsigned long xtal;
- unsigned long armclk;
- unsigned long sclk_dmc;
- unsigned long aclk_200;
- unsigned long aclk_100;
- unsigned long aclk_160;
- unsigned long aclk_133;
- unsigned int ptr;
-
- printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
- xtal_clk = clk_get(NULL, "xtal");
- BUG_ON(IS_ERR(xtal_clk));
-
- xtal = clk_get_rate(xtal_clk);
-
- xtal_rate = xtal;
-
- clk_put(xtal_clk);
-
- printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
- apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON0), pll_4508);
- mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON0), pll_4508);
- epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON0),
- __raw_readl(S5P_EPLL_CON1), pll_4600);
-
- vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
- vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0),
- __raw_readl(S5P_VPLL_CON1), pll_4650);
-
- clk_fout_apll.ops = &exynos4_fout_apll_ops;
- clk_fout_mpll.rate = mpll;
- clk_fout_epll.rate = epll;
- clk_fout_vpll.rate = vpll;
-
- printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
- apll, mpll, epll, vpll);
-
- armclk = clk_get_rate(&clk_armclk.clk);
- sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
-
- aclk_200 = clk_get_rate(&clk_aclk_200.clk);
- aclk_100 = clk_get_rate(&clk_aclk_100.clk);
- aclk_160 = clk_get_rate(&clk_aclk_160.clk);
- aclk_133 = clk_get_rate(&clk_aclk_133.clk);
-
- printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
- "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
- armclk, sclk_dmc, aclk_200,
- aclk_100, aclk_160, aclk_133);
-
- clk_f.rate = armclk;
- clk_h.rate = sclk_dmc;
- clk_p.rate = aclk_100;
-
- for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
- s3c_set_clksrc(&clksrcs[ptr], true);
-}
-
-static struct clk *clks[] __initdata = {
- /* Nothing here yet */
-};
-
-void __init exynos4_register_clocks(void)
-{
- int ptr;
-
- s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
-
- for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
- s3c_register_clksrc(sysclks[ptr], 1);
-
- s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
- s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
-
- s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
- s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
- s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
deleted file mode 100644
index bfd6214..0000000
--- a/arch/arm/mach-exynos4/cpu.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* linux/arch/arm/mach-exynos4/cpu.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/sched.h>
-#include <linux/sysdev.h>
-
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <asm/proc-fns.h>
-#include <asm/hardware/cache-l2x0.h>
-
-#include <plat/cpu.h>
-#include <plat/clock.h>
-#include <plat/exynos4.h>
-#include <plat/sdhci.h>
-#include <plat/devs.h>
-#include <plat/fimc-core.h>
-#include <plat/iic-core.h>
-
-#include <mach/regs-irq.h>
-
-extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
- unsigned int irq_start);
-extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
-
-/* Initial IO mappings */
-static struct map_desc exynos4_iodesc[] __initdata = {
- {
- .virtual = (unsigned long)S5P_VA_SYSTIMER,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_SYSRAM,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_CMU,
- .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
- .length = SZ_128K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_PMU,
- .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
- .length = SZ_64K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
- .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
- .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
- .length = SZ_8K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_L2CC,
- .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_GPIO1,
- .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO1),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_GPIO2,
- .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO2),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_GPIO3,
- .pfn = __phys_to_pfn(EXYNOS4_PA_GPIO3),
- .length = SZ_256,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_DMC0,
- .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_UART,
- .pfn = __phys_to_pfn(S3C_PA_UART),
- .length = SZ_512K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S5P_VA_SROMC,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }, {
- .virtual = (unsigned long)S3C_VA_USB_HSPHY,
- .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
- .length = SZ_4K,
- .type = MT_DEVICE,
- }
-};
-
-static void exynos4_idle(void)
-{
- if (!need_resched())
- cpu_do_idle();
-
- local_irq_enable();
-}
-
-/*
- * exynos4_map_io
- *
- * register the standard cpu IO areas
- */
-void __init exynos4_map_io(void)
-{
- iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-
- /* initialize device information early */
- exynos4_default_sdhci0();
- exynos4_default_sdhci1();
- exynos4_default_sdhci2();
- exynos4_default_sdhci3();
-
- s3c_fimc_setname(0, "exynos4-fimc");
- s3c_fimc_setname(1, "exynos4-fimc");
- s3c_fimc_setname(2, "exynos4-fimc");
- s3c_fimc_setname(3, "exynos4-fimc");
-
- /* The I2C bus controllers are directly compatible with s3c2440 */
- s3c_i2c0_setname("s3c2440-i2c");
- s3c_i2c1_setname("s3c2440-i2c");
- s3c_i2c2_setname("s3c2440-i2c");
-}
-
-void __init exynos4_init_clocks(int xtal)
-{
- printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
- s3c24xx_register_baseclocks(xtal);
- s5p_register_clocks(xtal);
- exynos4_register_clocks();
- exynos4_setup_clocks();
-}
-
-void __init exynos4_init_irq(void)
-{
- int irq;
-
- gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
-
- for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
-
- /*
- * From SPI(0) to SPI(39) and SPI(51), SPI(53) are
- * connected to the interrupt combiner. These irqs
- * should be initialized to support cascade interrupt.
- */
- if ((irq >= 40) && !(irq == 51) && !(irq == 53))
- continue;
-
- combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
- COMBINER_IRQ(irq, 0));
- combiner_cascade_irq(irq, IRQ_SPI(irq));
- }
-
- /* The parameters of s5p_init_irq() are for VIC init.
- * Theses parameters should be NULL and 0 because EXYNOS4
- * uses GIC instead of VIC.
- */
- s5p_init_irq(NULL, 0);
-}
-
-struct sysdev_class exynos4_sysclass = {
- .name = "exynos4-core",
-};
-
-static struct sys_device exynos4_sysdev = {
- .cls = &exynos4_sysclass,
-};
-
-static int __init exynos4_core_init(void)
-{
- return sysdev_class_register(&exynos4_sysclass);
-}
-
-core_initcall(exynos4_core_init);
-
-#ifdef CONFIG_CACHE_L2X0
-static int __init exynos4_l2x0_cache_init(void)
-{
- /* TAG, Data Latency Control: 2cycle */
- __raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
- __raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
-
- /* L2X0 Prefetch Control */
- __raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
-
- /* L2X0 Power Control */
- __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
- S5P_VA_L2CC + L2X0_POWER_CTRL);
-
- l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
-
- return 0;
-}
-
-early_initcall(exynos4_l2x0_cache_init);
-#endif
-
-int __init exynos4_init(void)
-{
- printk(KERN_INFO "EXYNOS4: Initializing architecture\n");
-
- /* set idle function */
- pm_idle = exynos4_idle;
-
- return sysdev_register(&exynos4_sysdev);
-}
diff --git a/arch/arm/mach-exynos4/cpufreq.c b/arch/arm/mach-exynos4/cpufreq.c
deleted file mode 100644
index a1bd258..0000000
--- a/arch/arm/mach-exynos4/cpufreq.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/* linux/arch/arm/mach-exynos4/cpufreq.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - CPU frequency scaling support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
-#include <linux/cpufreq.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-mem.h>
-
-#include <plat/clock.h>
-#include <plat/pm.h>
-
-static struct clk *cpu_clk;
-static struct clk *moutcore;
-static struct clk *mout_mpll;
-static struct clk *mout_apll;
-
-static struct regulator *arm_regulator;
-static struct regulator *int_regulator;
-
-static struct cpufreq_freqs freqs;
-static unsigned int memtype;
-
-enum exynos4_memory_type {
- DDR2 = 4,
- LPDDR2,
- DDR3,
-};
-
-enum cpufreq_level_index {
- L0, L1, L2, L3, CPUFREQ_LEVEL_END,
-};
-
-static struct cpufreq_frequency_table exynos4_freq_table[] = {
- {L0, 1000*1000},
- {L1, 800*1000},
- {L2, 400*1000},
- {L3, 100*1000},
- {0, CPUFREQ_TABLE_END},
-};
-
-static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = {
- /*
- * Clock divider value for following
- * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
- * DIVATB, DIVPCLK_DBG, DIVAPLL }
- */
-
- /* ARM L0: 1000MHz */
- { 0, 3, 7, 3, 3, 0, 1 },
-
- /* ARM L1: 800MHz */
- { 0, 3, 7, 3, 3, 0, 1 },
-
- /* ARM L2: 400MHz */
- { 0, 1, 3, 1, 3, 0, 1 },
-
- /* ARM L3: 100MHz */
- { 0, 0, 1, 0, 3, 1, 1 },
-};
-
-static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = {
- /*
- * Clock divider value for following
- * { DIVCOPY, DIVHPM }
- */
-
- /* ARM L0: 1000MHz */
- { 3, 0 },
-
- /* ARM L1: 800MHz */
- { 3, 0 },
-
- /* ARM L2: 400MHz */
- { 3, 0 },
-
- /* ARM L3: 100MHz */
- { 3, 0 },
-};
-
-static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = {
- /*
- * Clock divider value for following
- * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
- * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
- */
-
- /* DMC L0: 400MHz */
- { 3, 1, 1, 1, 1, 1, 3, 1 },
-
- /* DMC L1: 400MHz */
- { 3, 1, 1, 1, 1, 1, 3, 1 },
-
- /* DMC L2: 266.7MHz */
- { 7, 1, 1, 2, 1, 1, 3, 1 },
-
- /* DMC L3: 200MHz */
- { 7, 1, 1, 3, 1, 1, 3, 1 },
-};
-
-static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = {
- /*
- * Clock divider value for following
- * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
- */
-
- /* ACLK200 L0: 200MHz */
- { 3, 7, 4, 5, 1 },
-
- /* ACLK200 L1: 200MHz */
- { 3, 7, 4, 5, 1 },
-
- /* ACLK200 L2: 160MHz */
- { 4, 7, 5, 7, 1 },
-
- /* ACLK200 L3: 133.3MHz */
- { 5, 7, 7, 7, 1 },
-};
-
-static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = {
- /*
- * Clock divider value for following
- * { DIVGDL/R, DIVGPL/R }
- */
-
- /* ACLK_GDL/R L0: 200MHz */
- { 3, 1 },
-
- /* ACLK_GDL/R L1: 200MHz */
- { 3, 1 },
-
- /* ACLK_GDL/R L2: 160MHz */
- { 4, 1 },
-
- /* ACLK_GDL/R L3: 133.3MHz */
- { 5, 1 },
-};
-
-struct cpufreq_voltage_table {
- unsigned int index; /* any */
- unsigned int arm_volt; /* uV */
- unsigned int int_volt;
-};
-
-static struct cpufreq_voltage_table exynos4_volt_table[CPUFREQ_LEVEL_END] = {
- {
- .index = L0,
- .arm_volt = 1200000,
- .int_volt = 1100000,
- }, {
- .index = L1,
- .arm_volt = 1100000,
- .int_volt = 1100000,
- }, {
- .index = L2,
- .arm_volt = 1000000,
- .int_volt = 1000000,
- }, {
- .index = L3,
- .arm_volt = 900000,
- .int_volt = 1000000,
- },
-};
-
-static unsigned int exynos4_apll_pms_table[CPUFREQ_LEVEL_END] = {
- /* APLL FOUT L0: 1000MHz */
- ((250 << 16) | (6 << 8) | 1),
-
- /* APLL FOUT L1: 800MHz */
- ((200 << 16) | (6 << 8) | 1),
-
- /* APLL FOUT L2 : 400MHz */
- ((200 << 16) | (6 << 8) | 2),
-
- /* APLL FOUT L3: 100MHz */
- ((200 << 16) | (6 << 8) | 4),
-};
-
-int exynos4_verify_speed(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, exynos4_freq_table);
-}
-
-unsigned int exynos4_getspeed(unsigned int cpu)
-{
- return clk_get_rate(cpu_clk) / 1000;
-}
-
-void exynos4_set_clkdiv(unsigned int div_index)
-{
- unsigned int tmp;
-
- /* Change Divider - CPU0 */
-
- tmp = __raw_readl(S5P_CLKDIV_CPU);
-
- tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK |
- S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK |
- S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK |
- S5P_CLKDIV_CPU0_APLL_MASK);
-
- tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) |
- (clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) |
- (clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) |
- (clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) |
- (clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) |
- (clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) |
- (clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_CPU);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STATCPU);
- } while (tmp & 0x1111111);
-
- /* Change Divider - CPU1 */
-
- tmp = __raw_readl(S5P_CLKDIV_CPU1);
-
- tmp &= ~((0x7 << 4) | 0x7);
-
- tmp |= ((clkdiv_cpu1[div_index][0] << 4) |
- (clkdiv_cpu1[div_index][1] << 0));
-
- __raw_writel(tmp, S5P_CLKDIV_CPU1);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STATCPU1);
- } while (tmp & 0x11);
-
- /* Change Divider - DMC0 */
-
- tmp = __raw_readl(S5P_CLKDIV_DMC0);
-
- tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK |
- S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK |
- S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK |
- S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK);
-
- tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) |
- (clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) |
- (clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) |
- (clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) |
- (clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) |
- (clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) |
- (clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) |
- (clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_DMC0);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0);
- } while (tmp & 0x11111111);
-
- /* Change Divider - TOP */
-
- tmp = __raw_readl(S5P_CLKDIV_TOP);
-
- tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK |
- S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK |
- S5P_CLKDIV_TOP_ONENAND_MASK);
-
- tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) |
- (clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) |
- (clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) |
- (clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) |
- (clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_TOP);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_TOP);
- } while (tmp & 0x11111);
-
- /* Change Divider - LEFTBUS */
-
- tmp = __raw_readl(S5P_CLKDIV_LEFTBUS);
-
- tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
-
- tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
- (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_LEFTBUS);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS);
- } while (tmp & 0x11);
-
- /* Change Divider - RIGHTBUS */
-
- tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS);
-
- tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK);
-
- tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) |
- (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT));
-
- __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS);
-
- do {
- tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS);
- } while (tmp & 0x11);
-}
-
-static void exynos4_set_apll(unsigned int index)
-{
- unsigned int tmp;
-
- /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
- clk_set_parent(moutcore, mout_mpll);
-
- do {
- tmp = (__raw_readl(S5P_CLKMUX_STATCPU)
- >> S5P_CLKSRC_CPU_MUXCORE_SHIFT);
- tmp &= 0x7;
- } while (tmp != 0x2);
-
- /* 2. Set APLL Lock time */
- __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK);
-
- /* 3. Change PLL PMS values */
- tmp = __raw_readl(S5P_APLL_CON0);
- tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
- tmp |= exynos4_apll_pms_table[index];
- __raw_writel(tmp, S5P_APLL_CON0);
-
- /* 4. wait_lock_time */
- do {
- tmp = __raw_readl(S5P_APLL_CON0);
- } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT)));
-
- /* 5. MUX_CORE_SEL = APLL */
- clk_set_parent(moutcore, mout_apll);
-
- do {
- tmp = __raw_readl(S5P_CLKMUX_STATCPU);
- tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK;
- } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT));
-}
-
-static void exynos4_set_frequency(unsigned int old_index, unsigned int new_index)
-{
- unsigned int tmp;
-
- if (old_index > new_index) {
- /* The frequency changing to L0 needs to change apll */
- if (freqs.new == exynos4_freq_table[L0].frequency) {
- /* 1. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
-
- /* 2. Change the apll m,p,s value */
- exynos4_set_apll(new_index);
- } else {
- /* 1. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
-
- /* 2. Change just s value in apll m,p,s value */
- tmp = __raw_readl(S5P_APLL_CON0);
- tmp &= ~(0x7 << 0);
- tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
- __raw_writel(tmp, S5P_APLL_CON0);
- }
- }
-
- else if (old_index < new_index) {
- /* The frequency changing from L0 needs to change apll */
- if (freqs.old == exynos4_freq_table[L0].frequency) {
- /* 1. Change the apll m,p,s value */
- exynos4_set_apll(new_index);
-
- /* 2. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
- } else {
- /* 1. Change just s value in apll m,p,s value */
- tmp = __raw_readl(S5P_APLL_CON0);
- tmp &= ~(0x7 << 0);
- tmp |= (exynos4_apll_pms_table[new_index] & 0x7);
- __raw_writel(tmp, S5P_APLL_CON0);
-
- /* 2. Change the system clock divider values */
- exynos4_set_clkdiv(new_index);
- }
- }
-}
-
-static int exynos4_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- unsigned int index, old_index;
- unsigned int arm_volt, int_volt;
-
- freqs.old = exynos4_getspeed(policy->cpu);
-
- if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
- freqs.old, relation, &old_index))
- return -EINVAL;
-
- if (cpufreq_frequency_table_target(policy, exynos4_freq_table,
- target_freq, relation, &index))
- return -EINVAL;
-
- freqs.new = exynos4_freq_table[index].frequency;
- freqs.cpu = policy->cpu;
-
- if (freqs.new == freqs.old)
- return 0;
-
- /* get the voltage value */
- arm_volt = exynos4_volt_table[index].arm_volt;
- int_volt = exynos4_volt_table[index].int_volt;
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
- /* control regulator */
- if (freqs.new > freqs.old) {
- /* Voltage up */
- regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
- regulator_set_voltage(int_regulator, int_volt, int_volt);
- }
-
- /* Clock Configuration Procedure */
- exynos4_set_frequency(old_index, index);
-
- /* control regulator */
- if (freqs.new < freqs.old) {
- /* Voltage down */
- regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
- regulator_set_voltage(int_regulator, int_volt, int_volt);
- }
-
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int exynos4_cpufreq_suspend(struct cpufreq_policy *policy)
-{
- return 0;
-}
-
-static int exynos4_cpufreq_resume(struct cpufreq_policy *policy)
-{
- return 0;
-}
-#endif
-
-static int exynos4_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- policy->cur = policy->min = policy->max = exynos4_getspeed(policy->cpu);
-
- cpufreq_frequency_table_get_attr(exynos4_freq_table, policy->cpu);
-
- /* set the transition latency value */
- policy->cpuinfo.transition_latency = 100000;
-
- /*
- * EXYNOS4 multi-core processors has 2 cores
- * that the frequency cannot be set independently.
- * Each cpu is bound to the same speed.
- * So the affected cpu is all of the cpus.
- */
- cpumask_setall(policy->cpus);
-
- return cpufreq_frequency_table_cpuinfo(policy, exynos4_freq_table);
-}
-
-static struct cpufreq_driver exynos4_driver = {
- .flags = CPUFREQ_STICKY,
- .verify = exynos4_verify_speed,
- .target = exynos4_target,
- .get = exynos4_getspeed,
- .init = exynos4_cpufreq_cpu_init,
- .name = "exynos4_cpufreq",
-#ifdef CONFIG_PM
- .suspend = exynos4_cpufreq_suspend,
- .resume = exynos4_cpufreq_resume,
-#endif
-};
-
-static int __init exynos4_cpufreq_init(void)
-{
- cpu_clk = clk_get(NULL, "armclk");
- if (IS_ERR(cpu_clk))
- return PTR_ERR(cpu_clk);
-
- moutcore = clk_get(NULL, "moutcore");
- if (IS_ERR(moutcore))
- goto out;
-
- mout_mpll = clk_get(NULL, "mout_mpll");
- if (IS_ERR(mout_mpll))
- goto out;
-
- mout_apll = clk_get(NULL, "mout_apll");
- if (IS_ERR(mout_apll))
- goto out;
-
- arm_regulator = regulator_get(NULL, "vdd_arm");
- if (IS_ERR(arm_regulator)) {
- printk(KERN_ERR "failed to get resource %s\n", "vdd_arm");
- goto out;
- }
-
- int_regulator = regulator_get(NULL, "vdd_int");
- if (IS_ERR(int_regulator)) {
- printk(KERN_ERR "failed to get resource %s\n", "vdd_int");
- goto out;
- }
-
- /*
- * Check DRAM type.
- * Because DVFS level is different according to DRAM type.
- */
- memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET);
- memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT);
- memtype &= S5P_DMC0_MEMTYPE_MASK;
-
- if ((memtype < DDR2) && (memtype > DDR3)) {
- printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype);
- goto out;
- } else {
- printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype);
- }
-
- return cpufreq_register_driver(&exynos4_driver);
-
-out:
- if (!IS_ERR(cpu_clk))
- clk_put(cpu_clk);
-
- if (!IS_ERR(moutcore))
- clk_put(moutcore);
-
- if (!IS_ERR(mout_mpll))
- clk_put(mout_mpll);
-
- if (!IS_ERR(mout_apll))
- clk_put(mout_apll);
-
- if (!IS_ERR(arm_regulator))
- regulator_put(arm_regulator);
-
- if (!IS_ERR(int_regulator))
- regulator_put(int_regulator);
-
- printk(KERN_ERR "%s: failed initialization\n", __func__);
-
- return -EINVAL;
-}
-late_initcall(exynos4_cpufreq_init);
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
deleted file mode 100644
index bf7e96f..0000000
--- a/arch/arm/mach-exynos4/cpuidle.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* linux/arch/arm/mach-exynos4/cpuidle.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/cpuidle.h>
-#include <linux/io.h>
-
-#include <asm/proc-fns.h>
-
-static int exynos4_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_state *state);
-
-static struct cpuidle_state exynos4_cpuidle_set[] = {
- [0] = {
- .enter = exynos4_enter_idle,
- .exit_latency = 1,
- .target_residency = 100000,
- .flags = CPUIDLE_FLAG_TIME_VALID,
- .name = "IDLE",
- .desc = "ARM clock gating(WFI)",
- },
-};
-
-static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
-
-static struct cpuidle_driver exynos4_idle_driver = {
- .name = "exynos4_idle",
- .owner = THIS_MODULE,
-};
-
-static int exynos4_enter_idle(struct cpuidle_device *dev,
- struct cpuidle_state *state)
-{
- struct timeval before, after;
- int idle_time;
-
- local_irq_disable();
- do_gettimeofday(&before);
-
- cpu_do_idle();
-
- do_gettimeofday(&after);
- local_irq_enable();
- idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
- (after.tv_usec - before.tv_usec);
-
- return idle_time;
-}
-
-static int __init exynos4_init_cpuidle(void)
-{
- int i, max_cpuidle_state, cpu_id;
- struct cpuidle_device *device;
-
- cpuidle_register_driver(&exynos4_idle_driver);
-
- for_each_cpu(cpu_id, cpu_online_mask) {
- device = &per_cpu(exynos4_cpuidle_device, cpu_id);
- device->cpu = cpu_id;
-
- device->state_count = (sizeof(exynos4_cpuidle_set) /
- sizeof(struct cpuidle_state));
-
- max_cpuidle_state = device->state_count;
-
- for (i = 0; i < max_cpuidle_state; i++) {
- memcpy(&device->states[i], &exynos4_cpuidle_set[i],
- sizeof(struct cpuidle_state));
- }
-
- if (cpuidle_register_device(device)) {
- printk(KERN_ERR "CPUidle register device failed\n,");
- return -EIO;
- }
- }
- return 0;
-}
-device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c
deleted file mode 100644
index 983069a..0000000
--- a/arch/arm/mach-exynos4/dev-audio.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-audio.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-static const char *rclksrc[] = {
- [0] = "busclk",
- [1] = "i2sclk",
-};
-
-static int exynos4_cfg_i2s(struct platform_device *pdev)
-{
- /* configure GPIO for i2s port */
- switch (pdev->id) {
- case 0:
- s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
- break;
- case 1:
- s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
- break;
- case 2:
- s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
- break;
- default:
- printk(KERN_ERR "Invalid Device %d\n", pdev->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct s3c_audio_pdata i2sv5_pdata = {
- .cfg_gpio = exynos4_cfg_i2s,
- .type = {
- .i2s = {
- .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
- | QUIRK_NEED_RSTCLR,
- .src_clk = rclksrc,
- },
- },
-};
-
-static struct resource exynos4_i2s0_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_I2S0,
- .end = EXYNOS4_PA_I2S0 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_I2S0_TX,
- .end = DMACH_I2S0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_I2S0_RX,
- .end = DMACH_I2S0_RX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = DMACH_I2S0S_TX,
- .end = DMACH_I2S0S_TX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device exynos4_device_i2s0 = {
- .name = "samsung-i2s",
- .id = 0,
- .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
- .resource = exynos4_i2s0_resource,
- .dev = {
- .platform_data = &i2sv5_pdata,
- },
-};
-
-static const char *rclksrc_v3[] = {
- [0] = "sclk_i2s",
- [1] = "no_such_clock",
-};
-
-static struct s3c_audio_pdata i2sv3_pdata = {
- .cfg_gpio = exynos4_cfg_i2s,
- .type = {
- .i2s = {
- .quirks = QUIRK_NO_MUXPSR,
- .src_clk = rclksrc_v3,
- },
- },
-};
-
-static struct resource exynos4_i2s1_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_I2S1,
- .end = EXYNOS4_PA_I2S1 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_I2S1_TX,
- .end = DMACH_I2S1_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_I2S1_RX,
- .end = DMACH_I2S1_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device exynos4_device_i2s1 = {
- .name = "samsung-i2s",
- .id = 1,
- .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
- .resource = exynos4_i2s1_resource,
- .dev = {
- .platform_data = &i2sv3_pdata,
- },
-};
-
-static struct resource exynos4_i2s2_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_I2S2,
- .end = EXYNOS4_PA_I2S2 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_I2S2_TX,
- .end = DMACH_I2S2_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_I2S2_RX,
- .end = DMACH_I2S2_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device exynos4_device_i2s2 = {
- .name = "samsung-i2s",
- .id = 2,
- .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
- .resource = exynos4_i2s2_resource,
- .dev = {
- .platform_data = &i2sv3_pdata,
- },
-};
-
-/* PCM Controller platform_devices */
-
-static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
-{
- switch (pdev->id) {
- case 0:
- s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
- break;
- case 1:
- s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
- break;
- case 2:
- s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
- break;
- default:
- printk(KERN_DEBUG "Invalid PCM Controller number!");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct s3c_audio_pdata s3c_pcm_pdata = {
- .cfg_gpio = exynos4_pcm_cfg_gpio,
-};
-
-static struct resource exynos4_pcm0_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_PCM0,
- .end = EXYNOS4_PA_PCM0 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_PCM0_TX,
- .end = DMACH_PCM0_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_PCM0_RX,
- .end = DMACH_PCM0_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device exynos4_device_pcm0 = {
- .name = "samsung-pcm",
- .id = 0,
- .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
- .resource = exynos4_pcm0_resource,
- .dev = {
- .platform_data = &s3c_pcm_pdata,
- },
-};
-
-static struct resource exynos4_pcm1_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_PCM1,
- .end = EXYNOS4_PA_PCM1 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_PCM1_TX,
- .end = DMACH_PCM1_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_PCM1_RX,
- .end = DMACH_PCM1_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device exynos4_device_pcm1 = {
- .name = "samsung-pcm",
- .id = 1,
- .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
- .resource = exynos4_pcm1_resource,
- .dev = {
- .platform_data = &s3c_pcm_pdata,
- },
-};
-
-static struct resource exynos4_pcm2_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_PCM2,
- .end = EXYNOS4_PA_PCM2 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_PCM2_TX,
- .end = DMACH_PCM2_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_PCM2_RX,
- .end = DMACH_PCM2_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-struct platform_device exynos4_device_pcm2 = {
- .name = "samsung-pcm",
- .id = 2,
- .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
- .resource = exynos4_pcm2_resource,
- .dev = {
- .platform_data = &s3c_pcm_pdata,
- },
-};
-
-/* AC97 Controller platform devices */
-
-static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
-{
- return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
-}
-
-static struct resource exynos4_ac97_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_AC97,
- .end = EXYNOS4_PA_AC97 + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_AC97_PCMOUT,
- .end = DMACH_AC97_PCMOUT,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMACH_AC97_PCMIN,
- .end = DMACH_AC97_PCMIN,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = DMACH_AC97_MICIN,
- .end = DMACH_AC97_MICIN,
- .flags = IORESOURCE_DMA,
- },
- [4] = {
- .start = IRQ_AC97,
- .end = IRQ_AC97,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c_audio_pdata s3c_ac97_pdata = {
- .cfg_gpio = exynos4_ac97_cfg_gpio,
-};
-
-static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_ac97 = {
- .name = "samsung-ac97",
- .id = -1,
- .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
- .resource = exynos4_ac97_resource,
- .dev = {
- .platform_data = &s3c_ac97_pdata,
- .dma_mask = &exynos4_ac97_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
-
-/* S/PDIF Controller platform_device */
-
-static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
-{
- s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
-
- return 0;
-}
-
-static struct resource exynos4_spdif_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_SPDIF,
- .end = EXYNOS4_PA_SPDIF + 0x100 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMACH_SPDIF,
- .end = DMACH_SPDIF,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct s3c_audio_pdata samsung_spdif_pdata = {
- .cfg_gpio = exynos4_spdif_cfg_gpio,
-};
-
-static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device exynos4_device_spdif = {
- .name = "samsung-spdif",
- .id = -1,
- .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
- .resource = exynos4_spdif_resource,
- .dev = {
- .platform_data = &samsung_spdif_pdata,
- .dma_mask = &exynos4_spdif_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
-};
diff --git a/arch/arm/mach-exynos4/dev-pd.c b/arch/arm/mach-exynos4/dev-pd.c
deleted file mode 100644
index 3273f25..0000000
--- a/arch/arm/mach-exynos4/dev-pd.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-pd.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Power Domain support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-
-#include <mach/regs-pmu.h>
-
-#include <plat/pd.h>
-
-static int exynos4_pd_enable(struct device *dev)
-{
- struct samsung_pd_info *pdata = dev->platform_data;
- u32 timeout;
-
- __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
-
- /* Wait max 1ms */
- timeout = 10;
- while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
- != S5P_INT_LOCAL_PWR_EN) {
- if (timeout == 0) {
- printk(KERN_ERR "Power domain %s enable failed.\n",
- dev_name(dev));
- return -ETIMEDOUT;
- }
- timeout--;
- udelay(100);
- }
-
- return 0;
-}
-
-static int exynos4_pd_disable(struct device *dev)
-{
- struct samsung_pd_info *pdata = dev->platform_data;
- u32 timeout;
-
- __raw_writel(0, pdata->base);
-
- /* Wait max 1ms */
- timeout = 10;
- while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
- if (timeout == 0) {
- printk(KERN_ERR "Power domain %s disable failed.\n",
- dev_name(dev));
- return -ETIMEDOUT;
- }
- timeout--;
- udelay(100);
- }
-
- return 0;
-}
-
-struct platform_device exynos4_device_pd[] = {
- {
- .name = "samsung-pd",
- .id = 0,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_MFC_CONF,
- },
- },
- }, {
- .name = "samsung-pd",
- .id = 1,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_G3D_CONF,
- },
- },
- }, {
- .name = "samsung-pd",
- .id = 2,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_LCD0_CONF,
- },
- },
- }, {
- .name = "samsung-pd",
- .id = 3,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_LCD1_CONF,
- },
- },
- }, {
- .name = "samsung-pd",
- .id = 4,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_TV_CONF,
- },
- },
- }, {
- .name = "samsung-pd",
- .id = 5,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_CAM_CONF,
- },
- },
- }, {
- .name = "samsung-pd",
- .id = 6,
- .dev = {
- .platform_data = &(struct samsung_pd_info) {
- .enable = exynos4_pd_enable,
- .disable = exynos4_pd_disable,
- .base = S5P_PMU_GPS_CONF,
- },
- },
- },
-};
diff --git a/arch/arm/mach-exynos4/dev-sysmmu.c b/arch/arm/mach-exynos4/dev-sysmmu.c
deleted file mode 100644
index 3b7cae0..0000000
--- a/arch/arm/mach-exynos4/dev-sysmmu.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-sysmmu.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - System MMU support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/sysmmu.h>
-#include <plat/s5p-clock.h>
-
-/* These names must be equal to the clock names in mach-exynos4/clock.c */
-const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
- "SYSMMU_MDMA" ,
- "SYSMMU_SSS" ,
- "SYSMMU_FIMC0" ,
- "SYSMMU_FIMC1" ,
- "SYSMMU_FIMC2" ,
- "SYSMMU_FIMC3" ,
- "SYSMMU_JPEG" ,
- "SYSMMU_FIMD0" ,
- "SYSMMU_FIMD1" ,
- "SYSMMU_PCIe" ,
- "SYSMMU_G2D" ,
- "SYSMMU_ROTATOR",
- "SYSMMU_MDMA2" ,
- "SYSMMU_TV" ,
- "SYSMMU_MFC_L" ,
- "SYSMMU_MFC_R" ,
-};
-
-static struct resource exynos4_sysmmu_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_SYSMMU_MDMA,
- .end = EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_SYSMMU_MDMA0_0,
- .end = IRQ_SYSMMU_MDMA0_0,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = EXYNOS4_PA_SYSMMU_SSS,
- .end = EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [3] = {
- .start = IRQ_SYSMMU_SSS_0,
- .end = IRQ_SYSMMU_SSS_0,
- .flags = IORESOURCE_IRQ,
- },
- [4] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC0,
- .end = EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [5] = {
- .start = IRQ_SYSMMU_FIMC0_0,
- .end = IRQ_SYSMMU_FIMC0_0,
- .flags = IORESOURCE_IRQ,
- },
- [6] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC1,
- .end = EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [7] = {
- .start = IRQ_SYSMMU_FIMC1_0,
- .end = IRQ_SYSMMU_FIMC1_0,
- .flags = IORESOURCE_IRQ,
- },
- [8] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC2,
- .end = EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [9] = {
- .start = IRQ_SYSMMU_FIMC2_0,
- .end = IRQ_SYSMMU_FIMC2_0,
- .flags = IORESOURCE_IRQ,
- },
- [10] = {
- .start = EXYNOS4_PA_SYSMMU_FIMC3,
- .end = EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [11] = {
- .start = IRQ_SYSMMU_FIMC3_0,
- .end = IRQ_SYSMMU_FIMC3_0,
- .flags = IORESOURCE_IRQ,
- },
- [12] = {
- .start = EXYNOS4_PA_SYSMMU_JPEG,
- .end = EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [13] = {
- .start = IRQ_SYSMMU_JPEG_0,
- .end = IRQ_SYSMMU_JPEG_0,
- .flags = IORESOURCE_IRQ,
- },
- [14] = {
- .start = EXYNOS4_PA_SYSMMU_FIMD0,
- .end = EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [15] = {
- .start = IRQ_SYSMMU_LCD0_M0_0,
- .end = IRQ_SYSMMU_LCD0_M0_0,
- .flags = IORESOURCE_IRQ,
- },
- [16] = {
- .start = EXYNOS4_PA_SYSMMU_FIMD1,
- .end = EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [17] = {
- .start = IRQ_SYSMMU_LCD1_M1_0,
- .end = IRQ_SYSMMU_LCD1_M1_0,
- .flags = IORESOURCE_IRQ,
- },
- [18] = {
- .start = EXYNOS4_PA_SYSMMU_PCIe,
- .end = EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [19] = {
- .start = IRQ_SYSMMU_PCIE_0,
- .end = IRQ_SYSMMU_PCIE_0,
- .flags = IORESOURCE_IRQ,
- },
- [20] = {
- .start = EXYNOS4_PA_SYSMMU_G2D,
- .end = EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [21] = {
- .start = IRQ_SYSMMU_2D_0,
- .end = IRQ_SYSMMU_2D_0,
- .flags = IORESOURCE_IRQ,
- },
- [22] = {
- .start = EXYNOS4_PA_SYSMMU_ROTATOR,
- .end = EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [23] = {
- .start = IRQ_SYSMMU_ROTATOR_0,
- .end = IRQ_SYSMMU_ROTATOR_0,
- .flags = IORESOURCE_IRQ,
- },
- [24] = {
- .start = EXYNOS4_PA_SYSMMU_MDMA2,
- .end = EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [25] = {
- .start = IRQ_SYSMMU_MDMA1_0,
- .end = IRQ_SYSMMU_MDMA1_0,
- .flags = IORESOURCE_IRQ,
- },
- [26] = {
- .start = EXYNOS4_PA_SYSMMU_TV,
- .end = EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [27] = {
- .start = IRQ_SYSMMU_TV_M0_0,
- .end = IRQ_SYSMMU_TV_M0_0,
- .flags = IORESOURCE_IRQ,
- },
- [28] = {
- .start = EXYNOS4_PA_SYSMMU_MFC_L,
- .end = EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [29] = {
- .start = IRQ_SYSMMU_MFC_M0_0,
- .end = IRQ_SYSMMU_MFC_M0_0,
- .flags = IORESOURCE_IRQ,
- },
- [30] = {
- .start = EXYNOS4_PA_SYSMMU_MFC_R,
- .end = EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [31] = {
- .start = IRQ_SYSMMU_MFC_M1_0,
- .end = IRQ_SYSMMU_MFC_M1_0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device exynos4_device_sysmmu = {
- .name = "s5p-sysmmu",
- .id = 32,
- .num_resources = ARRAY_SIZE(exynos4_sysmmu_resource),
- .resource = exynos4_sysmmu_resource,
-};
-EXPORT_SYMBOL(exynos4_device_sysmmu);
-
-static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
-void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
-{
- sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
- if (IS_ERR(sysmmu_clk[ips]))
- sysmmu_clk[ips] = NULL;
- else
- clk_put(sysmmu_clk[ips]);
-}
-
-void sysmmu_clk_enable(sysmmu_ips ips)
-{
- if (sysmmu_clk[ips])
- clk_enable(sysmmu_clk[ips]);
-}
-
-void sysmmu_clk_disable(sysmmu_ips ips)
-{
- if (sysmmu_clk[ips])
- clk_disable(sysmmu_clk[ips]);
-}
diff --git a/arch/arm/mach-exynos4/dma.c b/arch/arm/mach-exynos4/dma.c
deleted file mode 100644
index 564bb53..0000000
--- a/arch/arm/mach-exynos4/dma.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dma.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-
-#include <plat/devs.h>
-#include <plat/irqs.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#include <plat/s3c-pl330-pdata.h>
-
-static u64 dma_dmamask = DMA_BIT_MASK(32);
-
-static struct resource exynos4_pdma0_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_PDMA0,
- .end = EXYNOS4_PA_PDMA0 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_PDMA0,
- .end = IRQ_PDMA0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
- .peri = {
- [0] = DMACH_PCM0_RX,
- [1] = DMACH_PCM0_TX,
- [2] = DMACH_PCM2_RX,
- [3] = DMACH_PCM2_TX,
- [4] = DMACH_MSM_REQ0,
- [5] = DMACH_MSM_REQ2,
- [6] = DMACH_SPI0_RX,
- [7] = DMACH_SPI0_TX,
- [8] = DMACH_SPI2_RX,
- [9] = DMACH_SPI2_TX,
- [10] = DMACH_I2S0S_TX,
- [11] = DMACH_I2S0_RX,
- [12] = DMACH_I2S0_TX,
- [13] = DMACH_I2S2_RX,
- [14] = DMACH_I2S2_TX,
- [15] = DMACH_UART0_RX,
- [16] = DMACH_UART0_TX,
- [17] = DMACH_UART2_RX,
- [18] = DMACH_UART2_TX,
- [19] = DMACH_UART4_RX,
- [20] = DMACH_UART4_TX,
- [21] = DMACH_SLIMBUS0_RX,
- [22] = DMACH_SLIMBUS0_TX,
- [23] = DMACH_SLIMBUS2_RX,
- [24] = DMACH_SLIMBUS2_TX,
- [25] = DMACH_SLIMBUS4_RX,
- [26] = DMACH_SLIMBUS4_TX,
- [27] = DMACH_AC97_MICIN,
- [28] = DMACH_AC97_PCMIN,
- [29] = DMACH_AC97_PCMOUT,
- [30] = DMACH_MAX,
- [31] = DMACH_MAX,
- },
-};
-
-static struct platform_device exynos4_device_pdma0 = {
- .name = "s3c-pl330",
- .id = 0,
- .num_resources = ARRAY_SIZE(exynos4_pdma0_resource),
- .resource = exynos4_pdma0_resource,
- .dev = {
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &exynos4_pdma0_pdata,
- },
-};
-
-static struct resource exynos4_pdma1_resource[] = {
- [0] = {
- .start = EXYNOS4_PA_PDMA1,
- .end = EXYNOS4_PA_PDMA1 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_PDMA1,
- .end = IRQ_PDMA1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
- .peri = {
- [0] = DMACH_PCM0_RX,
- [1] = DMACH_PCM0_TX,
- [2] = DMACH_PCM1_RX,
- [3] = DMACH_PCM1_TX,
- [4] = DMACH_MSM_REQ1,
- [5] = DMACH_MSM_REQ3,
- [6] = DMACH_SPI1_RX,
- [7] = DMACH_SPI1_TX,
- [8] = DMACH_I2S0S_TX,
- [9] = DMACH_I2S0_RX,
- [10] = DMACH_I2S0_TX,
- [11] = DMACH_I2S1_RX,
- [12] = DMACH_I2S1_TX,
- [13] = DMACH_UART0_RX,
- [14] = DMACH_UART0_TX,
- [15] = DMACH_UART1_RX,
- [16] = DMACH_UART1_TX,
- [17] = DMACH_UART3_RX,
- [18] = DMACH_UART3_TX,
- [19] = DMACH_SLIMBUS1_RX,
- [20] = DMACH_SLIMBUS1_TX,
- [21] = DMACH_SLIMBUS3_RX,
- [22] = DMACH_SLIMBUS3_TX,
- [23] = DMACH_SLIMBUS5_RX,
- [24] = DMACH_SLIMBUS5_TX,
- [25] = DMACH_SLIMBUS0AUX_RX,
- [26] = DMACH_SLIMBUS0AUX_TX,
- [27] = DMACH_SPDIF,
- [28] = DMACH_MAX,
- [29] = DMACH_MAX,
- [30] = DMACH_MAX,
- [31] = DMACH_MAX,
- },
-};
-
-static struct platform_device exynos4_device_pdma1 = {
- .name = "s3c-pl330",
- .id = 1,
- .num_resources = ARRAY_SIZE(exynos4_pdma1_resource),
- .resource = exynos4_pdma1_resource,
- .dev = {
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &exynos4_pdma1_pdata,
- },
-};
-
-static struct platform_device *exynos4_dmacs[] __initdata = {
- &exynos4_device_pdma0,
- &exynos4_device_pdma1,
-};
-
-static int __init exynos4_dma_init(void)
-{
- platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
-
- return 0;
-}
-arch_initcall(exynos4_dma_init);
diff --git a/arch/arm/mach-exynos4/include/mach/gpio.h b/arch/arm/mach-exynos4/include/mach/gpio.h
deleted file mode 100644
index be9266b..0000000
--- a/arch/arm/mach-exynos4/include/mach/gpio.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - GPIO lib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H __FILE__
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq __gpio_to_irq
-
-/* Practically, GPIO banks up to GPZ are the configurable gpio banks */
-
-/* GPIO bank sizes */
-#define EXYNOS4_GPIO_A0_NR (8)
-#define EXYNOS4_GPIO_A1_NR (6)
-#define EXYNOS4_GPIO_B_NR (8)
-#define EXYNOS4_GPIO_C0_NR (5)
-#define EXYNOS4_GPIO_C1_NR (5)
-#define EXYNOS4_GPIO_D0_NR (4)
-#define EXYNOS4_GPIO_D1_NR (4)
-#define EXYNOS4_GPIO_E0_NR (5)
-#define EXYNOS4_GPIO_E1_NR (8)
-#define EXYNOS4_GPIO_E2_NR (6)
-#define EXYNOS4_GPIO_E3_NR (8)
-#define EXYNOS4_GPIO_E4_NR (8)
-#define EXYNOS4_GPIO_F0_NR (8)
-#define EXYNOS4_GPIO_F1_NR (8)
-#define EXYNOS4_GPIO_F2_NR (8)
-#define EXYNOS4_GPIO_F3_NR (6)
-#define EXYNOS4_GPIO_J0_NR (8)
-#define EXYNOS4_GPIO_J1_NR (5)
-#define EXYNOS4_GPIO_K0_NR (7)
-#define EXYNOS4_GPIO_K1_NR (7)
-#define EXYNOS4_GPIO_K2_NR (7)
-#define EXYNOS4_GPIO_K3_NR (7)
-#define EXYNOS4_GPIO_L0_NR (8)
-#define EXYNOS4_GPIO_L1_NR (3)
-#define EXYNOS4_GPIO_L2_NR (8)
-#define EXYNOS4_GPIO_X0_NR (8)
-#define EXYNOS4_GPIO_X1_NR (8)
-#define EXYNOS4_GPIO_X2_NR (8)
-#define EXYNOS4_GPIO_X3_NR (8)
-#define EXYNOS4_GPIO_Y0_NR (6)
-#define EXYNOS4_GPIO_Y1_NR (4)
-#define EXYNOS4_GPIO_Y2_NR (6)
-#define EXYNOS4_GPIO_Y3_NR (8)
-#define EXYNOS4_GPIO_Y4_NR (8)
-#define EXYNOS4_GPIO_Y5_NR (8)
-#define EXYNOS4_GPIO_Y6_NR (8)
-#define EXYNOS4_GPIO_Z_NR (7)
-
-/* GPIO bank numbers */
-
-#define EXYNOS4_GPIO_NEXT(__gpio) \
- ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
-
-enum s5p_gpio_number {
- EXYNOS4_GPIO_A0_START = 0,
- EXYNOS4_GPIO_A1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A0),
- EXYNOS4_GPIO_B_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_A1),
- EXYNOS4_GPIO_C0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_B),
- EXYNOS4_GPIO_C1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C0),
- EXYNOS4_GPIO_D0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_C1),
- EXYNOS4_GPIO_D1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D0),
- EXYNOS4_GPIO_E0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_D1),
- EXYNOS4_GPIO_E1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E0),
- EXYNOS4_GPIO_E2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E1),
- EXYNOS4_GPIO_E3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E2),
- EXYNOS4_GPIO_E4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E3),
- EXYNOS4_GPIO_F0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_E4),
- EXYNOS4_GPIO_F1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F0),
- EXYNOS4_GPIO_F2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F1),
- EXYNOS4_GPIO_F3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F2),
- EXYNOS4_GPIO_J0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_F3),
- EXYNOS4_GPIO_J1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J0),
- EXYNOS4_GPIO_K0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_J1),
- EXYNOS4_GPIO_K1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K0),
- EXYNOS4_GPIO_K2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K1),
- EXYNOS4_GPIO_K3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K2),
- EXYNOS4_GPIO_L0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_K3),
- EXYNOS4_GPIO_L1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L0),
- EXYNOS4_GPIO_L2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L1),
- EXYNOS4_GPIO_X0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_L2),
- EXYNOS4_GPIO_X1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X0),
- EXYNOS4_GPIO_X2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X1),
- EXYNOS4_GPIO_X3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X2),
- EXYNOS4_GPIO_Y0_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_X3),
- EXYNOS4_GPIO_Y1_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y0),
- EXYNOS4_GPIO_Y2_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y1),
- EXYNOS4_GPIO_Y3_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y2),
- EXYNOS4_GPIO_Y4_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y3),
- EXYNOS4_GPIO_Y5_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y4),
- EXYNOS4_GPIO_Y6_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y5),
- EXYNOS4_GPIO_Z_START = EXYNOS4_GPIO_NEXT(EXYNOS4_GPIO_Y6),
-};
-
-/* EXYNOS4 GPIO number definitions */
-#define EXYNOS4_GPA0(_nr) (EXYNOS4_GPIO_A0_START + (_nr))
-#define EXYNOS4_GPA1(_nr) (EXYNOS4_GPIO_A1_START + (_nr))
-#define EXYNOS4_GPB(_nr) (EXYNOS4_GPIO_B_START + (_nr))
-#define EXYNOS4_GPC0(_nr) (EXYNOS4_GPIO_C0_START + (_nr))
-#define EXYNOS4_GPC1(_nr) (EXYNOS4_GPIO_C1_START + (_nr))
-#define EXYNOS4_GPD0(_nr) (EXYNOS4_GPIO_D0_START + (_nr))
-#define EXYNOS4_GPD1(_nr) (EXYNOS4_GPIO_D1_START + (_nr))
-#define EXYNOS4_GPE0(_nr) (EXYNOS4_GPIO_E0_START + (_nr))
-#define EXYNOS4_GPE1(_nr) (EXYNOS4_GPIO_E1_START + (_nr))
-#define EXYNOS4_GPE2(_nr) (EXYNOS4_GPIO_E2_START + (_nr))
-#define EXYNOS4_GPE3(_nr) (EXYNOS4_GPIO_E3_START + (_nr))
-#define EXYNOS4_GPE4(_nr) (EXYNOS4_GPIO_E4_START + (_nr))
-#define EXYNOS4_GPF0(_nr) (EXYNOS4_GPIO_F0_START + (_nr))
-#define EXYNOS4_GPF1(_nr) (EXYNOS4_GPIO_F1_START + (_nr))
-#define EXYNOS4_GPF2(_nr) (EXYNOS4_GPIO_F2_START + (_nr))
-#define EXYNOS4_GPF3(_nr) (EXYNOS4_GPIO_F3_START + (_nr))
-#define EXYNOS4_GPJ0(_nr) (EXYNOS4_GPIO_J0_START + (_nr))
-#define EXYNOS4_GPJ1(_nr) (EXYNOS4_GPIO_J1_START + (_nr))
-#define EXYNOS4_GPK0(_nr) (EXYNOS4_GPIO_K0_START + (_nr))
-#define EXYNOS4_GPK1(_nr) (EXYNOS4_GPIO_K1_START + (_nr))
-#define EXYNOS4_GPK2(_nr) (EXYNOS4_GPIO_K2_START + (_nr))
-#define EXYNOS4_GPK3(_nr) (EXYNOS4_GPIO_K3_START + (_nr))
-#define EXYNOS4_GPL0(_nr) (EXYNOS4_GPIO_L0_START + (_nr))
-#define EXYNOS4_GPL1(_nr) (EXYNOS4_GPIO_L1_START + (_nr))
-#define EXYNOS4_GPL2(_nr) (EXYNOS4_GPIO_L2_START + (_nr))
-#define EXYNOS4_GPX0(_nr) (EXYNOS4_GPIO_X0_START + (_nr))
-#define EXYNOS4_GPX1(_nr) (EXYNOS4_GPIO_X1_START + (_nr))
-#define EXYNOS4_GPX2(_nr) (EXYNOS4_GPIO_X2_START + (_nr))
-#define EXYNOS4_GPX3(_nr) (EXYNOS4_GPIO_X3_START + (_nr))
-#define EXYNOS4_GPY0(_nr) (EXYNOS4_GPIO_Y0_START + (_nr))
-#define EXYNOS4_GPY1(_nr) (EXYNOS4_GPIO_Y1_START + (_nr))
-#define EXYNOS4_GPY2(_nr) (EXYNOS4_GPIO_Y2_START + (_nr))
-#define EXYNOS4_GPY3(_nr) (EXYNOS4_GPIO_Y3_START + (_nr))
-#define EXYNOS4_GPY4(_nr) (EXYNOS4_GPIO_Y4_START + (_nr))
-#define EXYNOS4_GPY5(_nr) (EXYNOS4_GPIO_Y5_START + (_nr))
-#define EXYNOS4_GPY6(_nr) (EXYNOS4_GPIO_Y6_START + (_nr))
-#define EXYNOS4_GPZ(_nr) (EXYNOS4_GPIO_Z_START + (_nr))
-
-/* the end of the EXYNOS4 specific gpios */
-#define EXYNOS4_GPIO_END (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + 1)
-#define S3C_GPIO_END EXYNOS4_GPIO_END
-
-/* define the number of gpios we need to the one after the GPZ() range */
-#define ARCH_NR_GPIOS (EXYNOS4_GPZ(EXYNOS4_GPIO_Z_NR) + \
- CONFIG_SAMSUNG_GPIO_EXTRA + 1)
-
-#include <asm-generic/gpio.h>
-
-#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
deleted file mode 100644
index 5d03730..0000000
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/irqs.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - IRQ definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H __FILE__
-
-#include <plat/irqs.h>
-
-/* PPI: Private Peripheral Interrupt */
-
-#define IRQ_PPI(x) S5P_IRQ(x+16)
-
-#define IRQ_LOCALTIMER IRQ_PPI(13)
-
-/* SPI: Shared Peripheral Interrupt */
-
-#define IRQ_SPI(x) S5P_IRQ(x+32)
-
-#define IRQ_MCT1 IRQ_SPI(35)
-
-#define IRQ_EINT0 IRQ_SPI(40)
-#define IRQ_EINT1 IRQ_SPI(41)
-#define IRQ_EINT2 IRQ_SPI(42)
-#define IRQ_EINT3 IRQ_SPI(43)
-#define IRQ_USB_HSOTG IRQ_SPI(44)
-#define IRQ_USB_HOST IRQ_SPI(45)
-#define IRQ_MODEM_IF IRQ_SPI(46)
-#define IRQ_ROTATOR IRQ_SPI(47)
-#define IRQ_JPEG IRQ_SPI(48)
-#define IRQ_2D IRQ_SPI(49)
-#define IRQ_PCIE IRQ_SPI(50)
-#define IRQ_MCT0 IRQ_SPI(51)
-#define IRQ_MFC IRQ_SPI(52)
-#define IRQ_AUDIO_SS IRQ_SPI(54)
-#define IRQ_AC97 IRQ_SPI(55)
-#define IRQ_SPDIF IRQ_SPI(56)
-#define IRQ_KEYPAD IRQ_SPI(57)
-#define IRQ_INTFEEDCTRL_SSS IRQ_SPI(58)
-#define IRQ_SLIMBUS IRQ_SPI(59)
-#define IRQ_PMU IRQ_SPI(60)
-#define IRQ_TSI IRQ_SPI(61)
-#define IRQ_SATA IRQ_SPI(62)
-#define IRQ_GPS IRQ_SPI(63)
-
-#define MAX_IRQ_IN_COMBINER 8
-#define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
-#define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y)
-
-#define IRQ_SYSMMU_MDMA0_0 COMBINER_IRQ(4, 0)
-#define IRQ_SYSMMU_SSS_0 COMBINER_IRQ(4, 1)
-#define IRQ_SYSMMU_FIMC0_0 COMBINER_IRQ(4, 2)
-#define IRQ_SYSMMU_FIMC1_0 COMBINER_IRQ(4, 3)
-#define IRQ_SYSMMU_FIMC2_0 COMBINER_IRQ(4, 4)
-#define IRQ_SYSMMU_FIMC3_0 COMBINER_IRQ(4, 5)
-#define IRQ_SYSMMU_JPEG_0 COMBINER_IRQ(4, 6)
-#define IRQ_SYSMMU_2D_0 COMBINER_IRQ(4, 7)
-
-#define IRQ_SYSMMU_ROTATOR_0 COMBINER_IRQ(5, 0)
-#define IRQ_SYSMMU_MDMA1_0 COMBINER_IRQ(5, 1)
-#define IRQ_SYSMMU_LCD0_M0_0 COMBINER_IRQ(5, 2)
-#define IRQ_SYSMMU_LCD1_M1_0 COMBINER_IRQ(5, 3)
-#define IRQ_SYSMMU_TV_M0_0 COMBINER_IRQ(5, 4)
-#define IRQ_SYSMMU_MFC_M0_0 COMBINER_IRQ(5, 5)
-#define IRQ_SYSMMU_MFC_M1_0 COMBINER_IRQ(5, 6)
-#define IRQ_SYSMMU_PCIE_0 COMBINER_IRQ(5, 7)
-
-#define IRQ_PDMA0 COMBINER_IRQ(21, 0)
-#define IRQ_PDMA1 COMBINER_IRQ(21, 1)
-
-#define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0)
-#define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1)
-#define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2)
-#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
-#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4)
-
-#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0)
-#define IRQ_RTC_TIC COMBINER_IRQ(23, 1)
-
-#define IRQ_GPIO_XB COMBINER_IRQ(24, 0)
-#define IRQ_GPIO_XA COMBINER_IRQ(24, 1)
-
-#define IRQ_UART0 COMBINER_IRQ(26, 0)
-#define IRQ_UART1 COMBINER_IRQ(26, 1)
-#define IRQ_UART2 COMBINER_IRQ(26, 2)
-#define IRQ_UART3 COMBINER_IRQ(26, 3)
-#define IRQ_UART4 COMBINER_IRQ(26, 4)
-
-#define IRQ_IIC COMBINER_IRQ(27, 0)
-#define IRQ_IIC1 COMBINER_IRQ(27, 1)
-#define IRQ_IIC2 COMBINER_IRQ(27, 2)
-#define IRQ_IIC3 COMBINER_IRQ(27, 3)
-#define IRQ_IIC4 COMBINER_IRQ(27, 4)
-#define IRQ_IIC5 COMBINER_IRQ(27, 5)
-#define IRQ_IIC6 COMBINER_IRQ(27, 6)
-#define IRQ_IIC7 COMBINER_IRQ(27, 7)
-
-#define IRQ_HSMMC0 COMBINER_IRQ(29, 0)
-#define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
-#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
-#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
-
-#define IRQ_MIPI_CSIS0 COMBINER_IRQ(30, 0)
-#define IRQ_MIPI_CSIS1 COMBINER_IRQ(30, 1)
-
-#define IRQ_FIMC0 COMBINER_IRQ(32, 0)
-#define IRQ_FIMC1 COMBINER_IRQ(32, 1)
-#define IRQ_FIMC2 COMBINER_IRQ(33, 0)
-#define IRQ_FIMC3 COMBINER_IRQ(33, 1)
-
-#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
-
-#define IRQ_MCT_L1 COMBINER_IRQ(35, 3)
-
-#define IRQ_EINT4 COMBINER_IRQ(37, 0)
-#define IRQ_EINT5 COMBINER_IRQ(37, 1)
-#define IRQ_EINT6 COMBINER_IRQ(37, 2)
-#define IRQ_EINT7 COMBINER_IRQ(37, 3)
-#define IRQ_EINT8 COMBINER_IRQ(38, 0)
-
-#define IRQ_EINT9 COMBINER_IRQ(38, 1)
-#define IRQ_EINT10 COMBINER_IRQ(38, 2)
-#define IRQ_EINT11 COMBINER_IRQ(38, 3)
-#define IRQ_EINT12 COMBINER_IRQ(38, 4)
-#define IRQ_EINT13 COMBINER_IRQ(38, 5)
-#define IRQ_EINT14 COMBINER_IRQ(38, 6)
-#define IRQ_EINT15 COMBINER_IRQ(38, 7)
-
-#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
-
-#define IRQ_MCT_L0 COMBINER_IRQ(51, 0)
-
-#define IRQ_WDT COMBINER_IRQ(53, 0)
-#define IRQ_MCT_G0 COMBINER_IRQ(53, 4)
-
-#define MAX_COMBINER_NR 54
-
-#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
-
-#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
-#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
-
-/* optional GPIO interrupts */
-#define S5P_GPIOINT_BASE (S5P_IRQ_EINT_BASE + 32)
-#define IRQ_GPIO1_NR_GROUPS 16
-#define IRQ_GPIO2_NR_GROUPS 9
-#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
-
-/* Set the default NR_IRQS */
-#define NR_IRQS (IRQ_GPIO_END)
-
-#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
deleted file mode 100644
index 0009e77..0000000
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/map.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * EXYNOS4 - Memory map definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H __FILE__
-
-#include <plat/map-base.h>
-
-/*
- * EXYNOS4 UART offset is 0x10000 but the older S5P SoCs are 0x400.
- * So need to define it, and here is to avoid redefinition warning.
- */
-#define S3C_UART_OFFSET (0x10000)
-
-#include <plat/map-s5p.h>
-
-#define EXYNOS4_PA_SYSRAM 0x02020000
-
-#define EXYNOS4_PA_FIMC0 0x11800000
-#define EXYNOS4_PA_FIMC1 0x11810000
-#define EXYNOS4_PA_FIMC2 0x11820000
-#define EXYNOS4_PA_FIMC3 0x11830000
-
-#define EXYNOS4_PA_I2S0 0x03830000
-#define EXYNOS4_PA_I2S1 0xE3100000
-#define EXYNOS4_PA_I2S2 0xE2A00000
-
-#define EXYNOS4_PA_PCM0 0x03840000
-#define EXYNOS4_PA_PCM1 0x13980000
-#define EXYNOS4_PA_PCM2 0x13990000
-
-#define EXYNOS4_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
-
-#define EXYNOS4_PA_ONENAND 0x0C000000
-#define EXYNOS4_PA_ONENAND_DMA 0x0C600000
-
-#define EXYNOS4_PA_CHIPID 0x10000000
-
-#define EXYNOS4_PA_SYSCON 0x10010000
-#define EXYNOS4_PA_PMU 0x10020000
-#define EXYNOS4_PA_CMU 0x10030000
-
-#define EXYNOS4_PA_SYSTIMER 0x10050000
-#define EXYNOS4_PA_WATCHDOG 0x10060000
-#define EXYNOS4_PA_RTC 0x10070000
-
-#define EXYNOS4_PA_KEYPAD 0x100A0000
-
-#define EXYNOS4_PA_DMC0 0x10400000
-
-#define EXYNOS4_PA_COMBINER 0x10448000
-
-#define EXYNOS4_PA_COREPERI 0x10500000
-#define EXYNOS4_PA_GIC_CPU 0x10500100
-#define EXYNOS4_PA_TWD 0x10500600
-#define EXYNOS4_PA_GIC_DIST 0x10501000
-#define EXYNOS4_PA_L2CC 0x10502000
-
-#define EXYNOS4_PA_MDMA 0x10810000
-#define EXYNOS4_PA_PDMA0 0x12680000
-#define EXYNOS4_PA_PDMA1 0x12690000
-
-#define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000
-#define EXYNOS4_PA_SYSMMU_SSS 0x10A50000
-#define EXYNOS4_PA_SYSMMU_FIMC0 0x11A20000
-#define EXYNOS4_PA_SYSMMU_FIMC1 0x11A30000
-#define EXYNOS4_PA_SYSMMU_FIMC2 0x11A40000
-#define EXYNOS4_PA_SYSMMU_FIMC3 0x11A50000
-#define EXYNOS4_PA_SYSMMU_JPEG 0x11A60000
-#define EXYNOS4_PA_SYSMMU_FIMD0 0x11E20000
-#define EXYNOS4_PA_SYSMMU_FIMD1 0x12220000
-#define EXYNOS4_PA_SYSMMU_PCIe 0x12620000
-#define EXYNOS4_PA_SYSMMU_G2D 0x12A20000
-#define EXYNOS4_PA_SYSMMU_ROTATOR 0x12A30000
-#define EXYNOS4_PA_SYSMMU_MDMA2 0x12A40000
-#define EXYNOS4_PA_SYSMMU_TV 0x12E20000
-#define EXYNOS4_PA_SYSMMU_MFC_L 0x13620000
-#define EXYNOS4_PA_SYSMMU_MFC_R 0x13630000
-
-#define EXYNOS4_PA_GPIO1 0x11400000
-#define EXYNOS4_PA_GPIO2 0x11000000
-#define EXYNOS4_PA_GPIO3 0x03860000
-
-#define EXYNOS4_PA_MIPI_CSIS0 0x11880000
-#define EXYNOS4_PA_MIPI_CSIS1 0x11890000
-
-#define EXYNOS4_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
-
-#define EXYNOS4_PA_SATA 0x12560000
-#define EXYNOS4_PA_SATAPHY 0x125D0000
-#define EXYNOS4_PA_SATAPHY_CTRL 0x126B0000
-
-#define EXYNOS4_PA_SROMC 0x12570000
-
-#define EXYNOS4_PA_EHCI 0x12580000
-#define EXYNOS4_PA_HSPHY 0x125B0000
-
-#define EXYNOS4_PA_UART 0x13800000
-
-#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
-
-#define EXYNOS4_PA_AC97 0x139A0000
-
-#define EXYNOS4_PA_SPDIF 0x139B0000
-
-#define EXYNOS4_PA_TIMER 0x139D0000
-
-#define EXYNOS4_PA_SDRAM 0x40000000
-
-/* Compatibiltiy Defines */
-
-#define S3C_PA_HSMMC0 EXYNOS4_PA_HSMMC(0)
-#define S3C_PA_HSMMC1 EXYNOS4_PA_HSMMC(1)
-#define S3C_PA_HSMMC2 EXYNOS4_PA_HSMMC(2)
-#define S3C_PA_HSMMC3 EXYNOS4_PA_HSMMC(3)
-#define S3C_PA_IIC EXYNOS4_PA_IIC(0)
-#define S3C_PA_IIC1 EXYNOS4_PA_IIC(1)
-#define S3C_PA_IIC2 EXYNOS4_PA_IIC(2)
-#define S3C_PA_IIC3 EXYNOS4_PA_IIC(3)
-#define S3C_PA_IIC4 EXYNOS4_PA_IIC(4)
-#define S3C_PA_IIC5 EXYNOS4_PA_IIC(5)
-#define S3C_PA_IIC6 EXYNOS4_PA_IIC(6)
-#define S3C_PA_IIC7 EXYNOS4_PA_IIC(7)
-#define S3C_PA_RTC EXYNOS4_PA_RTC
-#define S3C_PA_WDT EXYNOS4_PA_WATCHDOG
-
-#define S5P_PA_CHIPID EXYNOS4_PA_CHIPID
-#define S5P_PA_FIMC0 EXYNOS4_PA_FIMC0
-#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
-#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
-#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
-#define S5P_PA_MIPI_CSIS0 EXYNOS4_PA_MIPI_CSIS0
-#define S5P_PA_MIPI_CSIS1 EXYNOS4_PA_MIPI_CSIS1
-#define S5P_PA_ONENAND EXYNOS4_PA_ONENAND
-#define S5P_PA_ONENAND_DMA EXYNOS4_PA_ONENAND_DMA
-#define S5P_PA_SDRAM EXYNOS4_PA_SDRAM
-#define S5P_PA_SROMC EXYNOS4_PA_SROMC
-#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
-#define S5P_PA_TIMER EXYNOS4_PA_TIMER
-#define S5P_PA_EHCI EXYNOS4_PA_EHCI
-
-#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD
-
-/* UART */
-
-#define S3C_PA_UART EXYNOS4_PA_UART
-
-#define S5P_PA_UART(x) (S3C_PA_UART + ((x) * S3C_UART_OFFSET))
-#define S5P_PA_UART0 S5P_PA_UART(0)
-#define S5P_PA_UART1 S5P_PA_UART(1)
-#define S5P_PA_UART2 S5P_PA_UART(2)
-#define S5P_PA_UART3 S5P_PA_UART(3)
-#define S5P_PA_UART4 S5P_PA_UART(4)
-
-#define S5P_SZ_UART SZ_256
-
-#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
deleted file mode 100644
index 6e311c1..0000000
--- a/arch/arm/mach-exynos4/include/mach/regs-clock.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-clock.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Clock register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_CLOCK_H
-#define __ASM_ARCH_REGS_CLOCK_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_CLKREG(x) (S5P_VA_CMU + (x))
-
-#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
-#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
-#define S5P_CLKGATE_IP_LEFTBUS S5P_CLKREG(0x04800)
-
-#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
-#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
-#define S5P_CLKGATE_IP_RIGHTBUS S5P_CLKREG(0x08800)
-
-#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
-#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
-#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120)
-#define S5P_VPLL_CON1 S5P_CLKREG(0x0C124)
-
-#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210)
-#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214)
-#define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220)
-#define S5P_CLKSRC_MFC S5P_CLKREG(0x0C228)
-#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
-#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
-#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
-#define S5P_CLKSRC_MAUDIO S5P_CLKREG(0x0C23C)
-#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
-#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
-#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
-
-#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
-#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
-#define S5P_CLKDIV_TV S5P_CLKREG(0x0C524)
-#define S5P_CLKDIV_MFC S5P_CLKREG(0x0C528)
-#define S5P_CLKDIV_G3D S5P_CLKREG(0x0C52C)
-#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
-#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
-#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
-#define S5P_CLKDIV_MAUDIO S5P_CLKREG(0x0C53C)
-#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
-#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
-#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548)
-#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C)
-#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550)
-#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554)
-#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
-#define S5P_CLKDIV_PERIL3 S5P_CLKREG(0x0C55C)
-#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
-#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
-
-#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
-#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
-#define S5P_CLKSRC_MASK_TV S5P_CLKREG(0x0C324)
-#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
-#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
-#define S5P_CLKSRC_MASK_MAUDIO S5P_CLKREG(0x0C33C)
-#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
-#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
-#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
-
-#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
-
-#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820)
-#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
-#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924)
-#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928)
-#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C)
-#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
-#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
-#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
-#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
-#define S5P_CLKGATE_IP_GPS S5P_CLKREG(0x0C94C)
-#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
-#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
-#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x0C970)
-
-#define S5P_CLKSRC_MASK_DMC S5P_CLKREG(0x10300)
-#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
-#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
-#define S5P_CLKDIV_DMC1 S5P_CLKREG(0x10504)
-#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
-#define S5P_CLKGATE_IP_DMC S5P_CLKREG(0x10900)
-
-#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
-#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
-#define S5P_APLL_CON0 S5P_CLKREG(0x14100)
-#define S5P_APLL_CON1 S5P_CLKREG(0x14104)
-#define S5P_MPLL_CON0 S5P_CLKREG(0x14108)
-#define S5P_MPLL_CON1 S5P_CLKREG(0x1410C)
-
-#define S5P_CLKSRC_CPU S5P_CLKREG(0x14200)
-#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
-
-#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
-#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
-#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
-#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
-
-#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
-#define S5P_CLKGATE_IP_CPU S5P_CLKREG(0x14900)
-
-#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
-
-#define S5P_APLLCON0_ENABLE_SHIFT (31)
-#define S5P_APLLCON0_LOCKED_SHIFT (29)
-#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
-#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
-
-#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
-#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
-
-#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
-#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
-#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
-#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
-#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
-#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
-#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
-#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
-#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
-#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
-#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
-#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
-#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
-#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
-
-#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
-#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
-#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
-#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
-#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
-#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
-#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
-#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
-#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
-#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
-#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
-#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
-#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
-#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
-#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
-#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
-
-#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
-#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
-#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
-#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
-#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
-#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
-#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
-#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
-
-#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
-#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
-#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
-#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
-
-/* Compatibility defines and inclusion */
-
-#include <mach/regs-pmu.h>
-
-#define S5P_EPLL_CON S5P_EPLL_CON0
-
-#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-gpio.h b/arch/arm/mach-exynos4/include/mach/regs-gpio.h
deleted file mode 100644
index 1401b21..0000000
--- a/arch/arm/mach-exynos4/include/mach/regs-gpio.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-gpio.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - GPIO (including EINT) register definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_GPIO_H
-#define __ASM_ARCH_REGS_GPIO_H __FILE__
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#define EXYNOS4_EINT40CON (S5P_VA_GPIO2 + 0xE00)
-#define S5P_EINT_CON(x) (EXYNOS4_EINT40CON + ((x) * 0x4))
-
-#define EXYNOS4_EINT40FLTCON0 (S5P_VA_GPIO2 + 0xE80)
-#define S5P_EINT_FLTCON(x) (EXYNOS4_EINT40FLTCON0 + ((x) * 0x4))
-
-#define EXYNOS4_EINT40MASK (S5P_VA_GPIO2 + 0xF00)
-#define S5P_EINT_MASK(x) (EXYNOS4_EINT40MASK + ((x) * 0x4))
-
-#define EXYNOS4_EINT40PEND (S5P_VA_GPIO2 + 0xF40)
-#define S5P_EINT_PEND(x) (EXYNOS4_EINT40PEND + ((x) * 0x4))
-
-#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
-
-#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
-
-#define EINT_MODE S3C_GPIO_SFN(0xf)
-
-#define EINT_GPIO_0(x) EXYNOS4_GPX0(x)
-#define EINT_GPIO_1(x) EXYNOS4_GPX1(x)
-#define EINT_GPIO_2(x) EXYNOS4_GPX2(x)
-#define EINT_GPIO_3(x) EXYNOS4_GPX3(x)
-
-#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
deleted file mode 100644
index a964337..0000000
--- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/regs-pmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Power management unit definition
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_PMU_H
-#define __ASM_ARCH_REGS_PMU_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
-
-#define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200)
-
-#define S5P_CENTRAL_LOWPWR_CFG (1 << 16)
-
-#define S5P_CENTRAL_SEQ_OPTION S5P_PMUREG(0x0208)
-
-#define S5P_USE_STANDBY_WFI0 (1 << 16)
-#define S5P_USE_STANDBY_WFI1 (1 << 17)
-#define S5P_USE_STANDBY_WFE0 (1 << 24)
-#define S5P_USE_STANDBY_WFE1 (1 << 25)
-#define S5P_USE_MASK ((0x3 << 16) | (0x3 << 24))
-
-#define S5P_WAKEUP_STAT S5P_PMUREG(0x0600)
-#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
-#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
-
-#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708)
-#define S5P_USBHOST_PHY_ENABLE (1 << 0)
-
-#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4)
-#define S5P_MIPI_DPHY_ENABLE (1 << 0)
-#define S5P_MIPI_DPHY_SRESETN (1 << 1)
-#define S5P_MIPI_DPHY_MRESETN (1 << 2)
-
-#define S5P_PMU_SATA_PHY_CONTROL S5P_PMUREG(0x0720)
-#define S5P_INFORM0 S5P_PMUREG(0x0800)
-#define S5P_INFORM1 S5P_PMUREG(0x0804)
-#define S5P_INFORM2 S5P_PMUREG(0x0808)
-#define S5P_INFORM3 S5P_PMUREG(0x080C)
-#define S5P_INFORM4 S5P_PMUREG(0x0810)
-#define S5P_INFORM5 S5P_PMUREG(0x0814)
-#define S5P_INFORM6 S5P_PMUREG(0x0818)
-#define S5P_INFORM7 S5P_PMUREG(0x081C)
-
-#define S5P_ARM_CORE0_LOWPWR S5P_PMUREG(0x1000)
-#define S5P_DIS_IRQ_CORE0 S5P_PMUREG(0x1004)
-#define S5P_DIS_IRQ_CENTRAL0 S5P_PMUREG(0x1008)
-#define S5P_ARM_CORE1_LOWPWR S5P_PMUREG(0x1010)
-#define S5P_DIS_IRQ_CORE1 S5P_PMUREG(0x1014)
-#define S5P_DIS_IRQ_CENTRAL1 S5P_PMUREG(0x1018)
-#define S5P_ARM_COMMON_LOWPWR S5P_PMUREG(0x1080)
-#define S5P_L2_0_LOWPWR S5P_PMUREG(0x10C0)
-#define S5P_L2_1_LOWPWR S5P_PMUREG(0x10C4)
-#define S5P_CMU_ACLKSTOP_LOWPWR S5P_PMUREG(0x1100)
-#define S5P_CMU_SCLKSTOP_LOWPWR S5P_PMUREG(0x1104)
-#define S5P_CMU_RESET_LOWPWR S5P_PMUREG(0x110C)
-#define S5P_APLL_SYSCLK_LOWPWR S5P_PMUREG(0x1120)
-#define S5P_MPLL_SYSCLK_LOWPWR S5P_PMUREG(0x1124)
-#define S5P_VPLL_SYSCLK_LOWPWR S5P_PMUREG(0x1128)
-#define S5P_EPLL_SYSCLK_LOWPWR S5P_PMUREG(0x112C)
-#define S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR S5P_PMUREG(0x1138)
-#define S5P_CMU_RESET_GPSALIVE_LOWPWR S5P_PMUREG(0x113C)
-#define S5P_CMU_CLKSTOP_CAM_LOWPWR S5P_PMUREG(0x1140)
-#define S5P_CMU_CLKSTOP_TV_LOWPWR S5P_PMUREG(0x1144)
-#define S5P_CMU_CLKSTOP_MFC_LOWPWR S5P_PMUREG(0x1148)
-#define S5P_CMU_CLKSTOP_G3D_LOWPWR S5P_PMUREG(0x114C)
-#define S5P_CMU_CLKSTOP_LCD0_LOWPWR S5P_PMUREG(0x1150)
-#define S5P_CMU_CLKSTOP_LCD1_LOWPWR S5P_PMUREG(0x1154)
-#define S5P_CMU_CLKSTOP_MAUDIO_LOWPWR S5P_PMUREG(0x1158)
-#define S5P_CMU_CLKSTOP_GPS_LOWPWR S5P_PMUREG(0x115C)
-#define S5P_CMU_RESET_CAM_LOWPWR S5P_PMUREG(0x1160)
-#define S5P_CMU_RESET_TV_LOWPWR S5P_PMUREG(0x1164)
-#define S5P_CMU_RESET_MFC_LOWPWR S5P_PMUREG(0x1168)
-#define S5P_CMU_RESET_G3D_LOWPWR S5P_PMUREG(0x116C)
-#define S5P_CMU_RESET_LCD0_LOWPWR S5P_PMUREG(0x1170)
-#define S5P_CMU_RESET_LCD1_LOWPWR S5P_PMUREG(0x1174)
-#define S5P_CMU_RESET_MAUDIO_LOWPWR S5P_PMUREG(0x1178)
-#define S5P_CMU_RESET_GPS_LOWPWR S5P_PMUREG(0x117C)
-#define S5P_TOP_BUS_LOWPWR S5P_PMUREG(0x1180)
-#define S5P_TOP_RETENTION_LOWPWR S5P_PMUREG(0x1184)
-#define S5P_TOP_PWR_LOWPWR S5P_PMUREG(0x1188)
-#define S5P_LOGIC_RESET_LOWPWR S5P_PMUREG(0x11A0)
-#define S5P_ONENAND_MEM_LOWPWR S5P_PMUREG(0x11C0)
-#define S5P_MODIMIF_MEM_LOWPWR S5P_PMUREG(0x11C4)
-#define S5P_G2D_ACP_MEM_LOWPWR S5P_PMUREG(0x11C8)
-#define S5P_USBOTG_MEM_LOWPWR S5P_PMUREG(0x11CC)
-#define S5P_HSMMC_MEM_LOWPWR S5P_PMUREG(0x11D0)
-#define S5P_CSSYS_MEM_LOWPWR S5P_PMUREG(0x11D4)
-#define S5P_SECSS_MEM_LOWPWR S5P_PMUREG(0x11D8)
-#define S5P_PCIE_MEM_LOWPWR S5P_PMUREG(0x11E0)
-#define S5P_SATA_MEM_LOWPWR S5P_PMUREG(0x11E4)
-#define S5P_PAD_RETENTION_DRAM_LOWPWR S5P_PMUREG(0x1200)
-#define S5P_PAD_RETENTION_MAUDIO_LOWPWR S5P_PMUREG(0x1204)
-#define S5P_PAD_RETENTION_GPIO_LOWPWR S5P_PMUREG(0x1220)
-#define S5P_PAD_RETENTION_UART_LOWPWR S5P_PMUREG(0x1224)
-#define S5P_PAD_RETENTION_MMCA_LOWPWR S5P_PMUREG(0x1228)
-#define S5P_PAD_RETENTION_MMCB_LOWPWR S5P_PMUREG(0x122C)
-#define S5P_PAD_RETENTION_EBIA_LOWPWR S5P_PMUREG(0x1230)
-#define S5P_PAD_RETENTION_EBIB_LOWPWR S5P_PMUREG(0x1234)
-#define S5P_PAD_RETENTION_ISOLATION_LOWPWR S5P_PMUREG(0x1240)
-#define S5P_PAD_RETENTION_ALV_SEL_LOWPWR S5P_PMUREG(0x1260)
-#define S5P_XUSBXTI_LOWPWR S5P_PMUREG(0x1280)
-#define S5P_XXTI_LOWPWR S5P_PMUREG(0x1284)
-#define S5P_EXT_REGULATOR_LOWPWR S5P_PMUREG(0x12C0)
-#define S5P_GPIO_MODE_LOWPWR S5P_PMUREG(0x1300)
-#define S5P_GPIO_MODE_MAUDIO_LOWPWR S5P_PMUREG(0x1340)
-#define S5P_CAM_LOWPWR S5P_PMUREG(0x1380)
-#define S5P_TV_LOWPWR S5P_PMUREG(0x1384)
-#define S5P_MFC_LOWPWR S5P_PMUREG(0x1388)
-#define S5P_G3D_LOWPWR S5P_PMUREG(0x138C)
-#define S5P_LCD0_LOWPWR S5P_PMUREG(0x1390)
-#define S5P_LCD1_LOWPWR S5P_PMUREG(0x1394)
-#define S5P_MAUDIO_LOWPWR S5P_PMUREG(0x1398)
-#define S5P_GPS_LOWPWR S5P_PMUREG(0x139C)
-#define S5P_GPS_ALIVE_LOWPWR S5P_PMUREG(0x13A0)
-
-#define S5P_ARM_CORE0_CONFIGURATION S5P_PMUREG(0x2000)
-#define S5P_ARM_CORE0_OPTION S5P_PMUREG(0x2008)
-#define S5P_ARM_CORE1_CONFIGURATION S5P_PMUREG(0x2080)
-#define S5P_ARM_CORE1_STATUS S5P_PMUREG(0x2084)
-#define S5P_ARM_CORE1_OPTION S5P_PMUREG(0x2088)
-
-#define S5P_ARM_COMMON_OPTION S5P_PMUREG(0x2408)
-#define S5P_TOP_PWR_OPTION S5P_PMUREG(0x2C48)
-#define S5P_CAM_OPTION S5P_PMUREG(0x3C08)
-#define S5P_TV_OPTION S5P_PMUREG(0x3C28)
-#define S5P_MFC_OPTION S5P_PMUREG(0x3C48)
-#define S5P_G3D_OPTION S5P_PMUREG(0x3C68)
-#define S5P_LCD0_OPTION S5P_PMUREG(0x3C88)
-#define S5P_LCD1_OPTION S5P_PMUREG(0x3CA8)
-#define S5P_MAUDIO_OPTION S5P_PMUREG(0x3CC8)
-#define S5P_GPS_OPTION S5P_PMUREG(0x3CE8)
-#define S5P_GPS_ALIVE_OPTION S5P_PMUREG(0x3D08)
-
-#define S5P_PAD_RET_MAUDIO_OPTION S5P_PMUREG(0x3028)
-#define S5P_PAD_RET_GPIO_OPTION S5P_PMUREG(0x3108)
-#define S5P_PAD_RET_UART_OPTION S5P_PMUREG(0x3128)
-#define S5P_PAD_RET_MMCA_OPTION S5P_PMUREG(0x3148)
-#define S5P_PAD_RET_MMCB_OPTION S5P_PMUREG(0x3168)
-#define S5P_PAD_RET_EBIA_OPTION S5P_PMUREG(0x3188)
-#define S5P_PAD_RET_EBIB_OPTION S5P_PMUREG(0x31A8)
-
-#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00)
-#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20)
-#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40)
-#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60)
-#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80)
-#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0)
-#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0)
-
-#define S5P_PMU_SATA_PHY_CONTROL_EN 0x1
-#define S5P_INT_LOCAL_PWR_EN 0x7
-
-#define S5P_CHECK_SLEEP 0x00000BAD
-
-#endif /* __ASM_ARCH_REGS_PMU_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
deleted file mode 100644
index c337cf3..0000000
--- a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef __PLAT_S5P_REGS_USB_PHY_H
-#define __PLAT_S5P_REGS_USB_PHY_H
-
-#define EXYNOS4_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
-
-#define EXYNOS4_PHYPWR EXYNOS4_HSOTG_PHYREG(0x00)
-#define PHY1_HSIC_NORMAL_MASK (0xf << 9)
-#define PHY1_HSIC1_SLEEP (1 << 12)
-#define PHY1_HSIC1_FORCE_SUSPEND (1 << 11)
-#define PHY1_HSIC0_SLEEP (1 << 10)
-#define PHY1_HSIC0_FORCE_SUSPEND (1 << 9)
-
-#define PHY1_STD_NORMAL_MASK (0x7 << 6)
-#define PHY1_STD_SLEEP (1 << 8)
-#define PHY1_STD_ANALOG_POWERDOWN (1 << 7)
-#define PHY1_STD_FORCE_SUSPEND (1 << 6)
-
-#define PHY0_NORMAL_MASK (0x39 << 0)
-#define PHY0_SLEEP (1 << 5)
-#define PHY0_OTG_DISABLE (1 << 4)
-#define PHY0_ANALOG_POWERDOWN (1 << 3)
-#define PHY0_FORCE_SUSPEND (1 << 0)
-
-#define EXYNOS4_PHYCLK EXYNOS4_HSOTG_PHYREG(0x04)
-#define PHY1_COMMON_ON_N (1 << 7)
-#define PHY0_COMMON_ON_N (1 << 4)
-#define PHY0_ID_PULLUP (1 << 2)
-#define CLKSEL_MASK (0x3 << 0)
-#define CLKSEL_SHIFT (0)
-#define CLKSEL_48M (0x0 << 0)
-#define CLKSEL_12M (0x2 << 0)
-#define CLKSEL_24M (0x3 << 0)
-
-#define EXYNOS4_RSTCON EXYNOS4_HSOTG_PHYREG(0x08)
-#define HOST_LINK_PORT_SWRST_MASK (0xf << 6)
-#define HOST_LINK_PORT2_SWRST (1 << 9)
-#define HOST_LINK_PORT1_SWRST (1 << 8)
-#define HOST_LINK_PORT0_SWRST (1 << 7)
-#define HOST_LINK_ALL_SWRST (1 << 6)
-
-#define PHY1_SWRST_MASK (0x7 << 3)
-#define PHY1_HSIC_SWRST (1 << 5)
-#define PHY1_STD_SWRST (1 << 4)
-#define PHY1_ALL_SWRST (1 << 3)
-
-#define PHY0_SWRST_MASK (0x7 << 0)
-#define PHY0_PHYLINK_SWRST (1 << 2)
-#define PHY0_HLINK_SWRST (1 << 1)
-#define PHY0_SWRST (1 << 0)
-
-#define EXYNOS4_PHY1CON EXYNOS4_HSOTG_PHYREG(0x34)
-#define FPENABLEN (1 << 0)
-
-#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/mach-exynos4/include/mach/sysmmu.h b/arch/arm/mach-exynos4/include/mach/sysmmu.h
deleted file mode 100644
index 6a5fbb5..0000000
--- a/arch/arm/mach-exynos4/include/mach/sysmmu.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung sysmmu driver for EXYNOS4
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARM_ARCH_SYSMMU_H
-#define __ASM_ARM_ARCH_SYSMMU_H __FILE__
-
-enum exynos4_sysmmu_ips {
- SYSMMU_MDMA,
- SYSMMU_SSS,
- SYSMMU_FIMC0,
- SYSMMU_FIMC1,
- SYSMMU_FIMC2,
- SYSMMU_FIMC3,
- SYSMMU_JPEG,
- SYSMMU_FIMD0,
- SYSMMU_FIMD1,
- SYSMMU_PCIe,
- SYSMMU_G2D,
- SYSMMU_ROTATOR,
- SYSMMU_MDMA2,
- SYSMMU_TV,
- SYSMMU_MFC_L,
- SYSMMU_MFC_R,
- EXYNOS4_SYSMMU_TOTAL_IPNUM,
-};
-
-#define S5P_SYSMMU_TOTAL_IPNUM EXYNOS4_SYSMMU_TOTAL_IPNUM
-
-extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM];
-
-typedef enum exynos4_sysmmu_ips sysmmu_ips;
-
-void sysmmu_clk_init(struct device *dev, sysmmu_ips ips);
-void sysmmu_clk_enable(sysmmu_ips ips);
-void sysmmu_clk_disable(sysmmu_ips ips);
-
-#endif /* __ASM_ARM_ARCH_SYSMMU_H */
diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
deleted file mode 100644
index 6bf3d0a..0000000
--- a/arch/arm/mach-exynos4/localtimer.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* linux/arch/arm/mach-exynos4/localtimer.c
- *
- * Cloned from linux/arch/arm/mach-realview/localtimer.c
- *
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
- evt->irq = IRQ_LOCALTIMER;
- twd_timer_setup(evt);
- return 0;
-}
diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
deleted file mode 100644
index e645f7a..0000000
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-smdkc210.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/smsc911x.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/regs-srom.h>
-#include <plat/exynos4.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/sdhci.h>
-#include <plat/iic.h>
-#include <plat/pd.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
- S3C2410_UCON_RXILEVEL | \
- S3C2410_UCON_TXIRQMODE | \
- S3C2410_UCON_RXIRQMODE | \
- S3C2410_UCON_RXFIFO_TOI | \
- S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
-
-#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
- S5PV210_UFCON_TXTRIG4 | \
- S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = SMDKC210_UCON_DEFAULT,
- .ulcon = SMDKC210_ULCON_DEFAULT,
- .ufcon = SMDKC210_UFCON_DEFAULT,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = SMDKC210_UCON_DEFAULT,
- .ulcon = SMDKC210_ULCON_DEFAULT,
- .ufcon = SMDKC210_UFCON_DEFAULT,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = SMDKC210_UCON_DEFAULT,
- .ulcon = SMDKC210_ULCON_DEFAULT,
- .ufcon = SMDKC210_UFCON_DEFAULT,
- },
- [3] = {
- .hwport = 3,
- .flags = 0,
- .ucon = SMDKC210_UCON_DEFAULT,
- .ulcon = SMDKC210_ULCON_DEFAULT,
- .ufcon = SMDKC210_UFCON_DEFAULT,
- },
-};
-
-static struct s3c_sdhci_platdata smdkc210_hsmmc0_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
- .ext_cd_gpio = EXYNOS4_GPK0(2),
- .ext_cd_gpio_invert = 1,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
- .max_width = 8,
- .host_caps = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkc210_hsmmc1_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
- .ext_cd_gpio = EXYNOS4_GPK0(2),
- .ext_cd_gpio_invert = 1,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct s3c_sdhci_platdata smdkc210_hsmmc2_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
- .ext_cd_gpio = EXYNOS4_GPK2(2),
- .ext_cd_gpio_invert = 1,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
- .max_width = 8,
- .host_caps = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
- .ext_cd_gpio = EXYNOS4_GPK2(2),
- .ext_cd_gpio_invert = 1,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct resource smdkc210_smsc911x_resources[] = {
- [0] = {
- .start = EXYNOS4_PA_SROM_BANK(1),
- .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_EINT(5),
- .end = IRQ_EINT(5),
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
- },
-};
-
-static struct smsc911x_platform_config smsc9215_config = {
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
- .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
- .phy_interface = PHY_INTERFACE_MODE_MII,
- .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
-};
-
-static struct platform_device smdkc210_smsc911x = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smdkc210_smsc911x_resources),
- .resource = smdkc210_smsc911x_resources,
- .dev = {
- .platform_data = &smsc9215_config,
- },
-};
-
-static struct i2c_board_info i2c_devs1[] __initdata = {
- {I2C_BOARD_INFO("wm8994", 0x1a),},
-};
-
-static struct platform_device *smdkc210_devices[] __initdata = {
- &s3c_device_hsmmc0,
- &s3c_device_hsmmc1,
- &s3c_device_hsmmc2,
- &s3c_device_hsmmc3,
- &s3c_device_i2c1,
- &s3c_device_rtc,
- &s3c_device_wdt,
- &exynos4_device_ac97,
- &exynos4_device_i2s0,
- &exynos4_device_pd[PD_MFC],
- &exynos4_device_pd[PD_G3D],
- &exynos4_device_pd[PD_LCD0],
- &exynos4_device_pd[PD_LCD1],
- &exynos4_device_pd[PD_CAM],
- &exynos4_device_pd[PD_TV],
- &exynos4_device_pd[PD_GPS],
- &exynos4_device_sysmmu,
- &samsung_asoc_dma,
- &smdkc210_smsc911x,
-};
-
-static void __init smdkc210_smsc911x_init(void)
-{
- u32 cs1;
-
- /* configure nCS1 width to 16 bits */
- cs1 = __raw_readl(S5P_SROM_BW) &
- ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
- cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
- (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
- (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
- S5P_SROM_BW__NCS1__SHIFT;
- __raw_writel(cs1, S5P_SROM_BW);
-
- /* set timing for nCS1 suitable for ethernet chip */
- __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
- (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
- (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
- (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
- (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
- (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
- (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
-}
-
-static void __init smdkc210_map_io(void)
-{
- s5p_init_io(NULL, 0, S5P_VA_CHIPID);
- s3c24xx_init_clocks(24000000);
- s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
-}
-
-static void __init smdkc210_machine_init(void)
-{
- s3c_i2c1_set_platdata(NULL);
- i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-
- smdkc210_smsc911x_init();
-
- s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
- s3c_sdhci1_set_platdata(&smdkc210_hsmmc1_pdata);
- s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
- s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
-
- platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
-}
-
-MACHINE_START(SMDKC210, "SMDKC210")
- /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
- .boot_params = S5P_PA_SDRAM + 0x100,
- .init_irq = exynos4_init_irq,
- .map_io = smdkc210_map_io,
- .init_machine = smdkc210_machine_init,
- .timer = &exynos4_timer,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
deleted file mode 100644
index edd8141..0000000
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mach-smdkv310.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/serial_core.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/smsc911x.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <plat/regs-serial.h>
-#include <plat/regs-srom.h>
-#include <plat/exynos4.h>
-#include <plat/cpu.h>
-#include <plat/devs.h>
-#include <plat/keypad.h>
-#include <plat/sdhci.h>
-#include <plat/iic.h>
-#include <plat/pd.h>
-
-#include <mach/map.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
- S3C2410_UCON_RXILEVEL | \
- S3C2410_UCON_TXIRQMODE | \
- S3C2410_UCON_RXIRQMODE | \
- S3C2410_UCON_RXFIFO_TOI | \
- S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDKV310_ULCON_DEFAULT S3C2410_LCON_CS8
-
-#define SMDKV310_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
- S5PV210_UFCON_TXTRIG4 | \
- S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
- [0] = {
- .hwport = 0,
- .flags = 0,
- .ucon = SMDKV310_UCON_DEFAULT,
- .ulcon = SMDKV310_ULCON_DEFAULT,
- .ufcon = SMDKV310_UFCON_DEFAULT,
- },
- [1] = {
- .hwport = 1,
- .flags = 0,
- .ucon = SMDKV310_UCON_DEFAULT,
- .ulcon = SMDKV310_ULCON_DEFAULT,
- .ufcon = SMDKV310_UFCON_DEFAULT,
- },
- [2] = {
- .hwport = 2,
- .flags = 0,
- .ucon = SMDKV310_UCON_DEFAULT,
- .ulcon = SMDKV310_ULCON_DEFAULT,
- .ufcon = SMDKV310_UFCON_DEFAULT,
- },
- [3] = {
- .hwport = 3,
- .flags = 0,
- .ucon = SMDKV310_UCON_DEFAULT,
- .ulcon = SMDKV310_ULCON_DEFAULT,
- .ufcon = SMDKV310_UFCON_DEFAULT,
- },
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_INTERNAL,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
- .max_width = 8,
- .host_caps = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
- .ext_cd_gpio = EXYNOS4_GPK0(2),
- .ext_cd_gpio_invert = 1,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_INTERNAL,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-#ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
- .max_width = 8,
- .host_caps = MMC_CAP_8_BIT_DATA,
-#endif
-};
-
-static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
- .ext_cd_gpio = EXYNOS4_GPK2(2),
- .ext_cd_gpio_invert = 1,
- .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
-};
-
-static struct resource smdkv310_smsc911x_resources[] = {
- [0] = {
- .start = EXYNOS4_PA_SROM_BANK(1),
- .end = EXYNOS4_PA_SROM_BANK(1) + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_EINT(5),
- .end = IRQ_EINT(5),
- .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
- },
-};
-
-static struct smsc911x_platform_config smsc9215_config = {
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
- .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
- .phy_interface = PHY_INTERFACE_MODE_MII,
- .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
-};
-
-static struct platform_device smdkv310_smsc911x = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
- .resource = smdkv310_smsc911x_resources,
- .dev = {
- .platform_data = &smsc9215_config,
- },
-};
-
-static uint32_t smdkv310_keymap[] __initdata = {
- /* KEY(row, col, keycode) */
- KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
- KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
- KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
- KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
-};
-
-static struct matrix_keymap_data smdkv310_keymap_data __initdata = {
- .keymap = smdkv310_keymap,
- .keymap_size = ARRAY_SIZE(smdkv310_keymap),
-};
-
-static struct samsung_keypad_platdata smdkv310_keypad_data __initdata = {
- .keymap_data = &smdkv310_keymap_data,
- .rows = 2,
- .cols = 8,
-};
-
-static struct i2c_board_info i2c_devs1[] __initdata = {
- {I2C_BOARD_INFO("wm8994", 0x1a),},
-};
-
-static struct platform_device *smdkv310_devices[] __initdata = {
- &s3c_device_hsmmc0,
- &s3c_device_hsmmc1,
- &s3c_device_hsmmc2,
- &s3c_device_hsmmc3,
- &s3c_device_i2c1,
- &s3c_device_rtc,
- &s3c_device_wdt,
- &exynos4_device_ac97,
- &exynos4_device_i2s0,
- &samsung_device_keypad,
- &exynos4_device_pd[PD_MFC],
- &exynos4_device_pd[PD_G3D],
- &exynos4_device_pd[PD_LCD0],
- &exynos4_device_pd[PD_LCD1],
- &exynos4_device_pd[PD_CAM],
- &exynos4_device_pd[PD_TV],
- &exynos4_device_pd[PD_GPS],
- &exynos4_device_sysmmu,
- &samsung_asoc_dma,
- &smdkv310_smsc911x,
-};
-
-static void __init smdkv310_smsc911x_init(void)
-{
- u32 cs1;
-
- /* configure nCS1 width to 16 bits */
- cs1 = __raw_readl(S5P_SROM_BW) &
- ~(S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS1__SHIFT);
- cs1 |= ((1 << S5P_SROM_BW__DATAWIDTH__SHIFT) |
- (1 << S5P_SROM_BW__WAITENABLE__SHIFT) |
- (1 << S5P_SROM_BW__BYTEENABLE__SHIFT)) <<
- S5P_SROM_BW__NCS1__SHIFT;
- __raw_writel(cs1, S5P_SROM_BW);
-
- /* set timing for nCS1 suitable for ethernet chip */
- __raw_writel((0x1 << S5P_SROM_BCX__PMC__SHIFT) |
- (0x9 << S5P_SROM_BCX__TACP__SHIFT) |
- (0xc << S5P_SROM_BCX__TCAH__SHIFT) |
- (0x1 << S5P_SROM_BCX__TCOH__SHIFT) |
- (0x6 << S5P_SROM_BCX__TACC__SHIFT) |
- (0x1 << S5P_SROM_BCX__TCOS__SHIFT) |
- (0x1 << S5P_SROM_BCX__TACS__SHIFT), S5P_SROM_BC1);
-}
-
-static void __init smdkv310_map_io(void)
-{
- s5p_init_io(NULL, 0, S5P_VA_CHIPID);
- s3c24xx_init_clocks(24000000);
- s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
-}
-
-static void __init smdkv310_machine_init(void)
-{
- s3c_i2c1_set_platdata(NULL);
- i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
-
- smdkv310_smsc911x_init();
-
- s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
- s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
- s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
- s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
-
- samsung_keypad_set_platdata(&smdkv310_keypad_data);
-
- platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-}
-
-MACHINE_START(SMDKV310, "SMDKV310")
- /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
- /* Maintainer: Changhwan Youn <chaos.youn@samsung.com> */
- .boot_params = S5P_PA_SDRAM + 0x100,
- .init_irq = exynos4_init_irq,
- .map_io = smdkv310_map_io,
- .init_machine = smdkv310_machine_init,
- .timer = &exynos4_timer,
-MACHINE_END
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c
deleted file mode 100644
index 8755ca8..0000000
--- a/arch/arm/mach-exynos4/pm.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/* linux/arch/arm/mach-exynos4/pm.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4210 - Power Management support
- *
- * Based on arch/arm/mach-s3c2410/pm.c
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/init.h>
-#include <linux/suspend.h>
-#include <linux/syscore_ops.h>
-#include <linux/io.h>
-
-#include <asm/cacheflush.h>
-#include <asm/hardware/cache-l2x0.h>
-
-#include <plat/cpu.h>
-#include <plat/pm.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-pmu.h>
-#include <mach/pm-core.h>
-
-static struct sleep_save exynos4_sleep[] = {
- { .reg = S5P_ARM_CORE0_LOWPWR , .val = 0x2, },
- { .reg = S5P_DIS_IRQ_CORE0 , .val = 0x0, },
- { .reg = S5P_DIS_IRQ_CENTRAL0 , .val = 0x0, },
- { .reg = S5P_ARM_CORE1_LOWPWR , .val = 0x2, },
- { .reg = S5P_DIS_IRQ_CORE1 , .val = 0x0, },
- { .reg = S5P_DIS_IRQ_CENTRAL1 , .val = 0x0, },
- { .reg = S5P_ARM_COMMON_LOWPWR , .val = 0x2, },
- { .reg = S5P_L2_0_LOWPWR , .val = 0x3, },
- { .reg = S5P_L2_1_LOWPWR , .val = 0x3, },
- { .reg = S5P_CMU_ACLKSTOP_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_SCLKSTOP_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_LOWPWR , .val = 0x0, },
- { .reg = S5P_APLL_SYSCLK_LOWPWR , .val = 0x0, },
- { .reg = S5P_MPLL_SYSCLK_LOWPWR , .val = 0x0, },
- { .reg = S5P_VPLL_SYSCLK_LOWPWR , .val = 0x0, },
- { .reg = S5P_EPLL_SYSCLK_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_GPSALIVE_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_CAM_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_TV_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_MFC_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_G3D_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_LCD0_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_LCD1_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_MAUDIO_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_CLKSTOP_GPS_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_CAM_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_TV_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_MFC_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_G3D_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_LCD0_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_LCD1_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_MAUDIO_LOWPWR , .val = 0x0, },
- { .reg = S5P_CMU_RESET_GPS_LOWPWR , .val = 0x0, },
- { .reg = S5P_TOP_BUS_LOWPWR , .val = 0x0, },
- { .reg = S5P_TOP_RETENTION_LOWPWR , .val = 0x1, },
- { .reg = S5P_TOP_PWR_LOWPWR , .val = 0x3, },
- { .reg = S5P_LOGIC_RESET_LOWPWR , .val = 0x0, },
- { .reg = S5P_ONENAND_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_MODIMIF_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_G2D_ACP_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_USBOTG_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_HSMMC_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_CSSYS_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_SECSS_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_PCIE_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_SATA_MEM_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_DRAM_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_MAUDIO_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_GPIO_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_UART_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_MMCA_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_MMCB_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_EBIA_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_EBIB_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_ISOLATION_LOWPWR , .val = 0x0, },
- { .reg = S5P_PAD_RETENTION_ALV_SEL_LOWPWR , .val = 0x0, },
- { .reg = S5P_XUSBXTI_LOWPWR , .val = 0x0, },
- { .reg = S5P_XXTI_LOWPWR , .val = 0x0, },
- { .reg = S5P_EXT_REGULATOR_LOWPWR , .val = 0x0, },
- { .reg = S5P_GPIO_MODE_LOWPWR , .val = 0x0, },
- { .reg = S5P_GPIO_MODE_MAUDIO_LOWPWR , .val = 0x0, },
- { .reg = S5P_CAM_LOWPWR , .val = 0x0, },
- { .reg = S5P_TV_LOWPWR , .val = 0x0, },
- { .reg = S5P_MFC_LOWPWR , .val = 0x0, },
- { .reg = S5P_G3D_LOWPWR , .val = 0x0, },
- { .reg = S5P_LCD0_LOWPWR , .val = 0x0, },
- { .reg = S5P_LCD1_LOWPWR , .val = 0x0, },
- { .reg = S5P_MAUDIO_LOWPWR , .val = 0x0, },
- { .reg = S5P_GPS_LOWPWR , .val = 0x0, },
- { .reg = S5P_GPS_ALIVE_LOWPWR , .val = 0x0, },
-};
-
-static struct sleep_save exynos4_set_clksrc[] = {
- { .reg = S5P_CLKSRC_MASK_TOP , .val = 0x00000001, },
- { .reg = S5P_CLKSRC_MASK_CAM , .val = 0x11111111, },
- { .reg = S5P_CLKSRC_MASK_TV , .val = 0x00000111, },
- { .reg = S5P_CLKSRC_MASK_LCD0 , .val = 0x00001111, },
- { .reg = S5P_CLKSRC_MASK_LCD1 , .val = 0x00001111, },
- { .reg = S5P_CLKSRC_MASK_MAUDIO , .val = 0x00000001, },
- { .reg = S5P_CLKSRC_MASK_FSYS , .val = 0x01011111, },
- { .reg = S5P_CLKSRC_MASK_PERIL0 , .val = 0x01111111, },
- { .reg = S5P_CLKSRC_MASK_PERIL1 , .val = 0x01110111, },
- { .reg = S5P_CLKSRC_MASK_DMC , .val = 0x00010000, },
-};
-
-static struct sleep_save exynos4_core_save[] = {
- /* CMU side */
- SAVE_ITEM(S5P_CLKDIV_LEFTBUS),
- SAVE_ITEM(S5P_CLKGATE_IP_LEFTBUS),
- SAVE_ITEM(S5P_CLKDIV_RIGHTBUS),
- SAVE_ITEM(S5P_CLKGATE_IP_RIGHTBUS),
- SAVE_ITEM(S5P_EPLL_CON0),
- SAVE_ITEM(S5P_EPLL_CON1),
- SAVE_ITEM(S5P_VPLL_CON0),
- SAVE_ITEM(S5P_VPLL_CON1),
- SAVE_ITEM(S5P_CLKSRC_TOP0),
- SAVE_ITEM(S5P_CLKSRC_TOP1),
- SAVE_ITEM(S5P_CLKSRC_CAM),
- SAVE_ITEM(S5P_CLKSRC_MFC),
- SAVE_ITEM(S5P_CLKSRC_IMAGE),
- SAVE_ITEM(S5P_CLKSRC_LCD0),
- SAVE_ITEM(S5P_CLKSRC_LCD1),
- SAVE_ITEM(S5P_CLKSRC_MAUDIO),
- SAVE_ITEM(S5P_CLKSRC_FSYS),
- SAVE_ITEM(S5P_CLKSRC_PERIL0),
- SAVE_ITEM(S5P_CLKSRC_PERIL1),
- SAVE_ITEM(S5P_CLKDIV_CAM),
- SAVE_ITEM(S5P_CLKDIV_TV),
- SAVE_ITEM(S5P_CLKDIV_MFC),
- SAVE_ITEM(S5P_CLKDIV_G3D),
- SAVE_ITEM(S5P_CLKDIV_IMAGE),
- SAVE_ITEM(S5P_CLKDIV_LCD0),
- SAVE_ITEM(S5P_CLKDIV_LCD1),
- SAVE_ITEM(S5P_CLKDIV_MAUDIO),
- SAVE_ITEM(S5P_CLKDIV_FSYS0),
- SAVE_ITEM(S5P_CLKDIV_FSYS1),
- SAVE_ITEM(S5P_CLKDIV_FSYS2),
- SAVE_ITEM(S5P_CLKDIV_FSYS3),
- SAVE_ITEM(S5P_CLKDIV_PERIL0),
- SAVE_ITEM(S5P_CLKDIV_PERIL1),
- SAVE_ITEM(S5P_CLKDIV_PERIL2),
- SAVE_ITEM(S5P_CLKDIV_PERIL3),
- SAVE_ITEM(S5P_CLKDIV_PERIL4),
- SAVE_ITEM(S5P_CLKDIV_PERIL5),
- SAVE_ITEM(S5P_CLKDIV_TOP),
- SAVE_ITEM(S5P_CLKSRC_MASK_CAM),
- SAVE_ITEM(S5P_CLKSRC_MASK_TV),
- SAVE_ITEM(S5P_CLKSRC_MASK_LCD0),
- SAVE_ITEM(S5P_CLKSRC_MASK_LCD1),
- SAVE_ITEM(S5P_CLKSRC_MASK_MAUDIO),
- SAVE_ITEM(S5P_CLKSRC_MASK_FSYS),
- SAVE_ITEM(S5P_CLKSRC_MASK_PERIL0),
- SAVE_ITEM(S5P_CLKSRC_MASK_PERIL1),
- SAVE_ITEM(S5P_CLKGATE_SCLKCAM),
- SAVE_ITEM(S5P_CLKGATE_IP_CAM),
- SAVE_ITEM(S5P_CLKGATE_IP_TV),
- SAVE_ITEM(S5P_CLKGATE_IP_MFC),
- SAVE_ITEM(S5P_CLKGATE_IP_G3D),
- SAVE_ITEM(S5P_CLKGATE_IP_IMAGE),
- SAVE_ITEM(S5P_CLKGATE_IP_LCD0),
- SAVE_ITEM(S5P_CLKGATE_IP_LCD1),
- SAVE_ITEM(S5P_CLKGATE_IP_FSYS),
- SAVE_ITEM(S5P_CLKGATE_IP_GPS),
- SAVE_ITEM(S5P_CLKGATE_IP_PERIL),
- SAVE_ITEM(S5P_CLKGATE_IP_PERIR),
- SAVE_ITEM(S5P_CLKGATE_BLOCK),
- SAVE_ITEM(S5P_CLKSRC_MASK_DMC),
- SAVE_ITEM(S5P_CLKSRC_DMC),
- SAVE_ITEM(S5P_CLKDIV_DMC0),
- SAVE_ITEM(S5P_CLKDIV_DMC1),
- SAVE_ITEM(S5P_CLKGATE_IP_DMC),
- SAVE_ITEM(S5P_CLKSRC_CPU),
- SAVE_ITEM(S5P_CLKDIV_CPU),
- SAVE_ITEM(S5P_CLKGATE_SCLKCPU),
- SAVE_ITEM(S5P_CLKGATE_IP_CPU),
- /* GIC side */
- SAVE_ITEM(S5P_VA_GIC_CPU + 0x000),
- SAVE_ITEM(S5P_VA_GIC_CPU + 0x004),
- SAVE_ITEM(S5P_VA_GIC_CPU + 0x008),
- SAVE_ITEM(S5P_VA_GIC_CPU + 0x00C),
- SAVE_ITEM(S5P_VA_GIC_CPU + 0x014),
- SAVE_ITEM(S5P_VA_GIC_CPU + 0x018),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x000),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x004),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x100),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x104),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x108),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x300),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x304),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x308),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x400),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x404),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x408),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x40C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x410),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x414),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x418),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x41C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x420),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x424),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x428),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x42C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x430),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x434),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x438),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x43C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x440),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x444),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x448),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x44C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x450),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x454),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x458),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x45C),
-
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x800),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x804),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x808),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x80C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x810),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x814),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x818),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x81C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x820),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x824),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x828),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x82C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x830),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x834),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x838),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x83C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x840),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x844),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x848),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x84C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x850),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x854),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x858),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0x85C),
-
- SAVE_ITEM(S5P_VA_GIC_DIST + 0xC00),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0xC04),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0xC08),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0xC0C),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0xC10),
- SAVE_ITEM(S5P_VA_GIC_DIST + 0xC14),
-
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x000),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x010),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x020),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x030),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x040),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x050),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x060),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x070),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x080),
- SAVE_ITEM(S5P_VA_COMBINER_BASE + 0x090),
-};
-
-static struct sleep_save exynos4_l2cc_save[] = {
- SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
- SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
- SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
- SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
- SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
-};
-
-void exynos4_cpu_suspend(void)
-{
- unsigned long tmp;
- unsigned long mask = 0xFFFFFFFF;
-
- /* Setting Central Sequence Register for power down mode */
-
- tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
- tmp &= ~(S5P_CENTRAL_LOWPWR_CFG);
- __raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
-
- /* Setting Central Sequence option Register */
-
- tmp = __raw_readl(S5P_CENTRAL_SEQ_OPTION);
- tmp &= ~(S5P_USE_MASK);
- tmp |= S5P_USE_STANDBY_WFI0;
- __raw_writel(tmp, S5P_CENTRAL_SEQ_OPTION);
-
- /* Clear all interrupt pending to avoid early wakeup */
-
- __raw_writel(mask, (S5P_VA_GIC_DIST + 0x280));
- __raw_writel(mask, (S5P_VA_GIC_DIST + 0x284));
- __raw_writel(mask, (S5P_VA_GIC_DIST + 0x288));
-
- /* Disable all interrupt */
-
- __raw_writel(0x0, (S5P_VA_GIC_CPU + 0x000));
- __raw_writel(0x0, (S5P_VA_GIC_DIST + 0x000));
- __raw_writel(mask, (S5P_VA_GIC_DIST + 0x184));
- __raw_writel(mask, (S5P_VA_GIC_DIST + 0x188));
-
- outer_flush_all();
-
- /* issue the standby signal into the pm unit. */
- cpu_do_idle();
-
- /* we should never get past here */
- panic("sleep resumed to originator?");
-}
-
-static void exynos4_pm_prepare(void)
-{
- u32 tmp;
-
- s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
- s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
-
- tmp = __raw_readl(S5P_INFORM1);
-
- /* Set value of power down register for sleep mode */
-
- s3c_pm_do_restore_core(exynos4_sleep, ARRAY_SIZE(exynos4_sleep));
- __raw_writel(S5P_CHECK_SLEEP, S5P_INFORM1);
-
- /* ensure at least INFORM0 has the resume address */
-
- __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
-
- /* Before enter central sequence mode, clock src register have to set */
-
- s3c_pm_do_restore_core(exynos4_set_clksrc, ARRAY_SIZE(exynos4_set_clksrc));
-
-}
-
-static int exynos4_pm_add(struct sys_device *sysdev)
-{
- pm_cpu_prep = exynos4_pm_prepare;
- pm_cpu_sleep = exynos4_cpu_suspend;
-
- return 0;
-}
-
-/* This function copy from linux/arch/arm/kernel/smp_scu.c */
-
-void exynos4_scu_enable(void __iomem *scu_base)
-{
- u32 scu_ctrl;
-
- scu_ctrl = __raw_readl(scu_base);
- /* already enabled? */
- if (scu_ctrl & 1)
- return;
-
- scu_ctrl |= 1;
- __raw_writel(scu_ctrl, scu_base);
-
- /*
- * Ensure that the data accessed by CPU0 before the SCU was
- * initialised is visible to the other CPUs.
- */
- flush_cache_all();
-}
-
-static struct sysdev_driver exynos4_pm_driver = {
- .add = exynos4_pm_add,
-};
-
-static __init int exynos4_pm_drvinit(void)
-{
- unsigned int tmp;
-
- s3c_pm_init();
-
- /* All wakeup disable */
-
- tmp = __raw_readl(S5P_WAKEUP_MASK);
- tmp |= ((0xFF << 8) | (0x1F << 1));
- __raw_writel(tmp, S5P_WAKEUP_MASK);
-
- return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
-}
-arch_initcall(exynos4_pm_drvinit);
-
-static void exynos4_pm_resume(void)
-{
- /* For release retention */
-
- __raw_writel((1 << 28), S5P_PAD_RET_MAUDIO_OPTION);
- __raw_writel((1 << 28), S5P_PAD_RET_GPIO_OPTION);
- __raw_writel((1 << 28), S5P_PAD_RET_UART_OPTION);
- __raw_writel((1 << 28), S5P_PAD_RET_MMCA_OPTION);
- __raw_writel((1 << 28), S5P_PAD_RET_MMCB_OPTION);
- __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
- __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
-
- s3c_pm_do_restore_core(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
-
- exynos4_scu_enable(S5P_VA_SCU);
-
-#ifdef CONFIG_CACHE_L2X0
- s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
- outer_inv_all();
- /* enable L2X0*/
- writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
-#endif
-}
-
-static struct syscore_ops exynos4_pm_syscore_ops = {
- .resume = exynos4_pm_resume,
-};
-
-static __init int exynos4_pm_syscore_init(void)
-{
- register_syscore_ops(&exynos4_pm_syscore_ops);
- return 0;
-}
-arch_initcall(exynos4_pm_syscore_init);
diff --git a/arch/arm/mach-exynos4/setup-sdhci-gpio.c b/arch/arm/mach-exynos4/setup-sdhci-gpio.c
deleted file mode 100644
index e8d08bf..0000000
--- a/arch/arm/mach-exynos4/setup-sdhci-gpio.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/* linux/arch/arm/mach-exynos4/setup-sdhci-gpio.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/card.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/regs-sdhci.h>
-#include <plat/sdhci.h>
-
-void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
-{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
-
- /* Set all the necessary GPK0[0:1] pins to special-function 2 */
- for (gpio = EXYNOS4_GPK0(0); gpio < EXYNOS4_GPK0(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- switch (width) {
- case 8:
- for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
- /* Data pin GPK1[3:6] to special-function 3 */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
- case 4:
- for (gpio = EXYNOS4_GPK0(3); gpio <= EXYNOS4_GPK0(6); gpio++) {
- /* Data pin GPK0[3:6] to special-function 2 */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
- default:
- break;
- }
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_cfgpin(EXYNOS4_GPK0(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(EXYNOS4_GPK0(2), S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-}
-
-void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
-{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
-
- /* Set all the necessary GPK1[0:1] pins to special-function 2 */
- for (gpio = EXYNOS4_GPK1(0); gpio < EXYNOS4_GPK1(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- for (gpio = EXYNOS4_GPK1(3); gpio <= EXYNOS4_GPK1(6); gpio++) {
- /* Data pin GPK1[3:6] to special-function 2 */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_cfgpin(EXYNOS4_GPK1(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(EXYNOS4_GPK1(2), S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-}
-
-void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
-{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
-
- /* Set all the necessary GPK2[0:1] pins to special-function 2 */
- for (gpio = EXYNOS4_GPK2(0); gpio < EXYNOS4_GPK2(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- switch (width) {
- case 8:
- for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
- /* Data pin GPK3[3:6] to special-function 3 */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
- case 4:
- for (gpio = EXYNOS4_GPK2(3); gpio <= EXYNOS4_GPK2(6); gpio++) {
- /* Data pin GPK2[3:6] to special-function 2 */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
- default:
- break;
- }
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_cfgpin(EXYNOS4_GPK2(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(EXYNOS4_GPK2(2), S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-}
-
-void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
-{
- struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
- unsigned int gpio;
-
- /* Set all the necessary GPK3[0:1] pins to special-function 2 */
- for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
- /* Data pin GPK3[3:6] to special-function 2 */
- s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
- s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-
- if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
- s3c_gpio_cfgpin(EXYNOS4_GPK3(2), S3C_GPIO_SFN(2));
- s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_UP);
- s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
- }
-}
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c
deleted file mode 100644
index 0883c1b..0000000
--- a/arch/arm/mach-exynos4/setup-usb-phy.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011 Samsung Electronics Co.Ltd
- * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <mach/regs-pmu.h>
-#include <mach/regs-usb-phy.h>
-#include <plat/cpu.h>
-#include <plat/usb-phy.h>
-
-static int exynos4_usb_phy1_init(struct platform_device *pdev)
-{
- struct clk *otg_clk;
- struct clk *xusbxti_clk;
- u32 phyclk;
- u32 rstcon;
- int err;
-
- otg_clk = clk_get(&pdev->dev, "otg");
- if (IS_ERR(otg_clk)) {
- dev_err(&pdev->dev, "Failed to get otg clock\n");
- return PTR_ERR(otg_clk);
- }
-
- err = clk_enable(otg_clk);
- if (err) {
- clk_put(otg_clk);
- return err;
- }
-
- writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
- S5P_USBHOST_PHY_CONTROL);
-
- /* set clock frequency for PLL */
- phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
-
- xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
- if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
- switch (clk_get_rate(xusbxti_clk)) {
- case 12 * MHZ:
- phyclk |= CLKSEL_12M;
- break;
- case 24 * MHZ:
- phyclk |= CLKSEL_24M;
- break;
- default:
- case 48 * MHZ:
- /* default reference clock */
- break;
- }
- clk_put(xusbxti_clk);
- }
-
- writel(phyclk, EXYNOS4_PHYCLK);
-
- /* floating prevention logic: disable */
- writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
-
- /* set to normal HSIC 0 and 1 of PHY1 */
- writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
- EXYNOS4_PHYPWR);
-
- /* set to normal standard USB of PHY1 */
- writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
-
- /* reset all ports of both PHY and Link */
- rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
- PHY1_SWRST_MASK;
- writel(rstcon, EXYNOS4_RSTCON);
- udelay(10);
-
- rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
- writel(rstcon, EXYNOS4_RSTCON);
- udelay(50);
-
- clk_disable(otg_clk);
- clk_put(otg_clk);
-
- return 0;
-}
-
-static int exynos4_usb_phy1_exit(struct platform_device *pdev)
-{
- struct clk *otg_clk;
- int err;
-
- otg_clk = clk_get(&pdev->dev, "otg");
- if (IS_ERR(otg_clk)) {
- dev_err(&pdev->dev, "Failed to get otg clock\n");
- return PTR_ERR(otg_clk);
- }
-
- err = clk_enable(otg_clk);
- if (err) {
- clk_put(otg_clk);
- return err;
- }
-
- writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
- EXYNOS4_PHYPWR);
-
- writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
- S5P_USBHOST_PHY_CONTROL);
-
- clk_disable(otg_clk);
- clk_put(otg_clk);
-
- return 0;
-}
-
-int s5p_usb_phy_init(struct platform_device *pdev, int type)
-{
- if (type == S5P_USB_PHY_HOST)
- return exynos4_usb_phy1_init(pdev);
-
- return -EINVAL;
-}
-
-int s5p_usb_phy_exit(struct platform_device *pdev, int type)
-{
- if (type == S5P_USB_PHY_HOST)
- return exynos4_usb_phy1_exit(pdev);
-
- return -EINVAL;
-}
diff --git a/arch/arm/mach-exynos4/time.c b/arch/arm/mach-exynos4/time.c
deleted file mode 100644
index ebb8f38..0000000
--- a/arch/arm/mach-exynos4/time.c
+++ /dev/null
@@ -1,301 +0,0 @@
-/* linux/arch/arm/mach-exynos4/time.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 (and compatible) HRT support
- * PWM 2/4 is used for this feature
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/platform_device.h>
-
-#include <asm/smp_twd.h>
-
-#include <mach/map.h>
-#include <plat/regs-timer.h>
-#include <asm/mach/time.h>
-
-static unsigned long clock_count_per_tick;
-
-static struct clk *tin2;
-static struct clk *tin4;
-static struct clk *tdiv2;
-static struct clk *tdiv4;
-static struct clk *timerclk;
-
-static void exynos4_pwm_stop(unsigned int pwm_id)
-{
- unsigned long tcon;
-
- tcon = __raw_readl(S3C2410_TCON);
-
- switch (pwm_id) {
- case 2:
- tcon &= ~S3C2410_TCON_T2START;
- break;
- case 4:
- tcon &= ~S3C2410_TCON_T4START;
- break;
- default:
- break;
- }
- __raw_writel(tcon, S3C2410_TCON);
-}
-
-static void exynos4_pwm_init(unsigned int pwm_id, unsigned long tcnt)
-{
- unsigned long tcon;
-
- tcon = __raw_readl(S3C2410_TCON);
-
- /* timers reload after counting zero, so reduce the count by 1 */
- tcnt--;
-
- /* ensure timer is stopped... */
- switch (pwm_id) {
- case 2:
- tcon &= ~(0xf<<12);
- tcon |= S3C2410_TCON_T2MANUALUPD;
-
- __raw_writel(tcnt, S3C2410_TCNTB(2));
- __raw_writel(tcnt, S3C2410_TCMPB(2));
- __raw_writel(tcon, S3C2410_TCON);
-
- break;
- case 4:
- tcon &= ~(7<<20);
- tcon |= S3C2410_TCON_T4MANUALUPD;
-
- __raw_writel(tcnt, S3C2410_TCNTB(4));
- __raw_writel(tcnt, S3C2410_TCMPB(4));
- __raw_writel(tcon, S3C2410_TCON);
-
- break;
- default:
- break;
- }
-}
-
-static inline void exynos4_pwm_start(unsigned int pwm_id, bool periodic)
-{
- unsigned long tcon;
-
- tcon = __raw_readl(S3C2410_TCON);
-
- switch (pwm_id) {
- case 2:
- tcon |= S3C2410_TCON_T2START;
- tcon &= ~S3C2410_TCON_T2MANUALUPD;
-
- if (periodic)
- tcon |= S3C2410_TCON_T2RELOAD;
- else
- tcon &= ~S3C2410_TCON_T2RELOAD;
- break;
- case 4:
- tcon |= S3C2410_TCON_T4START;
- tcon &= ~S3C2410_TCON_T4MANUALUPD;
-
- if (periodic)
- tcon |= S3C2410_TCON_T4RELOAD;
- else
- tcon &= ~S3C2410_TCON_T4RELOAD;
- break;
- default:
- break;
- }
- __raw_writel(tcon, S3C2410_TCON);
-}
-
-static int exynos4_pwm_set_next_event(unsigned long cycles,
- struct clock_event_device *evt)
-{
- exynos4_pwm_init(2, cycles);
- exynos4_pwm_start(2, 0);
- return 0;
-}
-
-static void exynos4_pwm_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- exynos4_pwm_stop(2);
-
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- exynos4_pwm_init(2, clock_count_per_tick);
- exynos4_pwm_start(2, 1);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_RESUME:
- break;
- }
-}
-
-static struct clock_event_device pwm_event_device = {
- .name = "pwm_timer2",
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .rating = 200,
- .shift = 32,
- .set_next_event = exynos4_pwm_set_next_event,
- .set_mode = exynos4_pwm_set_mode,
-};
-
-irqreturn_t exynos4_clock_event_isr(int irq, void *dev_id)
-{
- struct clock_event_device *evt = &pwm_event_device;
-
- evt->event_handler(evt);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction exynos4_clock_event_irq = {
- .name = "pwm_timer2_irq",
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .handler = exynos4_clock_event_isr,
-};
-
-static void __init exynos4_clockevent_init(void)
-{
- unsigned long pclk;
- unsigned long clock_rate;
- struct clk *tscaler;
-
- pclk = clk_get_rate(timerclk);
-
- /* configure clock tick */
-
- tscaler = clk_get_parent(tdiv2);
-
- clk_set_rate(tscaler, pclk / 2);
- clk_set_rate(tdiv2, pclk / 2);
- clk_set_parent(tin2, tdiv2);
-
- clock_rate = clk_get_rate(tin2);
-
- clock_count_per_tick = clock_rate / HZ;
-
- pwm_event_device.mult =
- div_sc(clock_rate, NSEC_PER_SEC, pwm_event_device.shift);
- pwm_event_device.max_delta_ns =
- clockevent_delta2ns(-1, &pwm_event_device);
- pwm_event_device.min_delta_ns =
- clockevent_delta2ns(1, &pwm_event_device);
-
- pwm_event_device.cpumask = cpumask_of(0);
- clockevents_register_device(&pwm_event_device);
-
- setup_irq(IRQ_TIMER2, &exynos4_clock_event_irq);
-}
-
-static cycle_t exynos4_pwm4_read(struct clocksource *cs)
-{
- return (cycle_t) ~__raw_readl(S3C_TIMERREG(0x40));
-}
-
-#ifdef CONFIG_PM
-static void exynos4_pwm4_resume(struct clocksource *cs)
-{
- unsigned long pclk;
-
- pclk = clk_get_rate(timerclk);
-
- clk_set_rate(tdiv4, pclk / 2);
- clk_set_parent(tin4, tdiv4);
-
- exynos4_pwm_init(4, ~0);
- exynos4_pwm_start(4, 1);
-}
-#endif
-
-struct clocksource pwm_clocksource = {
- .name = "pwm_timer4",
- .rating = 250,
- .read = exynos4_pwm4_read,
- .mask = CLOCKSOURCE_MASK(32),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS ,
-#ifdef CONFIG_PM
- .resume = exynos4_pwm4_resume,
-#endif
-};
-
-static void __init exynos4_clocksource_init(void)
-{
- unsigned long pclk;
- unsigned long clock_rate;
-
- pclk = clk_get_rate(timerclk);
-
- clk_set_rate(tdiv4, pclk / 2);
- clk_set_parent(tin4, tdiv4);
-
- clock_rate = clk_get_rate(tin4);
-
- exynos4_pwm_init(4, ~0);
- exynos4_pwm_start(4, 1);
-
- if (clocksource_register_hz(&pwm_clocksource, clock_rate))
- panic("%s: can't register clocksource\n", pwm_clocksource.name);
-}
-
-static void __init exynos4_timer_resources(void)
-{
- struct platform_device tmpdev;
-
- tmpdev.dev.bus = &platform_bus_type;
-
- timerclk = clk_get(NULL, "timers");
- if (IS_ERR(timerclk))
- panic("failed to get timers clock for system timer");
-
- clk_enable(timerclk);
-
- tmpdev.id = 2;
- tin2 = clk_get(&tmpdev.dev, "pwm-tin");
- if (IS_ERR(tin2))
- panic("failed to get pwm-tin2 clock for system timer");
-
- tdiv2 = clk_get(&tmpdev.dev, "pwm-tdiv");
- if (IS_ERR(tdiv2))
- panic("failed to get pwm-tdiv2 clock for system timer");
- clk_enable(tin2);
-
- tmpdev.id = 4;
- tin4 = clk_get(&tmpdev.dev, "pwm-tin");
- if (IS_ERR(tin4))
- panic("failed to get pwm-tin4 clock for system timer");
-
- tdiv4 = clk_get(&tmpdev.dev, "pwm-tdiv");
- if (IS_ERR(tdiv4))
- panic("failed to get pwm-tdiv4 clock for system timer");
-
- clk_enable(tin4);
-}
-
-static void __init exynos4_timer_init(void)
-{
-#ifdef CONFIG_LOCAL_TIMERS
- twd_base = S5P_VA_TWD;
-#endif
-
- exynos4_timer_resources();
- exynos4_clockevent_init();
- exynos4_clocksource_init();
-}
-
-struct sys_timer exynos4_timer = {
- .init = exynos4_timer_init,
-};
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index b2b2a5b..ad44a3d 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -201,4 +201,8 @@ static inline bool s3c_dma_has_circular(void)
return false;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return false;
+}
#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c2410/include/mach/pm-core.h
index 70a83b2..45eea52 100644
--- a/arch/arm/mach-s3c2410/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c2410/include/mach/pm-core.h
@@ -62,3 +62,6 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
{
}
+
+static inline void s3c_pm_restored_gpios(void) { }
+static inline void s3c_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index e4177e2..fdc89fc 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -142,6 +142,7 @@ config MACH_SMDK6410
select S3C_DEV_USB_HOST
select S3C_DEV_USB_HSOTG
select S3C_DEV_WDT
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
select HAVE_S3C2410_WATCHDOG if WATCHDOG
diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c
index 374e45e..6c498f9 100644
--- a/arch/arm/mach-s3c64xx/cpu.c
+++ b/arch/arm/mach-s3c64xx/cpu.c
@@ -43,16 +43,16 @@ static const char name_s3c6410[] = "S3C6410";
static struct cpu_table cpu_ids[] __initdata = {
{
- .idcode = 0x36400000,
- .idmask = 0xfffff000,
+ .idcode = S3C6400_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
.map_io = s3c6400_map_io,
.init_clocks = s3c6400_init_clocks,
.init_uarts = s3c6400_init_uarts,
.init = s3c6400_init,
.name = name_s3c6400,
}, {
- .idcode = 0x36410100,
- .idmask = 0xffffff00,
+ .idcode = S3C6410_CPU_ID,
+ .idmask = S3C64XX_CPU_MASK,
.map_io = s3c6410_map_io,
.init_clocks = s3c6410_init_clocks,
.init_uarts = s3c6410_init_uarts,
@@ -140,22 +140,14 @@ void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
{
- unsigned long idcode;
-
/* initialise the io descriptors we need for initialisation */
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
iotable_init(mach_desc, size);
- idcode = __raw_readl(S3C_VA_SYS + 0x118);
- if (!idcode) {
- /* S3C6400 has the ID register in a different place,
- * and needs a write before it can be read. */
-
- __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
- idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
- }
+ /* detect cpu id */
+ s3c64xx_init_cpu();
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
static __init int s3c64xx_sysdev_init(void)
diff --git a/arch/arm/mach-s3c64xx/dev-onenand1.c b/arch/arm/mach-s3c64xx/dev-onenand1.c
index 92ffd5b..999f9e1 100644
--- a/arch/arm/mach-s3c64xx/dev-onenand1.c
+++ b/arch/arm/mach-s3c64xx/dev-onenand1.c
@@ -19,6 +19,8 @@
#include <mach/irqs.h>
#include <mach/map.h>
+#include <plat/devs.h>
+
static struct resource s3c64xx_onenand1_resources[] = {
[0] = {
.start = S3C64XX_PA_ONENAND1,
@@ -46,10 +48,6 @@ struct platform_device s3c64xx_device_onenand1 = {
void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
{
- struct onenand_platform_data *pd;
-
- pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
- if (!pd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- s3c64xx_device_onenand1.dev.platform_data = pd;
+ s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
+ &s3c64xx_device_onenand1);
}
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 0a5d926..9e14383 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -63,6 +63,11 @@ static __inline__ bool s3c_dma_has_circular(void)
return true;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return false;
+}
+
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#include <plat/dma.h>
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
index 1e9f20f..38659be 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -53,7 +53,7 @@ static inline void s3c_pm_arch_show_resume_irqs(void)
* the IRQ wake controls depending on the CPU we are running on */
#define s3c_irqwake_eintallow ((1 << 28) - 1)
-#define s3c_irqwake_intallow (0)
+#define s3c_irqwake_intallow (~0)
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
@@ -96,3 +96,20 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
save->ucon = new_ucon;
}
}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+ /* ensure sleep mode has been cleared from the system */
+
+ __raw_writel(0, S3C64XX_SLPEN);
+}
+
+static inline void s3c_pm_saved_gpios(void)
+{
+ /* turn on the sleep mode and keep it there, as it seems that during
+ * suspend the xCON registers get re-set and thus you can end up with
+ * problems between going to sleep and resuming.
+ */
+
+ __raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN);
+}
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-fb.h b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
deleted file mode 100644
index a06ee0a..0000000
--- a/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Copyright 2009 Samsung Electronics Co.
- *
- * Pawel Osciak <p.osciak@samsung.com>
- * Based on plat-s3c/include/plat/regs-fb.h by Ben Dooks <ben@simtec.co.uk>
- *
- * Framebuffer register definitions for Samsung S3C64xx.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MACH_REGS_FB_H
-#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
-
-#include <plat/regs-fb-v4.h>
-
-#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-s3c64xx/irq.c b/arch/arm/mach-s3c64xx/irq.c
index 97660c8..75d9a0e 100644
--- a/arch/arm/mach-s3c64xx/irq.c
+++ b/arch/arm/mach-s3c64xx/irq.c
@@ -48,14 +48,22 @@ static struct s3c_uart_irq uart_irqs[] = {
},
};
+/* setup the sources the vic should advertise resume for, even though it
+ * is not doing the wake (set_irq_wake needs to be valid) */
+#define IRQ_VIC0_RESUME (1 << (IRQ_RTC_TIC - IRQ_VIC0_BASE))
+#define IRQ_VIC1_RESUME (1 << (IRQ_RTC_ALARM - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_PENDN - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC0 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC1 - IRQ_VIC1_BASE) | \
+ 1 << (IRQ_HSMMC2 - IRQ_VIC1_BASE))
void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
/* initialise the pair of VICs */
- vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, 0);
- vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0);
+ vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME);
+ vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME);
/* add the timer sub-irqs */
s3c_init_vic_timer_irq(5, IRQ_TIMER0);
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index a53cf14..cb88643 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -35,7 +35,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -44,6 +43,7 @@
#include <plat/regs-serial.h>
#include <plat/iic.h>
#include <plat/fb.h>
+#include <plat/regs-fb-v4.h>
#include <mach/s3c6410.h>
#include <plat/clock.h>
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index b263958..b3d93cc 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -27,7 +27,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -42,6 +41,7 @@
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/regs-fb-v4.h>
#define UCON S3C2410_UCON_DEFAULT
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index 89f35e0..527f49b 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -29,7 +29,6 @@
#include <asm/mach/map.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/regs-modem.h>
#include <mach/regs-srom.h>
@@ -42,6 +41,7 @@
#include <plat/nand.h>
#include <plat/regs-serial.h>
#include <plat/ts.h>
+#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index c498649..01c6857 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -30,7 +30,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -44,6 +43,7 @@
#include <plat/clock.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/regs-fb-v4.h>
#define UCON S3C2410_UCON_DEFAULT
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 4957ab0..95b04b1 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -30,7 +30,6 @@
#include <asm/mach/map.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/regs-modem.h>
#include <mach/regs-srom.h>
@@ -43,6 +42,7 @@
#include <plat/nand.h>
#include <plat/regs-serial.h>
#include <plat/ts.h>
+#include <plat/regs-fb-v4.h>
#include <video/platform_lcd.h>
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index 3a3e5ac..342e8df 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -21,7 +21,6 @@
#include <asm/mach/arch.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/s3c6410.h>
@@ -29,6 +28,7 @@
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
+#include <plat/regs-fb-v4.h>
#include "mach-smartq.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index e653758..5796397 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -21,7 +21,6 @@
#include <asm/mach/arch.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/s3c6410.h>
@@ -29,6 +28,7 @@
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
+#include <plat/regs-fb-v4.h>
#include "mach-smartq.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 2c0353a..ecbea92 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -48,7 +48,6 @@
#include <asm/mach/irq.h>
#include <mach/hardware.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <asm/irq.h>
@@ -71,6 +70,8 @@
#include <plat/adc.h>
#include <plat/ts.h>
#include <plat/keypad.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
@@ -209,17 +210,9 @@ static struct platform_device smdk6410_smsc911x = {
};
#ifdef CONFIG_REGULATOR
-static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = {
- {
- /* WM8580 */
- .supply = "PVDD",
- .dev_name = "0-001b",
- },
- {
- /* WM8580 */
- .supply = "AVDD",
- .dev_name = "0-001b",
- },
+static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] __initdata = {
+ REGULATOR_SUPPLY("PVDD", "0-001b"),
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
};
static struct regulator_init_data smdk6410_b_pwr_5v_data = {
@@ -337,16 +330,12 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&s3c_device_rtc,
&s3c_device_ts,
&s3c_device_wdt,
- &s3c_device_timer[1],
- &smdk6410_backlight_device,
};
#ifdef CONFIG_REGULATOR
/* ARM core */
static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = {
- {
- .supply = "vddarm",
- }
+ REGULATOR_SUPPLY("vddarm", NULL),
};
/* VDDARM, BUCK1 on J5 */
@@ -484,11 +473,7 @@ static struct regulator_init_data wm8350_dcdc3_data = {
/* USB, EXT, PCM, ADC/DAC, USB, MMC */
static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
- {
- /* WM8580 */
- .supply = "DVDD",
- .dev_name = "0-001b",
- },
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
};
static struct regulator_init_data wm8350_dcdc4_data = {
@@ -599,7 +584,7 @@ static struct regulator_init_data wm1192_dcdc3 = {
};
static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
- { .supply = "DVDD", .dev_name = "0-001b", }, /* WM8580 */
+ REGULATOR_SUPPLY("DVDD", "0-001b"), /* WM8580 */
};
static struct regulator_init_data wm1192_ldo1 = {
@@ -679,6 +664,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6410_bl_gpio_info = {
+ .no = S3C64XX_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6410_bl_data = {
+ .pwm_id = 1,
+};
+
static void __init smdk6410_map_io(void)
{
u32 tmp;
@@ -740,6 +735,8 @@ static void __init smdk6410_machine_init(void)
s3c_ide_set_platdata(&smdk6410_ide_pdata);
+ samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data);
+
platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
}
diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
index 8f30911..83d2afb 100644
--- a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -17,7 +17,6 @@
#include <linux/fb.h>
#include <linux/gpio.h>
-#include <mach/regs-fb.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 017af4c..65c7518 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -36,6 +36,7 @@ config MACH_SMDK6440
select S3C_DEV_WDT
select S3C64XX_DEV_SPI
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
select S5P64X0_SETUP_I2C1
@@ -50,6 +51,7 @@ config MACH_SMDK6450
select S3C_DEV_WDT
select S3C64XX_DEV_SPI
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
select S5P64X0_SETUP_I2C1
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index 2d559f1..346f8df 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -46,6 +46,7 @@
#include <plat/adc.h>
#include <plat/ts.h>
#include <plat/s5p-time.h>
+#include <plat/backlight.h>
#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -91,45 +92,6 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
},
};
-static int smdk6440_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5P6440_GPF(15), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
- return ret;
- }
-
- /* Configure GPIO pin with S5P6440_GPF15_PWM_TOUT1 */
- s3c_gpio_cfgpin(S5P6440_GPF(15), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-static void smdk6440_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5P6440_GPF(15), S3C_GPIO_OUTPUT);
- gpio_free(S5P6440_GPF(15));
-}
-
-static struct platform_pwm_backlight_data smdk6440_backlight_data = {
- .pwm_id = 1,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdk6440_backlight_init,
- .exit = smdk6440_backlight_exit,
-};
-
-static struct platform_device smdk6440_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[1].dev,
- .platform_data = &smdk6440_backlight_data,
- },
-};
-
static struct platform_device *smdk6440_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_rtc,
@@ -139,8 +101,6 @@ static struct platform_device *smdk6440_devices[] __initdata = {
&s3c_device_wdt,
&samsung_asoc_dma,
&s5p6440_device_iis,
- &s3c_device_timer[1],
- &smdk6440_backlight_device,
};
static struct s3c2410_platform_i2c s5p6440_i2c0_data __initdata = {
@@ -175,6 +135,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6440_bl_gpio_info = {
+ .no = S5P6440_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6440_bl_data = {
+ .pwm_id = 1,
+};
+
static void __init smdk6440_map_io(void)
{
s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
@@ -194,6 +164,8 @@ static void __init smdk6440_machine_init(void)
i2c_register_board_info(1, smdk6440_i2c_devs1,
ARRAY_SIZE(smdk6440_i2c_devs1));
+ samsung_bl_set(&smdk6440_bl_gpio_info, &smdk6440_bl_data);
+
platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
}
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index d19c469..33f2adf 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -46,6 +46,7 @@
#include <plat/adc.h>
#include <plat/ts.h>
#include <plat/s5p-time.h>
+#include <plat/backlight.h>
#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -109,45 +110,6 @@ static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
#endif
};
-static int smdk6450_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5P6450_GPF(15), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
- return ret;
- }
-
- /* Configure GPIO pin with S5P6450_GPF15_PWM_TOUT1 */
- s3c_gpio_cfgpin(S5P6450_GPF(15), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-static void smdk6450_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5P6450_GPF(15), S3C_GPIO_OUTPUT);
- gpio_free(S5P6450_GPF(15));
-}
-
-static struct platform_pwm_backlight_data smdk6450_backlight_data = {
- .pwm_id = 1,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdk6450_backlight_init,
- .exit = smdk6450_backlight_exit,
-};
-
-static struct platform_device smdk6450_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[1].dev,
- .platform_data = &smdk6450_backlight_data,
- },
-};
-
static struct platform_device *smdk6450_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_rtc,
@@ -157,8 +119,6 @@ static struct platform_device *smdk6450_devices[] __initdata = {
&s3c_device_wdt,
&samsung_asoc_dma,
&s5p6450_device_iis0,
- &s3c_device_timer[1],
- &smdk6450_backlight_device,
/* s5p6450_device_spi0 will be added */
};
@@ -194,6 +154,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdk6450_bl_gpio_info = {
+ .no = S5P6450_GPF(15),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdk6450_bl_data = {
+ .pwm_id = 1,
+};
+
static void __init smdk6450_map_io(void)
{
s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
@@ -213,6 +183,8 @@ static void __init smdk6450_machine_init(void)
i2c_register_board_info(1, smdk6450_i2c_devs1,
ARRAY_SIZE(smdk6450_i2c_devs1));
+ samsung_bl_set(&smdk6450_bl_gpio_info, &smdk6450_bl_data);
+
platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
}
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 608722f..e8a33c4 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -56,6 +56,7 @@ config MACH_SMDKC100
select S3C_DEV_RTC
select S3C_DEV_WDT
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 0305e9b..da2ea0a 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -976,48 +976,13 @@ struct clksrc_sources clk_src_sclk_spdif = {
.nr_sources = ARRAY_SIZE(clk_sclk_spdif_list),
};
-static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
-{
- struct clk *pclk;
- int ret;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- ret = pclk->ops->set_rate(pclk, rate);
- clk_put(pclk);
-
- return ret;
-}
-
-static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
-{
- struct clk *pclk;
- int rate;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- rate = pclk->ops->get_rate(clk);
- clk_put(pclk);
-
- return rate;
-}
-
-static struct clk_ops s5pc100_sclk_spdif_ops = {
- .set_rate = s5pc100_spdif_set_rate,
- .get_rate = s5pc100_spdif_get_rate,
-};
-
static struct clksrc_clk clk_sclk_spdif = {
.clk = {
.name = "sclk_spdif",
.id = -1,
.ctrlbit = (1 << 11),
.enable = s5pc100_sclk1_ctrl,
- .ops = &s5pc100_sclk_spdif_ops,
+ .ops = &s5p_sclk_spdif_ops,
},
.sources = &clk_src_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
deleted file mode 100644
index 07aa4d6..0000000
--- a/arch/arm/mach-s5pc100/include/mach/regs-fb.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* arch/arm/mach-s5pc100/include/mach/regs-fb.h
- *
- * Copyright 2009 Samsung Electronics Co.
- * Pawel Osciak <p.osciak@samsung.com>
- *
- * Framebuffer register definitions for Samsung S5PC100.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_FB_H
-#define __ASM_ARCH_REGS_FB_H __FILE__
-
-#include <plat/regs-fb-v4.h>
-
-/* VP1 interface timing control */
-#define VP1CON0 (0x118)
-#define VP1_RATECON_EN (1 << 31)
-#define VP1_CLKRATE_MASK (0xff)
-
-#define VP1CON1 (0x11c)
-#define VP1_VTREGCON_EN (1 << 31)
-#define VP1_VBPD_MASK (0xfff)
-#define VP1_VBPD_SHIFT (16)
-
-
-#define WPALCON_H (0x19c)
-#define WPALCON_L (0x1a0)
-
-/* Palette control for WPAL0 and WPAL1 is the same as in S3C64xx, but
- * different for WPAL2-4
- */
-/* In WPALCON_L (aka WPALCON) */
-#define WPALCON_W1PAL_32BPP_A888 (0x7 << 3)
-#define WPALCON_W0PAL_32BPP_A888 (0x7 << 0)
-
-/* To set W2PAL-W4PAL consist of one bit from WPALCON_L and two from WPALCON_H,
- * e.g. W2PAL[2..0] is made of (WPALCON_H[10..9], WPALCON_L[6]).
- */
-#define WPALCON_L_WxPAL_L_MASK (0x1)
-#define WPALCON_L_W2PAL_L_SHIFT (6)
-#define WPALCON_L_W3PAL_L_SHIFT (7)
-#define WPALCON_L_W4PAL_L_SHIFT (8)
-
-#define WPALCON_L_WxPAL_H_MASK (0x3)
-#define WPALCON_H_W2PAL_H_SHIFT (9)
-#define WPALCON_H_W3PAL_H_SHIFT (13)
-#define WPALCON_H_W4PAL_H_SHIFT (17)
-
-/* Per-window alpha value registers */
-/* For window 0 8-bit alpha values are in VIDW0ALPHAx,
- * for windows 1-4 alpha values consist of two parts, the 4 low bits are
- * taken from VIDWxALPHAx and 4 high bits are from VIDOSDxC,
- * e.g. WIN1_ALPHA0_B[7..0] = (VIDOSD1C[3..0], VIDW1ALPHA0[3..0])
- */
-#define VIDWxALPHA0(_win) (0x200 + (_win * 8))
-#define VIDWxALPHA1(_win) (0x204 + (_win * 8))
-
-/* Only for window 0 in VIDW0ALPHAx. */
-#define VIDW0ALPHAx_R(_x) ((_x) << 16)
-#define VIDW0ALPHAx_R_MASK (0xff << 16)
-#define VIDW0ALPHAx_R_SHIFT (16)
-#define VIDW0ALPHAx_G(_x) ((_x) << 8)
-#define VIDW0ALPHAx_G_MASK (0xff << 8)
-#define VIDW0ALPHAx_G_SHIFT (8)
-#define VIDW0ALPHAx_B(_x) ((_x) << 0)
-#define VIDW0ALPHAx_B_MASK (0xff << 0)
-#define VIDW0ALPHAx_B_SHIFT (0)
-
-/* Low 4 bits of alpha0-1 for windows 1-4 */
-#define VIDW14ALPHAx_R_L(_x) ((_x) << 16)
-#define VIDW14ALPHAx_R_L_MASK (0xf << 16)
-#define VIDW14ALPHAx_R_L_SHIFT (16)
-#define VIDW14ALPHAx_G_L(_x) ((_x) << 8)
-#define VIDW14ALPHAx_G_L_MASK (0xf << 8)
-#define VIDW14ALPHAx_G_L_SHIFT (8)
-#define VIDW14ALPHAx_B_L(_x) ((_x) << 0)
-#define VIDW14ALPHAx_B_L_MASK (0xf << 0)
-#define VIDW14ALPHAx_B_L_SHIFT (0)
-
-
-/* Per-window blending equation control registers */
-#define BLENDEQx(_win) (0x244 + ((_win) * 4))
-#define BLENDEQ1 (0x244)
-#define BLENDEQ2 (0x248)
-#define BLENDEQ3 (0x24c)
-#define BLENDEQ4 (0x250)
-
-#define BLENDEQx_Q_FUNC(_x) ((_x) << 18)
-#define BLENDEQx_Q_FUNC_MASK (0xf << 18)
-#define BLENDEQx_P_FUNC(_x) ((_x) << 12)
-#define BLENDEQx_P_FUNC_MASK (0xf << 12)
-#define BLENDEQx_B_FUNC(_x) ((_x) << 6)
-#define BLENDEQx_B_FUNC_MASK (0xf << 6)
-#define BLENDEQx_A_FUNC(_x) ((_x) << 0)
-#define BLENDEQx_A_FUNC_MASK (0xf << 0)
-
-#define BLENDCON (0x260)
-#define BLENDCON_8BIT_ALPHA (1 << 0)
-
-
-#endif /* __ASM_ARCH_REGS_FB_H */
-
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 0525cb3..227d890 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -29,7 +29,6 @@
#include <asm/mach/map.h>
#include <mach/map.h>
-#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <video/platform_lcd.h>
@@ -51,6 +50,8 @@
#include <plat/keypad.h>
#include <plat/ts.h>
#include <plat/audio.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -179,45 +180,6 @@ static struct samsung_keypad_platdata smdkc100_keypad_data __initdata = {
.cols = 8,
};
-static int smdkc100_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5PC100_GPD(0), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPF for PWM-OUT0\n");
- return ret;
- }
-
- /* Configure GPIO pin with S5PC100_GPD_TOUT_0 */
- s3c_gpio_cfgpin(S5PC100_GPD(0), S3C_GPIO_SFN(2));
-
- return 0;
-}
-
-static void smdkc100_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5PC100_GPD(0), S3C_GPIO_OUTPUT);
- gpio_free(S5PC100_GPD(0));
-}
-
-static struct platform_pwm_backlight_data smdkc100_backlight_data = {
- .pwm_id = 0,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdkc100_backlight_init,
- .exit = smdkc100_backlight_exit,
-};
-
-static struct platform_device smdkc100_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[0].dev,
- .platform_data = &smdkc100_backlight_data,
- },
-};
-
static struct platform_device *smdkc100_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_cfcon,
@@ -239,8 +201,6 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s5p_device_fimc1,
&s5p_device_fimc2,
&s5pc100_device_spdif,
- &s3c_device_timer[0],
- &smdkc100_backlight_device,
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
@@ -249,6 +209,16 @@ static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.oversampling_shift = 2,
};
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkc100_bl_gpio_info = {
+ .no = S5PC100_GPD(0),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkc100_bl_data = {
+ .pwm_id = 0,
+};
+
static void __init smdkc100_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -276,6 +246,9 @@ static void __init smdkc100_machine_init(void)
/* LCD init */
gpio_request(S5PC100_GPH0(6), "GPH0");
smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
+
+ samsung_bl_set(&smdkc100_bl_gpio_info, &smdkc100_bl_data);
+
platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
}
diff --git a/arch/arm/mach-s5pc100/setup-fb-24bpp.c b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
index d31c0f3..8978e4c 100644
--- a/arch/arm/mach-s5pc100/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
@@ -15,7 +15,6 @@
#include <linux/fb.h>
#include <linux/gpio.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 37b5a97..057a850 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -18,6 +18,11 @@ config CPU_S5PV210
help
Enable S5PV210 CPU support
+config CPU_S5PC110
+ bool
+ help
+ S5PC110(MCP) is one of package option of S5PV210.
+
config S5PV210_SETUP_I2C1
bool
help
@@ -105,14 +110,29 @@ config MACH_GONI
config MACH_SMDKC110
bool "SMDKC110"
select CPU_S5PV210
+ select CPU_S5PC110
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_RTC
select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_IDE
+ select S5PV210_SETUP_KEYPAD
+ select S5PV210_SETUP_SDHCI
+ select HAVE_PWM
help
Machine support for Samsung SMDKC110
S5PC110(MCP) is one of package option of S5PV210
@@ -134,6 +154,7 @@ config MACH_SMDKV210
select S3C_DEV_RTC
select S3C_DEV_WDT
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_BACKLIGHT
select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_KEYPAD
select SAMSUNG_DEV_PWM
@@ -144,6 +165,7 @@ config MACH_SMDKV210
select S5PV210_SETUP_IDE
select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI
+ select HAVE_PWM
help
Machine support for Samsung SMDKV210
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 50907ac..c3cd02a 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -5,7 +5,7 @@
#
# Licensed under GPLv2
-obj-y :=
+obj-y := reserve_mem-s5pv210.o
obj-m :=
obj-n :=
obj- :=
@@ -15,7 +15,7 @@ obj- :=
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
-obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o dev-cpufreq.o
# machine support
diff --git a/arch/arm/mach-s5pv210/Makefile.boot b/arch/arm/mach-s5pv210/Makefile.boot
index ff90aa1..7e1ea1f 100644
--- a/arch/arm/mach-s5pv210/Makefile.boot
+++ b/arch/arm/mach-s5pv210/Makefile.boot
@@ -1,2 +1,5 @@
zreladdr-y := 0x20008000
params_phys-y := 0x20000100
+
+ zreladdr-$(CONFIG_CPU_S5PC110) := 0x30008000
+params_phys-$(CONFIG_CPU_S5PC110) := 0x30000100
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 2d59949..5ea790f 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -24,12 +24,14 @@
#include <plat/cpu-freq.h>
#include <mach/regs-clock.h>
+#include <mach/regs-audss.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/pll.h>
#include <plat/s5p-clock.h>
#include <plat/clock-clksrc.h>
#include <plat/s5pv210.h>
+#include <plat/devs.h>
static unsigned long xtal;
@@ -185,6 +187,11 @@ static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
}
+static int s5pv210_clk_audss_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_AUDSS, clk, enable);
+}
+
static struct clk clk_sclk_hdmi27m = {
.name = "sclk_hdmi27m",
.id = -1,
@@ -311,18 +318,6 @@ static struct clk_ops clk_fout_apll_ops = {
static struct clk init_clocks_off[] = {
{
- .name = "pdma",
- .id = 0,
- .parent = &clk_hclk_psys.clk,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 3),
- }, {
- .name = "pdma",
- .id = 1,
- .parent = &clk_hclk_psys.clk,
- .enable = s5pv210_clk_ip0_ctrl,
- .ctrlbit = (1 << 4),
- }, {
.name = "rot",
.id = -1,
.parent = &clk_hclk_dsys.clk,
@@ -490,6 +485,37 @@ static struct clk init_clocks_off[] = {
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 0),
+ }, {
+ .name = "secss",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = &s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1 << 0),
+ }
+};
+
+static struct clk init_dmaclocks[] = {
+ {
+ .name = "pdma",
+ .id = 0,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 2),
+ .dev = &s5pv210_device_mdma.dev,
+ }, {
+ .name = "pdma",
+ .id = 1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 3),
+ .dev = &s5pv210_device_pdma0.dev,
+ }, {
+ .name = "pdma",
+ .id = 2,
+ .parent = &init_dmaclocks[1],
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 4),
+ .dev = &s5pv210_device_pdma1.dev,
},
};
@@ -656,6 +682,59 @@ static struct clksrc_clk clk_sclk_audio0 = {
.reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
};
+static struct clk *clkset_mout_audss_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_fout_epll,
+};
+
+static struct clksrc_sources clkset_mout_audss = {
+ .sources = clkset_mout_audss_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_audss_list),
+};
+
+static struct clksrc_clk clk_mout_audss = {
+ .clk = {
+ .name = "mout_audss",
+ .id = -1,
+ },
+ .sources = &clkset_mout_audss,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_mout_i2s_a_list[] = {
+ &clk_mout_audss.clk,
+ &clk_pcmcdclk0,
+ &clk_sclk_audio0.clk,
+};
+
+static struct clksrc_sources clkset_mout_i2s_a = {
+ .sources = clkset_mout_i2s_a_list,
+ .nr_sources = ARRAY_SIZE(clkset_mout_i2s_a_list),
+};
+
+static struct clksrc_clk clk_mout_i2s_a = {
+ .clk = {
+ .name = "audio-bus",
+ .id = 0,
+ .enable = s5pv210_clk_audss_ctrl,
+ .ctrlbit = (1 << 6),
+ },
+ .sources = &clkset_mout_i2s_a,
+ .reg_src = { .reg = S5P_CLKSRC_AUDSS, .shift = 2, .size = 2 },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 4, .size = 4 },
+};
+
+static struct clksrc_clk clk_dout_audio_bus_clk_i2s = {
+ .clk = {
+ .name = "dout_audio_bus_clk_i2s",
+ .id = -1,
+ .parent = &clk_mout_audss.clk,
+ .enable = s5pv210_clk_audss_ctrl,
+ .ctrlbit = (1 << 5),
+ },
+ .reg_div = { .reg = S5P_CLKDIV_AUDSS, .shift = 0, .size = 4 },
+};
+
static struct clk *clkset_sclk_audio1_list[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_pcmcdclk1,
@@ -725,48 +804,13 @@ static struct clksrc_sources clkset_sclk_spdif = {
.nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
};
-static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
-{
- struct clk *pclk;
- int ret;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- ret = pclk->ops->set_rate(pclk, rate);
- clk_put(pclk);
-
- return ret;
-}
-
-static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
-{
- struct clk *pclk;
- int rate;
-
- pclk = clk_get_parent(clk);
- if (IS_ERR(pclk))
- return -EINVAL;
-
- rate = pclk->ops->get_rate(clk);
- clk_put(pclk);
-
- return rate;
-}
-
-static struct clk_ops s5pv210_sclk_spdif_ops = {
- .set_rate = s5pv210_spdif_set_rate,
- .get_rate = s5pv210_spdif_get_rate,
-};
-
static struct clksrc_clk clk_sclk_spdif = {
.clk = {
.name = "sclk_spdif",
.id = -1,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 27),
- .ops = &s5pv210_sclk_spdif_ops,
+ .ops = &s5p_sclk_spdif_ops,
},
.sources = &clkset_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
@@ -1062,6 +1106,9 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_audio1,
&clk_sclk_audio2,
&clk_sclk_spdif,
+ &clk_mout_audss,
+ &clk_mout_i2s_a,
+ &clk_dout_audio_bus_clk_i2s,
};
static u32 epll_div[][6] = {
@@ -1159,7 +1206,6 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
u32 clkdiv0, clkdiv1;
/* Set functions for clk_fout_epll */
- clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5pv210_epll_ops;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
@@ -1239,5 +1285,9 @@ void __init s5pv210_register_clocks(void)
s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ /* Register DMA Clock */
+ s3c_register_clocks(init_dmaclocks, ARRAY_SIZE(init_dmaclocks));
+ s3c_disable_clocks(init_dmaclocks, ARRAY_SIZE(init_dmaclocks));
+
s3c_pwmclk_init();
}
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 61e6c24..d4a8605 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -38,9 +38,9 @@
#include <plat/ata-core.h>
#include <plat/fimc-core.h>
#include <plat/iic-core.h>
-#include <plat/keypad-core.h>
#include <plat/sdhci.h>
#include <plat/reset.h>
+#include <plat/ace-core.h>
/* Initial IO mappings */
@@ -91,6 +91,11 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.length = SZ_4K,
.type = MT_DEVICE,
}, {
+ .virtual = (unsigned long)S5P_VA_AUDSS,
+ .pfn = __phys_to_pfn(S5PV210_PA_AUDSS),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
.virtual = (unsigned long)S3C_VA_USB_HSPHY,
.pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
.length = SZ_4K,
@@ -126,7 +131,7 @@ void __init s5pv210_map_io(void)
s5pv210_default_sdhci2();
s5pv210_default_sdhci3();
- s3c_adc_setname("s3c64xx-adc");
+ s3c_adc_setname("samsung-adc-v3");
s3c_cfcon_setname("s5pv210-pata");
@@ -141,8 +146,9 @@ void __init s5pv210_map_io(void)
s3c_fb_setname("s5pv210-fb");
- /* Use s5pv210-keypad instead of samsung-keypad */
- samsung_keypad_setname("s5pv210-keypad");
+#ifdef CONFIG_S5P_DEV_ACE
+ s5p_ace_setname("s5pv210-ace");
+#endif
}
void __init s5pv210_init_clocks(int xtal)
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
index 153af8b..f18a574 100644..100755
--- a/arch/arm/mach-s5pv210/cpufreq.c
+++ b/arch/arm/mach-s5pv210/cpufreq.c
@@ -16,20 +16,39 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/reboot.h>
+#include <linux/regulator/consumer.h>
#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
+#include <mach/cpu-freq-v210.h>
static struct clk *cpu_clk;
static struct clk *dmc0_clk;
static struct clk *dmc1_clk;
static struct cpufreq_freqs freqs;
+static DEFINE_MUTEX(set_freq_lock);
/* APLL M,P,S values for 1G/800Mhz */
#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1)
#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1)
+#define SLEEP_FREQ (800 * 1000) /* Use 800MHz when entering sleep */
+
+/*
+ * relation has an additional symantics other than the standard of cpufreq
+ * DISALBE_FURTHER_CPUFREQ: disable further access to target until being re-enabled.
+ * ENABLE_FURTUER_CPUFREQ: re-enable access to target
+*/
+enum cpufreq_access {
+ DISABLE_FURTHER_CPUFREQ = 0x10,
+ ENABLE_FURTHER_CPUFREQ = 0x20,
+};
+static bool no_cpufreq_access;
+
/*
* DRAM configurations to calculate refresh counter for changing
* frequency of memory.
@@ -66,6 +85,40 @@ static struct cpufreq_frequency_table s5pv210_freq_table[] = {
{0, CPUFREQ_TABLE_END},
};
+static struct regulator *arm_regulator;
+static struct regulator *internal_regulator;
+
+struct s5pv210_dvs_conf {
+ unsigned long arm_volt; /* uV */
+ unsigned long int_volt; /* uV */
+};
+
+const unsigned long arm_volt_max = 1350000;
+const unsigned long int_volt_max = 1250000;
+
+static struct s5pv210_dvs_conf dvs_conf[] = {
+ [L0] = {
+ .arm_volt = 1250000,
+ .int_volt = 1100000,
+ },
+ [L1] = {
+ .arm_volt = 1200000,
+ .int_volt = 1100000,
+ },
+ [L2] = {
+ .arm_volt = 1050000,
+ .int_volt = 1100000,
+ },
+ [L3] = {
+ .arm_volt = 950000,
+ .int_volt = 1100000,
+ },
+ [L4] = {
+ .arm_volt = 950000,
+ .int_volt = 1000000,
+ },
+};
+
static u32 clkdiv_val[5][11] = {
/*
* Clock divider value for following
@@ -146,30 +199,66 @@ static int s5pv210_target(struct cpufreq_policy *policy,
unsigned int index, priv_index;
unsigned int pll_changing = 0;
unsigned int bus_speed_changing = 0;
+ unsigned int arm_volt, int_volt;
+ int ret = 0;
+
+ mutex_lock(&set_freq_lock);
+
+ if (relation & ENABLE_FURTHER_CPUFREQ)
+ no_cpufreq_access = false;
+ if (no_cpufreq_access) {
+#ifdef CONFIG_PM_VERBOSE
+ pr_err("%s:%d denied access to %s as it is disabled"
+ "temporarily\n", __FILE__, __LINE__, __func__);
+#endif
+ ret = -EINVAL;
+ goto out;
+ }
+ if (relation & DISABLE_FURTHER_CPUFREQ)
+ no_cpufreq_access = true;
+ relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ);
freqs.old = s5pv210_getspeed(0);
if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
- target_freq, relation, &index))
- return -EINVAL;
+ target_freq, relation, &index)) {
+ ret = -EINVAL;
+ goto out;
+ }
freqs.new = s5pv210_freq_table[index].frequency;
freqs.cpu = 0;
if (freqs.new == freqs.old)
- return 0;
+ goto out;
/* Finding current running level index */
if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
- freqs.old, relation, &priv_index))
- return -EINVAL;
+ freqs.old, relation, &priv_index)) {
+ ret = -EINVAL;
+ goto out;
+ }
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ arm_volt = dvs_conf[index].arm_volt;
+ int_volt = dvs_conf[index].int_volt;
if (freqs.new > freqs.old) {
- /* Voltage up: will be implemented */
+ /* Voltage up code: increase ARM first */
+ if (!IS_ERR_OR_NULL(arm_regulator) &&
+ !IS_ERR_OR_NULL(internal_regulator)) {
+ ret = regulator_set_voltage(arm_regulator,
+ arm_volt, arm_volt_max);
+ if (ret)
+ goto out;
+ ret = regulator_set_voltage(internal_regulator,
+ int_volt, int_volt_max);
+ if (ret)
+ goto out;
+ }
}
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
/* Check if there need to change PLL */
if ((index == L0) || (priv_index == L0))
pll_changing = 1;
@@ -380,15 +469,24 @@ static int s5pv210_target(struct cpufreq_policy *policy,
}
}
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
if (freqs.new < freqs.old) {
- /* Voltage down: will be implemented */
+ /* Voltage down: decrease INT first */
+ if (!IS_ERR_OR_NULL(arm_regulator) &&
+ !IS_ERR_OR_NULL(internal_regulator)) {
+ regulator_set_voltage(internal_regulator,
+ int_volt, int_volt_max);
+ regulator_set_voltage(arm_regulator,
+ arm_volt, arm_volt_max);
+ }
}
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
printk(KERN_DEBUG "Perf changed[L%d]\n", index);
- return 0;
+out:
+ mutex_unlock(&set_freq_lock);
+ return ret;
}
#ifdef CONFIG_PM
@@ -464,6 +562,40 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
}
+static int s5pv210_cpufreq_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ int ret;
+
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
+ DISABLE_FURTHER_CPUFREQ);
+ if (ret < 0)
+ return NOTIFY_BAD;
+ return NOTIFY_OK;
+ case PM_POST_RESTORE:
+ case PM_POST_SUSPEND:
+ cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
+ ENABLE_FURTHER_CPUFREQ);
+ return NOTIFY_OK;
+ }
+ return NOTIFY_DONE;
+}
+
+static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ int ret = 0;
+
+ ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
+ DISABLE_FURTHER_CPUFREQ);
+ if (ret < 0)
+ return NOTIFY_BAD;
+
+ return NOTIFY_DONE;
+}
+
static struct cpufreq_driver s5pv210_driver = {
.flags = CPUFREQ_STICKY,
.verify = s5pv210_verify_speed,
@@ -477,9 +609,71 @@ static struct cpufreq_driver s5pv210_driver = {
#endif
};
-static int __init s5pv210_cpufreq_init(void)
+static struct notifier_block s5pv210_cpufreq_notifier = {
+ .notifier_call = s5pv210_cpufreq_notifier_event,
+};
+
+static struct notifier_block s5pv210_cpufreq_reboot_notifier = {
+ .notifier_call = s5pv210_cpufreq_reboot_notifier_event,
+};
+
+static int __init s5pv210_cpufreq_probe(struct platform_device *pdev)
{
+ struct s5pv210_cpufreq_data *pdata = dev_get_platdata(&pdev->dev);
+ int i, j;
+
+ if (pdata && pdata->size) {
+ for (i = 0; i < pdata->size; i++) {
+ j = 0;
+ while (s5pv210_freq_table[j].frequency != CPUFREQ_TABLE_END) {
+ if (s5pv210_freq_table[j].frequency == pdata->volt[i].freq) {
+ dvs_conf[j].arm_volt = pdata->volt[i].varm;
+ dvs_conf[j].int_volt = pdata->volt[i].vint;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+
+ arm_regulator = regulator_get(NULL, "vddarm");
+ if (IS_ERR(arm_regulator)) {
+ pr_err("failed to get regulater resource vddarm\n");
+ goto error;
+ }
+ internal_regulator = regulator_get(NULL, "vddint");
+ if (IS_ERR(internal_regulator)) {
+ pr_err("failed to get regulater resource vddint\n");
+ goto error;
+ }
+ goto finish;
+error:
+ pr_warn("Cannot get vddarm or vddint. CPUFREQ Will not"
+ " change the voltage.\n");
+finish:
+ register_pm_notifier(&s5pv210_cpufreq_notifier);
+ register_reboot_notifier(&s5pv210_cpufreq_reboot_notifier);
+
return cpufreq_register_driver(&s5pv210_driver);
}
+static struct platform_driver s5pv210_cpufreq_drv = {
+ .probe = s5pv210_cpufreq_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s5pv210-cpufreq",
+ },
+};
+
+static int __init s5pv210_cpufreq_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&s5pv210_cpufreq_drv);
+ if (!ret)
+ pr_info("%s: S5PV210 cpu-freq driver\n", __func__);
+
+ return ret;
+}
+
late_initcall(s5pv210_cpufreq_init);
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
index 8d58f19..31a965e 100644
--- a/arch/arm/mach-s5pv210/dev-audio.c
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -49,8 +49,11 @@ static struct s3c_audio_pdata i2sv5_pdata = {
.cfg_gpio = s5pv210_cfg_i2s,
.type = {
.i2s = {
- .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
- | QUIRK_NEED_RSTCLR,
+ .quirks = QUIRK_PRI_6CHAN
+#ifdef CONFIG_SND_SOC_SAMSUNG_I2S_SEC
+ | QUIRK_SEC_DAI
+#endif
+ | QUIRK_NEED_RSTCLR,
.src_clk = rclksrc,
},
},
diff --git a/arch/arm/mach-s5pv210/dev-cpufreq.c b/arch/arm/mach-s5pv210/dev-cpufreq.c
new file mode 100644
index 0000000..ff0e0f1
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-cpufreq.c
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/arm/mach-s5pv210/dev-cpufreq.c
+ *
+ * Copyright (c) 2008-2010 Samsung Electronics
+ * Taekki Kim <taekki.kim@samsung.com>
+ *
+ * S5PV210 series device definition for cpufreq devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/cpu-freq-v210.h>
+
+struct platform_device s5pv210_device_cpufreq = {
+ .name = "s5pv210-cpufreq",
+ .id = -1,
+};
+
+void s5pv210_cpufreq_set_platdata(struct s5pv210_cpufreq_data *pdata)
+{
+ s5pv210_device_cpufreq.dev.platform_data = pdata;
+}
+
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 497d343..34cfacc 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -30,6 +30,71 @@
static u64 dma_dmamask = DMA_BIT_MASK(32);
+static struct resource s5pv210_mdma_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_MDMA,
+ .end = S5PV210_PA_MDMA + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MDMA,
+ .end = IRQ_MDMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pv210_mdma_pdata = {
+ .peri = {
+ /* The DMAC can have max 8 channel so there
+ * can be 8 M<->M requests served at any time.
+ */
+ [0] = DMACH_MTOM_0,
+ [1] = DMACH_MTOM_1,
+ [2] = DMACH_MTOM_2,
+ [3] = DMACH_MTOM_3,
+ [4] = DMACH_MTOM_4,
+ [5] = DMACH_MTOM_5,
+ [6] = DMACH_MTOM_6,
+ [7] = DMACH_MTOM_7,
+ [8] = DMACH_MAX,
+ [9] = DMACH_MAX,
+ [10] = DMACH_MAX,
+ [11] = DMACH_MAX,
+ [12] = DMACH_MAX,
+ [13] = DMACH_MAX,
+ [14] = DMACH_MAX,
+ [15] = DMACH_MAX,
+ [16] = DMACH_MAX,
+ [17] = DMACH_MAX,
+ [18] = DMACH_MAX,
+ [19] = DMACH_MAX,
+ [20] = DMACH_MAX,
+ [21] = DMACH_MAX,
+ [22] = DMACH_MAX,
+ [23] = DMACH_MAX,
+ [24] = DMACH_MAX,
+ [25] = DMACH_MAX,
+ [26] = DMACH_MAX,
+ [27] = DMACH_MAX,
+ [28] = DMACH_MAX,
+ [29] = DMACH_MAX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+struct platform_device s5pv210_device_mdma = {
+ .name = "s3c-pl330",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv210_mdma_resource),
+ .resource = s5pv210_mdma_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv210_mdma_pdata,
+ },
+};
+
static struct resource s5pv210_pdma0_resource[] = {
[0] = {
.start = S5PV210_PA_PDMA0,
@@ -80,9 +145,9 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
},
};
-static struct platform_device s5pv210_device_pdma0 = {
+struct platform_device s5pv210_device_pdma0 = {
.name = "s3c-pl330",
- .id = 0,
+ .id = 1,
.num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
.resource = s5pv210_pdma0_resource,
.dev = {
@@ -142,9 +207,9 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
},
};
-static struct platform_device s5pv210_device_pdma1 = {
+struct platform_device s5pv210_device_pdma1 = {
.name = "s3c-pl330",
- .id = 1,
+ .id = 2,
.num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
.resource = s5pv210_pdma1_resource,
.dev = {
@@ -155,6 +220,7 @@ static struct platform_device s5pv210_device_pdma1 = {
};
static struct platform_device *s5pv210_dmacs[] __initdata = {
+ &s5pv210_device_mdma,
&s5pv210_device_pdma0,
&s5pv210_device_pdma1,
};
diff --git a/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h b/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
new file mode 100644
index 0000000..8274a01
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
@@ -0,0 +1,31 @@
+/* arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * S5PV210/S5PC110 CPU frequency scaling support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CPU_FREQ_H
+#define __ASM_ARCH_CPU_FREQ_H
+
+#include <linux/cpufreq.h>
+
+/* For cpu-freq driver */
+struct s5pv210_cpufreq_voltage {
+ unsigned int freq; /* kHz */
+ unsigned long varm; /* uV */
+ unsigned long vint; /* uV */
+};
+
+struct s5pv210_cpufreq_data {
+ struct s5pv210_cpufreq_voltage *volt;
+ unsigned int size;
+};
+
+extern void s5pv210_cpufreq_set_platdata(struct s5pv210_cpufreq_data *pdata);
+
+#endif /* __ASM_ARCH_CPU_FREQ_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index b9f9ec3..1e3ad87 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -99,8 +99,8 @@
#define IRQ_TC IRQ_PENDN
#define IRQ_KEYPAD S5P_IRQ_VIC2(25)
#define IRQ_CG S5P_IRQ_VIC2(26)
-#define IRQ_SSS_INT S5P_IRQ_VIC2(27)
-#define IRQ_SSS_HASH S5P_IRQ_VIC2(28)
+#define IRQ_SSS_HASH S5P_IRQ_VIC2(27)
+#define IRQ_SSS_INT S5P_IRQ_VIC2(28)
#define IRQ_PCM2 S5P_IRQ_VIC2(29)
#define IRQ_SDMIRQ S5P_IRQ_VIC2(30)
#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 1dd5883..4f09492 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -16,7 +16,11 @@
#include <plat/map-base.h>
#include <plat/map-s5p.h>
+#ifdef CONFIG_CPU_S5PC110
+#define S5PV210_PA_SDRAM 0x30000000
+#else
#define S5PV210_PA_SDRAM 0x20000000
+#endif
#define S5PV210_PA_SROM_BANK5 0xA8000000
@@ -59,11 +63,15 @@
#define S5PV210_PA_CFCON 0xE8200000
+#define S5PV210_PA_ACE 0xEA000000
+
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
#define S5PV210_PA_HSOTG 0xEC000000
#define S5PV210_PA_HSPHY 0xEC100000
+#define S5PV210_PA_AUDSS 0xEEE10000
+
#define S5PV210_PA_IIS0 0xEEE30000
#define S5PV210_PA_IIS1 0xE2100000
#define S5PV210_PA_IIS2 0xE2A00000
@@ -99,8 +107,8 @@
#define S3C_PA_IIC1 S5PV210_PA_IIC1
#define S3C_PA_IIC2 S5PV210_PA_IIC2
#define S3C_PA_RTC S5PV210_PA_RTC
-#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S3C_PA_WDT S5PV210_PA_WATCHDOG
+#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S5P_PA_CHIPID S5PV210_PA_CHIPID
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
@@ -113,11 +121,15 @@
#define S5P_PA_SROMC S5PV210_PA_SROMC
#define S5P_PA_SYSCON S5PV210_PA_SYSCON
#define S5P_PA_TIMER S5PV210_PA_TIMER
+#define S5P_PA_HSOTG S5PV210_PA_HSOTG
+#define S5P_PA_HSPHY S5PV210_PA_HSPHY
#define SAMSUNG_PA_ADC S5PV210_PA_ADC
#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
#define SAMSUNG_PA_KEYPAD S5PV210_PA_KEYPAD
+#define S5P_PA_ACE S5PV210_PA_ACE
+
/* UART */
#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
diff --git a/arch/arm/mach-s5pv210/include/mach/media.h b/arch/arm/mach-s5pv210/include/mach/media.h
new file mode 100644
index 0000000..573cd8f
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/media.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/media.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung Media device descriptions for s5pv210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S5PV210_MEDIA_H
+#define _S5PV210_MEDIA_H
+
+#define S5P_MDEV_FIMC0 0
+#define S5P_MDEV_FIMC1 1
+#define S5P_MDEV_FIMC2 2
+#define S5P_MDEV_MFC 4
+#define S5P_MDEV_JPEG 5
+#define S5P_MDEV_FIMD 6
+#define S5P_MDEV_FIMG2D 7
+#define S5P_MDEV_TEXSTREAM 8
+
+#define S5P_RANGE_MFC SZ_256M
+#endif
diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h
index 7b5fcf0..5c42a7a 100644
--- a/arch/arm/mach-s5pv210/include/mach/memory.h
+++ b/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -13,7 +13,11 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
+#ifdef CONFIG_CPU_S5PC110
+#define PLAT_PHYS_OFFSET UL(0x30000000)
+#else
#define PLAT_PHYS_OFFSET UL(0x20000000)
+#endif
#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M)
/*
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
index e8d394f..3e22109 100644
--- a/arch/arm/mach-s5pv210/include/mach/pm-core.h
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -41,3 +41,6 @@ static inline void s3c_pm_arch_update_uart(void __iomem *regs,
{
/* nothing here yet */
}
+
+static inline void s3c_pm_restored_gpios(void) { }
+static inline void s3c_pm_saved_gpios(void) { }
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-audss.h b/arch/arm/mach-s5pv210/include/mach/regs-audss.h
new file mode 100644
index 0000000..cb6ccd1
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-audss.h
@@ -0,0 +1,44 @@
+/* arch/arm/mach-s5pv210/include/mach/regs-audss.h
+ *
+ * Copyright 2011 Samsung Electronics
+ *
+ * S5PV2XX Audio SubSystem clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __MACH_REGS_AUDSS_H
+#define __MACH_REGS_AUDSS_H __FILE__
+
+#define S5P_AUDSSREG(x) (S5P_VA_AUDSS + (x))
+
+#define S5P_CLKSRC_AUDSS S5P_AUDSSREG(0x0)
+#define S5P_CLKDIV_AUDSS S5P_AUDSSREG(0x4)
+#define S5P_CLKGATE_AUDSS S5P_AUDSSREG(0x8)
+
+/* CLKSRC0 */
+#define S5P_AUDSS_CLKSRC_MAIN_MASK (0x1<<0)
+#define S5P_AUDSS_CLKSRC_MAIN_SHIFT (0)
+#define S5P_AUDSS_CLKSRC_BUSCLK_MASK (0x1<<1)
+#define S5P_AUDSS_CLKSRC_BUSCLK_SHIFT (1)
+#define S5P_AUDSS_CLKSRC_I2SCLK_MASK (0x3<<2)
+#define S5P_AUDSS_CLKSRC_I2SCLK_SHIFT (2)
+
+/* CLKDIV0 */
+#define S5P_AUDSS_CLKDIV_BUSCLK_MASK (0xf<<0)
+#define S5P_AUDSS_CLKDIV_BUSCLK_SHIFT (0)
+#define S5P_AUDSS_CLKDIV_I2SCLK_MASK (0xf<<4)
+#define S5P_AUDSS_CLKDIV_I2SCLK_SHIFT (4)
+
+/* IP Clock Gate 0 Registers */
+#define S5P_AUDSS_CLKGATE_HCLKRP (1<<0)
+#define S5P_AUDSS_CLKGATE_HCLKBUF (1<<1)
+#define S5P_AUDSS_CLKGATE_HCLKDMA (1<<2)
+#define S5P_AUDSS_CLKGATE_HCLKHWA (1<<3)
+#define S5P_AUDSS_CLKGATE_HCLKUART (1<<4)
+#define S5P_AUDSS_CLKGATE_HCLKI2S (1<<5)
+#define S5P_AUDSS_CLKGATE_CLKI2S (1<<6)
+
+#endif /* _MACH_REGS_AUDSS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index 78925c5..7a843d1 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -118,6 +118,32 @@
#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
+/* CLK_OUT register */
+#define S5P_CLKOUT_DIVVAL_SHIFT (20)
+#define S5P_CLKOUT_DIVVAL_MASK (0xF << S5P_CLKOUT_DIVVAL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SHIFT (12)
+#define S5P_CLKOUT_CLKSEL_MASK (0x1F << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_APLL (0 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_MPLL (1 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_EPLL (2 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_VPLL (3 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_USBPHY0 (4 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_USBPHY1 (5 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_HDMIPHY (6 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_RTC (7 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_TICK (8 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_HCLK200 (9 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_PCLK100 (10 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_HCLK166 (11 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_PCLK83 (12 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_HCLK133 (13 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_PCLK66 (14 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_ARMCLK (15 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_SCLK_HPM (16 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_XXTI (17 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_XUSBXTI (18 << S5P_CLKOUT_CLKSEL_SHIFT)
+#define S5P_CLKOUT_CLKSEL_DOUT (19 << S5P_CLKOUT_CLKSEL_SHIFT)
+
#define S5P_SWRESET S5P_CLKREG(0x2000)
#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
@@ -197,6 +223,11 @@
#define S5P_OTHERS_RET_MMC (1 << 29)
#define S5P_OTHERS_RET_UART (1 << 28)
#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
+#define S5P_OTHERS_CLKOUT_SHIFT (8)
+#define S5P_OTHERS_CLKOUT_MASK (0x3 << S5P_OTHERS_CLKOUT_SHIFT)
+#define S5P_OTHERS_CLKOUT_SYSCON (0 << S5P_OTHERS_CLKOUT_SHIFT)
+#define S5P_OTHERS_CLKOUT_XXIT (2 << S5P_OTHERS_CLKOUT_SHIFT)
+#define S5P_OTHERS_CLKOUT_XUSBXTI (3 << S5P_OTHERS_CLKOUT_SHIFT)
/* S5P_DAC_CONTROL */
#define S5P_DAC_ENABLE (1)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-fb.h b/arch/arm/mach-s5pv210/include/mach/regs-fb.h
deleted file mode 100644
index 60d9929..0000000
--- a/arch/arm/mach-s5pv210/include/mach/regs-fb.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
- *
- * Dummy framebuffer to allow build for the moment.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_MACH_REGS_FB_H
-#define __ASM_ARCH_MACH_REGS_FB_H __FILE__
-
-#include <plat/regs-fb-v4.h>
-
-static inline unsigned int s3c_fb_pal_reg(unsigned int window, int reg)
-{
- return 0x2400 + (window * 256 *4 ) + reg;
-}
-
-#endif /* __ASM_ARCH_MACH_REGS_FB_H */
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 4e1d8ff..509627f 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -29,7 +29,6 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
-#include <mach/regs-fb.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-serial.h>
@@ -40,6 +39,7 @@
#include <plat/fimc-core.h>
#include <plat/sdhci.h>
#include <plat/s5p-time.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define AQUILA_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 31d5aa7..e0c4d06 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -34,7 +34,6 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
-#include <mach/regs-fb.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-serial.h>
@@ -47,6 +46,7 @@
#include <plat/sdhci.h>
#include <plat/clock.h>
#include <plat/s5p-time.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index 6c412c8..85d1b73 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -10,27 +10,51 @@
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8698.h>
#include <linux/init.h>
#include <linux/serial_core.h>
-#include <linux/i2c.h>
#include <linux/sysdev.h>
+#include <linux/dm9000.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/delay.h>
+#include <linux/pwm_backlight.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
+#include <video/platform_lcd.h>
+
#include <mach/map.h>
+#include <mach/gpio.h>
#include <mach/regs-clock.h>
+#include <mach/cpu-freq-v210.h>
+#include <mach/media.h>
#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/gpio-cfg.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
#include <plat/ata.h>
#include <plat/iic.h>
+#include <plat/keypad.h>
#include <plat/pm.h>
+#include <plat/fb.h>
#include <plat/s5p-time.h>
+#include <plat/media.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -77,23 +101,511 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
},
};
+#ifdef CONFIG_CPU_FREQ
+static struct s5pv210_cpufreq_voltage smdkc110_cpufreq_volt[] = {
+ {
+ .freq = 1000000,
+ .varm = 1275000,
+ .vint = 1100000,
+ }, {
+ .freq = 800000,
+ .varm = 1200000,
+ .vint = 1100000,
+ }, {
+ .freq = 400000,
+ .varm = 1050000,
+ .vint = 1100000,
+ }, {
+ .freq = 200000,
+ .varm = 950000,
+ .vint = 1100000,
+ }, {
+ .freq = 100000,
+ .varm = 950000,
+ .vint = 1000000,
+ },
+};
+
+static struct s5pv210_cpufreq_data smdkc110_cpufreq_plat = {
+ .volt = smdkc110_cpufreq_volt,
+ .size = ARRAY_SIZE(smdkc110_cpufreq_volt),
+};
+#endif
+
+#if defined(CONFIG_REGULATOR_MAX8698)
+/* LDO */
+static struct regulator_consumer_supply smdkc110_ldo3_consumer[] = {
+ REGULATOR_SUPPLY("pd_io", "s3c-usbgadget")
+};
+
+static struct regulator_consumer_supply smdkc110_ldo5_consumer[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
+};
+
+static struct regulator_consumer_supply smdkc110_ldo8_consumer[] = {
+ REGULATOR_SUPPLY("pd_core", "s3c-usbgadget")
+};
+
+static struct regulator_init_data smdkc110_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo3_data = {
+ .constraints = {
+ .name = "VUOTG_D+VUHOST_D_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo3_consumer),
+ .consumer_supplies = smdkc110_ldo3_consumer,
+};
+
+static struct regulator_init_data smdkc110_ldo4_data = {
+ .constraints = {
+ .name = "V_MIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo5_data = {
+ .constraints = {
+ .name = "VMMC+VEXT_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo5_consumer),
+ .consumer_supplies = smdkc110_ldo5_consumer,
+};
+
+static struct regulator_init_data smdkc110_ldo6_data = {
+ .constraints = {
+ .name = "VCC_2.6V",
+ .min_uV = 2600000,
+ .max_uV = 2600000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo7_data = {
+ .constraints = {
+ .name = "VDAC_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkc110_ldo8_data = {
+ .constraints = {
+ .name = "VUOTG_A+VUHOST_A_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkc110_ldo8_consumer),
+ .consumer_supplies = smdkc110_ldo8_consumer,
+};
+
+static struct regulator_init_data smdkc110_ldo9_data = {
+ .constraints = {
+ .name = "VADC+VSYS+VKEY_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply smdkc110_buck1_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct regulator_consumer_supply smdkc110_buck2_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_init_data smdkc110_buck1_data = {
+ .constraints = {
+ .name = "VCC_ARM",
+ .min_uV = 750000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1250000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &smdkc110_buck1_consumer,
+};
+
+static struct regulator_init_data smdkc110_buck2_data = {
+ .constraints = {
+ .name = "VCC_INTERNAL",
+ .min_uV = 950000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &smdkc110_buck2_consumer,
+};
+
+static struct regulator_init_data smdkc110_buck3_data = {
+ .constraints = {
+ .name = "VCC_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .apply_uV = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct max8698_regulator_data smdkc110_regulators[] = {
+ { MAX8698_LDO2, &smdkc110_ldo2_data },
+ { MAX8698_LDO3, &smdkc110_ldo3_data },
+ { MAX8698_LDO4, &smdkc110_ldo4_data },
+ { MAX8698_LDO5, &smdkc110_ldo5_data },
+ { MAX8698_LDO6, &smdkc110_ldo6_data },
+ { MAX8698_LDO7, &smdkc110_ldo7_data },
+ { MAX8698_LDO8, &smdkc110_ldo8_data },
+ { MAX8698_LDO9, &smdkc110_ldo9_data },
+ { MAX8698_BUCK1, &smdkc110_buck1_data },
+ { MAX8698_BUCK2, &smdkc110_buck2_data },
+ { MAX8698_BUCK3, &smdkc110_buck3_data },
+};
+
+static struct max8698_platform_data smdkc110_max8698_pdata = {
+ .num_regulators = ARRAY_SIZE(smdkc110_regulators),
+ .regulators = smdkc110_regulators,
+
+ /* 1GHz default voltage */
+ .dvsarm1 = 0xa, /* 1.25v */
+ .dvsarm2 = 0x9, /* 1.20V */
+ .dvsarm3 = 0x6, /* 1.05V */
+ .dvsarm4 = 0x4, /* 0.95V */
+ .dvsint1 = 0x7, /* 1.10v */
+ .dvsint2 = 0x5, /* 1.00V */
+
+ .set1 = S5PV210_GPH1(6),
+ .set2 = S5PV210_GPH1(7),
+ .set3 = S5PV210_GPH0(4),
+};
+#endif
+
static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
.setup_gpio = s5pv210_ide_setup_gpio,
};
+static uint32_t smdkc110_keymap[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 3, KEY_1), KEY(0, 4, KEY_2), KEY(0, 5, KEY_3),
+ KEY(0, 6, KEY_4), KEY(0, 7, KEY_5),
+ KEY(1, 3, KEY_A), KEY(1, 4, KEY_B), KEY(1, 5, KEY_C),
+ KEY(1, 6, KEY_D), KEY(1, 7, KEY_E)
+};
+
+static struct matrix_keymap_data smdkc110_keymap_data __initdata = {
+ .keymap = smdkc110_keymap,
+ .keymap_size = ARRAY_SIZE(smdkc110_keymap),
+};
+
+static struct samsung_keypad_platdata smdkc110_keypad_data __initdata = {
+ .keymap_data = &smdkc110_keymap_data,
+ .rows = 2,
+ .cols = 8,
+};
+
+static struct resource smdkc110_dm9000_resources[] = {
+ [0] = {
+ .start = S5PV210_PA_SROM_BANK5,
+ .end = S5PV210_PA_SROM_BANK5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S5PV210_PA_SROM_BANK5 + 2,
+ .end = S5PV210_PA_SROM_BANK5 + 2,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_EINT(9),
+ .end = IRQ_EINT(9),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct dm9000_plat_data smdkc110_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+ .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
+};
+
+struct platform_device smdkc110_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkc110_dm9000_resources),
+ .resource = smdkc110_dm9000_resources,
+ .dev = {
+ .platform_data = &smdkc110_dm9000_platdata,
+ },
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdkc110_b_pwr_5v_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "PVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data smdkc110_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkc110_b_pwr_5v_consumers),
+ .consumer_supplies = smdkc110_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdkc110_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdkc110_b_pwr_5v_data,
+};
+
+static struct platform_device smdkc110_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdkc110_b_pwr_5v_pdata,
+ },
+};
+#endif
+
+static void smdkc110_lte480wv_set_power(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(S5PV210_GPD0(3), "GPD0");
+ gpio_direction_output(S5PV210_GPD0(3), 1);
+ gpio_free(S5PV210_GPD0(3));
+#endif
+
+ /* fire nRESET on power up */
+ gpio_request(S5PV210_GPH0(6), "GPH0");
+
+ gpio_direction_output(S5PV210_GPH0(6), 1);
+
+ gpio_set_value(S5PV210_GPH0(6), 0);
+ mdelay(10);
+
+ gpio_set_value(S5PV210_GPH0(6), 1);
+ mdelay(10);
+
+ gpio_free(S5PV210_GPH0(6));
+ } else {
+#if !defined(CONFIG_BACKLIGHT_PWM)
+ gpio_request(S5PV210_GPD0(3), "GPD0");
+ gpio_direction_output(S5PV210_GPD0(3), 0);
+ gpio_free(S5PV210_GPD0(3));
+#endif
+ }
+}
+
+static struct plat_lcd_data smdkc110_lcd_lte480wv_data = {
+ .set_power = smdkc110_lte480wv_set_power,
+};
+
+static struct platform_device smdkc110_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdkc110_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkc110_fb_win0 = {
+ .win_mode = {
+ .left_margin = 13,
+ .right_margin = 8,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 24,
+};
+
+static struct s3c_fb_platdata smdkc110_lcd0_pdata __initdata = {
+ .win[0] = &smdkc110_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+};
+
+static struct gpio_event_direct_entry smdkc110_keypad_key_map[] = {
+ {
+ .gpio = S5PV210_GPH3(7),
+ .code = KEY_POWER,
+ }
+};
+
+static struct gpio_event_input_info smdkc110_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdkc110_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdkc110_keypad_key_map)
+};
+
+static struct gpio_event_info *smdkc110_input_info[] = {
+ &smdkc110_keypad_key_info.info,
+};
+
+static struct gpio_event_platform_data smdkc110_input_data = {
+ .names = {
+ "smdkc110-keypad",
+ NULL,
+ },
+ .info = smdkc110_input_info,
+ .info_count = ARRAY_SIZE(smdkc110_input_info),
+};
+
+static struct platform_device smdkc110_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdkc110_input_data,
+ },
+};
+
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
static struct platform_device *smdkc110_devices[] __initdata = {
- &samsung_asoc_dma,
- &s5pv210_device_iis0,
- &s5pv210_device_ac97,
- &s5pv210_device_spdif,
+ &s3c_device_adc,
&s3c_device_cfcon,
+ &s3c_device_fb,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_i2c2,
&s3c_device_rtc,
+ &s3c_device_ts,
&s3c_device_wdt,
+ &s5pv210_device_ac97,
+ &s5pv210_device_iis0,
+ &s5pv210_device_spdif,
+#ifdef CONFIG_CPU_FREQ
+ &s5pv210_device_cpufreq,
+#endif
+ &samsung_asoc_dma,
+ &samsung_device_keypad,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
+ &smdkc110_dm9000,
+ &smdkc110_lcd_lte480wv,
+ &smdkc110_input_device,
+#ifdef CONFIG_REGULATOR
+ &smdkc110_b_pwr_5v,
+#endif
+#ifdef CONFIG_CRYPTO_S5P_DEV_ACE
+ &s5p_device_ace,
+#endif
};
+static void __init smdkc110_button_init(void)
+{
+ s3c_gpio_cfgpin(S5PV210_GPH3(7), (0xf << 28));
+ s3c_gpio_setpull(S5PV210_GPH3(7), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(4), (0xf << 16));
+ s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE);
+}
+
+static void __init smdkc110_dm9000_init(void)
+{
+ unsigned int tmp;
+
+ gpio_request(S5PV210_MP01(5), "nCS5");
+ s3c_gpio_cfgpin(S5PV210_MP01(5), S3C_GPIO_SFN(2));
+ gpio_free(S5PV210_MP01(5));
+
+ tmp = (5 << S5P_SROM_BCX__TACC__SHIFT);
+ __raw_writel(tmp, S5P_SROM_BC5);
+
+ tmp = __raw_readl(S5P_SROM_BW);
+ tmp &= (S5P_SROM_BW__CS_MASK << S5P_SROM_BW__NCS5__SHIFT);
+ tmp |= (1 << S5P_SROM_BW__NCS5__SHIFT);
+ __raw_writel(tmp, S5P_SROM_BW);
+}
+
static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
{ I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
{ I2C_BOARD_INFO("wm8580", 0x1b), },
@@ -104,7 +616,51 @@ static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
};
static struct i2c_board_info smdkc110_i2c_devs2[] __initdata = {
- /* To Be Updated */
+#if defined(CONFIG_REGULATOR_MAX8698)
+ {
+ I2C_BOARD_INFO("max8698", 0xCC >> 1),
+ .platform_data = &smdkc110_max8698_pdata,
+ },
+#endif
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cal_x_max = 800,
+ .cal_y_max = 480,
+ .cal_param = {
+ -13357, -85, 53858048, -95, -8493, 32809514, 65536
+ },
+};
+
+static void smdkc110_sound_init(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_CLK_OUT);
+ reg &= ~S5P_CLKOUT_CLKSEL_MASK;
+ reg &= ~S5P_CLKOUT_DIVVAL_MASK;
+ reg |= S5P_CLKOUT_CLKSEL_XUSBXTI;
+ reg |= 0x1 << S5P_CLKOUT_DIVVAL_SHIFT;
+ __raw_writel(reg, S5P_CLK_OUT);
+
+ reg = __raw_readl(S5P_OTHERS);
+ reg &= ~S5P_OTHERS_CLKOUT_MASK;
+ reg |= S5P_OTHERS_CLKOUT_SYSCON;
+ __raw_writel(reg, S5P_OTHERS);
+}
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkc110_bl_gpio_info = {
+ .no = S5PV210_GPD0(3),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkc110_bl_data = {
+ .pwm_id = 3,
+ .pwm_period_ns = 1000,
};
static void __init smdkc110_map_io(void)
@@ -112,13 +668,21 @@ static void __init smdkc110_map_io(void)
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
- s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+ s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+
+ s5p_reserve_mem(S5P_RANGE_MFC);
}
static void __init smdkc110_machine_init(void)
{
s3c_pm_init();
+ smdkc110_button_init();
+ smdkc110_dm9000_init();
+
+ samsung_keypad_set_platdata(&smdkc110_keypad_data);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_i2c2_set_platdata(NULL);
@@ -131,6 +695,17 @@ static void __init smdkc110_machine_init(void)
s3c_ide_set_platdata(&smdkc110_ide_pdata);
+ s3c_fb_set_platdata(&smdkc110_lcd0_pdata);
+
+#ifdef CONFIG_CPU_FREQ
+ s5pv210_cpufreq_set_platdata(&smdkc110_cpufreq_plat);
+#endif
+
+ /* SOUND */
+ smdkc110_sound_init();
+
+ samsung_bl_set(&smdkc110_bl_gpio_info, &smdkc110_bl_data);
+
platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
}
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index c6a9e86..614ac9a 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -11,12 +11,17 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/max8698.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/sysdev.h>
#include <linux/dm9000.h>
#include <linux/fb.h>
#include <linux/gpio.h>
+#include <linux/gpio_event.h>
#include <linux/delay.h>
#include <linux/pwm_backlight.h>
@@ -28,8 +33,9 @@
#include <video/platform_lcd.h>
#include <mach/map.h>
+#include <mach/gpio.h>
#include <mach/regs-clock.h>
-#include <mach/regs-fb.h>
+#include <mach/media.h>
#include <plat/regs-serial.h>
#include <plat/regs-srom.h>
@@ -45,6 +51,9 @@
#include <plat/pm.h>
#include <plat/fb.h>
#include <plat/s5p-time.h>
+#include <plat/media.h>
+#include <plat/backlight.h>
+#include <plat/regs-fb-v4.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -91,6 +100,223 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
},
};
+#if defined(CONFIG_REGULATOR_MAX8698)
+/* LDO */
+static struct regulator_consumer_supply smdkv210_ldo3_consumer[] = {
+ REGULATOR_SUPPLY("pd_io", "s3c-usbgadget")
+};
+
+static struct regulator_consumer_supply smdkv210_ldo5_consumer[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("DVDD", "0-001b"),
+};
+
+static struct regulator_consumer_supply smdkv210_ldo8_consumer[] = {
+ REGULATOR_SUPPLY("pd_core", "s3c-usbgadget")
+};
+
+static struct regulator_init_data smdkv210_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo3_data = {
+ .constraints = {
+ .name = "VUOTG_D+VUHOST_D_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkv210_ldo3_consumer),
+ .consumer_supplies = smdkv210_ldo3_consumer,
+};
+
+static struct regulator_init_data smdkv210_ldo4_data = {
+ .constraints = {
+ .name = "V_MIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo5_data = {
+ .constraints = {
+ .name = "VMMC+VEXT_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkv210_ldo5_consumer),
+ .consumer_supplies = smdkv210_ldo5_consumer,
+};
+
+static struct regulator_init_data smdkv210_ldo6_data = {
+ .constraints = {
+ .name = "VCC_2.6V",
+ .min_uV = 2600000,
+ .max_uV = 2600000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo7_data = {
+ .constraints = {
+ .name = "VDAC_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data smdkv210_ldo8_data = {
+ .constraints = {
+ .name = "VUOTG_A+VUHOST_A_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkv210_ldo8_consumer),
+ .consumer_supplies = smdkv210_ldo8_consumer,
+};
+
+static struct regulator_init_data smdkv210_ldo9_data = {
+ .constraints = {
+ .name = "VADC+VSYS+VKEY_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply smdkv210_buck1_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct regulator_consumer_supply smdkv210_buck2_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_init_data smdkv210_buck1_data = {
+ .constraints = {
+ .name = "VCC_ARM",
+ .min_uV = 750000,
+ .max_uV = 1500000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1250000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &smdkv210_buck1_consumer,
+};
+
+static struct regulator_init_data smdkv210_buck2_data = {
+ .constraints = {
+ .name = "VCC_INTERNAL",
+ .min_uV = 950000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .uV = 1100000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &smdkv210_buck2_consumer,
+};
+
+static struct regulator_init_data smdkv210_buck3_data = {
+ .constraints = {
+ .name = "VCC_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .apply_uV = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+};
+
+static struct max8698_regulator_data smdkv210_regulators[] = {
+ { MAX8698_LDO2, &smdkv210_ldo2_data },
+ { MAX8698_LDO3, &smdkv210_ldo3_data },
+ { MAX8698_LDO4, &smdkv210_ldo4_data },
+ { MAX8698_LDO5, &smdkv210_ldo5_data },
+ { MAX8698_LDO6, &smdkv210_ldo6_data },
+ { MAX8698_LDO7, &smdkv210_ldo7_data },
+ { MAX8698_LDO8, &smdkv210_ldo8_data },
+ { MAX8698_LDO9, &smdkv210_ldo9_data },
+ { MAX8698_BUCK1, &smdkv210_buck1_data },
+ { MAX8698_BUCK2, &smdkv210_buck2_data },
+ { MAX8698_BUCK3, &smdkv210_buck3_data },
+};
+
+static struct max8698_platform_data smdkv210_max8698_pdata = {
+ .num_regulators = ARRAY_SIZE(smdkv210_regulators),
+ .regulators = smdkv210_regulators,
+
+ /* 1GHz default voltage */
+ .dvsarm1 = 0xa, /* 1.25v */
+ .dvsarm2 = 0x9, /* 1.20V */
+ .dvsarm3 = 0x6, /* 1.05V */
+ .dvsarm4 = 0x4, /* 0.95V */
+ .dvsint1 = 0x7, /* 1.10v */
+ .dvsint2 = 0x5, /* 1.00V */
+
+ .set1 = S5PV210_GPH1(6),
+ .set2 = S5PV210_GPH1(7),
+ .set3 = S5PV210_GPH0(4),
+};
+#endif
+
static struct s3c_ide_platdata smdkv210_ide_pdata __initdata = {
.setup_gpio = s5pv210_ide_setup_gpio,
};
@@ -110,7 +336,7 @@ static struct matrix_keymap_data smdkv210_keymap_data __initdata = {
static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
.keymap_data = &smdkv210_keymap_data,
- .rows = 8,
+ .rows = 2,
.cols = 8,
};
@@ -147,6 +373,38 @@ struct platform_device smdkv210_dm9000 = {
},
};
+#ifdef CONFIG_REGULATOR
+static struct regulator_consumer_supply smdkv210_b_pwr_5v_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "PVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data smdkv210_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdkv210_b_pwr_5v_consumers),
+ .consumer_supplies = smdkv210_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdkv210_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdkv210_b_pwr_5v_data,
+};
+
+static struct platform_device smdkv210_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdkv210_b_pwr_5v_pdata,
+ },
+};
+#endif
+
static void smdkv210_lte480wv_set_power(struct plat_lcd_data *pd,
unsigned int power)
{
@@ -210,45 +468,50 @@ static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
.setup_gpio = s5pv210_fb_gpio_setup_24bpp,
};
-static int smdkv210_backlight_init(struct device *dev)
-{
- int ret;
-
- ret = gpio_request(S5PV210_GPD0(3), "Backlight");
- if (ret) {
- printk(KERN_ERR "failed to request GPD for PWM-OUT 3\n");
- return ret;
+static struct gpio_event_direct_entry smdkv210_keypad_key_map[] = {
+ {
+ .gpio = S5PV210_GPH3(7),
+ .code = KEY_POWER,
}
+};
- /* Configure GPIO pin with S5PV210_GPD_0_3_TOUT_3 */
- s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_SFN(2));
-
- return 0;
-}
+static struct gpio_event_input_info smdkv210_keypad_key_info = {
+ .info.func = gpio_event_input_func,
+ .info.no_suspend = true,
+ .debounce_time.tv64 = 5 * NSEC_PER_MSEC,
+ .type = EV_KEY,
+ .keymap = smdkv210_keypad_key_map,
+ .keymap_size = ARRAY_SIZE(smdkv210_keypad_key_map)
+};
-static void smdkv210_backlight_exit(struct device *dev)
-{
- s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_OUTPUT);
- gpio_free(S5PV210_GPD0(3));
-}
+static struct gpio_event_info *smdkv210_input_info[] = {
+ &smdkv210_keypad_key_info.info,
+};
-static struct platform_pwm_backlight_data smdkv210_backlight_data = {
- .pwm_id = 3,
- .max_brightness = 255,
- .dft_brightness = 255,
- .pwm_period_ns = 78770,
- .init = smdkv210_backlight_init,
- .exit = smdkv210_backlight_exit,
+static struct gpio_event_platform_data smdkv210_input_data = {
+ .names = {
+ "smdkv210-keypad",
+ NULL,
+ },
+ .info = smdkv210_input_info,
+ .info_count = ARRAY_SIZE(smdkv210_input_info),
};
-static struct platform_device smdkv210_backlight_device = {
- .name = "pwm-backlight",
- .dev = {
- .parent = &s3c_device_timer[3].dev,
- .platform_data = &smdkv210_backlight_data,
+static struct platform_device smdkv210_input_device = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &smdkv210_input_data,
},
};
+#ifdef CONFIG_BATTERY_SAMSUNG
+static struct platform_device samsung_device_battery = {
+ .name = "samsung-fake-battery",
+ .id = -1,
+};
+#endif
+
static struct platform_device *smdkv210_devices[] __initdata = {
&s3c_device_adc,
&s3c_device_cfcon,
@@ -268,12 +531,26 @@ static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_spdif,
&samsung_asoc_dma,
&samsung_device_keypad,
+#ifdef CONFIG_BATTERY_SAMSUNG
+ &samsung_device_battery,
+#endif
&smdkv210_dm9000,
&smdkv210_lcd_lte480wv,
- &s3c_device_timer[3],
- &smdkv210_backlight_device,
+ &smdkv210_input_device,
+#ifdef CONFIG_REGULATOR
+ &smdkv210_b_pwr_5v,
+#endif
};
+static void __init smdkv210_button_init(void)
+{
+ s3c_gpio_cfgpin(S5PV210_GPH3(7), (0xf << 28));
+ s3c_gpio_setpull(S5PV210_GPH3(7), S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(S5PV210_GPH0(4), (0xf << 16));
+ s3c_gpio_setpull(S5PV210_GPH0(4), S3C_GPIO_PULL_NONE);
+}
+
static void __init smdkv210_dm9000_init(void)
{
unsigned int tmp;
@@ -301,13 +578,51 @@ static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
};
static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {
- /* To Be Updated */
+#if defined(CONFIG_REGULATOR_MAX8698)
+ {
+ I2C_BOARD_INFO("max8698", 0xCC >> 1),
+ .platform_data = &smdkv210_max8698_pdata,
+ },
+#endif
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
+ .cal_x_max = 800,
+ .cal_y_max = 480,
+ .cal_param = {
+ -13357, -85, 53858048, -95, -8493, 32809514, 65536
+ },
+};
+
+static void smdkv210_sound_init(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(S5P_CLK_OUT);
+ reg &= ~S5P_CLKOUT_CLKSEL_MASK;
+ reg &= ~S5P_CLKOUT_DIVVAL_MASK;
+ reg |= S5P_CLKOUT_CLKSEL_XUSBXTI;
+ reg |= 0x1 << S5P_CLKOUT_DIVVAL_SHIFT;
+ __raw_writel(reg, S5P_CLK_OUT);
+
+ reg = __raw_readl(S5P_OTHERS);
+ reg &= ~S5P_OTHERS_CLKOUT_MASK;
+ reg |= S5P_OTHERS_CLKOUT_SYSCON;
+ __raw_writel(reg, S5P_OTHERS);
+}
+
+/* LCD Backlight data */
+static struct samsung_bl_gpio_info smdkv210_bl_gpio_info = {
+ .no = S5PV210_GPD0(3),
+ .func = S3C_GPIO_SFN(2),
+};
+
+static struct platform_pwm_backlight_data smdkv210_bl_data = {
+ .pwm_id = 3,
+ .pwm_period_ns = 1000,
};
static void __init smdkv210_map_io(void)
@@ -316,12 +631,15 @@ static void __init smdkv210_map_io(void)
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+
+ s5p_reserve_mem(S5P_RANGE_MFC);
}
static void __init smdkv210_machine_init(void)
{
s3c_pm_init();
+ smdkv210_button_init();
smdkv210_dm9000_init();
samsung_keypad_set_platdata(&smdkv210_keypad_data);
@@ -341,6 +659,11 @@ static void __init smdkv210_machine_init(void)
s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
+ /* SOUND */
+ smdkv210_sound_init();
+
+ samsung_bl_set(&smdkv210_bl_gpio_info, &smdkv210_bl_data);
+
platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
}
diff --git a/arch/arm/mach-s5pv210/reserve_mem-s5pv210.c b/arch/arm/mach-s5pv210/reserve_mem-s5pv210.c
new file mode 100644
index 0000000..d5a7d0a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/reserve_mem-s5pv210.c
@@ -0,0 +1,113 @@
+/* linux/arch/arm/mach-s5pv210/reserve_mem-s5pv210.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * reserve_mem helper functions for S5PV210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/setup.h>
+#include <linux/io.h>
+#include <mach/memory.h>
+#include <plat/media.h>
+#include <mach/media.h>
+
+struct s5p_media_device media_devs[] = {
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0
+ {
+ .id = S5P_MDEV_MFC,
+ .name = "mfc",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1
+ {
+ .id = S5P_MDEV_MFC,
+ .name = "mfc",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD
+ {
+ .id = S5P_MDEV_FIMD,
+ .name = "fimd",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0
+ {
+ .id = S5P_MDEV_FIMC0,
+ .name = "fimc0",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1
+ {
+ .id = S5P_MDEV_FIMC1,
+ .name = "fimc1",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2
+ {
+ .id = S5P_MDEV_FIMC2,
+ .name = "fimc2",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2 * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D
+ {
+ .id = S5P_MDEV_FIMG2D,
+ .name = "fimg2d",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMG2D * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
+ {
+ .id = S5P_MDEV_JPEG,
+ .name = "jpeg",
+ .bank = 0,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_TEXSTREAM
+ {
+ .id = S5P_MDEV_TEXSTREAM,
+ .name = "texstream",
+ .bank = 1,
+ .memsize = CONFIG_VIDEO_SAMSUNG_MEMSIZE_TEXSTREAM * SZ_1K,
+ .paddr = 0,
+ },
+#endif
+};
+
+int nr_media_devs = (sizeof(media_devs) / sizeof(media_devs[0]));
diff --git a/arch/arm/mach-s5pv210/setup-fb-24bpp.c b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
index e932ebf..55103c8 100644
--- a/arch/arm/mach-s5pv210/setup-fb-24bpp.c
+++ b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
@@ -15,7 +15,6 @@
#include <linux/fb.h>
#include <linux/gpio.h>
-#include <mach/regs-fb.h>
#include <mach/map.h>
#include <plat/fb.h>
#include <mach/regs-clock.h>
diff --git a/arch/arm/mach-s5pv210/setup-keypad.c b/arch/arm/mach-s5pv210/setup-keypad.c
index c56420a..d631917 100644
--- a/arch/arm/mach-s5pv210/setup-keypad.c
+++ b/arch/arm/mach-s5pv210/setup-keypad.c
@@ -17,7 +17,8 @@
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{
/* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
- s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
+ s3c_gpio_cfgall_range(S5PV210_GPH3(0), rows,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 0074b8d..cbab5c5 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -629,6 +629,16 @@ config IO_36
comment "Processor Features"
+config ARM_TRUSTZONE
+ bool "Support TrustZone-enabled Trusted Execution Environment"
+ default n
+ help
+ Select if you want a kernel to be executed at non-secure world.
+ This option should be used with related secure bootloader and
+ TrustZone software.
+
+ If you don't know about TrustZone, say 'N'.
+
config ARM_THUMB
bool "Support Thumb user binaries"
depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index bca7e61..16ce69d 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -2,11 +2,17 @@
# Makefile for the linux arm-specific parts of the memory manager.
#
-obj-y := dma-mapping.o extable.o fault.o init.o \
+obj-y := extable.o fault.o \
iomap.o
+obj-y += dma-mapping.o init.o
+
obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
- mmap.o pgd.o mmu.o vmregion.o
+ mmap.o pgd.o vmregion.o
+
+ifeq ($(CONFIG_MMU),y)
+obj-y += mmu.o
+endif
ifneq ($(CONFIG_MMU),y)
obj-y += nommu.o
@@ -100,3 +106,4 @@ obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o
obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o
+obj-$(CONFIG_CACHE_PERF) += cache_perf.o
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 1fa6f71..0720163 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -242,16 +242,5 @@ ENDPROC(fa_dma_unmap_area)
__INITDATA
- .type fa_cache_fns, #object
-ENTRY(fa_cache_fns)
- .long fa_flush_icache_all
- .long fa_flush_kern_cache_all
- .long fa_flush_user_cache_all
- .long fa_flush_user_cache_range
- .long fa_coherent_kern_range
- .long fa_coherent_user_range
- .long fa_flush_kern_dcache_area
- .long fa_dma_map_area
- .long fa_dma_unmap_area
- .long fa_dma_flush_range
- .size fa_cache_fns, . - fa_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions fa
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 44c0867..68052e6 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -29,6 +29,16 @@ static void __iomem *l2x0_base;
static DEFINE_SPINLOCK(l2x0_lock);
static uint32_t l2x0_way_mask; /* Bitmask of active ways */
static uint32_t l2x0_size;
+static u32 l2x0_cache_id;
+static unsigned int l2x0_sets;
+static unsigned int l2x0_ways;
+
+static inline bool is_pl310_rev(int rev)
+{
+ return (l2x0_cache_id &
+ (L2X0_CACHE_ID_PART_MASK | L2X0_CACHE_ID_REV_MASK)) ==
+ (L2X0_CACHE_ID_PART_L310 | rev);
+}
static inline void cache_wait_way(void __iomem *reg, unsigned long mask)
{
@@ -120,6 +130,23 @@ static void l2x0_cache_sync(void)
spin_unlock_irqrestore(&l2x0_lock, flags);
}
+#ifdef CONFIG_PL310_ERRATA_727915
+static void l2x0_for_each_set_way(void __iomem *reg)
+{
+ int set;
+ int way;
+ unsigned long flags;
+
+ for (way = 0; way < l2x0_ways; way++) {
+ spin_lock_irqsave(&l2x0_lock, flags);
+ for (set = 0; set < l2x0_sets; set++)
+ writel_relaxed((way << 28) | (set << 5), reg);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ }
+}
+#endif
+
static void __l2x0_flush_all(void)
{
debug_writel(0x03);
@@ -133,6 +160,13 @@ static void l2x0_flush_all(void)
{
unsigned long flags;
+#ifdef CONFIG_PL310_ERRATA_727915
+ if (is_pl310_rev(REV_PL310_R2P0)) {
+ l2x0_for_each_set_way(l2x0_base + L2X0_CLEAN_INV_LINE_IDX);
+ return;
+ }
+#endif
+
/* clean all ways */
spin_lock_irqsave(&l2x0_lock, flags);
__l2x0_flush_all();
@@ -143,11 +177,20 @@ static void l2x0_clean_all(void)
{
unsigned long flags;
+#ifdef CONFIG_PL310_ERRATA_727915
+ if (is_pl310_rev(REV_PL310_R2P0)) {
+ l2x0_for_each_set_way(l2x0_base + L2X0_CLEAN_LINE_IDX);
+ return;
+ }
+#endif
+
/* clean all ways */
spin_lock_irqsave(&l2x0_lock, flags);
+ debug_writel(0x03);
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_WAY);
cache_wait_way(l2x0_base + L2X0_CLEAN_WAY, l2x0_way_mask);
cache_sync();
+ debug_writel(0x00);
spin_unlock_irqrestore(&l2x0_lock, flags);
}
@@ -280,47 +323,46 @@ static void l2x0_disable(void)
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
- __u32 cache_id;
__u32 way_size = 0;
- int ways;
const char *type;
l2x0_base = base;
- cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
+ l2x0_cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
aux &= aux_mask;
aux |= aux_val;
/* Determine the number of ways */
- switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+ switch (l2x0_cache_id & L2X0_CACHE_ID_PART_MASK) {
case L2X0_CACHE_ID_PART_L310:
if (aux & (1 << 16))
- ways = 16;
+ l2x0_ways = 16;
else
- ways = 8;
+ l2x0_ways = 8;
type = "L310";
break;
case L2X0_CACHE_ID_PART_L210:
- ways = (aux >> 13) & 0xf;
+ l2x0_ways = (aux >> 13) & 0xf;
type = "L210";
break;
default:
/* Assume unknown chips have 8 ways */
- ways = 8;
+ l2x0_ways = 8;
type = "L2x0 series";
break;
}
- l2x0_way_mask = (1 << ways) - 1;
+ l2x0_way_mask = (1 << l2x0_ways) - 1;
/*
* L2 cache Size = Way size * Number of ways
*/
way_size = (aux & L2X0_AUX_CTRL_WAY_SIZE_MASK) >> 17;
- way_size = 1 << (way_size + 3);
- l2x0_size = ways * way_size * SZ_1K;
+ way_size = SZ_1K << (way_size + 3);
+ l2x0_size = l2x0_ways * way_size;
+ l2x0_sets = way_size / CACHE_LINE_SIZE;
/*
* Check if l2x0 controller is already enabled.
@@ -344,10 +386,11 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.sync = l2x0_cache_sync;
outer_cache.flush_all = l2x0_flush_all;
outer_cache.inv_all = l2x0_inv_all;
+ outer_cache.clean_all = l2x0_clean_all;
outer_cache.disable = l2x0_disable;
outer_cache.set_debug = l2x0_set_debug;
printk(KERN_INFO "%s cache controller enabled\n", type);
printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
- ways, cache_id, aux, l2x0_size);
+ l2x0_ways, l2x0_cache_id, aux, l2x0_size);
}
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
index 2e2bc40..c2301f2 100644
--- a/arch/arm/mm/cache-v3.S
+++ b/arch/arm/mm/cache-v3.S
@@ -129,16 +129,5 @@ ENDPROC(v3_dma_map_area)
__INITDATA
- .type v3_cache_fns, #object
-ENTRY(v3_cache_fns)
- .long v3_flush_icache_all
- .long v3_flush_kern_cache_all
- .long v3_flush_user_cache_all
- .long v3_flush_user_cache_range
- .long v3_coherent_kern_range
- .long v3_coherent_user_range
- .long v3_flush_kern_dcache_area
- .long v3_dma_map_area
- .long v3_dma_unmap_area
- .long v3_dma_flush_range
- .size v3_cache_fns, . - v3_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v3
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index a8fefb5..fd9bb7a 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -141,16 +141,5 @@ ENDPROC(v4_dma_map_area)
__INITDATA
- .type v4_cache_fns, #object
-ENTRY(v4_cache_fns)
- .long v4_flush_icache_all
- .long v4_flush_kern_cache_all
- .long v4_flush_user_cache_all
- .long v4_flush_user_cache_range
- .long v4_coherent_kern_range
- .long v4_coherent_user_range
- .long v4_flush_kern_dcache_area
- .long v4_dma_map_area
- .long v4_dma_unmap_area
- .long v4_dma_flush_range
- .size v4_cache_fns, . - v4_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index f40c696..4f2c141 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -253,16 +253,5 @@ ENDPROC(v4wb_dma_unmap_area)
__INITDATA
- .type v4wb_cache_fns, #object
-ENTRY(v4wb_cache_fns)
- .long v4wb_flush_icache_all
- .long v4wb_flush_kern_cache_all
- .long v4wb_flush_user_cache_all
- .long v4wb_flush_user_cache_range
- .long v4wb_coherent_kern_range
- .long v4wb_coherent_user_range
- .long v4wb_flush_kern_dcache_area
- .long v4wb_dma_map_area
- .long v4wb_dma_unmap_area
- .long v4wb_dma_flush_range
- .size v4wb_cache_fns, . - v4wb_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4wb
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index a7b276d..4d7b467 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -197,16 +197,5 @@ ENDPROC(v4wt_dma_map_area)
__INITDATA
- .type v4wt_cache_fns, #object
-ENTRY(v4wt_cache_fns)
- .long v4wt_flush_icache_all
- .long v4wt_flush_kern_cache_all
- .long v4wt_flush_user_cache_all
- .long v4wt_flush_user_cache_range
- .long v4wt_coherent_kern_range
- .long v4wt_coherent_user_range
- .long v4wt_flush_kern_dcache_area
- .long v4wt_dma_map_area
- .long v4wt_dma_unmap_area
- .long v4wt_dma_flush_range
- .size v4wt_cache_fns, . - v4wt_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v4wt
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 73b4a8b..2edb6f6 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -272,6 +272,11 @@ v6_dma_clean_range:
* - end - virtual end address of region
*/
ENTRY(v6_dma_flush_range)
+#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT
+ sub r2, r1, r0
+ cmp r2, #CONFIG_CACHE_FLUSH_RANGE_LIMIT
+ bhi v6_dma_flush_dcache_all
+#endif
#ifdef CONFIG_DMA_CACHE_RWFO
ldrb r2, [r0] @ read for ownership
strb r2, [r0] @ write for ownership
@@ -294,6 +299,18 @@ ENTRY(v6_dma_flush_range)
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
mov pc, lr
+#ifdef CONFIG_CACHE_FLUSH_RANGE_LIMIT
+v6_dma_flush_dcache_all:
+ mov r0, #0
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate
+#else
+ mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+#endif
+
/*
* dma_map_area(start, size, dir)
* - start - kernel virtual start address
@@ -330,16 +347,5 @@ ENDPROC(v6_dma_unmap_area)
__INITDATA
- .type v6_cache_fns, #object
-ENTRY(v6_cache_fns)
- .long v6_flush_icache_all
- .long v6_flush_kern_cache_all
- .long v6_flush_user_cache_all
- .long v6_flush_user_cache_range
- .long v6_coherent_kern_range
- .long v6_coherent_user_range
- .long v6_flush_kern_dcache_area
- .long v6_dma_map_area
- .long v6_dma_unmap_area
- .long v6_dma_flush_range
- .size v6_cache_fns, . - v6_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v6
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 3593119..07c4bc8 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -345,16 +345,5 @@ ENDPROC(v7_dma_unmap_area)
__INITDATA
- .type v7_cache_fns, #object
-ENTRY(v7_cache_fns)
- .long v7_flush_icache_all
- .long v7_flush_kern_cache_all
- .long v7_flush_user_cache_all
- .long v7_flush_user_cache_range
- .long v7_coherent_kern_range
- .long v7_coherent_user_range
- .long v7_flush_kern_dcache_area
- .long v7_dma_map_area
- .long v7_dma_unmap_area
- .long v7_dma_flush_range
- .size v7_cache_fns, . - v7_cache_fns
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions v7
diff --git a/arch/arm/mm/cache_perf.c b/arch/arm/mm/cache_perf.c
new file mode 100644
index 0000000..a29bcb1
--- /dev/null
+++ b/arch/arm/mm/cache_perf.c
@@ -0,0 +1,348 @@
+/* linux/arch/arm/mm/cache-perf.c
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/types.h>
+#include <linux/math64.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include <asm/outercache.h>
+#include <asm/cacheflush.h>
+#include <linux/string.h>
+
+enum memtype {
+ MT_WBWA = 1,
+ MT_NC,
+ MT_SO,
+ MT_MAX,
+};
+
+static unsigned int try_cnt = 100;
+module_param(try_cnt, uint, S_IRUGO);
+MODULE_PARM_DESC(try_cnt, "Try count to test");
+
+static bool l1 = 1;
+module_param(l1, bool, S_IRUGO);
+MODULE_PARM_DESC(l1, "Set for L1 check");
+
+static bool l2 = 1;
+module_param(l2, bool, S_IRUGO);
+MODULE_PARM_DESC(l2, "Set for L2 check");
+
+static unsigned int mcpy = MT_WBWA;
+module_param(mcpy, uint, S_IRUGO);
+MODULE_PARM_DESC(mcpy, "Set for mcpy");
+
+static bool cm = 1;
+module_param(cm, bool, S_IRUGO);
+MODULE_PARM_DESC(cm, "Set for cache maintenance");
+
+static unsigned int mcpy_size = SZ_4M;
+module_param(mcpy_size, uint, S_IRUGO);
+MODULE_PARM_DESC(mcpy_size, "Set for mcpy size");
+
+struct task_struct *cacheperf_task;
+static bool thread_running;
+
+#define START_SIZE (64)
+#define END_SIZE (SZ_4M)
+#define OUT_TRY_CNT 100
+#define SCRAMBLE_SIZE (128+64+32+16+8+4+2+1)
+#define SMALL_SIZE (7)
+
+enum cachemaintenance {
+ CM_CLEAN,
+ CM_INV,
+ CM_FLUSH,
+ CM_FLUSHALL,
+};
+
+static long update_timeval(struct timespec lhs, struct timespec rhs)
+{
+ long val;
+ struct timespec ts;
+
+ ts = timespec_sub(rhs, lhs);
+ val = ts.tv_sec*NSEC_PER_SEC + ts.tv_nsec;
+
+ return val;
+}
+
+bool buf_compare(u8 src[], u8 dst[], unsigned int bytes)
+{
+ unsigned int i;
+
+ for (i = 0; i < bytes; i++) {
+ if (src[i] != dst[i]) {
+ printk(KERN_ERR "Failed to compare: %d, %x:%x-%x:%x\n",
+ i, (u32)src, src[i], (u32)dst, dst[i]);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void *remap_vm(dma_addr_t phys, u32 size, pgprot_t pgprot)
+{
+ unsigned long num_pages, i;
+ struct page **pages;
+ void *virt;
+
+ num_pages = size >> PAGE_SHIFT;
+ pages = kmalloc(num_pages * sizeof(struct page *), GFP_KERNEL);
+
+ if (!pages)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < num_pages; i++)
+ pages[i] = pfn_to_page((phys >> PAGE_SHIFT) + i);
+
+ virt = vmap(pages, num_pages, VM_MAP, pgprot);
+
+ if (!virt) {
+ kfree(pages);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ kfree(pages);
+
+ return virt;
+}
+
+static void memcpyperf(void *src, void *dst, u32 size, u32 cnt)
+{
+ struct timespec beforets;
+ struct timespec afterts;
+ long val[OUT_TRY_CNT];
+ long sum = 0;
+ u32 i, j;
+
+ memset(src, 0xab, size);
+ memset(dst, 0x00, size);
+
+ for (j = 0; j < OUT_TRY_CNT; j++) {
+ getnstimeofday(&beforets);
+ for (i = 0; i < cnt; i++)
+ memcpy(dst, src, size);
+ getnstimeofday(&afterts);
+ mdelay(100);
+ val[j] = update_timeval(beforets, afterts)/cnt;
+ }
+
+ for (j = 0; j < OUT_TRY_CNT; j++)
+ sum += val[j];
+
+ printk(KERN_ERR "%lu\n", sum/OUT_TRY_CNT);
+
+ if (buf_compare(src, dst, size))
+ printk(KERN_ERR "copy err\n");
+}
+
+static void cacheperf(void *vbuf, enum cachemaintenance id)
+{
+ struct timespec beforets;
+ struct timespec afterts;
+ phys_addr_t pbuf = virt_to_phys(vbuf);
+ u32 pbufend, xfer_size, i;
+ long timeval;
+
+ xfer_size = START_SIZE;
+ while (xfer_size <= END_SIZE) {
+ pbufend = pbuf + xfer_size;
+ timeval = 0;
+
+ for (i = 0; i < try_cnt; i++) {
+ memset(vbuf, i, xfer_size);
+ getnstimeofday(&beforets);
+
+ switch (id) {
+ case CM_CLEAN:
+ if (l1)
+ dmac_map_area(vbuf, xfer_size,
+ DMA_TO_DEVICE);
+ if (l2)
+ outer_clean_range(pbuf, pbufend);
+ break;
+ case CM_INV:
+ if (l2)
+ outer_inv_range(pbuf, pbufend);
+ if (l1)
+ dmac_unmap_area(vbuf, xfer_size,
+ DMA_FROM_DEVICE);
+ break;
+ case CM_FLUSH:
+ if (l1)
+ dmac_flush_range(vbuf,
+ (void *)((u32) vbuf + xfer_size));
+ if (l2)
+ outer_flush_range(pbuf, pbufend);
+ break;
+ case CM_FLUSHALL:
+ if (l1)
+ flush_cache_all();
+ if (l2)
+ outer_flush_all();
+ break;
+ }
+ getnstimeofday(&afterts);
+ timeval += update_timeval(beforets, afterts);
+ }
+ printk(KERN_INFO "%lu\n", timeval/try_cnt);
+ xfer_size *= 2;
+ }
+}
+
+static int perfmain(void)
+{
+ phys_addr_t dmasrc, dmadst;
+ void *srcbuf[MT_MAX];
+ void *dstbuf[MT_MAX];
+ u32 xfer_size;
+
+ srcbuf[MT_WBWA] = kmalloc(END_SIZE, GFP_KERNEL);
+ dstbuf[MT_WBWA] = kmalloc(END_SIZE, GFP_KERNEL);
+ srcbuf[MT_NC] = dma_alloc_writecombine(
+ NULL, mcpy_size, &dmasrc, GFP_KERNEL);
+ dstbuf[MT_NC] = dma_alloc_writecombine(
+ NULL, mcpy_size, &dmadst, GFP_KERNEL);
+ if (!srcbuf[MT_WBWA] && !srcbuf[MT_NC] &&
+ !dstbuf[MT_WBWA] && !dstbuf[MT_NC]) {
+ printk(KERN_ERR "Memory allocation error!\n");
+ dma_free_coherent(NULL, mcpy_size, srcbuf[MT_NC], dmasrc);
+ dma_free_coherent(NULL, mcpy_size, dstbuf[MT_NC], dmadst);
+ kfree(srcbuf[MT_WBWA]);
+ kfree(dstbuf[MT_WBWA]);
+ return 0;
+ }
+
+ if (mcpy) {
+ printk(KERN_INFO "## Memcpy perf (ns, unit tr size: %dKB)\n",
+ mcpy_size/SZ_1K);
+
+ if (mcpy >= MT_SO) {
+ printk(KERN_INFO "1. SO type\n");
+ srcbuf[MT_SO] = remap_vm(dmasrc, mcpy_size,
+ pgprot_noncached(PAGE_KERNEL));
+ dstbuf[MT_SO] = remap_vm(dmadst, mcpy_size,
+ pgprot_noncached(PAGE_KERNEL));
+ xfer_size = START_SIZE;
+ while (xfer_size <= END_SIZE) {
+ memcpyperf(srcbuf[MT_SO], dstbuf[MT_SO],
+ xfer_size, 10);
+ xfer_size *= 2;
+ }
+ vunmap(srcbuf[MT_SO]);
+ vunmap(dstbuf[MT_SO]);
+ }
+
+ if (mcpy >= MT_NC) {
+ printk(KERN_INFO "2. Normal NCNB type\n");
+ xfer_size = START_SIZE;
+ while (xfer_size <= END_SIZE) {
+ memcpyperf(srcbuf[MT_NC], dstbuf[MT_NC],
+ xfer_size, 10);
+ xfer_size *= 2;
+ }
+ }
+
+ printk(KERN_INFO "3. Cache memcpy\n");
+ printk(KERN_INFO "scramble size:");
+ memcpyperf(srcbuf[MT_WBWA], dstbuf[MT_WBWA],
+ SCRAMBLE_SIZE, try_cnt);
+ memset(dstbuf[MT_WBWA], 0x0, SCRAMBLE_SIZE);
+
+ printk(KERN_INFO "small size:");
+ memcpyperf(srcbuf[MT_WBWA], dstbuf[MT_WBWA],
+ SMALL_SIZE, try_cnt);
+ memset(dstbuf[MT_WBWA], 0x0, SMALL_SIZE);
+
+ printk(KERN_INFO "size (%d ~ %d)\n ", START_SIZE, END_SIZE);
+ xfer_size = START_SIZE;
+ while (xfer_size <= END_SIZE) {
+ memcpyperf(srcbuf[MT_WBWA], dstbuf[MT_WBWA],
+ xfer_size, try_cnt);
+ xfer_size *= 2;
+ }
+ }
+
+ if (cm) {
+ printk(KERN_INFO "## Memcpy perf (ns)\n");
+
+ printk(KERN_INFO "1. Clean perf\n");
+ cacheperf(srcbuf[MT_WBWA], CM_CLEAN);
+
+ printk(KERN_INFO "2. Invalidate perf\n");
+ cacheperf(srcbuf[MT_WBWA], CM_INV);
+
+ printk(KERN_INFO "3. Flush perf\n");
+ cacheperf(srcbuf[MT_WBWA], CM_FLUSH);
+
+ printk(KERN_INFO "4. Flush all perf\n");
+ cacheperf(srcbuf[MT_WBWA], CM_FLUSHALL);
+ }
+
+ dma_free_coherent(NULL, mcpy_size, srcbuf[MT_NC], dmasrc);
+ dma_free_coherent(NULL, mcpy_size, dstbuf[MT_NC], dmadst);
+ kfree(srcbuf[MT_WBWA]);
+ kfree(dstbuf[MT_WBWA]);
+
+ return 0;
+}
+
+static int thread_func(void *data)
+{
+ thread_running = 1;
+ perfmain();
+ thread_running = 0;
+
+ return 0;
+}
+
+int __init cacheperf_init(void)
+{
+#ifndef CONFIG_OUTER_CACHE
+ l2 = 0;
+#endif
+
+ printk(KERN_ERR "Test condition: l1: %d, l2: %d, try_cnt:%d, (%dB ~ %dMB)\n",
+ l1, l2, try_cnt, START_SIZE, END_SIZE/SZ_1M);
+
+ cacheperf_task = kzalloc(sizeof(struct task_struct), GFP_KERNEL);
+ cacheperf_task = kthread_run(thread_func, NULL, "cacheperf_thread");
+ if (IS_ERR(cacheperf_task))
+ printk(KERN_INFO "Failed to create module\n");
+
+ return 0;
+}
+module_init(cacheperf_init)
+
+void cacheperf_exit(void)
+{
+ printk(KERN_ERR "Exit module: thread_running: %d\n", thread_running);
+
+ if (thread_running)
+ kthread_stop(cacheperf_task);
+
+ kfree(cacheperf_task);
+}
+module_exit(cacheperf_exit);
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index ab50627..42f099e 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -22,6 +22,7 @@
*/
#include <linux/module.h>
#include <linux/errno.h>
+#include <linux/memblock.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
@@ -204,7 +205,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
/*
* Don't allow RAM to be mapped - this causes problems with ARMv6+
*/
- if (WARN_ON(pfn_valid(pfn)))
+ if (WARN_ON(memblock_is_memory(pfn << PAGE_SHIFT)))
return NULL;
type = get_mem_type(mtype);
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 6c4e7fd..6746966 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -364,17 +364,8 @@ ENTRY(arm1020_dma_unmap_area)
mov pc, lr
ENDPROC(arm1020_dma_unmap_area)
-ENTRY(arm1020_cache_fns)
- .long arm1020_flush_icache_all
- .long arm1020_flush_kern_cache_all
- .long arm1020_flush_user_cache_all
- .long arm1020_flush_user_cache_range
- .long arm1020_coherent_kern_range
- .long arm1020_coherent_user_range
- .long arm1020_flush_kern_dcache_area
- .long arm1020_dma_map_area
- .long arm1020_dma_unmap_area
- .long arm1020_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1020
.align 5
ENTRY(cpu_arm1020_dcache_clean_area)
@@ -477,38 +468,14 @@ arm1020_crval:
crval clear=0x0000593f, mmuset=0x00003935, ucset=0x00001930
__INITDATA
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1020, dabort=v4t_early_abort, pabort=legacy_pabort
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1020_processor_functions, #object
-arm1020_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm1020_proc_init
- .word cpu_arm1020_proc_fin
- .word cpu_arm1020_reset
- .word cpu_arm1020_do_idle
- .word cpu_arm1020_dcache_clean_area
- .word cpu_arm1020_switch_mm
- .word cpu_arm1020_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv5t"
+ string cpu_elf_name, "v5"
.type cpu_arm1020_name, #object
cpu_arm1020_name:
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 4ce947c..4251421 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -350,17 +350,8 @@ ENTRY(arm1020e_dma_unmap_area)
mov pc, lr
ENDPROC(arm1020e_dma_unmap_area)
-ENTRY(arm1020e_cache_fns)
- .long arm1020e_flush_icache_all
- .long arm1020e_flush_kern_cache_all
- .long arm1020e_flush_user_cache_all
- .long arm1020e_flush_user_cache_range
- .long arm1020e_coherent_kern_range
- .long arm1020e_coherent_user_range
- .long arm1020e_flush_kern_dcache_area
- .long arm1020e_dma_map_area
- .long arm1020e_dma_unmap_area
- .long arm1020e_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1020e
.align 5
ENTRY(cpu_arm1020e_dcache_clean_area)
@@ -458,43 +449,14 @@ arm1020e_crval:
crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1020e_processor_functions, #object
-arm1020e_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm1020e_proc_init
- .word cpu_arm1020e_proc_fin
- .word cpu_arm1020e_reset
- .word cpu_arm1020e_do_idle
- .word cpu_arm1020e_dcache_clean_area
- .word cpu_arm1020e_switch_mm
- .word cpu_arm1020e_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1020e_processor_functions, . - arm1020e_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1020e, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm1020e_name, #object
-cpu_arm1020e_name:
- .asciz "ARM1020E"
- .size cpu_arm1020e_name, . - cpu_arm1020e_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_arm1020e_name, "ARM1020E"
.align
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index c8884c5..d283cf3 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -339,17 +339,8 @@ ENTRY(arm1022_dma_unmap_area)
mov pc, lr
ENDPROC(arm1022_dma_unmap_area)
-ENTRY(arm1022_cache_fns)
- .long arm1022_flush_icache_all
- .long arm1022_flush_kern_cache_all
- .long arm1022_flush_user_cache_all
- .long arm1022_flush_user_cache_range
- .long arm1022_coherent_kern_range
- .long arm1022_coherent_user_range
- .long arm1022_flush_kern_dcache_area
- .long arm1022_dma_map_area
- .long arm1022_dma_unmap_area
- .long arm1022_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1022
.align 5
ENTRY(cpu_arm1022_dcache_clean_area)
@@ -441,43 +432,14 @@ arm1022_crval:
crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1022_processor_functions, #object
-arm1022_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm1022_proc_init
- .word cpu_arm1022_proc_fin
- .word cpu_arm1022_reset
- .word cpu_arm1022_do_idle
- .word cpu_arm1022_dcache_clean_area
- .word cpu_arm1022_switch_mm
- .word cpu_arm1022_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1022_processor_functions, . - arm1022_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1022, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm1022_name, #object
-cpu_arm1022_name:
- .asciz "ARM1022"
- .size cpu_arm1022_name, . - cpu_arm1022_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_arm1022_name, "ARM1022"
.align
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 4136846..678a1ce 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -333,17 +333,8 @@ ENTRY(arm1026_dma_unmap_area)
mov pc, lr
ENDPROC(arm1026_dma_unmap_area)
-ENTRY(arm1026_cache_fns)
- .long arm1026_flush_icache_all
- .long arm1026_flush_kern_cache_all
- .long arm1026_flush_user_cache_all
- .long arm1026_flush_user_cache_range
- .long arm1026_coherent_kern_range
- .long arm1026_coherent_user_range
- .long arm1026_flush_kern_dcache_area
- .long arm1026_dma_map_area
- .long arm1026_dma_unmap_area
- .long arm1026_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm1026
.align 5
ENTRY(cpu_arm1026_dcache_clean_area)
@@ -436,45 +427,15 @@ arm1026_crval:
crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001934
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm1026_processor_functions, #object
-arm1026_processor_functions:
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_arm1026_proc_init
- .word cpu_arm1026_proc_fin
- .word cpu_arm1026_reset
- .word cpu_arm1026_do_idle
- .word cpu_arm1026_dcache_clean_area
- .word cpu_arm1026_switch_mm
- .word cpu_arm1026_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm1026_processor_functions, . - arm1026_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm1026, dabort=v5t_early_abort, pabort=legacy_pabort
.section .rodata
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5tej"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv5tej"
+ string cpu_elf_name, "v5"
.align
-
- .type cpu_arm1026_name, #object
-cpu_arm1026_name:
- .asciz "ARM1026EJ-S"
- .size cpu_arm1026_name, . - cpu_arm1026_name
-
+ string cpu_arm1026_name, "ARM1026EJ-S"
.align
.section ".proc.info.init", #alloc, #execinstr
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 5f79dc4..ebc0ca7 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -269,159 +269,57 @@ __arm7_setup: mov r0, #0
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm6_processor_functions, #object
-ENTRY(arm6_processor_functions)
- .word cpu_arm6_data_abort
- .word legacy_pabort
- .word cpu_arm6_proc_init
- .word cpu_arm6_proc_fin
- .word cpu_arm6_reset
- .word cpu_arm6_do_idle
- .word cpu_arm6_dcache_clean_area
- .word cpu_arm6_switch_mm
- .word cpu_arm6_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm6_processor_functions, . - arm6_processor_functions
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm7_processor_functions, #object
-ENTRY(arm7_processor_functions)
- .word cpu_arm7_data_abort
- .word legacy_pabort
- .word cpu_arm7_proc_init
- .word cpu_arm7_proc_fin
- .word cpu_arm7_reset
- .word cpu_arm7_do_idle
- .word cpu_arm7_dcache_clean_area
- .word cpu_arm7_switch_mm
- .word cpu_arm7_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm7_processor_functions, . - arm7_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm6, dabort=cpu_arm6_data_abort, pabort=legacy_pabort
+ define_processor_functions arm7, dabort=cpu_arm7_data_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name: .asciz "armv3"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name: .asciz "v3"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm6_name, #object
-cpu_arm6_name: .asciz "ARM6"
- .size cpu_arm6_name, . - cpu_arm6_name
-
- .type cpu_arm610_name, #object
-cpu_arm610_name:
- .asciz "ARM610"
- .size cpu_arm610_name, . - cpu_arm610_name
-
- .type cpu_arm7_name, #object
-cpu_arm7_name: .asciz "ARM7"
- .size cpu_arm7_name, . - cpu_arm7_name
-
- .type cpu_arm710_name, #object
-cpu_arm710_name:
- .asciz "ARM710"
- .size cpu_arm710_name, . - cpu_arm710_name
+ string cpu_arch_name, "armv3"
+ string cpu_elf_name, "v3"
+ string cpu_arm6_name, "ARM6"
+ string cpu_arm610_name, "ARM610"
+ string cpu_arm7_name, "ARM7"
+ string cpu_arm710_name, "ARM710"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm6_proc_info, #object
-__arm6_proc_info:
- .long 0x41560600
- .long 0xfffffff0
- .long 0x00000c1e
+.macro arm67_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
+ cpu_mm_mmu_flags:req, cpu_flush:req, cpu_proc_funcs:req
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long \cpu_mm_mmu_flags
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __arm6_setup
+ b \cpu_flush
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm6_name
- .long arm6_processor_functions
+ .long \cpu_name
+ .long \cpu_proc_funcs
.long v3_tlb_fns
.long v3_user_fns
.long v3_cache_fns
- .size __arm6_proc_info, . - __arm6_proc_info
-
- .type __arm610_proc_info, #object
-__arm610_proc_info:
- .long 0x41560610
- .long 0xfffffff0
- .long 0x00000c1e
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm6_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm610_name
- .long arm6_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm610_proc_info, . - __arm610_proc_info
-
- .type __arm7_proc_info, #object
-__arm7_proc_info:
- .long 0x41007000
- .long 0xffffff00
- .long 0x00000c1e
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm7_name
- .long arm7_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm7_proc_info, . - __arm7_proc_info
-
- .type __arm710_proc_info, #object
-__arm710_proc_info:
- .long 0x41007100
- .long 0xfff8ff00
- .long PMD_TYPE_SECT | \
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm67_proc_info arm6, 0x41560600, 0xfffffff0, cpu_arm6_name, \
+ 0x00000c1e, __arm6_setup, arm6_processor_functions
+ arm67_proc_info arm610, 0x41560610, 0xfffffff0, cpu_arm610_name, \
+ 0x00000c1e, __arm6_setup, arm6_processor_functions
+ arm67_proc_info arm7, 0x41007000, 0xffffff00, cpu_arm7_name, \
+ 0x00000c1e, __arm7_setup, arm7_processor_functions
+ arm67_proc_info arm710, 0x41007100, 0xfff8ff00, cpu_arm710_name, \
+ PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm710_name
- .long arm7_processor_functions
- .long v3_tlb_fns
- .long v3_user_fns
- .long v3_cache_fns
- .size __arm710_proc_info, . - __arm710_proc_info
+ PMD_SECT_AP_READ, \
+ __arm7_setup, arm7_processor_functions
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 7a06e59..55f4e29 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -169,46 +169,15 @@ arm720_crval:
crval clear=0x00002f3f, mmuset=0x0000213d, ucset=0x00000130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm720_processor_functions, #object
-ENTRY(arm720_processor_functions)
- .word v4t_late_abort
- .word legacy_pabort
- .word cpu_arm720_proc_init
- .word cpu_arm720_proc_fin
- .word cpu_arm720_reset
- .word cpu_arm720_do_idle
- .word cpu_arm720_dcache_clean_area
- .word cpu_arm720_switch_mm
- .word cpu_arm720_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm720_processor_functions, . - arm720_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm720, dabort=v4t_late_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name: .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name: .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm710_name, #object
-cpu_arm710_name:
- .asciz "ARM710T"
- .size cpu_arm710_name, . - cpu_arm710_name
-
- .type cpu_arm720_name, #object
-cpu_arm720_name:
- .asciz "ARM720T"
- .size cpu_arm720_name, . - cpu_arm720_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm710_name, "ARM710T"
+ string cpu_arm720_name, "ARM720T"
.align
@@ -218,10 +187,11 @@ cpu_arm720_name:
.section ".proc.info.init", #alloc, #execinstr
- .type __arm710_proc_info, #object
-__arm710_proc_info:
- .long 0x41807100 @ cpu_val
- .long 0xffffff00 @ cpu_mask
+.macro arm720_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cpu_flush:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -232,38 +202,17 @@ __arm710_proc_info:
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- b __arm710_setup @ cpu_flush
+ b \cpu_flush @ cpu_flush
.long cpu_arch_name @ arch_name
.long cpu_elf_name @ elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap
- .long cpu_arm710_name @ name
+ .long \cpu_name
.long arm720_processor_functions
.long v4_tlb_fns
.long v4wt_user_fns
.long v4_cache_fns
- .size __arm710_proc_info, . - __arm710_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __arm720_proc_info, #object
-__arm720_proc_info:
- .long 0x41807200 @ cpu_val
- .long 0xffffff00 @ cpu_mask
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm720_setup @ cpu_flush
- .long cpu_arch_name @ arch_name
- .long cpu_elf_name @ elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap
- .long cpu_arm720_name @ name
- .long arm720_processor_functions
- .long v4_tlb_fns
- .long v4wt_user_fns
- .long v4_cache_fns
- .size __arm720_proc_info, . - __arm720_proc_info
+ arm720_proc_info arm710, 0x41807100, 0xffffff00, cpu_arm710_name, __arm710_setup
+ arm720_proc_info arm720, 0x41807200, 0xffffff00, cpu_arm720_name, __arm720_setup
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 6f9d12e..4506be3 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <asm/ptrace.h>
+#include "proc-macros.S"
+
.text
/*
* cpu_arm740_proc_init()
@@ -115,42 +117,14 @@ __arm740_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm740_processor_functions, #object
-ENTRY(arm740_processor_functions)
- .word v4t_late_abort
- .word legacy_pabort
- .word cpu_arm740_proc_init
- .word cpu_arm740_proc_fin
- .word cpu_arm740_reset
- .word cpu_arm740_do_idle
- .word cpu_arm740_dcache_clean_area
- .word cpu_arm740_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm740_processor_functions, . - arm740_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm740, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm740_name, #object
-cpu_arm740_name:
- .ascii "ARM740T"
- .size cpu_arm740_name, . - cpu_arm740_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_arm740_name, "ARM740T"
.align
@@ -170,5 +144,3 @@ __arm740_proc_info:
.long 0
.long v3_cache_fns @ cache model
.size __arm740_proc_info, . - __arm740_proc_info
-
-
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 537ffcb..7e0e1fe 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <asm/ptrace.h>
+#include "proc-macros.S"
+
.text
/*
* cpu_arm7tdmi_proc_init()
@@ -55,197 +57,57 @@ __arm7tdmi_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm7tdmi_processor_functions, #object
-ENTRY(arm7tdmi_processor_functions)
- .word v4t_late_abort
- .word legacy_pabort
- .word cpu_arm7tdmi_proc_init
- .word cpu_arm7tdmi_proc_fin
- .word cpu_arm7tdmi_reset
- .word cpu_arm7tdmi_do_idle
- .word cpu_arm7tdmi_dcache_clean_area
- .word cpu_arm7tdmi_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm7tdmi, dabort=v4t_late_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm7tdmi_name, #object
-cpu_arm7tdmi_name:
- .asciz "ARM7TDMI"
- .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name
-
- .type cpu_triscenda7_name, #object
-cpu_triscenda7_name:
- .asciz "Triscend-A7x"
- .size cpu_triscenda7_name, . - cpu_triscenda7_name
-
- .type cpu_at91_name, #object
-cpu_at91_name:
- .asciz "Atmel-AT91M40xxx"
- .size cpu_at91_name, . - cpu_at91_name
-
- .type cpu_s3c3410_name, #object
-cpu_s3c3410_name:
- .asciz "Samsung-S3C3410"
- .size cpu_s3c3410_name, . - cpu_s3c3410_name
-
- .type cpu_s3c44b0x_name, #object
-cpu_s3c44b0x_name:
- .asciz "Samsung-S3C44B0x"
- .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name
-
- .type cpu_s3c4510b, #object
-cpu_s3c4510b_name:
- .asciz "Samsung-S3C4510B"
- .size cpu_s3c4510b_name, . - cpu_s3c4510b_name
-
- .type cpu_s3c4530_name, #object
-cpu_s3c4530_name:
- .asciz "Samsung-S3C4530"
- .size cpu_s3c4530_name, . - cpu_s3c4530_name
-
- .type cpu_netarm_name, #object
-cpu_netarm_name:
- .asciz "NETARM"
- .size cpu_netarm_name, . - cpu_netarm_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm7tdmi_name, "ARM7TDMI"
+ string cpu_triscenda7_name, "Triscend-A7x"
+ string cpu_at91_name, "Atmel-AT91M40xxx"
+ string cpu_s3c3410_name, "Samsung-S3C3410"
+ string cpu_s3c44b0x_name, "Samsung-S3C44B0x"
+ string cpu_s3c4510b_name, "Samsung-S3C4510B"
+ string cpu_s3c4530_name, "Samsung-S3C4530"
+ string cpu_netarm_name, "NETARM"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm7tdmi_proc_info, #object
-__arm7tdmi_proc_info:
- .long 0x41007700
- .long 0xfff8ff00
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_26BIT
- .long cpu_arm7tdmi_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __arm7tdmi_proc_info, . - __arm7tdmi_proc_info
-
- .type __triscenda7_proc_info, #object
-__triscenda7_proc_info:
- .long 0x0001d2ff
- .long 0x0001ffff
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_triscenda7_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __triscenda7_proc_info, . - __triscenda7_proc_info
-
- .type __at91_proc_info, #object
-__at91_proc_info:
- .long 0x14000040
- .long 0xfff000e0
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_at91_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __at91_proc_info, . - __at91_proc_info
-
- .type __s3c4510b_proc_info, #object
-__s3c4510b_proc_info:
- .long 0x36365000
- .long 0xfffff000
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c4510b_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __s3c4510b_proc_info, . - __s3c4510b_proc_info
-
- .type __s3c4530_proc_info, #object
-__s3c4530_proc_info:
- .long 0x4c000000
- .long 0xfff000e0
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c4530_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __s3c4530_proc_info, . - __s3c4530_proc_info
-
- .type __s3c3410_proc_info, #object
-__s3c3410_proc_info:
- .long 0x34100000
- .long 0xffff0000
- .long 0
- .long 0
- b __arm7tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c3410_name
- .long arm7tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __s3c3410_proc_info, . - __s3c3410_proc_info
-
- .type __s3c44b0x_proc_info, #object
-__s3c44b0x_proc_info:
- .long 0x44b00000
- .long 0xffff0000
+.macro arm7tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \
+ extra_hwcaps=0
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long 0
.long 0
b __arm7tdmi_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_s3c44b0x_name
+ .long HWCAP_SWP | HWCAP_26BIT | ( \extra_hwcaps )
+ .long \cpu_name
.long arm7tdmi_processor_functions
.long 0
.long 0
.long v4_cache_fns
- .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ arm7tdmi_proc_info arm7tdmi, 0x41007700, 0xfff8ff00, \
+ cpu_arm7tdmi_name
+ arm7tdmi_proc_info triscenda7, 0x0001d2ff, 0x0001ffff, \
+ cpu_triscenda7_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info at91, 0x14000040, 0xfff000e0, \
+ cpu_at91_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c4510b, 0x36365000, 0xfffff000, \
+ cpu_s3c4510b_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c4530, 0x4c000000, 0xfff000e0, \
+ cpu_s3c4530_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c3410, 0x34100000, 0xffff0000, \
+ cpu_s3c3410_name, extra_hwcaps=HWCAP_THUMB
+ arm7tdmi_proc_info s3c44b0x, 0x44b00000, 0xffff0000, \
+ cpu_s3c44b0x_name, extra_hwcaps=HWCAP_THUMB
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index bf8a1d1..0dea376 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -315,18 +315,8 @@ ENTRY(arm920_dma_unmap_area)
mov pc, lr
ENDPROC(arm920_dma_unmap_area)
-ENTRY(arm920_cache_fns)
- .long arm920_flush_icache_all
- .long arm920_flush_kern_cache_all
- .long arm920_flush_user_cache_all
- .long arm920_flush_user_cache_range
- .long arm920_coherent_kern_range
- .long arm920_coherent_user_range
- .long arm920_flush_kern_dcache_area
- .long arm920_dma_map_area
- .long arm920_dma_unmap_area
- .long arm920_dma_flush_range
-
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm920
#endif
@@ -450,43 +440,14 @@ arm920_crval:
crval clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm920_processor_functions, #object
-arm920_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm920_proc_init
- .word cpu_arm920_proc_fin
- .word cpu_arm920_reset
- .word cpu_arm920_do_idle
- .word cpu_arm920_dcache_clean_area
- .word cpu_arm920_switch_mm
- .word cpu_arm920_set_pte_ext
- .word cpu_arm920_suspend_size
- .word cpu_arm920_do_suspend
- .word cpu_arm920_do_resume
- .size arm920_processor_functions, . - arm920_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm920, dabort=v4t_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm920_name, #object
-cpu_arm920_name:
- .asciz "ARM920T"
- .size cpu_arm920_name, . - cpu_arm920_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm920_name, "ARM920T"
.align
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 95ba1fc..490e188 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -317,18 +317,8 @@ ENTRY(arm922_dma_unmap_area)
mov pc, lr
ENDPROC(arm922_dma_unmap_area)
-ENTRY(arm922_cache_fns)
- .long arm922_flush_icache_all
- .long arm922_flush_kern_cache_all
- .long arm922_flush_user_cache_all
- .long arm922_flush_user_cache_range
- .long arm922_coherent_kern_range
- .long arm922_coherent_user_range
- .long arm922_flush_kern_dcache_area
- .long arm922_dma_map_area
- .long arm922_dma_unmap_area
- .long arm922_dma_flush_range
-
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm922
#endif
@@ -420,43 +410,14 @@ arm922_crval:
crval clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm922_processor_functions, #object
-arm922_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm922_proc_init
- .word cpu_arm922_proc_fin
- .word cpu_arm922_reset
- .word cpu_arm922_do_idle
- .word cpu_arm922_dcache_clean_area
- .word cpu_arm922_switch_mm
- .word cpu_arm922_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm922_processor_functions, . - arm922_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm922, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm922_name, #object
-cpu_arm922_name:
- .asciz "ARM922T"
- .size cpu_arm922_name, . - cpu_arm922_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm922_name, "ARM922T"
.align
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 541e477..51d494b 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -372,17 +372,8 @@ ENTRY(arm925_dma_unmap_area)
mov pc, lr
ENDPROC(arm925_dma_unmap_area)
-ENTRY(arm925_cache_fns)
- .long arm925_flush_icache_all
- .long arm925_flush_kern_cache_all
- .long arm925_flush_user_cache_all
- .long arm925_flush_user_cache_range
- .long arm925_coherent_kern_range
- .long arm925_coherent_user_range
- .long arm925_flush_kern_dcache_area
- .long arm925_dma_map_area
- .long arm925_dma_unmap_area
- .long arm925_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm925
ENTRY(cpu_arm925_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -487,52 +478,24 @@ arm925_crval:
crval clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130
__INITDATA
-
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm925_processor_functions, #object
-arm925_processor_functions:
- .word v4t_early_abort
- .word legacy_pabort
- .word cpu_arm925_proc_init
- .word cpu_arm925_proc_fin
- .word cpu_arm925_reset
- .word cpu_arm925_do_idle
- .word cpu_arm925_dcache_clean_area
- .word cpu_arm925_switch_mm
- .word cpu_arm925_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size arm925_processor_functions, . - arm925_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm925, dabort=v4t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm925_name, #object
-cpu_arm925_name:
- .asciz "ARM925T"
- .size cpu_arm925_name, . - cpu_arm925_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm925_name, "ARM925T"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm925_proc_info,#object
-__arm925_proc_info:
- .long 0x54029250
- .long 0xfffffff0
+.macro arm925_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_BIT4 | \
PMD_SECT_AP_WRITE | \
@@ -550,27 +513,8 @@ __arm925_proc_info:
.long v4wbi_tlb_fns
.long v4wb_user_fns
.long arm925_cache_fns
- .size __arm925_proc_info, . - __arm925_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __arm915_proc_info,#object
-__arm915_proc_info:
- .long 0x54029150
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __arm925_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
- .long cpu_arm925_name
- .long arm925_processor_functions
- .long v4wbi_tlb_fns
- .long v4wb_user_fns
- .long arm925_cache_fns
- .size __arm925_proc_info, . - __arm925_proc_info
+ arm925_proc_info arm925, 0x54029250, 0xfffffff0, cpu_arm925_name
+ arm925_proc_info arm915, 0x54029150, 0xfffffff0, cpu_arm925_name
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 0ed85d9..b2f9bde 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -335,17 +335,8 @@ ENTRY(arm926_dma_unmap_area)
mov pc, lr
ENDPROC(arm926_dma_unmap_area)
-ENTRY(arm926_cache_fns)
- .long arm926_flush_icache_all
- .long arm926_flush_kern_cache_all
- .long arm926_flush_user_cache_all
- .long arm926_flush_user_cache_range
- .long arm926_coherent_kern_range
- .long arm926_coherent_user_range
- .long arm926_flush_kern_dcache_area
- .long arm926_dma_map_area
- .long arm926_dma_unmap_area
- .long arm926_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm926
ENTRY(cpu_arm926_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -475,42 +466,14 @@ arm926_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm926_processor_functions, #object
-arm926_processor_functions:
- .word v5tj_early_abort
- .word legacy_pabort
- .word cpu_arm926_proc_init
- .word cpu_arm926_proc_fin
- .word cpu_arm926_reset
- .word cpu_arm926_do_idle
- .word cpu_arm926_dcache_clean_area
- .word cpu_arm926_switch_mm
- .word cpu_arm926_set_pte_ext
- .word cpu_arm926_suspend_size
- .word cpu_arm926_do_suspend
- .word cpu_arm926_do_resume
- .size arm926_processor_functions, . - arm926_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm926, dabort=v5tj_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5tej"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm926_name, #object
-cpu_arm926_name:
- .asciz "ARM926EJ-S"
- .size cpu_arm926_name, . - cpu_arm926_name
+ string cpu_arch_name, "armv5tej"
+ string cpu_elf_name, "v5"
+ string cpu_arm926_name, "ARM926EJ-S"
.align
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 26aea3f..ac750d5 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -264,17 +264,8 @@ ENTRY(arm940_dma_unmap_area)
mov pc, lr
ENDPROC(arm940_dma_unmap_area)
-ENTRY(arm940_cache_fns)
- .long arm940_flush_icache_all
- .long arm940_flush_kern_cache_all
- .long arm940_flush_user_cache_all
- .long arm940_flush_user_cache_range
- .long arm940_coherent_kern_range
- .long arm940_coherent_user_range
- .long arm940_flush_kern_dcache_area
- .long arm940_dma_map_area
- .long arm940_dma_unmap_area
- .long arm940_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm940
__CPUINIT
@@ -348,42 +339,14 @@ __arm940_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm940_processor_functions, #object
-ENTRY(arm940_processor_functions)
- .word nommu_early_abort
- .word legacy_pabort
- .word cpu_arm940_proc_init
- .word cpu_arm940_proc_fin
- .word cpu_arm940_reset
- .word cpu_arm940_do_idle
- .word cpu_arm940_dcache_clean_area
- .word cpu_arm940_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm940_processor_functions, . - arm940_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm940, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
-.type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm940_name, #object
-cpu_arm940_name:
- .ascii "ARM940T"
- .size cpu_arm940_name, . - cpu_arm940_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm940_name, "ARM940T"
.align
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 8063345..f8f7ea3 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -306,18 +306,8 @@ ENTRY(arm946_dma_unmap_area)
mov pc, lr
ENDPROC(arm946_dma_unmap_area)
-ENTRY(arm946_cache_fns)
- .long arm946_flush_icache_all
- .long arm946_flush_kern_cache_all
- .long arm946_flush_user_cache_all
- .long arm946_flush_user_cache_range
- .long arm946_coherent_kern_range
- .long arm946_coherent_user_range
- .long arm946_flush_kern_dcache_area
- .long arm946_dma_map_area
- .long arm946_dma_unmap_area
- .long arm946_dma_flush_range
-
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions arm946
ENTRY(cpu_arm946_dcache_clean_area)
#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -403,43 +393,14 @@ __arm946_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm946_processor_functions, #object
-ENTRY(arm946_processor_functions)
- .word nommu_early_abort
- .word legacy_pabort
- .word cpu_arm946_proc_init
- .word cpu_arm946_proc_fin
- .word cpu_arm946_reset
- .word cpu_arm946_do_idle
-
- .word cpu_arm946_dcache_clean_area
- .word cpu_arm946_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm946_processor_functions, . - arm946_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm946, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5t"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm946_name, #object
-cpu_arm946_name:
- .ascii "ARM946E-S"
- .size cpu_arm946_name, . - cpu_arm946_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5t"
+ string cpu_arm946_name, "ARM946E-S"
.align
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index 546b54d..2120f9e 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -17,6 +17,8 @@
#include <asm/pgtable.h>
#include <asm/ptrace.h>
+#include "proc-macros.S"
+
.text
/*
* cpu_arm9tdmi_proc_init()
@@ -55,82 +57,38 @@ __arm9tdmi_setup:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type arm9tdmi_processor_functions, #object
-ENTRY(arm9tdmi_processor_functions)
- .word nommu_early_abort
- .word legacy_pabort
- .word cpu_arm9tdmi_proc_init
- .word cpu_arm9tdmi_proc_fin
- .word cpu_arm9tdmi_reset
- .word cpu_arm9tdmi_do_idle
- .word cpu_arm9tdmi_dcache_clean_area
- .word cpu_arm9tdmi_switch_mm
- .word 0 @ cpu_*_set_pte
- .word 0
- .word 0
- .word 0
- .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions arm9tdmi, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_arm9tdmi_name, #object
-cpu_arm9tdmi_name:
- .asciz "ARM9TDMI"
- .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name
-
- .type cpu_p2001_name, #object
-cpu_p2001_name:
- .asciz "P2001"
- .size cpu_p2001_name, . - cpu_p2001_name
+ string cpu_arch_name, "armv4t"
+ string cpu_elf_name, "v4"
+ string cpu_arm9tdmi_name, "ARM9TDMI"
+ string cpu_p2001_name, "P2001"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __arm9tdmi_proc_info, #object
-__arm9tdmi_proc_info:
- .long 0x41009900
- .long 0xfff8ff00
+.macro arm9tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
+ .type __\name\()_proc_info, #object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long 0
.long 0
b __arm9tdmi_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_arm9tdmi_name
+ .long \cpu_name
.long arm9tdmi_processor_functions
.long 0
.long 0
.long v4_cache_fns
- .size __arm9tdmi_proc_info, . - __arm9tdmi_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __p2001_proc_info, #object
-__p2001_proc_info:
- .long 0x41029000
- .long 0xffffffff
- .long 0
- .long 0
- b __arm9tdmi_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT
- .long cpu_p2001_name
- .long arm9tdmi_processor_functions
- .long 0
- .long 0
- .long v4_cache_fns
- .size __p2001_proc_info, . - __p2001_proc_info
+ arm9tdmi_proc_info arm9tdmi, 0x41009900, 0xfff8ff00, cpu_arm9tdmi_name
+ arm9tdmi_proc_info p2001, 0x41029000, 0xffffffff, cpu_p2001_name
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index fc2a4ae..4c7a571 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -180,42 +180,14 @@ fa526_cr1_set:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type fa526_processor_functions, #object
-fa526_processor_functions:
- .word v4_early_abort
- .word legacy_pabort
- .word cpu_fa526_proc_init
- .word cpu_fa526_proc_fin
- .word cpu_fa526_reset
- .word cpu_fa526_do_idle
- .word cpu_fa526_dcache_clean_area
- .word cpu_fa526_switch_mm
- .word cpu_fa526_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size fa526_processor_functions, . - fa526_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions fa526, dabort=v4_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_fa526_name, #object
-cpu_fa526_name:
- .asciz "FA526"
- .size cpu_fa526_name, . - cpu_fa526_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_fa526_name, "FA526"
.align
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index d3883ee..8a6c2f7 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -411,29 +411,28 @@ ENTRY(feroceon_dma_unmap_area)
mov pc, lr
ENDPROC(feroceon_dma_unmap_area)
-ENTRY(feroceon_cache_fns)
- .long feroceon_flush_icache_all
- .long feroceon_flush_kern_cache_all
- .long feroceon_flush_user_cache_all
- .long feroceon_flush_user_cache_range
- .long feroceon_coherent_kern_range
- .long feroceon_coherent_user_range
- .long feroceon_flush_kern_dcache_area
- .long feroceon_dma_map_area
- .long feroceon_dma_unmap_area
- .long feroceon_dma_flush_range
-
-ENTRY(feroceon_range_cache_fns)
- .long feroceon_flush_icache_all
- .long feroceon_flush_kern_cache_all
- .long feroceon_flush_user_cache_all
- .long feroceon_flush_user_cache_range
- .long feroceon_coherent_kern_range
- .long feroceon_coherent_user_range
- .long feroceon_range_flush_kern_dcache_area
- .long feroceon_range_dma_map_area
- .long feroceon_dma_unmap_area
- .long feroceon_range_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions feroceon
+
+.macro range_alias basename
+ .globl feroceon_range_\basename
+ .type feroceon_range_\basename , %function
+ .equ feroceon_range_\basename , feroceon_\basename
+.endm
+
+/*
+ * Most of the cache functions are unchanged for this case.
+ * Export suitable alias symbols for the unchanged functions:
+ */
+ range_alias flush_icache_all
+ range_alias flush_user_cache_all
+ range_alias flush_kern_cache_all
+ range_alias flush_user_cache_range
+ range_alias coherent_kern_range
+ range_alias coherent_user_range
+ range_alias dma_unmap_area
+
+ define_cache_functions feroceon_range
.align 5
ENTRY(cpu_feroceon_dcache_clean_area)
@@ -539,93 +538,27 @@ feroceon_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type feroceon_processor_functions, #object
-feroceon_processor_functions:
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_feroceon_proc_init
- .word cpu_feroceon_proc_fin
- .word cpu_feroceon_reset
- .word cpu_feroceon_do_idle
- .word cpu_feroceon_dcache_clean_area
- .word cpu_feroceon_switch_mm
- .word cpu_feroceon_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size feroceon_processor_functions, . - feroceon_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions feroceon, dabort=v5t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_feroceon_name, #object
-cpu_feroceon_name:
- .asciz "Feroceon"
- .size cpu_feroceon_name, . - cpu_feroceon_name
-
- .type cpu_88fr531_name, #object
-cpu_88fr531_name:
- .asciz "Feroceon 88FR531-vd"
- .size cpu_88fr531_name, . - cpu_88fr531_name
-
- .type cpu_88fr571_name, #object
-cpu_88fr571_name:
- .asciz "Feroceon 88FR571-vd"
- .size cpu_88fr571_name, . - cpu_88fr571_name
-
- .type cpu_88fr131_name, #object
-cpu_88fr131_name:
- .asciz "Feroceon 88FR131"
- .size cpu_88fr131_name, . - cpu_88fr131_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_feroceon_name, "Feroceon"
+ string cpu_88fr531_name, "Feroceon 88FR531-vd"
+ string cpu_88fr571_name, "Feroceon 88FR571-vd"
+ string cpu_88fr131_name, "Feroceon 88FR131"
.align
.section ".proc.info.init", #alloc, #execinstr
-#ifdef CONFIG_CPU_FEROCEON_OLD_ID
- .type __feroceon_old_id_proc_info,#object
-__feroceon_old_id_proc_info:
- .long 0x41009260
- .long 0xff00fff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __feroceon_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_feroceon_name
- .long feroceon_processor_functions
- .long v4wbi_tlb_fns
- .long feroceon_user_fns
- .long feroceon_cache_fns
- .size __feroceon_old_id_proc_info, . - __feroceon_old_id_proc_info
-#endif
-
- .type __88fr531_proc_info,#object
-__88fr531_proc_info:
- .long 0x56055310
- .long 0xfffffff0
+.macro feroceon_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -640,59 +573,22 @@ __88fr531_proc_info:
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_88fr531_name
+ .long \cpu_name
.long feroceon_processor_functions
.long v4wbi_tlb_fns
.long feroceon_user_fns
- .long feroceon_cache_fns
- .size __88fr531_proc_info, . - __88fr531_proc_info
+ .long \cache
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __88fr571_proc_info,#object
-__88fr571_proc_info:
- .long 0x56155710
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __feroceon_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_88fr571_name
- .long feroceon_processor_functions
- .long v4wbi_tlb_fns
- .long feroceon_user_fns
- .long feroceon_range_cache_fns
- .size __88fr571_proc_info, . - __88fr571_proc_info
+#ifdef CONFIG_CPU_FEROCEON_OLD_ID
+ feroceon_proc_info feroceon_old_id, 0x41009260, 0xff00fff0, \
+ cpu_name=cpu_feroceon_name, cache=feroceon_cache_fns
+#endif
- .type __88fr131_proc_info,#object
-__88fr131_proc_info:
- .long 0x56251310
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_BIT4 | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __feroceon_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_88fr131_name
- .long feroceon_processor_functions
- .long v4wbi_tlb_fns
- .long feroceon_user_fns
- .long feroceon_range_cache_fns
- .size __88fr131_proc_info, . - __88fr131_proc_info
+ feroceon_proc_info 88fr531, 0x56055310, 0xfffffff0, cpu_88fr531_name, \
+ cache=feroceon_cache_fns
+ feroceon_proc_info 88fr571, 0x56155710, 0xfffffff0, cpu_88fr571_name, \
+ cache=feroceon_range_cache_fns
+ feroceon_proc_info 88fr131, 0x56251310, 0xfffffff0, cpu_88fr131_name, \
+ cache=feroceon_range_cache_fns
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 34261f9..4ae9b44 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -254,3 +254,66 @@
mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
mcr p15, 0, ip, c7, c10, 4 @ data write barrier
.endm
+
+.macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0
+ .type \name\()_processor_functions, #object
+ .align 2
+ENTRY(\name\()_processor_functions)
+ .word \dabort
+ .word \pabort
+ .word cpu_\name\()_proc_init
+ .word cpu_\name\()_proc_fin
+ .word cpu_\name\()_reset
+ .word cpu_\name\()_do_idle
+ .word cpu_\name\()_dcache_clean_area
+ .word cpu_\name\()_switch_mm
+
+ .if \nommu
+ .word 0
+ .else
+ .word cpu_\name\()_set_pte_ext
+ .endif
+
+ .if \suspend
+ .word cpu_\name\()_suspend_size
+ .word cpu_\name\()_do_suspend
+ .word cpu_\name\()_do_resume
+ .else
+ .word 0
+ .word 0
+ .word 0
+ .endif
+
+ .size \name\()_processor_functions, . - \name\()_processor_functions
+.endm
+
+.macro define_cache_functions name:req
+ .align 2
+ .type \name\()_cache_fns, #object
+ENTRY(\name\()_cache_fns)
+ .long \name\()_flush_icache_all
+ .long \name\()_flush_kern_cache_all
+ .long \name\()_flush_user_cache_all
+ .long \name\()_flush_user_cache_range
+ .long \name\()_coherent_kern_range
+ .long \name\()_coherent_user_range
+ .long \name\()_flush_kern_dcache_area
+ .long \name\()_dma_map_area
+ .long \name\()_dma_unmap_area
+ .long \name\()_dma_flush_range
+ .size \name\()_cache_fns, . - \name\()_cache_fns
+.endm
+
+.macro define_tlb_functions name:req, flags_up:req, flags_smp
+ .type \name\()_tlb_fns, #object
+ENTRY(\name\()_tlb_fns)
+ .long \name\()_flush_user_tlb_range
+ .long \name\()_flush_kern_tlb_range
+ .ifnb \flags_smp
+ ALT_SMP(.long \flags_smp )
+ ALT_UP(.long \flags_up )
+ .else
+ .long \flags_up
+ .endif
+ .size \name\()_tlb_fns, . - \name\()_tlb_fns
+.endm
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 9d4f2ae..db52b0f 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -93,6 +93,17 @@ ENTRY(cpu_mohawk_do_idle)
mov pc, lr
/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(mohawk_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(mohawk_flush_icache_all)
+
+/*
* flush_user_cache_all()
*
* Clean and invalidate all cache entries in a particular
@@ -288,16 +299,8 @@ ENTRY(mohawk_dma_unmap_area)
mov pc, lr
ENDPROC(mohawk_dma_unmap_area)
-ENTRY(mohawk_cache_fns)
- .long mohawk_flush_kern_cache_all
- .long mohawk_flush_user_cache_all
- .long mohawk_flush_user_cache_range
- .long mohawk_coherent_kern_range
- .long mohawk_coherent_user_range
- .long mohawk_flush_kern_dcache_area
- .long mohawk_dma_map_area
- .long mohawk_dma_unmap_area
- .long mohawk_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions mohawk
ENTRY(cpu_mohawk_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -373,42 +376,14 @@ mohawk_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
- .type mohawk_processor_functions, #object
-mohawk_processor_functions:
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_mohawk_proc_init
- .word cpu_mohawk_proc_fin
- .word cpu_mohawk_reset
- .word cpu_mohawk_do_idle
- .word cpu_mohawk_dcache_clean_area
- .word cpu_mohawk_switch_mm
- .word cpu_mohawk_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size mohawk_processor_functions, . - mohawk_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions mohawk, dabort=v5t_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_mohawk_name, #object
-cpu_mohawk_name:
- .asciz "Marvell 88SV331x"
- .size cpu_mohawk_name, . - cpu_mohawk_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_mohawk_name, "Marvell 88SV331x"
.align
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 46f09ed..d50ada2 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -187,43 +187,14 @@ sa110_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
- .type sa110_processor_functions, #object
-ENTRY(sa110_processor_functions)
- .word v4_early_abort
- .word legacy_pabort
- .word cpu_sa110_proc_init
- .word cpu_sa110_proc_fin
- .word cpu_sa110_reset
- .word cpu_sa110_do_idle
- .word cpu_sa110_dcache_clean_area
- .word cpu_sa110_switch_mm
- .word cpu_sa110_set_pte_ext
- .word 0
- .word 0
- .word 0
- .size sa110_processor_functions, . - sa110_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions sa110, dabort=v4_early_abort, pabort=legacy_pabort
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_sa110_name, #object
-cpu_sa110_name:
- .asciz "StrongARM-110"
- .size cpu_sa110_name, . - cpu_sa110_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_sa110_name, "StrongARM-110"
.align
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 184a9c9..c7e08ca 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -236,59 +236,28 @@ sa1100_crval:
__INITDATA
/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
-/*
* SA1100 and SA1110 share the same function calls
*/
- .type sa1100_processor_functions, #object
-ENTRY(sa1100_processor_functions)
- .word v4_early_abort
- .word legacy_pabort
- .word cpu_sa1100_proc_init
- .word cpu_sa1100_proc_fin
- .word cpu_sa1100_reset
- .word cpu_sa1100_do_idle
- .word cpu_sa1100_dcache_clean_area
- .word cpu_sa1100_switch_mm
- .word cpu_sa1100_set_pte_ext
- .word cpu_sa1100_suspend_size
- .word cpu_sa1100_do_suspend
- .word cpu_sa1100_do_resume
- .size sa1100_processor_functions, . - sa1100_processor_functions
-
- .section ".rodata"
-
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions sa1100, dabort=v4_early_abort, pabort=legacy_pabort, suspend=1
- .type cpu_sa1100_name, #object
-cpu_sa1100_name:
- .asciz "StrongARM-1100"
- .size cpu_sa1100_name, . - cpu_sa1100_name
+ .section ".rodata"
- .type cpu_sa1110_name, #object
-cpu_sa1110_name:
- .asciz "StrongARM-1110"
- .size cpu_sa1110_name, . - cpu_sa1110_name
+ string cpu_arch_name, "armv4"
+ string cpu_elf_name, "v4"
+ string cpu_sa1100_name, "StrongARM-1100"
+ string cpu_sa1110_name, "StrongARM-1110"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __sa1100_proc_info,#object
-__sa1100_proc_info:
- .long 0x4401a110
- .long 0xfffffff0
+.macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -301,32 +270,13 @@ __sa1100_proc_info:
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
- .long cpu_sa1100_name
+ .long \cpu_name
.long sa1100_processor_functions
.long v4wb_tlb_fns
.long v4_mc_user_fns
.long v4wb_cache_fns
- .size __sa1100_proc_info, . - __sa1100_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
- .type __sa1110_proc_info,#object
-__sa1110_proc_info:
- .long 0x6901b110
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __sa1100_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
- .long cpu_sa1110_name
- .long sa1100_processor_functions
- .long v4wb_tlb_fns
- .long v4_mc_user_fns
- .long v4wb_cache_fns
- .size __sa1110_proc_info, . - __sa1110_proc_info
+ sa1100_proc_info sa1100, 0x4401a110, 0xfffffff0, cpu_sa1100_name
+ sa1100_proc_info sa1110, 0x6901b110, 0xfffffff0, cpu_sa1110_name
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 1d2b845..aedf3c5 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -56,6 +56,11 @@ ENTRY(cpu_v6_proc_fin)
*/
.align 5
ENTRY(cpu_v6_reset)
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x1 @ ...............m
+ mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 4 @ ISB
mov pc, r0
/*
@@ -169,11 +174,7 @@ cpu_resume_l1_flags:
#define cpu_v6_do_resume 0
#endif
-
- .type cpu_v6_name, #object
-cpu_v6_name:
- .asciz "ARMv6-compatible processor"
- .size cpu_v6_name, . - cpu_v6_name
+ string cpu_v6_name, "ARMv6-compatible processor"
.align
@@ -239,33 +240,13 @@ v6_crval:
__INITDATA
- .type v6_processor_functions, #object
-ENTRY(v6_processor_functions)
- .word v6_early_abort
- .word v6_pabort
- .word cpu_v6_proc_init
- .word cpu_v6_proc_fin
- .word cpu_v6_reset
- .word cpu_v6_do_idle
- .word cpu_v6_dcache_clean_area
- .word cpu_v6_switch_mm
- .word cpu_v6_set_pte_ext
- .word cpu_v6_suspend_size
- .word cpu_v6_do_suspend
- .word cpu_v6_do_resume
- .size v6_processor_functions, . - v6_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions v6, dabort=v6_early_abort, pabort=v6_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv6"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v6"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv6"
+ string cpu_elf_name, "v6"
.align
.section ".proc.info.init", #alloc, #execinstr
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 089c0b5..0a309aa 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -17,6 +17,8 @@
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable.h>
+#include <mach/smc.h>
+
#include "proc-macros.S"
#define TTB_S (1 << 1)
@@ -58,9 +60,16 @@ ENDPROC(cpu_v7_proc_fin)
* to what would be the reset vector.
*
* - loc - location to jump to for soft reset
+ *
+ * This code must be executed using a flat identity mapping with
+ * caches disabled.
*/
.align 5
ENTRY(cpu_v7_reset)
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x1 @ ...............m
+ mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ isb
mov pc, r0
ENDPROC(cpu_v7_reset)
@@ -173,8 +182,7 @@ ENTRY(cpu_v7_set_pte_ext)
mov pc, lr
ENDPROC(cpu_v7_set_pte_ext)
-cpu_v7_name:
- .ascii "ARMv7 Processor"
+ string cpu_v7_name, "ARMv7 Processor"
.align
/*
@@ -279,13 +287,20 @@ cpu_resume_l1_flags:
* It is assumed that:
* - cache type register is implemented
*/
+__v7_ca5mp_setup:
__v7_ca9mp_setup:
+ mov r10, #(1 << 0) @ TLB ops broadcasting
+ b 1f
+__v7_ca15mp_setup:
+ mov r10, #0
+1:
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, r0, c1, c0, 1)
ALT_UP(mov r0, #(1 << 6)) @ fake it for UP
tst r0, #(1 << 6) @ SMP/nAMP mode enabled?
- orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and
- mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting
+ orreq r0, r0, #(1 << 6) @ Enable SMP/nAMP mode
+ orreq r0, r0, r10 @ Enable CPU-specific SMP bits
+ mcreq p15, 0, r0, c1, c0, 1
#endif
__v7_setup:
adr r12, __v7_setup_stack @ the local stack
@@ -326,12 +341,23 @@ __v7_setup:
orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit
mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register
#endif
- b 3f
+ b 4f
/* Cortex-A9 Errata */
2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number
teq r0, r10
bne 3f
+#ifndef CONFIG_ARM_TRUSTZONE
+ cmp r6, #0x10 @ power ctrl reg added r1p0
+ mrcge p15, 0, r10, c15, c0, 0 @ read power control register
+ orrge r10, r10, #1 @ enable dynamic clock gating
+ mcrge p15, 0, r10, c15, c0, 0 @ write power control register
+#ifdef CONFIG_ARM_ERRATA_720791
+ teq r5, #0x00100000 @ only present in r1p*
+ mrceq p15, 0, r10, c15, c0, 2 @ read "chicken power ctrl" reg
+ orreq r10, r10, #0x30 @ disable core clk gate on
+ mcreq p15, 0, r10, c15, c0, 2 @ instr-side waits
+#endif
#ifdef CONFIG_ARM_ERRATA_742230
cmp r6, #0x22 @ only present up to r2p2
mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
@@ -347,10 +373,13 @@ __v7_setup:
orreq r10, r10, #1 << 22 @ set bit #22
mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
+#ifdef CONFIG_ARM_ERRATA_761320
+ mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orr r10, r10, #1 << 21 @ set bit #21
+ mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
#ifdef CONFIG_ARM_ERRATA_743622
- teq r6, #0x20 @ present in r2p0
- teqne r6, #0x21 @ present in r2p1
- teqne r6, #0x22 @ present in r2p2
+ teq r5, #0x00200000 @ present in r2p*
mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
orreq r10, r10, #1 << 6 @ set bit #6
mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
@@ -361,8 +390,68 @@ __v7_setup:
orrlt r10, r10, #1 << 11 @ set bit #11
mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
+#endif
+ b 4f
+
+ /* Cortex-A15 Errata */
+3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
+ teq r0, r10
+ bne 4f
+
+#ifdef CONFIG_ARM_TRUSTZONE
+ stmia r12, {r0-r3}
+ mov r3, #0
+#endif
+#ifdef CONFIG_ARM_ERRATA_761171
+ teq r6, #0x0 @ present in r0p0
+ teqne r6, #0x1 @ present in r0p1
+ teqne r6, #0x2 @ present in r0p2
+ mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
+ orreq r10, r10, #3 << 27 @ set [28:27] bit
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldreq r0, =SMC_CMD_REG
+ ldreq r1, =SMC_REG_ID_CP15(1, 0, 0, 1)
+ moveq r2, r10
+ smceq 0
+#else
+ mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+#endif
+#ifdef CONFIG_ARM_ERRATA_762974
+ teq r6, #0x0 @ present in r0p0
+ teqne r6, #0x1 @ present in r0p1
+ teqne r6, #0x2 @ present in r0p2
+ ldreq r10, =0x400 @ disable l2 prefetch function
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldreq r0, =SMC_CMD_REG
+ ldreq r1, =SMC_REG_ID_CP15(15, 1, 0, 3)
+ moveq r2, r10
+ smceq 0
+#else
+ mcreq p15, 1, r10, c15, c0, 3 @ write l2 prefetch ctrl register
+#endif
+#endif
+#ifdef CONFIG_ARM_ERRATA_763722
+ teq r6, #0x0 @ present in r0p0
+ teqne r6, #0x1 @ present in r0p1
+ teqne r6, #0x2 @ present in r0p2
+ teqne r6, #0x3 @ present in r0p3
+ mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
+ orreq r10, r10, #15 << 25 @ set [28:25] bit
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldreq r0, =SMC_CMD_REG
+ ldreq r1, =SMC_REG_ID_CP15(1, 0, 0, 1)
+ moveq r2, r10
+ smceq 0
+#else
+ mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+#endif
+#ifdef CONFIG_ARM_TRUSTZONE
+ ldmia r12, {r0-r3}
+#endif
-3: mov r10, #0
+4: mov r10, #0
#ifdef HARVARD_CACHE
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
#endif
@@ -411,94 +500,79 @@ __v7_setup_stack:
__INITDATA
- .type v7_processor_functions, #object
-ENTRY(v7_processor_functions)
- .word v7_early_abort
- .word v7_pabort
- .word cpu_v7_proc_init
- .word cpu_v7_proc_fin
- .word cpu_v7_reset
- .word cpu_v7_do_idle
- .word cpu_v7_dcache_clean_area
- .word cpu_v7_switch_mm
- .word cpu_v7_set_pte_ext
- .word cpu_v7_suspend_size
- .word cpu_v7_do_suspend
- .word cpu_v7_do_resume
- .size v7_processor_functions, . - v7_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+#ifdef CONFIG_PM_SLEEP
+ define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
+#else
+ define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=0
+#endif
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv7"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v7"
- .size cpu_elf_name, . - cpu_elf_name
+ string cpu_arch_name, "armv7"
+ string cpu_elf_name, "v7"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __v7_ca9mp_proc_info, #object
-__v7_ca9mp_proc_info:
- .long 0x410fc090 @ Required ID value
- .long 0xff0ffff0 @ Mask for ID
- ALT_SMP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_SMP)
- ALT_UP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_UP)
- .long PMD_TYPE_SECT | \
- PMD_SECT_XN | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- W(b) __v7_ca9mp_setup
+ /*
+ * Standard v7 proc info content
+ */
+.macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
+ PMD_FLAGS_SMP | \mm_mmuflags)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
+ PMD_FLAGS_UP | \mm_mmuflags)
+ .long PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ | \io_mmuflags
+ W(b) \initfunc
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \
+ HWCAP_EDSP | HWCAP_TLS | \hwcaps
.long cpu_v7_name
.long v7_processor_functions
.long v7wbi_tlb_fns
.long v6_user_fns
.long v7_cache_fns
+.endm
+
+ /*
+ * ARM Ltd. Cortex A5 processor.
+ */
+ .type __v7_ca5mp_proc_info, #object
+__v7_ca5mp_proc_info:
+ .long 0x410fc050
+ .long 0xff0ffff0
+ __v7_proc __v7_ca5mp_setup
+ .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info
+
+ /*
+ * ARM Ltd. Cortex A9 processor.
+ */
+ .type __v7_ca9mp_proc_info, #object
+__v7_ca9mp_proc_info:
+ .long 0x410fc090
+ .long 0xff0ffff0
+ __v7_proc __v7_ca9mp_setup
.size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info
/*
+ * ARM Ltd. Cortex A15 processor.
+ */
+ .type __v7_ca15mp_proc_info, #object
+__v7_ca15mp_proc_info:
+ .long 0x410fc0f0
+ .long 0xff0ffff0
+ __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV
+ .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
+
+ /*
* Match any ARMv7 processor core.
*/
.type __v7_proc_info, #object
__v7_proc_info:
.long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID
- ALT_SMP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_SMP)
- ALT_UP(.long \
- PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ | \
- PMD_FLAGS_UP)
- .long PMD_TYPE_SECT | \
- PMD_SECT_XN | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- W(b) __v7_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
- .long cpu_v7_name
- .long v7_processor_functions
- .long v7wbi_tlb_fns
- .long v6_user_fns
- .long v7_cache_fns
+ __v7_proc __v7_setup
.size __v7_proc_info, . - __v7_proc_info
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 5962136..1508f9b 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -335,17 +335,8 @@ ENTRY(xsc3_dma_unmap_area)
mov pc, lr
ENDPROC(xsc3_dma_unmap_area)
-ENTRY(xsc3_cache_fns)
- .long xsc3_flush_icache_all
- .long xsc3_flush_kern_cache_all
- .long xsc3_flush_user_cache_all
- .long xsc3_flush_user_cache_range
- .long xsc3_coherent_kern_range
- .long xsc3_coherent_user_range
- .long xsc3_flush_kern_dcache_area
- .long xsc3_dma_map_area
- .long xsc3_dma_unmap_area
- .long xsc3_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xsc3
ENTRY(cpu_xsc3_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
@@ -503,52 +494,24 @@ xsc3_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
- .type xsc3_processor_functions, #object
-ENTRY(xsc3_processor_functions)
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_xsc3_proc_init
- .word cpu_xsc3_proc_fin
- .word cpu_xsc3_reset
- .word cpu_xsc3_do_idle
- .word cpu_xsc3_dcache_clean_area
- .word cpu_xsc3_switch_mm
- .word cpu_xsc3_set_pte_ext
- .word cpu_xsc3_suspend_size
- .word cpu_xsc3_do_suspend
- .word cpu_xsc3_do_resume
- .size xsc3_processor_functions, . - xsc3_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions xsc3, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_xsc3_name, #object
-cpu_xsc3_name:
- .asciz "XScale-V3 based processor"
- .size cpu_xsc3_name, . - cpu_xsc3_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+ string cpu_xsc3_name, "XScale-V3 based processor"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __xsc3_proc_info,#object
-__xsc3_proc_info:
- .long 0x69056000
- .long 0xffffe000
+.macro xsc3_proc_info name:req, cpu_val:req, cpu_mask:req
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
@@ -566,29 +529,10 @@ __xsc3_proc_info:
.long v4wbi_tlb_fns
.long xsc3_mc_user_fns
.long xsc3_cache_fns
- .size __xsc3_proc_info, . - __xsc3_proc_info
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
-/* Note: PXA935 changed its implementor ID from Intel to Marvell */
+ xsc3_proc_info xsc3, 0x69056000, 0xffffe000
- .type __xsc3_pxa935_proc_info,#object
-__xsc3_pxa935_proc_info:
- .long 0x56056000
- .long 0xffffe000
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xsc3_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_xsc3_name
- .long xsc3_processor_functions
- .long v4wbi_tlb_fns
- .long xsc3_mc_user_fns
- .long xsc3_cache_fns
- .size __xsc3_pxa935_proc_info, . - __xsc3_pxa935_proc_info
+/* Note: PXA935 changed its implementor ID from Intel to Marvell */
+ xsc3_proc_info xsc3_pxa935, 0x56056000, 0xffffe000
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 42af976..76a8046 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -390,12 +390,12 @@ ENDPROC(xscale_dma_map_area)
* - size - size of region
* - dir - DMA direction
*/
-ENTRY(xscale_dma_a0_map_area)
+ENTRY(xscale_80200_A0_A1_dma_map_area)
add r1, r1, r0
teq r2, #DMA_TO_DEVICE
beq xscale_dma_clean_range
b xscale_dma_flush_range
-ENDPROC(xscale_dma_a0_map_area)
+ENDPROC(xscale_80200_A0_A1_dma_map_area)
/*
* dma_unmap_area(start, size, dir)
@@ -407,17 +407,8 @@ ENTRY(xscale_dma_unmap_area)
mov pc, lr
ENDPROC(xscale_dma_unmap_area)
-ENTRY(xscale_cache_fns)
- .long xscale_flush_icache_all
- .long xscale_flush_kern_cache_all
- .long xscale_flush_user_cache_all
- .long xscale_flush_user_cache_range
- .long xscale_coherent_kern_range
- .long xscale_coherent_user_range
- .long xscale_flush_kern_dcache_area
- .long xscale_dma_map_area
- .long xscale_dma_unmap_area
- .long xscale_dma_flush_range
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xscale
/*
* On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
@@ -432,16 +423,28 @@ ENTRY(xscale_cache_fns)
* revision January 22, 2003, available at:
* http://www.intel.com/design/iio/specupdt/273415.htm
*/
-ENTRY(xscale_80200_A0_A1_cache_fns)
- .long xscale_flush_kern_cache_all
- .long xscale_flush_user_cache_all
- .long xscale_flush_user_cache_range
- .long xscale_coherent_kern_range
- .long xscale_coherent_user_range
- .long xscale_flush_kern_dcache_area
- .long xscale_dma_a0_map_area
- .long xscale_dma_unmap_area
- .long xscale_dma_flush_range
+.macro a0_alias basename
+ .globl xscale_80200_A0_A1_\basename
+ .type xscale_80200_A0_A1_\basename , %function
+ .equ xscale_80200_A0_A1_\basename , xscale_\basename
+.endm
+
+/*
+ * Most of the cache functions are unchanged for these processor revisions.
+ * Export suitable alias symbols for the unchanged functions:
+ */
+ a0_alias flush_icache_all
+ a0_alias flush_user_cache_all
+ a0_alias flush_kern_cache_all
+ a0_alias flush_user_cache_range
+ a0_alias coherent_kern_range
+ a0_alias coherent_user_range
+ a0_alias flush_kern_dcache_area
+ a0_alias dma_flush_range
+ a0_alias dma_unmap_area
+
+ @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
+ define_cache_functions xscale_80200_A0_A1
ENTRY(cpu_xscale_dcache_clean_area)
1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
@@ -587,432 +590,74 @@ xscale_crval:
__INITDATA
-/*
- * Purpose : Function pointers used to access above functions - all calls
- * come through these
- */
-
- .type xscale_processor_functions, #object
-ENTRY(xscale_processor_functions)
- .word v5t_early_abort
- .word legacy_pabort
- .word cpu_xscale_proc_init
- .word cpu_xscale_proc_fin
- .word cpu_xscale_reset
- .word cpu_xscale_do_idle
- .word cpu_xscale_dcache_clean_area
- .word cpu_xscale_switch_mm
- .word cpu_xscale_set_pte_ext
- .word cpu_xscale_suspend_size
- .word cpu_xscale_do_suspend
- .word cpu_xscale_do_resume
- .size xscale_processor_functions, . - xscale_processor_functions
+ @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
+ define_processor_functions xscale, dabort=v5t_early_abort, pabort=legacy_pabort, suspend=1
.section ".rodata"
- .type cpu_arch_name, #object
-cpu_arch_name:
- .asciz "armv5te"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
-cpu_elf_name:
- .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
-
- .type cpu_80200_A0_A1_name, #object
-cpu_80200_A0_A1_name:
- .asciz "XScale-80200 A0/A1"
- .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name
-
- .type cpu_80200_name, #object
-cpu_80200_name:
- .asciz "XScale-80200"
- .size cpu_80200_name, . - cpu_80200_name
-
- .type cpu_80219_name, #object
-cpu_80219_name:
- .asciz "XScale-80219"
- .size cpu_80219_name, . - cpu_80219_name
-
- .type cpu_8032x_name, #object
-cpu_8032x_name:
- .asciz "XScale-IOP8032x Family"
- .size cpu_8032x_name, . - cpu_8032x_name
-
- .type cpu_8033x_name, #object
-cpu_8033x_name:
- .asciz "XScale-IOP8033x Family"
- .size cpu_8033x_name, . - cpu_8033x_name
-
- .type cpu_pxa250_name, #object
-cpu_pxa250_name:
- .asciz "XScale-PXA250"
- .size cpu_pxa250_name, . - cpu_pxa250_name
-
- .type cpu_pxa210_name, #object
-cpu_pxa210_name:
- .asciz "XScale-PXA210"
- .size cpu_pxa210_name, . - cpu_pxa210_name
-
- .type cpu_ixp42x_name, #object
-cpu_ixp42x_name:
- .asciz "XScale-IXP42x Family"
- .size cpu_ixp42x_name, . - cpu_ixp42x_name
-
- .type cpu_ixp43x_name, #object
-cpu_ixp43x_name:
- .asciz "XScale-IXP43x Family"
- .size cpu_ixp43x_name, . - cpu_ixp43x_name
-
- .type cpu_ixp46x_name, #object
-cpu_ixp46x_name:
- .asciz "XScale-IXP46x Family"
- .size cpu_ixp46x_name, . - cpu_ixp46x_name
-
- .type cpu_ixp2400_name, #object
-cpu_ixp2400_name:
- .asciz "XScale-IXP2400"
- .size cpu_ixp2400_name, . - cpu_ixp2400_name
-
- .type cpu_ixp2800_name, #object
-cpu_ixp2800_name:
- .asciz "XScale-IXP2800"
- .size cpu_ixp2800_name, . - cpu_ixp2800_name
-
- .type cpu_pxa255_name, #object
-cpu_pxa255_name:
- .asciz "XScale-PXA255"
- .size cpu_pxa255_name, . - cpu_pxa255_name
-
- .type cpu_pxa270_name, #object
-cpu_pxa270_name:
- .asciz "XScale-PXA270"
- .size cpu_pxa270_name, . - cpu_pxa270_name
+ string cpu_arch_name, "armv5te"
+ string cpu_elf_name, "v5"
+
+ string cpu_80200_A0_A1_name, "XScale-80200 A0/A1"
+ string cpu_80200_name, "XScale-80200"
+ string cpu_80219_name, "XScale-80219"
+ string cpu_8032x_name, "XScale-IOP8032x Family"
+ string cpu_8033x_name, "XScale-IOP8033x Family"
+ string cpu_pxa250_name, "XScale-PXA250"
+ string cpu_pxa210_name, "XScale-PXA210"
+ string cpu_ixp42x_name, "XScale-IXP42x Family"
+ string cpu_ixp43x_name, "XScale-IXP43x Family"
+ string cpu_ixp46x_name, "XScale-IXP46x Family"
+ string cpu_ixp2400_name, "XScale-IXP2400"
+ string cpu_ixp2800_name, "XScale-IXP2800"
+ string cpu_pxa255_name, "XScale-PXA255"
+ string cpu_pxa270_name, "XScale-PXA270"
.align
.section ".proc.info.init", #alloc, #execinstr
- .type __80200_A0_A1_proc_info,#object
-__80200_A0_A1_proc_info:
- .long 0x69052000
- .long 0xfffffffe
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_80200_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_80200_A0_A1_cache_fns
- .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info
-
- .type __80200_proc_info,#object
-__80200_proc_info:
- .long 0x69052000
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
+.macro xscale_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache
+ .type __\name\()_proc_info,#object
+__\name\()_proc_info:
+ .long \cpu_val
+ .long \cpu_mask
+ .long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
+ .long PMD_TYPE_SECT | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
b __xscale_setup
.long cpu_arch_name
.long cpu_elf_name
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_80200_name
+ .long \cpu_name
.long xscale_processor_functions
.long v4wbi_tlb_fns
.long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __80200_proc_info, . - __80200_proc_info
-
- .type __80219_proc_info,#object
-__80219_proc_info:
- .long 0x69052e20
- .long 0xffffffe0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_80219_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __80219_proc_info, . - __80219_proc_info
-
- .type __8032x_proc_info,#object
-__8032x_proc_info:
- .long 0x69052420
- .long 0xfffff7e0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_8032x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __8032x_proc_info, . - __8032x_proc_info
-
- .type __8033x_proc_info,#object
-__8033x_proc_info:
- .long 0x69054010
- .long 0xfffffd30
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_8033x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __8033x_proc_info, . - __8033x_proc_info
-
- .type __pxa250_proc_info,#object
-__pxa250_proc_info:
- .long 0x69052100
- .long 0xfffff7f0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa250_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa250_proc_info, . - __pxa250_proc_info
-
- .type __pxa210_proc_info,#object
-__pxa210_proc_info:
- .long 0x69052120
- .long 0xfffff3f0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa210_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa210_proc_info, . - __pxa210_proc_info
-
- .type __ixp2400_proc_info, #object
-__ixp2400_proc_info:
- .long 0x69054190
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp2400_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp2400_proc_info, . - __ixp2400_proc_info
-
- .type __ixp2800_proc_info, #object
-__ixp2800_proc_info:
- .long 0x690541a0
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp2800_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp2800_proc_info, . - __ixp2800_proc_info
-
- .type __ixp42x_proc_info, #object
-__ixp42x_proc_info:
- .long 0x690541c0
- .long 0xffffffc0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp42x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp42x_proc_info, . - __ixp42x_proc_info
-
- .type __ixp43x_proc_info, #object
-__ixp43x_proc_info:
- .long 0x69054040
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp43x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp43x_proc_info, . - __ixp43x_proc_info
-
- .type __ixp46x_proc_info, #object
-__ixp46x_proc_info:
- .long 0x69054200
- .long 0xffffff00
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_ixp46x_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __ixp46x_proc_info, . - __ixp46x_proc_info
-
- .type __pxa255_proc_info,#object
-__pxa255_proc_info:
- .long 0x69052d00
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa255_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa255_proc_info, . - __pxa255_proc_info
-
- .type __pxa270_proc_info,#object
-__pxa270_proc_info:
- .long 0x69054110
- .long 0xfffffff0
- .long PMD_TYPE_SECT | \
- PMD_SECT_BUFFERABLE | \
- PMD_SECT_CACHEABLE | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- .long PMD_TYPE_SECT | \
- PMD_SECT_AP_WRITE | \
- PMD_SECT_AP_READ
- b __xscale_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
- .long cpu_pxa270_name
- .long xscale_processor_functions
- .long v4wbi_tlb_fns
- .long xscale_mc_user_fns
- .long xscale_cache_fns
- .size __pxa270_proc_info, . - __pxa270_proc_info
-
+ .ifb \cache
+ .long xscale_cache_fns
+ .else
+ .long \cache
+ .endif
+ .size __\name\()_proc_info, . - __\name\()_proc_info
+.endm
+
+ xscale_proc_info 80200_A0_A1, 0x69052000, 0xfffffffe, cpu_80200_name, \
+ cache=xscale_80200_A0_A1_cache_fns
+ xscale_proc_info 80200, 0x69052000, 0xfffffff0, cpu_80200_name
+ xscale_proc_info 80219, 0x69052e20, 0xffffffe0, cpu_80219_name
+ xscale_proc_info 8032x, 0x69052420, 0xfffff7e0, cpu_8032x_name
+ xscale_proc_info 8033x, 0x69054010, 0xfffffd30, cpu_8033x_name
+ xscale_proc_info pxa250, 0x69052100, 0xfffff7f0, cpu_pxa250_name
+ xscale_proc_info pxa210, 0x69052120, 0xfffff3f0, cpu_pxa210_name
+ xscale_proc_info ixp2400, 0x69054190, 0xfffffff0, cpu_ixp2400_name
+ xscale_proc_info ixp2800, 0x690541a0, 0xfffffff0, cpu_ixp2800_name
+ xscale_proc_info ixp42x, 0x690541c0, 0xffffffc0, cpu_ixp42x_name
+ xscale_proc_info ixp43x, 0x69054040, 0xfffffff0, cpu_ixp43x_name
+ xscale_proc_info ixp46x, 0x69054200, 0xffffff00, cpu_ixp46x_name
+ xscale_proc_info pxa255, 0x69052d00, 0xfffffff0, cpu_pxa255_name
+ xscale_proc_info pxa270, 0x69054110, 0xfffffff0, cpu_pxa270_name
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S
index 9694f1f..7a2e56c 100644
--- a/arch/arm/mm/tlb-fa.S
+++ b/arch/arm/mm/tlb-fa.S
@@ -67,9 +67,5 @@ ENTRY(fa_flush_kern_tlb_range)
__INITDATA
- .type fa_tlb_fns, #object
-ENTRY(fa_tlb_fns)
- .long fa_flush_user_tlb_range
- .long fa_flush_kern_tlb_range
- .long fa_tlb_flags
- .size fa_tlb_fns, . - fa_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions fa, fa_tlb_flags
diff --git a/arch/arm/mm/tlb-v3.S b/arch/arm/mm/tlb-v3.S
index c10786e..d253995 100644
--- a/arch/arm/mm/tlb-v3.S
+++ b/arch/arm/mm/tlb-v3.S
@@ -44,9 +44,5 @@ ENTRY(v3_flush_kern_tlb_range)
__INITDATA
- .type v3_tlb_fns, #object
-ENTRY(v3_tlb_fns)
- .long v3_flush_user_tlb_range
- .long v3_flush_kern_tlb_range
- .long v3_tlb_flags
- .size v3_tlb_fns, . - v3_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v3, v3_tlb_flags
diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
index d6c9445..17a025a 100644
--- a/arch/arm/mm/tlb-v4.S
+++ b/arch/arm/mm/tlb-v4.S
@@ -57,9 +57,5 @@ ENTRY(v4_flush_user_tlb_range)
__INITDATA
- .type v4_tlb_fns, #object
-ENTRY(v4_tlb_fns)
- .long v4_flush_user_tlb_range
- .long v4_flush_kern_tlb_range
- .long v4_tlb_flags
- .size v4_tlb_fns, . - v4_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4, v4_tlb_flags
diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
index cb829ca..c04598f 100644
--- a/arch/arm/mm/tlb-v4wb.S
+++ b/arch/arm/mm/tlb-v4wb.S
@@ -69,9 +69,5 @@ ENTRY(v4wb_flush_kern_tlb_range)
__INITDATA
- .type v4wb_tlb_fns, #object
-ENTRY(v4wb_tlb_fns)
- .long v4wb_flush_user_tlb_range
- .long v4wb_flush_kern_tlb_range
- .long v4wb_tlb_flags
- .size v4wb_tlb_fns, . - v4wb_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4wb, v4wb_tlb_flags
diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S
index 60cfc4a..1f6062b 100644
--- a/arch/arm/mm/tlb-v4wbi.S
+++ b/arch/arm/mm/tlb-v4wbi.S
@@ -60,9 +60,5 @@ ENTRY(v4wbi_flush_kern_tlb_range)
__INITDATA
- .type v4wbi_tlb_fns, #object
-ENTRY(v4wbi_tlb_fns)
- .long v4wbi_flush_user_tlb_range
- .long v4wbi_flush_kern_tlb_range
- .long v4wbi_tlb_flags
- .size v4wbi_tlb_fns, . - v4wbi_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v4wbi, v4wbi_tlb_flags
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
index 73d7d89..a685944 100644
--- a/arch/arm/mm/tlb-v6.S
+++ b/arch/arm/mm/tlb-v6.S
@@ -90,9 +90,5 @@ ENTRY(v6wbi_flush_kern_tlb_range)
__INIT
- .type v6wbi_tlb_fns, #object
-ENTRY(v6wbi_tlb_fns)
- .long v6wbi_flush_user_tlb_range
- .long v6wbi_flush_kern_tlb_range
- .long v6wbi_tlb_flags
- .size v6wbi_tlb_fns, . - v6wbi_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v6wbi, v6wbi_tlb_flags
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index 53cd5b4..ebd4290 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -85,10 +85,5 @@ ENDPROC(v7wbi_flush_kern_tlb_range)
__INIT
- .type v7wbi_tlb_fns, #object
-ENTRY(v7wbi_tlb_fns)
- .long v7wbi_flush_user_tlb_range
- .long v7wbi_flush_kern_tlb_range
- ALT_SMP(.long v7wbi_tlb_flags_smp)
- ALT_UP(.long v7wbi_tlb_flags_up)
- .size v7wbi_tlb_fns, . - v7wbi_tlb_fns
+ /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */
+ define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp
diff --git a/arch/arm/mvp/Kconfig b/arch/arm/mvp/Kconfig
new file mode 100644
index 0000000..4f2c5c7
--- /dev/null
+++ b/arch/arm/mvp/Kconfig
@@ -0,0 +1,24 @@
+config VMWARE_MVP
+ bool "Build VMware Mobile Virtualization Platform modules"
+ select MODULES
+ select MODULE_UNLOAD
+ select SYSFS
+ select NAMESPACES
+ select NET_NS
+ select INET
+ select IPV6
+ select TUN
+ select NETFILTER
+ help
+ Say Y here to enable the building of kernel modules
+ for VMware's Mobile Virtualization Platform
+
+config VMWARE_MVP_DEBUG
+ bool "Enable debug for VMware Mobile Virtualization Platform modules"
+ depends on VMWARE_MVP
+ select IKCONFIG
+ select IKCONFIG_PROC
+ help
+ Say Y here to enable debug on kernel modules
+ for VMware's Mobile Virtualization Platform.
+ This should be enabled for eng or userdebug builds.
diff --git a/arch/arm/mvp/Makefile b/arch/arm/mvp/Makefile
new file mode 100644
index 0000000..cd38d75
--- /dev/null
+++ b/arch/arm/mvp/Makefile
@@ -0,0 +1,3 @@
+obj-y += mvpkm/
+obj-y += commkm/
+obj-y += pvtcpkm/
diff --git a/arch/arm/mvp/commkm/COPYING b/arch/arm/mvp/commkm/COPYING
new file mode 100644
index 0000000..10828e0
--- /dev/null
+++ b/arch/arm/mvp/commkm/COPYING
@@ -0,0 +1,341 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/arch/arm/mvp/commkm/Kbuild b/arch/arm/mvp/commkm/Kbuild
new file mode 100644
index 0000000..de43a5c
--- /dev/null
+++ b/arch/arm/mvp/commkm/Kbuild
@@ -0,0 +1,9 @@
+# Warning: autogenerated
+obj-m := commkm.o
+commkm-objs := check_kconfig.o comm_ev_kernel.o comm.o comm_os_linux.o comm_os_mod_linux.o comm_svc.o comm_transp_mvp.o
+
+ccflags-y += -fno-pic -fno-dwarf2-cfi-asm -march=armv7-a -D__linux__
+ccflags-y += -DCOMM_BUILDING_SERVER
+ccflags-y += -mfpu=neon -DIN_MODULE -DGPLED_CODE
+ccflags-y += --std=gnu89 -O2 -g2 -ggdb -mapcs -fno-optimize-sibling-calls -mno-sched-prolog
+ccflags-$(CONFIG_VMWARE_MVP_DEBUG) += -DMVP_DEBUG
diff --git a/arch/arm/mvp/commkm/Makefile b/arch/arm/mvp/commkm/Makefile
new file mode 100644
index 0000000..16eb389
--- /dev/null
+++ b/arch/arm/mvp/commkm/Makefile
@@ -0,0 +1 @@
+# Warning: autogenerated
diff --git a/arch/arm/mvp/commkm/check_kconfig.c b/arch/arm/mvp/commkm/check_kconfig.c
new file mode 100644
index 0000000..0867d74
--- /dev/null
+++ b/arch/arm/mvp/commkm/check_kconfig.c
@@ -0,0 +1,91 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ * @brief Check for required kernel configuration
+ *
+ * Check to make sure that the kernel options that the MVP hypervisor requires
+ * have been enabled in the kernel that this kernel module is being built
+ * against.
+ */
+#include <linux/version.h>
+
+/*
+ * Minimum kernel version
+ * - network namespace support is only really functional starting in 2.6.29
+ * - Android Gingerbread requires 2.6.35
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+#error "MVP requires a host kernel newer than 2.6.35"
+#endif
+
+/* module loading ability */
+#ifndef CONFIG_MODULES
+#error "MVP requires kernel loadable module support be enabled (CONFIG_MODULES)"
+#endif
+#ifndef CONFIG_MODULE_UNLOAD
+#error "MVP requires kernel module unload support be enabled (CONFIG_MODULE_UNLOAD)"
+#endif
+
+/* sysfs */
+#ifndef CONFIG_SYSFS
+#error "MVP requires sysfs support (CONFIG_SYSFS)"
+#endif
+
+/* network traffic isolation */
+#ifndef CONFIG_NAMESPACES
+#error "MVP networking support requires namespace support (CONFIG_NAMESPACES)"
+#endif
+#ifndef CONFIG_NET_NS
+#error "MVP networking support requires Network Namespace support to be enabled (CONFIG_NET_NS)"
+#endif
+
+/* TCP/IP networking */
+#ifndef CONFIG_INET
+#error "MVP networking requires IPv4 support (CONFIG_INET)"
+#endif
+#ifndef CONFIG_IPV6
+#error "MVP networking requires IPv6 support (CONFIG_IPV6)"
+#endif
+
+/* VPN support */
+#if !defined(CONFIG_TUN) && !defined(CONFIG_TUN_MODULE)
+#error "MVP VPN support requires TUN device support (CONFIG_TUN)"
+#endif
+
+#if !defined(CONFIG_NETFILTER) && !defined(PVTCP_DISABLE_NETFILTER)
+#error "MVP networking support requires netfilter support (CONFIG_NETFILTER)"
+#endif
+
+/* Force /proc/config.gz support for eng/userdebug builds */
+#ifdef MVP_DEBUG
+#if !defined(CONFIG_IKCONFIG) || !defined(CONFIG_IKCONFIG_PROC)
+#error "MVP kernel /proc/config.gz support required for debuggability (CONFIG_IKCONFIG_PROC)"
+#endif
+#endif
+
+/* Sanity check we're only dealing with the memory hotplug + migrate and/or
+ * compaction combo */
+#ifdef CONFIG_MIGRATION
+#if defined(CONFIG_NUMA) || defined(CONFIG_CPUSETS) || defined(CONFIG_MEMORY_FAILURE)
+#error "MVP not tested with migration features other than CONFIG_MEMORY_HOTPLUG and CONFIG_COMPACTION"
+#endif
+#endif
diff --git a/arch/arm/mvp/commkm/comm.c b/arch/arm/mvp/commkm/comm.c
new file mode 100644
index 0000000..8fd591c
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm.c
@@ -0,0 +1,1457 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Communication functions based on transport functionality.
+ */
+
+#include "comm.h"
+#include "comm_transp_impl.h"
+
+
+/* Constant and macro definitions */
+
+#if defined(COMM_INSTRUMENT)
+static CommOSAtomic commMaxCoalesceSize;
+static CommOSAtomic commPacketsReceived;
+static CommOSAtomic commCommittedPacketsReceived;
+static CommOSAtomic commOpCalls;
+#endif
+
+#define COMM_DISPATCH_EXTRA_WRITER_WAKEUP 1
+
+#define COMM_CHANNEL_MAX_CAPACITY 2048
+#define COMM_CHANNEL_FREE 0x0
+#define COMM_CHANNEL_INITIALIZED 0x1
+#define COMM_CHANNEL_OPENED 0x2
+#define COMM_CHANNEL_ACTIVE 0x4
+#define COMM_CHANNEL_ZOMBIE 0x8
+
+#define CommIsFree(chan) \
+ ((chan)->lifecycleState == COMM_CHANNEL_FREE)
+#define CommIsInitialized(chan) \
+ ((chan)->lifecycleState == COMM_CHANNEL_INITIALIZED)
+#define CommIsOpened(chan) \
+ ((chan)->lifecycleState == COMM_CHANNEL_OPENED)
+#define CommIsActive(chan) \
+ ((chan)->lifecycleState == COMM_CHANNEL_ACTIVE)
+#define CommIsZombie(chan) \
+ ((chan)->lifecycleState == COMM_CHANNEL_ZOMBIE)
+
+#define CommSetFree(chan) \
+ SetLifecycleState(chan, COMM_CHANNEL_FREE)
+#define CommSetInitialized(chan) \
+ SetLifecycleState(chan, COMM_CHANNEL_INITIALIZED)
+#define CommSetOpened(chan) \
+ SetLifecycleState(chan, COMM_CHANNEL_OPENED)
+#define CommSetActive(chan) \
+ SetLifecycleState(chan, COMM_CHANNEL_ACTIVE)
+#define CommSetZombie(chan) \
+ SetLifecycleState(chan, COMM_CHANNEL_ZOMBIE)
+
+#define CommGlobalLock() CommOS_SpinLock(&commGlobalLock)
+#define CommGlobalUnlock() CommOS_SpinUnlock(&commGlobalLock)
+#define CommGlobalLockBH() CommOS_SpinLockBH(&commGlobalLock)
+#define CommGlobalUnlockBH() CommOS_SpinUnlockBH(&commGlobalLock)
+
+#define DispatchTrylock(chan) CommOS_MutexTrylock(&(chan)->dispatchMutex)
+#define DispatchUnlock(chan) CommOS_MutexUnlock(&(chan)->dispatchMutex)
+
+#define WriteLock(chan) CommOS_MutexLock(&(chan)->writeMutex)
+#define WriteTrylock(chan) CommOS_MutexTrylock(&(chan)->writeMutex)
+#define WriteUnlock(chan) CommOS_MutexUnlock(&(chan)->writeMutex)
+
+#define StateLock(chan) CommOS_MutexLock(&(chan)->stateMutex)
+#define StateTrylock(chan) CommOS_MutexTrylock(&(chan)->stateMutex)
+#define StateUnlock(chan) CommOS_MutexUnlock(&(chan)->stateMutex)
+
+#define CommHoldInit(chan) CommOS_WriteAtomic(&(chan)->holds, 0)
+#define CommHold(chan) CommOS_AddReturnAtomic(&(chan)->holds, 1)
+#define CommRelease(chan) CommOS_SubReturnAtomic(&(chan)->holds, 1)
+#define CommIsHeld(chan) (CommOS_ReadAtomic(&(chan)->holds) > 0)
+
+#define PacketLenOverLimit(chan, len) \
+ (((len) - sizeof (CommPacket)) > ((chan)->transpArgs.capacity / 4))
+
+
+/*
+ * Data structure describing the offload <-> paravirtualized module
+ * communication channel.
+ */
+
+struct CommChannelPriv {
+ CommOSAtomic holds; // Active readers and writers
+ CommTranspInitArgs transpArgs; // Transport initialization arguments
+ CommTransp transp; // Transport handle
+ CommOSMutex dispatchMutex; // Dispatch mutex
+ CommOSMutex writeMutex; // Non-BH write mutex
+ CommOSMutex stateMutex; // Upper-layer state mutex
+ CommOSWaitQueue availableWaitQ; // Available write space wait data
+ unsigned int desiredWriteSpace; // Size of write space needed
+ const CommImpl *impl; // Implementation
+ unsigned int implNmbOps; // Number of implementation operations
+ unsigned int lifecycleState; // Lifecycle state
+ void *state; // Upper layer-specific state
+};
+
+
+static volatile int running; // Initialized and running.
+static CommOSWaitQueue exitWaitQ; // Exit wait queue.
+static CommOSSpinlock commGlobalLock; // Global lock.
+
+
+/* Communication channel slots. */
+
+static unsigned int commChannelCapacity; // Maximum number of channels.
+static unsigned int commChannelSize; // Current size of channel array.
+static unsigned int commChannelAllocated; // Nmb. entries currently in use.
+static struct CommChannelPriv *commChannels; // Allocated channel array.
+
+
+/**
+ * @brief Callback function called when the other side created a transport
+ * handle to which we need to potentially attach.
+ * @param[in,out] transpArgs arguments used when shared memory area was created.
+ * @param probeData our callback data, an implementation block.
+ * @return 0 if successful, -1 otherwise.
+ * @sideeffects May allocate a channel.
+ */
+
+static int
+DefaultTranspListener(CommTranspInitArgs *transpArgs,
+ void *probeData)
+{
+ int rc = -1;
+ const int inBH = 1;
+ const CommImpl *impl;
+
+ if (!transpArgs || !probeData) {
+ CommOS_Debug(("%s: NULL args [0x%p, 0x%p].\n",
+ __FUNCTION__, transpArgs, probeData));
+ goto out;
+ }
+
+ impl = probeData;
+ CommOS_Debug(("%s: Received attach info [%u,%u,%u:%u].\n",
+ __FUNCTION__,
+ transpArgs->capacity, transpArgs->type,
+ transpArgs->id.d32[0], transpArgs->id.d32[1]));
+
+ if (impl->checkArgs(transpArgs)) {
+ goto out;
+ }
+ transpArgs->mode = COMM_TRANSP_INIT_ATTACH; /* Ensure we attach. */
+
+ /* We recognized it, so don't let others waste any time. Even if we fail. */
+
+ rc = 0;
+ if (Comm_Alloc(transpArgs, impl, inBH, NULL)) {
+ impl->closeNtf(impl->closeNtfData, transpArgs, inBH);
+ CommOS_Log(("%s: Can't allocate new channel!\n", __FUNCTION__));
+ }
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Sets the lifecycle state of a channel entry
+ * @param channel channel to update
+ * @param newState state to update to
+ */
+
+static inline void
+SetLifecycleState(CommChannel channel,
+ unsigned int newState)
+{
+
+ channel->lifecycleState = newState;
+}
+
+
+/* Wait conditions: functions returning 1: true, 0: false, < 0: error. */
+
+/**
+ * @brief Wait condition function to check whether module can be unloaded.
+ * @param arg1 dummy
+ * @param arg2 dummy
+ * @return 1 if no channels are currently allocated, 0 if there are
+ */
+
+static int
+ExitCondition(void *arg1,
+ void *arg2)
+{
+ unsigned int i;
+ int rc;
+
+ (void)arg1;
+ (void)arg2;
+ CommOS_Debug(("%s: running [%d] "
+ "commChannelAllocated [%u] commChannelSize [%u].\n",
+ __FUNCTION__, running, commChannelAllocated, commChannelSize));
+ rc = !running && (commChannelAllocated == 0);
+ if (!rc) {
+ for (i = 0; i < commChannelCapacity; i++) {
+ CommOS_Debug(("%s: channel[%u] state [0x%x].\n",
+ __FUNCTION__, i, commChannels[i].lifecycleState));
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Wait condition function to check available write space.
+ * @param arg1 pointer to CommChannel struct
+ * @param arg2 size argument
+ * @return 1 if there is enough write space, 0 if not, -ENOMEM if comm down.
+ */
+
+static int
+WriteSpaceCondition(void *arg1,
+ void *arg2)
+{
+ CommChannel channel = arg1;
+
+ if (!CommIsActive(channel)) {
+ return -ENOMEM;
+ }
+ return channel->desiredWriteSpace < CommTransp_EnqueueSpace(channel->transp);
+}
+
+
+/**
+ * @brief Registers an implementation block used when attaching to channels
+ * in response to transport attach events.
+ * @param impl implementation block.
+ * @return 0 if successful, non-zero otherwise.
+ */
+
+int
+Comm_RegisterImpl(const CommImpl *impl)
+{
+ CommTranspListener listener = {
+ .probe = DefaultTranspListener,
+ .probeData = (void *)impl
+ };
+
+ return CommTransp_Register(&listener);
+}
+
+
+/**
+ * @brief Unregisters an implementation block used when attaching to channels
+ * in response to transport attach events.
+ * @param impl implementation block.
+ */
+
+void
+Comm_UnregisterImpl(const CommImpl *impl)
+{
+ CommTranspListener listener = {
+ .probe = DefaultTranspListener,
+ .probeData = (void *)impl
+ };
+
+ CommTransp_Unregister(&listener);
+}
+
+
+/**
+ * @brief Allocates and initializes comm global state. Single-threaded use.
+ * @param maxChannels maximum number of channels.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+int
+Comm_Init(unsigned int maxChannels)
+{
+ int rc = -1;
+ unsigned int i;
+
+ if (running || commChannels ||
+ (maxChannels == 0) || (maxChannels > COMM_CHANNEL_MAX_CAPACITY)) {
+ goto out;
+ }
+
+#if defined(COMM_INSTRUMENT)
+ CommOS_WriteAtomic(&commMaxCoalesceSize, 0);
+ CommOS_WriteAtomic(&commPacketsReceived, 0);
+ CommOS_WriteAtomic(&commCommittedPacketsReceived, 0);
+ CommOS_WriteAtomic(&commOpCalls, 0);
+#endif
+
+ CommOS_WaitQueueInit(&exitWaitQ);
+ CommOS_SpinlockInit(&commGlobalLock);
+ commChannelCapacity = maxChannels;
+ commChannelAllocated = 0;
+ commChannels = CommOS_Kmalloc((sizeof *commChannels) * commChannelCapacity);
+ if (!commChannels) {
+ goto out;
+ }
+
+ memset(commChannels, 0, (sizeof *commChannels) * commChannelCapacity);
+ for (i = 0; i < commChannelCapacity; i++ ) {
+ CommChannel channel;
+
+ channel = &commChannels[i];
+ CommHoldInit(channel);
+ channel->transp = NULL;
+ CommOS_MutexInit(&channel->dispatchMutex);
+ CommOS_MutexInit(&channel->writeMutex);
+ CommOS_MutexInit(&channel->stateMutex);
+ CommOS_WaitQueueInit(&channel->availableWaitQ);
+ channel->desiredWriteSpace = -1U;
+ channel->state = NULL;
+ CommSetFree(channel);
+ }
+
+ rc = CommTransp_Init();
+ if (!rc) {
+ commChannelSize = 0;
+ running = 1;
+ rc = 0;
+ } else {
+ CommOS_Kfree(commChannels);
+ }
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Initiates and finishes, comm global state deallocations.
+ * @param timeoutMillis initialization timeout in milliseconds
+ * @return zero if deallocations done, non-zero if more calls are needed.
+ */
+
+int
+Comm_Finish(unsigned long long *timeoutMillis)
+{
+ int rc;
+ unsigned int i;
+ unsigned long long timeout;
+
+ for (i = 0; i < commChannelSize; i++) {
+ Comm_Zombify(&commChannels[i], 0);
+ }
+
+ running = 0;
+ timeout = timeoutMillis ? *timeoutMillis : 0;
+ /* coverity[var_deref_model] */
+ rc = CommOS_Wait(&exitWaitQ, ExitCondition, NULL, NULL, &timeout);
+ if (rc == 1) {
+ /*
+ * Didn't time out, task wasn't interrupted, we can wrap it up..
+ */
+
+ CommTransp_Exit();
+ CommOS_Kfree(commChannels);
+ commChannels = NULL;
+ commChannelSize = 0;
+#if defined(COMM_INSTRUMENT)
+ CommOS_Log(("%s: commMaxCoalesceSize = %lu.\n",
+ __FUNCTION__,
+ CommOS_ReadAtomic(&commMaxCoalesceSize)));
+ CommOS_Log(("%s: commPacketsReceived = %lu.\n",
+ __FUNCTION__,
+ CommOS_ReadAtomic(&commPacketsReceived)));
+ CommOS_Log(("%s: commCommittedPacketsReceived = %lu.\n",
+ __FUNCTION__,
+ CommOS_ReadAtomic(&commCommittedPacketsReceived)));
+ CommOS_Log(("%s: commOpCalls = %lu.\n",
+ __FUNCTION__,
+ CommOS_ReadAtomic)(&commOpCalls)));
+#endif
+ rc = 0;
+ } else {
+ rc = -1;
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Finds a free entry and initializes it with the information provided.
+ * May be called from BH. It doesn't call potentially blocking functions.
+ *
+ * @note Depending on the choice of shared memory transport (VMCI or MVP QP),
+ * the 'inBH' distinction is important. VMCI datagrams are received under
+ * some circumstances in bottom-half context, so 'inBH' should be set. This
+ * is not a restriction on MVP.
+ *
+ * @param transpArgs transport initialization arguments.
+ * @param impl implementation block.
+ * @param inBH non-zero if called in bottom half.
+ * @param[out] newChannel newly allocated channel.
+ * @return zero if successful, non-zero otherwise.
+ * @sideeffects Initializes the communications channel with given parameters
+ */
+
+int
+Comm_Alloc(const CommTranspInitArgs *transpArgs,
+ const CommImpl *impl,
+ int inBH,
+ CommChannel *newChannel)
+{
+ unsigned int i;
+ CommChannel channel = NULL;
+ int restoreSize = 0;
+ int modHeld = 0;
+ int rc = -1;
+
+ if (inBH) {
+ CommGlobalLock();
+ } else {
+ CommGlobalLockBH();
+ }
+
+ if (!running || !transpArgs || !impl) {
+ goto out;
+ }
+
+ if (CommOS_ModuleGet(impl->owner)) {
+ goto out;
+ }
+ modHeld = 1;
+
+ for (i = 0; i < commChannelSize; i++) {
+ /*
+ * Check if this channel is already allocated. We don't match against
+ * ANY because those channels are in the process of being opened; after
+ * that happens, they'll get proper IDs.
+ */
+
+ if (!CommIsFree(&commChannels[i]) &&
+ (transpArgs->id.d64 != COMM_TRANSP_ID_64_ANY) &&
+ (transpArgs->id.d64 == commChannels[i].transpArgs.id.d64)) {
+ goto out;
+ }
+ if (!channel && CommIsFree(&commChannels[i])) {
+ channel = &commChannels[i];
+ }
+ }
+ if (!channel) {
+ if (commChannelSize == commChannelCapacity) {
+ goto out;
+ }
+ channel = &commChannels[commChannelSize];
+ commChannelSize++;
+ restoreSize = 1;
+ }
+
+ if (channel->transp) { /* Inconsistency! */
+ if (restoreSize) {
+ commChannelSize--;
+ }
+ goto out;
+ }
+
+ channel->transpArgs = *transpArgs;
+ channel->impl = impl;
+ for (i = 0; impl->operations[i]; i++) {
+ ;
+ }
+ channel->implNmbOps = i;
+ channel->desiredWriteSpace = -1U;
+ commChannelAllocated++;
+ CommSetInitialized(channel);
+ if (newChannel) {
+ *newChannel = channel;
+ }
+ rc = 0;
+ CommOS_ScheduleDisp();
+
+out:
+ if (inBH) {
+ CommGlobalUnlock();
+ } else {
+ CommGlobalUnlockBH();
+ }
+ if (rc && modHeld) {
+ CommOS_ModulePut(impl->owner);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Zombifies a channel. May fail if channel isn't active.
+ * @param[in,out] channel channel to zombify.
+ * @param inBH non-zero if called in bottom half.
+ * @return zero if channel zombified, non-zero otherwise.
+ */
+
+int
+Comm_Zombify(CommChannel channel,
+ int inBH)
+{
+ int rc = -1;
+
+ if (!running) {
+ goto out;
+ }
+ if (inBH) {
+ CommGlobalLock();
+ } else {
+ CommGlobalLockBH();
+ }
+ if (CommIsActive(channel) || CommIsOpened(channel)) {
+ CommSetZombie(channel);
+ rc = 0;
+ }
+ if (inBH) {
+ CommGlobalUnlock();
+ } else {
+ CommGlobalUnlockBH();
+ }
+
+out:
+ if (!rc) {
+ CommOS_ScheduleDisp();
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Reports whether a channel is active.
+ * @param channel channel to report on.
+ * @return non-zero if channel active, zero otherwise.
+ */
+
+int
+Comm_IsActive(CommChannel channel)
+{
+ return channel ? CommIsActive(channel) : 0;
+}
+
+
+/**
+ * @brief Wakes up potential writer on the channel. This function must be
+ * called on an active channel, with either the dispatch lock taken, or
+ * the channel ref count incremented.
+ * @param channel CommChannel structure on which potential writer waits.
+ */
+
+static inline void
+WakeUpWriter(CommChannel channel)
+{
+ if (WriteSpaceCondition(channel, NULL)) {
+ CommOS_WakeUp(&channel->availableWaitQ);
+ }
+}
+
+
+/**
+ * @brief Transport event handler for comm channels.
+ * @param transp transport handle.
+ * @param event type of event.
+ * @param data callback data.
+ * @sideeffects may put the channel into zombie state, or schedule it for I/O.
+ */
+
+static void
+TranspEventHandler(CommTransp transp,
+ CommTranspIOEvent event,
+ void *data)
+{
+ CommChannel channel = (CommChannel)data;
+
+ switch (event) {
+ case COMM_TRANSP_IO_DETACH:
+ CommOS_Debug(("%s: Detach event. Zombifying channel.\n", __FUNCTION__));
+ Comm_Zombify(channel, 1);
+ break;
+
+ case COMM_TRANSP_IO_IN:
+ case COMM_TRANSP_IO_INOUT:
+ /*
+ * The dispatch threads may not have been started because either:
+ * a) we're not running in the CommSvc service, or
+ * b) the Comm client didn't create them explicitly (CommOS_StartIO()).
+ *
+ * If so, the CommOS_ScheduleDisp() call is ineffective. This is
+ * the intended behavior: the client obviously wants to call the Comm
+ * dispatch function(s) directly.
+ */
+
+ CommOS_ScheduleDisp();
+ break;
+
+ case COMM_TRANSP_IO_OUT:
+ CommHold(channel);
+ if (CommIsActive(channel)) {
+ WakeUpWriter(channel);
+ }
+ CommRelease(channel);
+ if (CommIsZombie(channel)) {
+ /*
+ * After releasing the hold on the channel, we must check if it was
+ * set to zombie and the dispatcher was supposed to nuke it. If the
+ * dispatcher had made its run while we were holding the channel, it
+ * gave up. So schedule it.
+ */
+
+ CommOS_ScheduleDisp();
+ }
+ break;
+
+ default:
+ CommOS_Debug(("%s: Unhandled event [%u, %p, %p].\n",
+ __FUNCTION__, event, transp, data));
+ }
+}
+
+
+/**
+ * @brief Destroys upper layer state, unregisters event handlers and
+ * detaches from or deletes shared memory.
+ * @param[in,out] channel CommChannel structure to close.
+ */
+
+static void
+CommClose(CommChannel channel)
+{
+ const CommImpl *impl = channel->impl;
+
+ StateLock(channel);
+ if (impl->stateDtor && channel->state) {
+ impl->stateDtor(channel->state);
+ }
+ channel->state = NULL;
+ StateUnlock(channel);
+
+ CommOS_ModulePut(impl->owner);
+
+ if (channel->transp) {
+ CommTransp_Close(channel->transp);
+ channel->transp = NULL;
+ }
+
+ CommGlobalLockBH();
+ CommSetFree(channel);
+ commChannelAllocated--;
+ if (channel == &commChannels[commChannelSize - 1]) {
+ commChannelSize--;
+ }
+ CommGlobalUnlockBH();
+ if (!running && (commChannelAllocated == 0)) {
+ CommOS_WakeUp(&exitWaitQ);
+ }
+}
+
+
+/**
+ * @brief Allocates upper layer state, registers transport event handler
+ * and creates or attaches to shared memory.
+ * @param[in,out] channel CommChannel structure to open.
+ * @return zero if successful, -1 otherwise
+ * @sideeffects Memory may be allocated, event handlers registered and
+ * QP allocated or attached to.
+ */
+
+static int
+CommOpen(CommChannel channel)
+{
+ int rc = -1;
+ CommTranspEvent transpEvent = {
+ .ioEvent = TranspEventHandler,
+ .ioEventData = channel
+ };
+ const CommImpl *impl;
+
+ if (!channel || !CommIsInitialized(channel)) {
+ return rc;
+ }
+
+ if (!running) { /* Ok, toggle it back to FREE. */
+ goto out;
+ }
+
+ impl = channel->impl;
+ if (impl->stateCtor) {
+ channel->state = impl->stateCtor(channel);
+ if (!channel->state) {
+ goto out;
+ }
+ }
+
+ if (!CommTransp_Open(&channel->transp, &channel->transpArgs, &transpEvent)) {
+ rc = 0;
+ } else {
+ channel->transp = NULL;
+ }
+
+out:
+ if (!rc) {
+ CommSetOpened(channel);
+ } else {
+ CommClose(channel);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Retrieves a channel's transport initialization arguments.
+ * It doesn't lock, the caller must ensure the channel may be accessed.
+ * @param channel CommChannel structure to get initialization arguments from.
+ * @return initialization arguments used to allocate/attach to channel.
+ */
+
+CommTranspInitArgs
+Comm_GetTranspInitArgs(CommChannel channel)
+{
+ if (!channel) {
+ CommTranspInitArgs res = { .capacity = 0 };
+
+ return res;
+ }
+ return channel->transpArgs;
+}
+
+
+/**
+ * @brief Retrieves upper layer state (pointer). It doesn't lock, the caller
+ * must ensure the channel may be accessed.
+ * @param channel CommChannel structure to get state from.
+ * @return pointer to upper layer state.
+ */
+
+void *
+Comm_GetState(CommChannel channel)
+{
+ if (!channel) {
+ return NULL;
+ }
+ return channel->state;
+}
+
+
+/**
+ * @brief Main input processing function operating on a given channel.
+ * @param channel CommChannel structure to process.
+ * @return number of processed channels (0 or 1), or -1 if channel closed.
+ * @sideeffects Lifecycle states are transitioned to and from. Channel may
+ * be opened or destroyed, waiting writers may be woken up, and input
+ * may be handed off to operation callbacks.
+ */
+
+int
+Comm_Dispatch(CommChannel channel)
+{
+ int rc = 0;
+ int zombify = 0;
+ CommPacket packet;
+ CommPacket firstPacket;
+ unsigned int dataLen;
+#define VEC_SIZE 32
+ struct kvec vec[VEC_SIZE];
+ unsigned int vecLen;
+
+ /*
+ * Taking the reader mutex is safe in all cases: entries, including
+ * free ones, are guaranteed to have initialized mutexes and locks.
+ * Locking empty entries may seem wasteful, but those entries are rare.
+ */
+
+ if (DispatchTrylock(channel)) {
+ return 0;
+ }
+
+ /* Process input and writer wake-up. */
+
+ if (CommIsActive(channel)) {
+ /*
+ * The entry may have transitioned to ZOMBIE, somehow. That's OK
+ * since it can't be freed just yet (it's currently locked).
+ */
+
+ /* Wake up any waiting writers, if necessary. */
+
+ WakeUpWriter(channel);
+
+ /* Read packets, payloads. */
+ CommTransp_DequeueReset(channel->transp);
+
+ for (vecLen = 0; vecLen < VEC_SIZE; vecLen++) {
+ if (!running) {
+ break;
+ }
+
+ /* Read header. */
+
+ rc = CommTransp_DequeueSegment(channel->transp,
+ &packet, sizeof packet);
+ if (rc <= 0) {
+ /* No packet (header). */
+
+ rc = vecLen == 0 ? 0 : 1;
+ break;
+ }
+#if defined(COMM_INSTRUMENT)
+ CommOS_AddReturnAtomic(commPacketsReceived, 1);
+#endif
+ if ((rc != sizeof packet) || (packet.len < sizeof packet)) {
+ rc = -1; /* Fatal protocol error, close down comm. */
+ break;
+ }
+ rc = 1;
+
+ /* Read payload, if any. */
+
+ dataLen = packet.len - sizeof packet;
+ if (vecLen == 0) {
+ /* Save header of first packet. */
+
+ firstPacket = packet;
+ if (dataLen == 0) {
+ /* Commit no-payload packet read and we're done. */
+
+ CommTransp_DequeueCommit(channel->transp);
+#if defined(COMM_INSTRUMENT)
+ CommOS_AddReturnAtomic(&commCommittedPacketsReceived, 1);
+#endif
+ break;
+ }
+ } else {
+ /*
+ * Check if non-equivalent packet or above coalescing limit.
+ * If so, don't commit the read.
+ */
+
+ if (memcmp(&packet.opCode, &firstPacket.opCode,
+ sizeof packet - offsetof(CommPacket, opCode)) ||
+ PacketLenOverLimit(channel, firstPacket.len + dataLen)) {
+ break;
+ }
+ }
+
+ if (dataLen == 0) {
+ /*
+ * Received equivalent packet with zero-sized payload. This may
+ * happen in certain cases, such as pvtcp forwarding zero-sized
+ * datagrams. So don't break the loop, but keep going for as
+ * along as we can.
+ */
+
+ vec[vecLen].iov_base = NULL;
+ goto dequeueCommit;
+ }
+
+ /* The packet has a payload (dataLen > 0). */
+
+ if (!(vec[vecLen].iov_base = channel->impl->dataAlloc(dataLen))) {
+ /*
+ * We treat out-of-(net?-)memory errors as "nothing to read".
+ * Memory pressure may either subside, in which case a future
+ * read may be successful, or be severe enough for the kernel
+ * to oops, anyway. Leave packet uncommitted.
+ */
+
+ CommOS_Debug(("%s: COULD NOT ALLOC PAYLOAD BYTES!\n",
+ __FUNCTION__));
+ rc = vecLen == 0 ? 0 : 1;
+ break;
+ }
+
+ /* Read payload and commit (packet and payload). */
+
+ rc = CommTransp_DequeueSegment(channel->transp,
+ vec[vecLen].iov_base, dataLen);
+ if (rc != dataLen) {
+ channel->impl->dataFree(vec[vecLen].iov_base);
+ CommOS_Log(("%s: BOOG -- COULD NOT DEQUEUE PAYLOAD! [%d != %u]",
+ __FUNCTION__, rc, dataLen));
+ rc = -1; /* Fatal protocol error, close down comm. */
+ break;
+ }
+ rc = 1;
+
+dequeueCommit:
+ CommTransp_DequeueCommit(channel->transp);
+#if defined(COMM_INSTRUMENT)
+ CommOS_AddReturnAtomic(&commCommittedPacketsReceived, 1);
+#endif
+ vec[vecLen].iov_len = dataLen;
+ if (vecLen > 0) {
+ firstPacket.len += dataLen;
+ if (packet.flags) {
+ /* Update to latest flags _iff_ latter non-zero. */
+
+ firstPacket.flags = packet.flags;
+ }
+ }
+#if defined(COMM_INSTRUMENT)
+ if (firstPacket.len >
+ CommOS_ReadAtomic(&commMaxCoalesceSize)) {
+ CommOS_WriteAtomic(&commMaxCoalesceSize, firstPacket.len);
+ }
+#endif
+ if (COMM_OPF_TEST_ERR(packet.flags)) {
+ /* If error bit is set, we're done (no more coalescing). */
+
+ vecLen++;
+ break;
+ }
+ }
+
+ if (rc <= 0) {
+ if (rc < 0) {
+ zombify = 1;
+ rc = 1;
+ }
+ goto outUnlockAndFreeIovec;
+ }
+
+#if defined(COMM_DISPATCH_EXTRA_WRITER_WAKEUP)
+ /* Check again if we need to wake up any writers. */
+
+ WakeUpWriter(channel);
+#endif
+
+ if (firstPacket.opCode >= channel->implNmbOps) {
+ CommOS_Debug(("%s: Ignoring illegal opCode [%u]!\n",
+ __FUNCTION__, (unsigned int)firstPacket.opCode));
+ CommOS_Debug(("%s: Max opCode: %u\n",
+ __FUNCTION__, channel->implNmbOps));
+ goto outUnlockAndFreeIovec;
+ }
+
+ /*
+ * NOTE:
+ * DispatchUnlock() _must_ be called from the operation callback.
+ * The reason for doing so is that, for better scalability, we want
+ * it released as soon as possible, BUT:
+ * - releasing it here, before calling into the operation, doesn't
+ * let the latter coordinate its own lock acquisition, such as
+ * potential socket or state locks.
+ * - alternatively, always releasing the dispatch lock after the
+ * operation completes, ties up the channel and imposes too much
+ * serialization between sockets.
+ * - to prevent the channel from being torn down while an operation
+ * is in flight (and potentially having released the dispatch lock),
+ * we increment the ref count on the channel and then release it
+ * after the function returns.
+ */
+
+#if defined(COMM_INSTRUMENT)
+ CommOS_AddReturnAtomic(&commOpCalls, 1);
+#endif
+
+ CommHold(channel);
+ channel->impl->operations[firstPacket.opCode](channel, channel->state,
+ &firstPacket, vec, vecLen);
+ CommRelease(channel);
+ goto out; /* No unlocking, see comment above. */
+ }
+
+ /* Process state changes. */
+
+ if (CommIsZombie(channel) && !CommIsHeld(channel)) {
+ CommTranspInitArgs transpArgs = channel->transpArgs;
+ void (*closeNtf)(void *,
+ const CommTranspInitArgs *,
+ int inBH) = channel->impl->closeNtf;
+ void *closeNtfData = channel->impl->closeNtfData;
+
+ while (WriteTrylock(channel)) {
+ /* Take the write lock; kick writers out if necessary. */
+
+ CommOS_Debug(("%s: Kicking writers out...\n", __FUNCTION__));
+ CommOS_WakeUp(&channel->availableWaitQ);
+ }
+ WriteUnlock(channel);
+
+ CommOS_Debug(("%s: Nuking zombie channel.\n", __FUNCTION__));
+ CommClose(channel);
+ if (closeNtf) {
+ closeNtf(closeNtfData, &transpArgs, 0);
+ }
+ rc = -1;
+ } else if (CommIsInitialized(channel) &&
+ (channel->impl->openAtMillis <=
+ CommOS_GetCurrentMillis())) {
+ if (!CommOpen(channel)) {
+ if (channel->transpArgs.mode == COMM_TRANSP_INIT_CREATE) {
+ /*
+ * If the attach side doesn't get notified, the entry will
+ * time out in OPENED and will be collected.
+ * Note that during the CommOpen(Transp_Open) call, the IDs
+ * in the transpArgs may have changed. Use those.
+ */
+
+ CommTransp_Notify(&channel->impl->ntfCenterID,
+ &channel->transpArgs);
+ } else { /* Attach mode */
+ packet.len = sizeof packet;
+ packet.opCode = 0xff;
+ packet.flags = 0x00;
+
+ /*
+ * Send out control packet, attach ack, and transition straight
+ * to ACTIVE.
+ */
+
+ rc = CommTransp_EnqueueAtomic(channel->transp,
+ &packet, sizeof packet);
+ if (rc == sizeof packet) {
+ /* Guard against potentially concurrent zombify. */
+
+ CommGlobalLockBH();
+ if (CommIsOpened(channel)) {
+ CommOS_Debug(("%s: Sent attach ack. Activating channel.\n",
+ __FUNCTION__));
+ CommSetActive(channel);
+ }
+ CommGlobalUnlockBH();
+ }
+ }
+ rc = 1;
+ }
+ } else if (CommIsOpened(channel) &&
+ (channel->transpArgs.mode == COMM_TRANSP_INIT_CREATE)) {
+ /*
+ * Get control packet (opCode == 0xff), attach ack (flags == 0x0),
+ * or check whether the channel timed out in OPENED.
+ */
+
+ rc = CommTransp_DequeueAtomic(channel->transp,
+ &packet, sizeof packet);
+ if (rc == sizeof packet) {
+ void (*activateNtf)(void *activateNtfData, CommChannel) = NULL;
+ void *activateNtfData = NULL;
+
+ /* Guard against potentially concurrent zombify. */
+
+ CommGlobalLockBH();
+ if (CommIsOpened(channel) &&
+ (packet.opCode == 0xff) && (packet.flags == 0x0)) {
+ activateNtf = channel->impl->activateNtf;
+ activateNtfData = channel->impl->activateNtfData;
+
+ CommSetActive(channel);
+ CommOS_Debug(("%s: Received attach ack. Activating channel.\n",
+ __FUNCTION__));
+ }
+ CommHold(channel);
+ CommGlobalUnlockBH();
+
+ if (activateNtf) {
+ /* The callback must be short and 'put' the channel when done. */
+
+ activateNtf(activateNtfData, channel);
+ } else {
+ /* Don't forget to put back the channel if no activate callback. */
+
+ CommRelease(channel);
+ }
+ } else if ((channel->impl->openTimeoutAtMillis <=
+ CommOS_GetCurrentMillis()) ||
+ !running) {
+ zombify = 1;
+ CommOS_Debug(("%s: Zombifying expired opened channel.\n",
+ __FUNCTION__));
+ }
+ rc = 1;
+ }
+ DispatchUnlock(channel);
+
+out:
+ if (zombify) {
+ Comm_Zombify(channel, 0);
+ }
+ return rc;
+
+outUnlockAndFreeIovec:
+ DispatchUnlock(channel);
+ for ( ; vecLen; ) {
+ if (vec[--vecLen].iov_base) {
+ channel->impl->dataFree(vec[vecLen].iov_base);
+ vec[vecLen].iov_base = NULL;
+ }
+ vec[vecLen].iov_len = 0;
+ }
+ goto out;
+#undef VEC_SIZE
+}
+
+
+/**
+ * @brief Main input processing function operating on all channels.
+ * @return number of processed channels.
+ * @sideeffects Lifecycle states are transitioned to and from. Channels may
+ * be opened and destroyed, waiting writers may be woken up, and input
+ * may be handed off to operation callbacks.
+ */
+
+unsigned int
+Comm_DispatchAll(void)
+{
+ unsigned int i;
+ unsigned int hits;
+
+ for (hits = 0, i = 0; running && (i < commChannelSize); i++) {
+ hits += !!Comm_Dispatch(&commChannels[i]);
+ }
+ return hits;
+}
+
+
+/**
+ * @brief Writes a fully formatted packet (containing payload data, if
+ * applicable) to the specified channel.
+ *
+ * The operation may block until enough write space is available, but no
+ * more than the specified interval. The operation either writes the full
+ * amount of bytes, or it fails. Warning: callers must _not_ use the
+ * _Lock/_Unlock functions to bracket calls to this function.
+ * @param[in,out] channel channel to write to.
+ * @param packet packet to write.
+ * @param[in,out] timeoutMillis interval in milliseconds to wait.
+ * @return number of bytes written, 0 if it times out, -1 error.
+ * @sideeffects Data may be written to the channel.
+ */
+
+int
+Comm_Write(CommChannel channel,
+ const CommPacket *packet,
+ unsigned long long *timeoutMillis)
+{
+ int rc = -1;
+ int zombify;
+
+ if (!channel || !timeoutMillis ||
+ !packet || (packet->len < sizeof *packet)) {
+ return rc;
+ }
+
+ zombify = (*timeoutMillis >= COMM_MAX_TO);
+
+ WriteLock(channel);
+ if (!CommIsActive(channel)) {
+ goto out;
+ }
+
+ CommTransp_EnqueueReset(channel->transp);
+ channel->desiredWriteSpace = packet->len;
+ rc = CommOS_DoWait(&channel->availableWaitQ, WriteSpaceCondition,
+ channel, NULL, timeoutMillis,
+ (*timeoutMillis != COMM_MAX_TO_UNINT));
+ channel->desiredWriteSpace = -1U;
+
+ if (rc) { /* Don't zombify, if it didn't time out. */
+ zombify = 0;
+ }
+ if (rc == 1) { /* Enough write space, enqueue the packet. */
+ rc = CommTransp_EnqueueAtomic(channel->transp, packet, packet->len);
+ if (rc != packet->len) {
+ zombify = 1;
+ rc = -1; /* Fatal protocol error. */
+ }
+ }
+
+out:
+ WriteUnlock(channel);
+ if (zombify) {
+ Comm_Zombify(channel, 0);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Writes a packet and associated payload data to the specified channel.
+ * The operation may block until enough write space is available, but
+ * not more than the specified interval.
+ * The operation either writes the full amount of bytes, or it fails.
+ * If there is not enough data in the vector, padding will be added to
+ * reach the specified packet length, if the flags parameter requires it.
+ * Users may call this function successively to write several packets
+ * from large {io|k}vecs, when the flags parameter indicates it. If this
+ * is the case, the packet header needs to be updated accordingly in
+ * between calls, for the different (total) lengths.
+ * Warning: callers must _not_ use the _Lock/_Unlock functions to bracket
+ * calls to this function.
+ * @param[in,out] channel the specified channel.
+ * @param packet packet to write.
+ * @param[in,out] vec kvec to write from.
+ * @param[in,out] vecLen length of kvec.
+ * @param[in,out] timeoutMillis interval in milliseconds to wait.
+ * @param[in,out] iovOffset must be set to 0 before first call (internal cookie)
+ * @return number of bytes written, 0 if it timed out, -1 error.
+ * @sideeffects data may be written to the channel.
+ */
+
+int
+Comm_WriteVec(CommChannel channel,
+ const CommPacket *packet,
+ struct kvec **vec,
+ unsigned int *vecLen,
+ unsigned long long *timeoutMillis,
+ unsigned int *iovOffset)
+{
+ int rc;
+ int zombify;
+ unsigned int dataLen;
+ unsigned int vecDataLen;
+ unsigned int vecNdx;
+ unsigned int iovLen;
+ void *iovBase;
+
+ if (!channel || !timeoutMillis || !iovOffset ||
+ !packet || (packet->len < sizeof *packet) ||
+ (((dataLen = packet->len - sizeof *packet) > 0) &&
+ (!*vec || !*vecLen))) {
+ return -1;
+ }
+
+ zombify = (*timeoutMillis >= COMM_MAX_TO);
+
+ WriteLock(channel);
+ if (!CommIsActive(channel)) {
+ rc = -1;
+ goto out;
+ }
+
+ CommTransp_EnqueueReset(channel->transp);
+ channel->desiredWriteSpace = packet->len;
+ rc = CommOS_DoWait(&channel->availableWaitQ, WriteSpaceCondition,
+ channel, NULL, timeoutMillis,
+ (*timeoutMillis != COMM_MAX_TO_UNINT));
+ channel->desiredWriteSpace = -1U;
+
+ if (rc) { /* Don't zombify, if it didn't time out. */
+ zombify = 0;
+ }
+ if (rc == 1) { /* Enough write space, enqueue the packet. */
+ iovLen = 0;
+ rc = CommTransp_EnqueueSegment(channel->transp, packet, sizeof *packet);
+ if (rc != sizeof *packet) {
+ zombify = 1;
+ rc = -1; /* Fatal protocol error. */
+ goto out;
+ }
+
+ if (dataLen > 0) {
+ int done = 0;
+
+ for (vecDataLen = 0, vecNdx = 0; vecNdx < *vecLen; vecNdx++) {
+ if (vecNdx) {
+ *iovOffset = 0;
+ }
+ iovLen = (*vec)[vecNdx].iov_len - *iovOffset;
+ iovBase = (*vec)[vecNdx].iov_base + *iovOffset;
+
+ if (!iovLen) {
+ continue;
+ }
+
+ vecDataLen += iovLen;
+ if (vecDataLen >= dataLen) {
+ iovLen -= (vecDataLen - dataLen);
+ done = 1;
+ }
+
+ rc = CommTransp_EnqueueSegment(channel->transp, iovBase, iovLen);
+ if (rc != iovLen) {
+ zombify = 1;
+ rc = -1; /* Fatal protocol error, close down comm. */
+ goto out;
+ }
+
+ if (done) {
+ CommTransp_EnqueueCommit(channel->transp);
+ if (vecDataLen == dataLen) {
+ vecNdx++;
+ *iovOffset = 0;
+ } else {
+ *iovOffset += iovLen;
+ }
+ *vecLen -= vecNdx;
+ *vec += vecNdx;
+ break;
+ }
+ }
+
+ if (!done) {
+ /*
+ * We exhausted all the bytes in the given vector, but total length
+ * in the packet header is more than we sent (was available).
+ * If so, we pad by sending zero bytes to reach length required.
+ */
+
+ static char pad[1024];
+ unsigned int delta;
+ unsigned int toSend;
+
+ while (vecDataLen < dataLen) {
+ delta = dataLen - vecDataLen;
+ toSend = delta <= sizeof pad ? delta : sizeof pad;
+ if (toSend == delta) {
+ done = 1;
+ }
+ vecDataLen += toSend;
+
+ rc = CommTransp_EnqueueSegment(channel->transp, pad, toSend);
+ if (rc != toSend) {
+ zombify = 1;
+ rc = -1; /* Fatal protocol error, close down comm. */
+ goto out;
+ }
+
+ if (done) {
+ CommTransp_EnqueueCommit(channel->transp);
+ *vec = NULL;
+ *vecLen = 0;
+ *iovOffset = 0;
+ break;
+ }
+ }
+ }
+ } else {
+ CommTransp_EnqueueCommit(channel->transp);
+ }
+ rc = (int)packet->len;
+ } else {
+ CommOS_Debug(("%s: timed out...\n", __FUNCTION__));
+ }
+
+out:
+ WriteUnlock(channel);
+ if (zombify) {
+ Comm_Zombify(channel, 0);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Releases channel ref count. This function is exported for the upper
+ * layer's 'activateNtf' callback which may be run asynchronously. The
+ * callback is protected from concurrent channel releases until it calls
+ * this function.
+ * @param[in,out] channel CommChannel structure to release.
+ */
+
+void
+Comm_Put(CommChannel channel)
+{
+ if (channel) {
+ CommRelease(channel);
+ }
+}
+
+
+/**
+ * @brief Uses the read lock. This function is exported for the upper layer
+ * such that it can order acquisition of a different lock (socket) with
+ * the release of the dispatch lock.
+ * @param[in,out] channel CommChannel structure to unlock.
+ */
+
+void
+Comm_DispatchUnlock(CommChannel channel)
+{
+ if (channel) {
+ DispatchUnlock(channel);
+ }
+}
+
+
+/**
+ * @brief Lock the channel for upper layer state.
+ * This function is exported for the upper layer to ensure that channel
+ * isn't closed while updating the layer state. Operations using this
+ * function are expected to be short, since unlike the _Write functions,
+ * these callers cannot be signaled.
+ * @param[in,out] channel CommChannel structure to lock.
+ * @return zero if successful, -1 otherwise.
+ */
+
+int
+Comm_Lock(CommChannel channel)
+{
+ if (!channel) {
+ return -1;
+ }
+ StateLock(channel);
+ if (!CommIsActive(channel) && !CommIsZombie(channel)) {
+ StateUnlock(channel);
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Uses the writer lock. This function is exported for the upper layer
+ * to ensure that channel isn't closed while updating the layer state.
+ * See Comm_Lock for details).
+ * @param[in,out] channel CommChannel structure to unlock.
+ */
+
+void
+Comm_Unlock(CommChannel channel)
+{
+ if (channel) {
+ StateUnlock(channel);
+ }
+}
+
+
+/**
+ * @brief Requests events be posted in-line after the function completes.
+ * @param channel channel object.
+ * @return current number of requests for inline event posting, or -1 on error.
+ */
+
+unsigned int
+Comm_RequestInlineEvents(CommChannel channel)
+{
+ if (channel->transp) {
+ return CommTransp_RequestInlineEvents(channel->transp);
+ } else {
+ return (unsigned int)-1;
+ }
+}
+
+
+/**
+ * @brief Requests events be posted out-of-band after the function completes.
+ * @param channel channel object.
+ * @return current number of requests for inline event posting, or -1 on error.
+ */
+
+unsigned int
+Comm_ReleaseInlineEvents(CommChannel channel)
+{
+ if (channel->transp) {
+ return CommTransp_ReleaseInlineEvents(channel->transp);
+ } else {
+ return (unsigned int)-1;
+ }
+}
diff --git a/arch/arm/mvp/commkm/comm.h b/arch/arm/mvp/commkm/comm.h
new file mode 100644
index 0000000..8291ae4
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm.h
@@ -0,0 +1,171 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Communication functions based on queue pair transport APIs.
+ *
+ * Comm is a shared memory-based mechanism that facilitates the implementation
+ * of kernel components that require host-to-guest, or guest-to-guest
+ * communication.
+ * This facility assumes the availability of a minimal shared memory queue pair
+ * implementation, such as MVP queue pairs or VMCI queue pairs. The latter must
+ * provide primitives for queue pair creation and destruction, and reading and
+ * writing from/to queue pairs.
+ * Comm assumes that the queue pair (transport) layer is not concerned with
+ * multi-threading, locking or flow control, and does not require such features.
+ */
+
+#ifndef _COMM_H_
+#define _COMM_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "comm_os.h"
+#include "comm_transp.h"
+
+
+/* Default/maximum Comm timeouts (in milliseconds). */
+#define COMM_MAX_TO 60000ULL
+#define COMM_MAX_TO_UNINT (COMM_MAX_TO + 1)
+
+#define COMM_OPF_SET_ERR(flags) ((flags) |= 128)
+#define COMM_OPF_CLEAR_ERR(flags) ((flags) &= 127)
+#define COMM_OPF_TEST_ERR(flags) ((flags) & 128)
+
+#define COMM_OPF_SET_VAL(flags, val) ((flags) |= ((val) & 127))
+#define COMM_OPF_GET_VAL(flags) ((flags) & 127)
+
+/**
+ * Packet (header) structure.
+ * NB: Do not change this structure, especially the first three fields; there
+ * will be consequences. It may be extended, but it's not recommended: all
+ * operations carry this header, so it's better kept in its minimal form.
+ */
+
+typedef struct CommPacket {
+ unsigned int len; // Total length
+ unsigned char flags; // Operation flags
+ unsigned char opCode; // Operation to call
+ unsigned short data16; // Auxiliary data
+ unsigned long long data64;
+ unsigned long long data64ex;
+ union {
+ struct {
+ unsigned int data32;
+ unsigned int data32ex;
+ };
+ unsigned long long data64ex2;
+ };
+} CommPacket;
+
+
+/* Opaque structure representing a communication channel. */
+
+struct CommChannelPriv;
+typedef struct CommChannelPriv *CommChannel;
+
+
+/* Input operations associated with a comm channel. */
+
+typedef void (*CommOperationFunc)(CommChannel channel,
+ void *state,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen);
+
+
+/* Helper macros */
+
+#define COMM_DEFINE_OP(funcName) \
+void \
+funcName(CommChannel channel, \
+ void *state, \
+ CommPacket *packet, \
+ struct kvec *vec, \
+ unsigned int vecLen)
+
+
+/* Comm-based implementations. */
+
+typedef struct CommImpl {
+ struct module *owner;
+ int (*checkArgs)(CommTranspInitArgs *transpArgs);
+ void *(*stateCtor)(CommChannel channel);
+ void (*stateDtor)(void *state);
+ void *(*dataAlloc)(unsigned int dataLen);
+ void (*dataFree)(void *data);
+ const CommOperationFunc *operations;
+ void (*closeNtf)(void *closeNtfData,
+ const CommTranspInitArgs *transpArgs,
+ int inBH);
+ void *closeNtfData;
+ void (*activateNtf)(void *activateNtfData,
+ CommChannel channel);
+ void *activateNtfData;
+ unsigned long long openAtMillis;
+ unsigned long long openTimeoutAtMillis;
+ CommTranspID ntfCenterID;
+} CommImpl;
+
+
+int Comm_Init(unsigned int maxChannels);
+int Comm_Finish(unsigned long long *timeoutMillis);
+int Comm_RegisterImpl(const CommImpl *impl);
+void Comm_UnregisterImpl(const CommImpl *impl);
+int Comm_IsActive(CommChannel channel);
+CommTranspInitArgs Comm_GetTranspInitArgs(CommChannel channel);
+void *Comm_GetState(CommChannel channel);
+int Comm_Dispatch(CommChannel channel);
+unsigned int Comm_DispatchAll(void);
+void Comm_Put(CommChannel channel);
+void Comm_DispatchUnlock(CommChannel channel);
+int Comm_Lock(CommChannel channel);
+void Comm_Unlock(CommChannel channel);
+int Comm_Zombify(CommChannel channel, int inBH);
+
+int
+Comm_Alloc(const CommTranspInitArgs *transpArgs,
+ const CommImpl *impl,
+ int inBH,
+ CommChannel *newChannel);
+
+
+int
+Comm_Write(CommChannel channel,
+ const CommPacket *packet,
+ unsigned long long *timeoutMillis);
+
+int
+Comm_WriteVec(CommChannel channel,
+ const CommPacket *packet,
+ struct kvec **vec,
+ unsigned int *vecLen,
+ unsigned long long *timeoutMillis,
+ unsigned int *iovOffset);
+
+unsigned int Comm_RequestInlineEvents(CommChannel channel);
+unsigned int Comm_ReleaseInlineEvents(CommChannel channel);
+
+#endif // _COMM_H_
diff --git a/arch/arm/mvp/commkm/comm_ev.h b/arch/arm/mvp/commkm/comm_ev.h
new file mode 100644
index 0000000..bf629c3
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_ev.h
@@ -0,0 +1,51 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief various comm event signaling types and signatures
+ */
+
+#ifndef _COMM_EV_H
+#define _COMM_EV_H
+
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_MODULE
+#include "include_check.h"
+
+/**
+ * @name Identifiers of comm event signaling class methods
+ * @{
+ */
+#define MVP_COMM_EV_SIGNATURE 0x4d4d4f43 ///< 'COMM'
+#define MVP_COMM_EV_SIGNAL (MVP_OBJECT_CUSTOM_BASE + 0) ///< Signal host
+#define MVP_COMM_EV_READ_EVENT_DATA (MVP_OBJECT_CUSTOM_BASE + 1) ///< read event data
+#define MVP_COMM_EV_LAST (MVP_OBJECT_CUSTOM_BASE + 2) ///< Number of methods
+/**@}*/
+
+typedef struct CommEvent {
+ CommTranspID id;
+ CommTranspIOEvent event;
+} CommEvent;
+
+#endif
diff --git a/arch/arm/mvp/commkm/comm_ev_kernel.c b/arch/arm/mvp/commkm/comm_ev_kernel.c
new file mode 100644
index 0000000..0701945
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_ev_kernel.c
@@ -0,0 +1,136 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Comm event signaling, host kernel side.
+ */
+
+#include <linux/net.h>
+
+#include "mvp_types.h"
+#include "comm_os.h"
+#include "comm_transp_impl.h"
+#include "mksck_sockaddr.h"
+#include "comm_ev.h"
+#include "mvpkm_comm_ev.h"
+
+static struct socket *sock;
+
+/**
+ * @brief Raises a transport event on the provided event ID (address). This
+ * function is called from a comm_transp provider, such as comm_transp_mvp,
+ * when it needs to signal an event on a given channel.
+ * @param targetEvID opaque event channel ID (interpreted by implementation).
+ * @param transpID ID of transport to signal.
+ * @param eventType event type to raise.
+ * @return 0 if successful, -1 otherwise.
+ */
+
+int
+CommTranspEvent_Raise(unsigned int targetEvID, // unused
+ CommTranspID *transpID,
+ CommTranspIOEvent eventType)
+{
+ struct sockaddr_mk guestAddr;
+ struct msghdr msg;
+ struct kvec vec[1];
+ int rc;
+ CommEvent event;
+
+ if (!transpID) {
+ return -1;
+ }
+
+ guestAddr.mk_family = AF_MKSCK;
+ guestAddr.mk_addr.addr = Mksck_AddrInit(transpID->d32[0], MKSCK_PORT_COMM_EV);
+
+ memset(&msg, 0, sizeof (struct msghdr));
+ msg.msg_name = &guestAddr;
+ msg.msg_namelen = sizeof (guestAddr);
+
+ event.id = *transpID;
+ event.event = eventType;
+
+ vec[0].iov_base = &event;
+ vec[0].iov_len = sizeof (CommEvent);
+
+ rc = kernel_sendmsg(sock,
+ &msg,
+ vec,
+ 1,
+ sizeof (CommEvent));
+ rc = (rc < 0) ? -1 : 0;
+ return rc;
+}
+
+
+/**
+ * @brief Performs one-time, global initialization of event provider.
+ * @return 0 if successful, -1 otherwise.
+ */
+int
+CommTranspEvent_Init(void)
+{
+ struct sockaddr_mk addr = { AF_MKSCK, { .addr = MKSCK_ADDR_UNDEF } };
+ int rc;
+
+ rc = sock_create_kern(AF_MKSCK, SOCK_DGRAM, 0, &sock);
+ if (rc < 0) {
+ goto out;
+ }
+
+ rc = kernel_bind(sock, (struct sockaddr *) &addr, sizeof addr);
+ if (rc < 0) {
+ sock_release(sock);
+ sock = NULL;
+ goto out;
+ }
+
+ Mvpkm_CommEvRegisterProcessCB(CommTranspEvent_Process);
+
+out:
+ if (rc) {
+ CommOS_Log(("%s: Failed to initialize transport event signaling\n",
+ __FUNCTION__));
+ } else {
+ CommOS_Log(("%s: Transport event signaling initialization successful\n",
+ __FUNCTION__));
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Performs global clean-up of event provider.
+ */
+
+void
+CommTranspEvent_Exit(void)
+{
+ Mvpkm_CommEvUnregisterProcessCB();
+ if (sock) {
+ sock_release(sock);
+ sock = NULL;
+ }
+
+ CommOS_Debug(("%s: done.\n", __FUNCTION__));
+}
diff --git a/arch/arm/mvp/commkm/comm_os.h b/arch/arm/mvp/commkm/comm_os.h
new file mode 100644
index 0000000..f98c8d4
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_os.h
@@ -0,0 +1,150 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Cross-platform base type definitions and function declarations.
+ * Includes OS-specific base type definitions and function declarations.
+ */
+
+#ifndef _COMM_OS_H_
+#define _COMM_OS_H_
+
+/* For-ever timeout constant (in milliseconds). */
+#define COMM_OS_4EVER_TO ((unsigned long long)(~0UL >> 1))
+
+/* Condition function prototype. Returns 1: true, 0: false, < 0: error code. */
+typedef int (*CommOSWaitConditionFunc)(void *arg1, void *arg2);
+
+/* Dispatch function prototype. Called by input (dispatch) kernel threads. */
+typedef unsigned int (*CommOSDispatchFunc)(void);
+
+/* Module initialization and exit callback functions. */
+extern int (*commOSModInit)(void *args);
+extern void (*commOSModExit)(void);
+
+/* Macro to assign Init and Exit callbacks. */
+#define COMM_OS_MOD_INIT(init, exit) \
+ int (*commOSModInit)(void *args) = init; \
+ void (*commOSModExit)(void) = exit
+
+
+/*
+ * OS-specific implementations must provide the following:
+ * 1. Types:
+ * CommOSAtomic
+ * CommOSSpinlock
+ * CommOSMutex
+ * CommOSWaitQueue
+ * CommOSWork
+ * CommOSWorkFunc
+ * CommOSList
+ * CommOSModule
+ * struct kvec
+ *
+ * 2. Definition, initializers:
+ * CommOSSpinlock_Define()
+ *
+ * 3. Functions:
+ * void CommOS_Debug(const char *format, ...);
+ * void CommOS_Log(const char *format, ...);
+ * void CommOS_WriteAtomic(CommOSAtomic *atomic, int val);
+ * int CommOS_ReadAtomic(CommOSAtomic *atomic);
+ * int CommOS_AddReturnAtomic(CommOSAtomic *atomic, int val);
+ * int CommOS_SubReturnAtomic(CommOSAtomic *atomic, int val);
+ * void CommOS_SpinlockInit(CommOSSpinlock *lock);
+ * void CommOS_SpinLockBH(CommOSSpinlock *lock);
+ * int CommOS_SpinTrylockBH(CommOSSpinlock *lock);
+ * void CommOS_SpinUnlockBH(CommOSSpinlock *lock);
+ * void CommOS_SpinLock(CommOSSpinlock *lock);
+ * int CommOS_SpinTrylock(CommOSSpinlock *lock);
+ * void CommOS_SpinUnlock(CommOSSpinlock *lock);
+ * void CommOS_MutexInit(CommOSMutex *mutex);
+ * void CommOS_MutexLock(CommOSMutex *mutex);
+ * int CommOS_MutexLockUninterruptible(CommOSMutex *mutex);
+ * int CommOS_MutexTrylock(CommOSMutex *mutex);
+ * void CommOS_MutexUnlock(CommOSMutex *mutex);
+ * void CommOS_WaitQueueInit(CommOSWaitQueue *wq);
+ * CommOS_DoWait(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc cond,
+ * void *condArg1,
+ * void *condArg2,
+ * unsigned long long *timeoutMillis,
+ * int interruptible);
+ * int CommOS_Wait(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc func,
+ * void *funcArg1,
+ * void *funcArg2,
+ * unsigned long long *timeoutMillis);
+ * int CommOS_WaitUninterruptible(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc func,
+ * void *funcArg1,
+ * void *funcArg2,
+ * unsigned long long *timeoutMillis);
+ * void CommOS_WakeUp(CommOSWaitQueue *wq);
+ * void *CommOS_KmallocNoSleep(unsigned int size);
+ * void *CommOS_Kmalloc(unsigned int size);
+ * void CommOS_Kfree(void *arg);
+ * void CommOS_Yield(void);
+ * unsigned long long CommOS_GetCurrentMillis(void);
+ * void CommOS_ListInit(CommOSList *list);
+ * int CommOS_ListEmpty(CommOSList *list);
+ * void CommOS_ListAdd(CommOSList *list, CommOSList *listElem);
+ * void CommOS_ListAddTail(CommOSList *list, CommOSList *listElem);
+ * void int CommOS_ListDel(CommOSList *listElem);
+ * Macros:
+ * CommOS_ListForEach(*list, *item, itemListFieldName);
+ * CommOS_ListForEachSafe(*list, *item, *tmp, itemListFieldName);
+ * void CommOS_ListSplice(CommOSList *list, CommOSList *listToAdd);
+ * void CommOS_ListSpliceTail(CommOSList *list, CommOSList *listToAdd);
+ * CommOSModule CommOS_ModuleSelf(void);
+ * int CommOS_ModuleGet(CommOSModule module);
+ * void CommOS_ModulePut(CommOSModule module);
+ * void CommOS_MemBarrier(void);
+ *
+ * These cannot be defined here: a) non-pointer type definitions need size
+ * information, and b) functions may or may not be inlined, or macros may
+ * be used instead.
+ */
+
+
+#ifdef __linux__
+#include "comm_os_linux.h"
+#else
+#error "Unsupported OS"
+#endif
+
+/* Functions to start and stop the dispatch and aio kernel threads. */
+void CommOS_StopIO(void);
+void CommOS_ScheduleDisp(void);
+void CommOS_InitWork(CommOSWork *work, CommOSWorkFunc func);
+int CommOS_ScheduleAIOWork(CommOSWork *work);
+void CommOS_FlushAIOWork(CommOSWork *work);
+
+int
+CommOS_StartIO(const char *dispatchTaskName,
+ CommOSDispatchFunc dispatchHandler,
+ unsigned int interval,
+ unsigned int maxCycles,
+ const char *aioTaskName);
+
+
+#endif /* _COMM_OS_H_ */
diff --git a/arch/arm/mvp/commkm/comm_os_linux.c b/arch/arm/mvp/commkm/comm_os_linux.c
new file mode 100644
index 0000000..74f99f5
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_os_linux.c
@@ -0,0 +1,371 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Linux-specific functions/types.
+ */
+
+#include "comm_os.h"
+
+#define DISPATCH_MAX_CYCLES 8192
+
+/* Type definitions */
+
+typedef struct workqueue_struct CommOSWorkQueue;
+
+
+/* Static data */
+
+static volatile int running;
+static int numCpus;
+static CommOSWorkQueue *dispatchWQ;
+static CommOSDispatchFunc dispatch;
+static CommOSWork dispatchWorksNow[NR_CPUS];
+static CommOSWork dispatchWorks[NR_CPUS];
+static unsigned int dispatchInterval = 1;
+static unsigned int dispatchMaxCycles = 2048;
+static CommOSWorkQueue *aioWQ;
+
+
+/**
+ * @brief Initializes a workqueue consisting of per-cpu kernel threads.
+ * @param name workqueue name
+ * @return workqueue handle if successful, NULL otherwise
+ */
+
+static inline CommOSWorkQueue *
+CreateWorkqueue(const char *name)
+{
+ return create_workqueue(name);
+}
+
+
+/**
+ * @brief Destroys a workqueue and stops its threads.
+ * @param[in,out] wq workqueue to destroy.
+ * @return workqueue handle is successful, NULL otherwise.
+ */
+
+static inline void
+DestroyWorkqueue(CommOSWorkQueue *wq)
+{
+ destroy_workqueue(wq);
+}
+
+
+/**
+ * @brief Force execution of a work item.
+ * @param[in,out] work work item to dequeue.
+ */
+
+static inline void
+FlushDelayedWork(CommOSWork *work)
+{
+ flush_delayed_work(work);
+}
+
+
+/**
+ * @brief Enqueue a work item to a workqueue for execution on a given cpu
+ * and after the specified interval.
+ * @param cpu cpu number. If negative, work item is enqueued on current cpu.
+ * @param[in,out] wq target work queue.
+ * @param[in,out] work work item to enqueue.
+ * @param jif delay interval.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+QueueDelayedWorkOn(int cpu,
+ CommOSWorkQueue *wq,
+ CommOSWork *work,
+ unsigned long jif)
+{
+ if (cpu < 0) {
+ return !queue_delayed_work(wq, work, jif) ? -1 : 0;
+ } else {
+ return !queue_delayed_work_on(cpu, wq, work, jif) ? -1 : 0;
+ }
+}
+
+
+/**
+ * @brief Enqueues a work item to a workqueue for execution on the current cpu
+ * and after the specified interval.
+ * @param[in,out] wq target work queue.
+ * @param[in,out] work work item to enqueue.
+ * @param jif delay interval.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+QueueDelayedWork(CommOSWorkQueue *wq,
+ CommOSWork *work,
+ unsigned long jif)
+{
+ return QueueDelayedWorkOn(-1, wq, work, jif);
+}
+
+
+/**
+ * @brief Cancels a queued delayed work item and synchronizes with its
+ * completion.
+ * @param[in,out] work work item to cancel
+ */
+
+static inline void
+WaitForDelayedWork(CommOSWork *work)
+{
+ cancel_delayed_work_sync(work);
+}
+
+
+/**
+ * @brief Discards work items queued to the specified workqueue.
+ * @param[in,out] wq work queue to flush.
+ */
+
+static inline void
+FlushWorkqueue(CommOSWorkQueue *wq)
+{
+ flush_workqueue(wq);
+}
+
+
+/**
+ * @brief Schedules dispatcher threads for immediate execution.
+ */
+
+void
+CommOS_ScheduleDisp(void)
+{
+ CommOSWork *work = &dispatchWorksNow[get_cpu()];
+
+ put_cpu();
+ if (running) {
+ QueueDelayedWork(dispatchWQ, work, 0);
+ }
+}
+
+
+/**
+ * @brief Default delayed work callback function implementation.
+ * Calls the input function specified at initialization.
+ * @param[in,out] work work item.
+ */
+
+static void
+DispatchWrapper(CommOSWork *work)
+{
+ unsigned int misses;
+
+ for (misses = 0; running && (misses < dispatchMaxCycles); ) {
+ /* We run for at most dispatchMaxCycles worth of channel no-ops. */
+
+ if (!dispatch()) {
+ /* No useful work was done, on any of the channels. */
+
+ misses++;
+ if ((misses % 32) == 0) {
+ CommOS_Yield();
+ }
+ } else {
+ misses = 0;
+ }
+ }
+
+ if (running &&
+ (work >= &dispatchWorks[0]) &&
+ (work <= &dispatchWorks[NR_CPUS - 1])) {
+ /*
+ * If still running _and_ this was a regular, time-based run, then
+ * re-arm the timer.
+ */
+
+ QueueDelayedWork(dispatchWQ, work, dispatchInterval);
+ }
+}
+
+
+/**
+ * @brief Initializes work item with specified callback function.
+ * @param[in,out] work work queue to initialize.
+ * @param func work item to initialize the queue with.
+ */
+
+void
+CommOS_InitWork(CommOSWork *work,
+ CommOSWorkFunc func)
+{
+ INIT_DELAYED_WORK(work, (work_func_t)func);
+}
+
+
+/**
+ * @brief Flush execution of a work item
+ * @param{in,out] work work item to dequeue
+ */
+void
+CommOS_FlushAIOWork(CommOSWork *work)
+{
+ if (aioWQ && work) {
+ FlushDelayedWork(work);
+ }
+}
+
+
+/**
+ * @brief Queue a work item to the AIO workqueue.
+ * @param[in,out] work work item to enqueue.
+ * @return zero if work enqueued, non-zero otherwise.
+ */
+
+int
+CommOS_ScheduleAIOWork(CommOSWork *work)
+{
+ if (running && aioWQ && work) {
+ return QueueDelayedWork(aioWQ, work, 0);
+ }
+ return -1;
+}
+
+
+/**
+ * @brief Initializes the base IO system.
+ * @param dispatchTaskName dispatch thread(s) name.
+ * @param dispatchFunc dispatch function.
+ * @param intervalMillis periodic interval in milliseconds to call dispatch.
+ * The floor is 1 jiffy, regardless of how small intervalMillis is
+ * @param maxCycles number of cycles to do adaptive polling before scheduling.
+ * The maximum number of cycles is DISPATCH_MAX_CYCLES.
+ * @param aioTaskName AIO thread(s) name. If NULL, AIO threads aren't started.
+ * @return zero is successful, -1 otherwise.
+ * @sideeffects Dispatch threads, and if applicable, AIO threads are started.
+ */
+
+int
+CommOS_StartIO(const char *dispatchTaskName, // IN
+ CommOSDispatchFunc dispatchFunc, // IN
+ unsigned int intervalMillis, // IN
+ unsigned int maxCycles, // IN
+ const char *aioTaskName) // IN
+{
+ int rc;
+ int cpu;
+
+ if (running) {
+ CommOS_Debug(("%s: I/O tasks already running.\n", __FUNCTION__));
+ return 0;
+ }
+
+ /*
+ * OK, let's test the handler against NULL. Though, the whole concept
+ * of checking for NULL pointers, outside cases where NULL is meaningful
+ * to the implementation, is relatively useless: garbage, random pointers
+ * rarely happen to be all-zeros.
+ */
+
+ if (!dispatchFunc) {
+ CommOS_Log(("%s: a NULL Dispatch handler was passed.\n", __FUNCTION__));
+ return -1;
+ }
+ dispatch = dispatchFunc;
+
+ if (intervalMillis == 0) {
+ intervalMillis = 4;
+ }
+ if ((dispatchInterval = msecs_to_jiffies(intervalMillis)) < 1) {
+ dispatchInterval = 1;
+ }
+ if (maxCycles > DISPATCH_MAX_CYCLES) {
+ dispatchMaxCycles = DISPATCH_MAX_CYCLES;
+ } else if (maxCycles > 0) {
+ dispatchMaxCycles = maxCycles;
+ }
+ CommOS_Debug(("%s: Interval millis %u (jif:%u).\n", __FUNCTION__,
+ intervalMillis, dispatchInterval));
+ CommOS_Debug(("%s: Max cycles %u.\n", __FUNCTION__, dispatchMaxCycles));
+
+ numCpus = num_present_cpus();
+ dispatchWQ = CreateWorkqueue(dispatchTaskName);
+ if (!dispatchWQ) {
+ CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__,
+ dispatchTaskName));
+ return -1;
+ }
+
+ if (aioTaskName) {
+ aioWQ = CreateWorkqueue(aioTaskName);
+ if (!aioWQ) {
+ CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__,
+ aioTaskName));
+ DestroyWorkqueue(dispatchWQ);
+ return -1;
+ }
+ } else {
+ aioWQ = NULL;
+ }
+
+ running = 1;
+ for (cpu = 0; cpu < numCpus; cpu++) {
+ CommOS_InitWork(&dispatchWorksNow[cpu], DispatchWrapper);
+ CommOS_InitWork(&dispatchWorks[cpu], DispatchWrapper);
+ rc = QueueDelayedWorkOn(cpu, dispatchWQ,
+ &dispatchWorks[cpu],
+ dispatchInterval);
+ if (rc != 0) {
+ CommOS_StopIO();
+ return -1;
+ }
+ }
+ CommOS_Log(("%s: Created I/O task(s) successfully.\n", __FUNCTION__));
+ return 0;
+}
+
+
+/**
+ * @brief Stops the base IO system.
+ * @sideeffects Dispatch threads, and if applicable, AIO threads are stopped.
+ */
+
+void
+CommOS_StopIO(void)
+{
+ int cpu;
+
+ if (running) {
+ running = 0;
+ if (aioWQ) {
+ FlushWorkqueue(aioWQ);
+ DestroyWorkqueue(aioWQ);
+ aioWQ = NULL;
+ }
+ FlushWorkqueue(dispatchWQ);
+ for (cpu = 0; cpu < numCpus; cpu++) {
+ WaitForDelayedWork(&dispatchWorksNow[cpu]);
+ WaitForDelayedWork(&dispatchWorks[cpu]);
+ }
+ DestroyWorkqueue(dispatchWQ);
+ dispatchWQ = NULL;
+ CommOS_Log(("%s: I/O tasks stopped.\n", __FUNCTION__));
+ }
+}
diff --git a/arch/arm/mvp/commkm/comm_os_linux.h b/arch/arm/mvp/commkm/comm_os_linux.h
new file mode 100644
index 0000000..f92c8bd
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_os_linux.h
@@ -0,0 +1,699 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Contains linux-specific type definitions and function declarations
+ */
+
+#ifndef _COMM_OS_LINUX_H_
+#define _COMM_OS_LINUX_H_
+
+#include <linux/types.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#error "Kernel versions lower than 2.6.20 are not supported"
+#endif
+
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+
+/*
+ * Type definitions.
+ */
+
+typedef atomic_t CommOSAtomic;
+typedef spinlock_t CommOSSpinlock;
+typedef struct mutex CommOSMutex;
+typedef wait_queue_head_t CommOSWaitQueue;
+typedef struct delayed_work CommOSWork;
+typedef void (*CommOSWorkFunc)(CommOSWork *work);
+typedef struct list_head CommOSList;
+typedef struct module *CommOSModule;
+
+
+/*
+ * Initializers.
+ */
+
+#define CommOSSpinlock_Define DEFINE_SPINLOCK
+
+
+#define COMM_OS_DOLOG(...) printk(KERN_INFO __VA_ARGS__)
+
+
+/**
+ * @brief Logs given arguments in debug builds.
+ */
+
+#if defined(COMM_OS_DEBUG)
+ #define CommOS_Debug(args) COMM_OS_DOLOG args
+#else
+ #define CommOS_Debug(args)
+#endif
+
+
+/**
+ * @brief Logs given arguments.
+ */
+
+#define CommOS_Log(args) COMM_OS_DOLOG args
+
+
+/**
+ * @brief Logs function name and location.
+ */
+
+#if defined(COMM_OS_TRACE)
+#define TRACE(ptr) \
+ do { \
+ CommOS_Debug(("%p:%s: at [%s:%d] with arg ptr [0x%p].\n", current, \
+ __FUNCTION__, __FILE__, __LINE__, (ptr))); \
+ } while (0)
+#else
+#define TRACE(ptr)
+#endif
+
+
+/**
+ * @brief Write atomic variable
+ * @param[in,out] atomic variable to write
+ * @param val new value
+ */
+
+static inline void
+CommOS_WriteAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ atomic_set(atomic, val);
+}
+
+
+/**
+ * @brief Reads atomic variable
+ * @param atomic variable to read
+ * @return value
+ */
+
+static inline int
+CommOS_ReadAtomic(CommOSAtomic *atomic)
+{
+ return atomic_read(atomic);
+}
+
+
+/**
+ * @brief Atomically add value to atomic variable, return new value.
+ * @param[in,out] atomic variable
+ * @param val value to add
+ * @return new value
+ */
+
+static inline int
+CommOS_AddReturnAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ return atomic_add_return(val, atomic);
+}
+
+
+/**
+ * @brief Atomically substract value from atomic variable, return new value.
+ * @param[in,out] atomic variable
+ * @param val value to substract
+ * @return new value
+ */
+
+static inline int
+CommOS_SubReturnAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ return atomic_sub_return(val, atomic);
+}
+
+
+/**
+ * @brief Initializes a given lock.
+ * @param[in,out] lock lock to initialize
+ */
+
+static inline void
+CommOS_SpinlockInit(CommOSSpinlock *lock)
+{
+ spin_lock_init(lock);
+}
+
+
+/**
+ * @brief Locks given lock and disables bottom half processing.
+ * @param[in,out] lock lock to lock
+ */
+
+static inline void
+CommOS_SpinLockBH(CommOSSpinlock *lock)
+{
+ spin_lock_bh(lock);
+}
+
+
+/**
+ * @brief Attempts to lock the given lock and disable BH processing.
+ * @param[in,out] lock lock to lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_SpinTrylockBH(CommOSSpinlock *lock)
+{
+ return !spin_trylock_bh(lock);
+}
+
+
+/**
+ * @brief Unlocks given lock and re-enables BH processing.
+ * @param[in,out] lock lock to unlock
+ */
+
+static inline void
+CommOS_SpinUnlockBH(CommOSSpinlock *lock)
+{
+ spin_unlock_bh(lock);
+}
+
+
+/**
+ * @brief Locks the given lock.
+ * @param[in,out] lock lock to lock
+ */
+
+static inline void
+CommOS_SpinLock(CommOSSpinlock *lock)
+{
+ spin_lock(lock);
+}
+
+
+/**
+ * @brief Attempts to lock the given lock.
+ * @param[in,out] lock lock to try-lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_SpinTrylock(CommOSSpinlock *lock)
+{
+ return !spin_trylock(lock);
+}
+
+
+/**
+ * @brief Unlocks given lock.
+ * @param[in,out] lock lock to unlock
+ */
+
+static inline void
+CommOS_SpinUnlock(CommOSSpinlock *lock)
+{
+ spin_unlock(lock);
+}
+
+
+/**
+ * @brief Initializes given mutex.
+ * @param[in,out] mutex mutex to initialize
+ */
+
+static inline void
+CommOS_MutexInit(CommOSMutex *mutex)
+{
+ mutex_init(mutex);
+}
+
+
+/**
+ * @brief Acquires mutex.
+ * @param[in,out] mutex mutex to lock
+ * @return zero if successful, non-zero otherwise (interrupted)
+ */
+
+static inline int
+CommOS_MutexLock(CommOSMutex *mutex)
+{
+ return mutex_lock_interruptible(mutex);
+}
+
+
+/**
+ * @brief Acquires mutex in uninterruptible mode.
+ * @param[in,out] mutex mutex to lock
+ */
+
+static inline void
+CommOS_MutexLockUninterruptible(CommOSMutex *mutex)
+{
+ mutex_lock(mutex);
+}
+
+
+/**
+ * @brief Attempts to acquire given mutex.
+ * @param[in,out] mutex mutex to try-lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_MutexTrylock(CommOSMutex *mutex)
+{
+ return !mutex_trylock(mutex);
+}
+
+
+/**
+ * @brief Releases a given mutex.
+ * @param[in,out] mutex mutex to unlock
+ */
+
+static inline void
+CommOS_MutexUnlock(CommOSMutex *mutex)
+{
+ mutex_unlock(mutex);
+}
+
+
+/**
+ * @brief Initializes a wait queue.
+ * @param[in,out] wq workqueue to initialize
+ */
+
+static inline void
+CommOS_WaitQueueInit(CommOSWaitQueue *wq)
+{
+ init_waitqueue_head(wq);
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * - a signal is pending
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @param interruptible enable/disable signal pending check
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, if a signal is pending or other error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_DoWait(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis,
+ int interruptible)
+{
+ int rc;
+ DEFINE_WAIT(wait);
+ long timeout;
+#if defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ long tmpTimeout;
+ long retTimeout;
+ const unsigned int interval = 50;
+#endif
+
+ if (!timeoutMillis) {
+ return -1;
+ }
+ if ((rc = cond(condArg1, condArg2)) != 0) {
+ return rc;
+ }
+
+#if defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ timeout = msecs_to_jiffies(interval < *timeoutMillis ?
+ interval : (unsigned int)*timeoutMillis);
+ retTimeout = msecs_to_jiffies((unsigned int)(*timeoutMillis));
+
+ for (; retTimeout >= 0; ) {
+ prepare_to_wait(wq, &wait,
+ (interruptible?TASK_INTERRUPTIBLE:TASK_UNINTERRUPTIBLE));
+ if ((rc = cond(condArg1, condArg2))) {
+ break;
+ }
+ if (interruptible && signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if ((tmpTimeout = schedule_timeout(timeout))) {
+ retTimeout -= (timeout - tmpTimeout);
+ } else {
+ retTimeout -= timeout;
+ }
+ if (retTimeout < 0) {
+ retTimeout = 0;
+ }
+ }
+ finish_wait(wq, &wait);
+ if (rc == 0) {
+ rc = cond(condArg1, condArg2);
+ if (rc && (retTimeout == 0)) {
+ retTimeout = 1;
+ }
+ }
+ *timeoutMillis = (unsigned long long)jiffies_to_msecs(retTimeout);
+#else // !defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ timeout = msecs_to_jiffies((unsigned int)(*timeoutMillis));
+
+ for (;;) {
+ prepare_to_wait(wq, &wait,
+ (interruptible?TASK_INTERRUPTIBLE:TASK_UNINTERRUPTIBLE));
+ if ((rc = cond(condArg1, condArg2)) != 0) {
+ break;
+ }
+ if (interruptible && signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if ((timeout = schedule_timeout(timeout)) == 0) {
+ rc = 0;
+ break;
+ }
+ }
+ finish_wait(wq, &wait);
+ if (rc == 0) {
+ rc = cond(condArg1, condArg2);
+ if (rc && (timeout == 0)) {
+ timeout = 1;
+ }
+ }
+ *timeoutMillis = (unsigned long long)jiffies_to_msecs(timeout);
+#endif
+
+ return rc;
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * - a signal is pending
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, if a signal is pending or other error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_Wait(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis)
+{
+ return CommOS_DoWait(wq, cond, condArg1, condArg2, timeoutMillis, 1);
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_WaitUninterruptible(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis)
+{
+ return CommOS_DoWait(wq, cond, condArg1, condArg2, timeoutMillis, 0);
+}
+
+
+/**
+ * @brief Wakes up task(s) waiting on the given wait queue.
+ * @param[in,out] wq wait queue.
+ */
+
+static inline void
+CommOS_WakeUp(CommOSWaitQueue *wq)
+{
+ wake_up(wq);
+}
+
+
+/**
+ * @brief Allocates kernel memory of specified size; does not sleep.
+ * @param size size to allocate.
+ * @return Address of allocated memory or NULL if the allocation fails.
+ */
+
+static inline void *
+CommOS_KmallocNoSleep(unsigned int size)
+{
+ return kmalloc(size, GFP_ATOMIC);
+}
+
+
+/**
+ * @brief Allocates kernel memory of specified size; may sleep.
+ * @param size size to allocate.
+ * @return Address of allocated memory or NULL if the allocation fails.
+ */
+
+static inline void *
+CommOS_Kmalloc(unsigned int size)
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+
+/**
+ * @brief Frees previously allocated kernel memory.
+ * @param obj object to free.
+ */
+
+static inline void
+CommOS_Kfree(void *obj)
+{
+ if (obj) {
+ kfree(obj);
+ }
+}
+
+
+/**
+ * @brief Yields the current cpu to other runnable tasks.
+ */
+
+static inline void
+CommOS_Yield(void)
+{
+ cond_resched();
+}
+
+
+/**
+ * @brief Gets the current time in milliseconds.
+ * @return Current time in milliseconds, with precision of at most one tick.
+ */
+
+static inline unsigned long long
+CommOS_GetCurrentMillis(void)
+{
+ return (unsigned long long)jiffies_to_msecs(jiffies);
+}
+
+
+/**
+ * @brief Initializes given list.
+ * @param list list to initialize.
+ */
+
+static inline void
+CommOS_ListInit(CommOSList *list)
+{
+ INIT_LIST_HEAD(list);
+}
+
+
+/**
+ * @brief Tests if list is empty.
+ * @param list list to test.
+ * @return non-zero if empty, zero otherwise.
+ */
+
+#define CommOS_ListEmpty(list) list_empty((list))
+
+
+/**
+ * @brief Adds given element to beginning of list.
+ * @param list list to add to.
+ * @param elem element to add.
+ */
+
+#define CommOS_ListAdd(list, elem) list_add((elem), (list))
+
+
+/**
+ * @brief Adds given element to end of list.
+ * @param list list to add to.
+ * @param elem element to add.
+ */
+
+#define CommOS_ListAddTail(list, elem) list_add_tail((elem), (list))
+
+
+/**
+ * @brief Deletes given element from its list.
+ * @param elem element to delete.
+ */
+
+#define CommOS_ListDel(elem) \
+ do { \
+ list_del((elem)); \
+ INIT_LIST_HEAD((elem)); \
+ } while (0)
+
+
+/**
+ * @brief Iterates over a list.
+ * @param list list to iterate over.
+ * @param[out] item stores next element.
+ * @param itemListFieldName name in the item structure storing the list head.
+ */
+
+#define CommOS_ListForEach(list, item, itemListFieldName) \
+ list_for_each_entry((item), (list), itemListFieldName)
+
+
+/**
+ * @brief Iterates safely over a list.
+ * @param list list to iterate over.
+ * @param[out] item stores next element. May be deleted in the loop.
+ * @param[out] tmpItem saves iteration element.
+ * @param itemListFieldName name in the item structure storing the list head.
+ */
+
+#define CommOS_ListForEachSafe(list, item, tmpItem, itemListFieldName) \
+ list_for_each_entry_safe((item), (tmpItem), (list), itemListFieldName)
+
+
+/**
+ * @brief Combines two lists, adds second list to beginning of first one.
+ * @param list list to add to.
+ * @param list2 list to add.
+ */
+
+#define CommOS_ListSplice(list, list2) list_splice((list2), (list))
+
+
+/**
+ * @brief Combines two lists, adds second list to end of first one.
+ * @param list list to add to.
+ * @param list2 list to add.
+ */
+
+#define CommOS_ListSpliceTail(list, list2) list_splice_tail((list2), (list))
+
+
+/**
+ * @brief Gets current module handle.
+ * @return module handle.
+ */
+
+static inline CommOSModule
+CommOS_ModuleSelf(void)
+{
+ return THIS_MODULE;
+}
+
+
+/**
+ * @brief Retains module.
+ * @param[in,out] module to retain.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+CommOS_ModuleGet(CommOSModule module)
+{
+ int rc = 0;
+
+ if (!module) {
+ goto out;
+ }
+ if (!try_module_get(module)) {
+ rc = -1;
+ }
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Releases module.
+ * @param[in,out] module to release.
+ */
+
+static inline void
+CommOS_ModulePut(CommOSModule module)
+{
+ if (module) {
+ module_put(module);
+ }
+}
+
+
+/**
+ * @brief Inserts r/w memory barrier.
+ */
+
+#define CommOS_MemBarrier smp_mb
+
+#endif /* _COMM_OS_LINUX_H_ */
diff --git a/arch/arm/mvp/commkm/comm_os_mod_linux.c b/arch/arm/mvp/commkm/comm_os_mod_linux.c
new file mode 100644
index 0000000..8470de6
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_os_mod_linux.c
@@ -0,0 +1,105 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Linux-specific module loading, unloading functions.
+ */
+
+#include "comm_os.h"
+#include "comm_os_mod_ver.h"
+
+#include <linux/moduleparam.h>
+
+
+/* Module parameters -- passed as one 'name=value'-list string. */
+
+static char modParams[256];
+module_param_string(COMM_OS_MOD_SHORT_NAME, modParams, sizeof modParams, 0644);
+
+
+/**
+ * @brief Module initialization entry point. Calls the commOSModInit
+ * function pointer to perform upper layer initialization.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static int __init
+ModInit(void)
+{
+ int rc;
+
+ if (!commOSModInit) {
+ CommOS_Log(("%s: Can't find \'init\' function for module \'" \
+ COMM_OS_MOD_SHORT_NAME_STRING "\'.\n", __FUNCTION__));
+ return -1;
+ }
+
+ CommOS_Debug(("%s: Module parameters: [%s].\n", __FUNCTION__, modParams));
+
+ rc = (*commOSModInit)(modParams);
+ if (rc == 0) {
+ CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \
+ "\' has been successfully initialized.\n", __FUNCTION__));
+ } else {
+ CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \
+ "\' could not be initialized [%d].\n", __FUNCTION__, rc));
+ }
+
+ return rc > 0 ? -rc : rc;
+}
+
+
+/**
+ * @brief Module exit function. Calls the commOSModExit function pointer
+ * to perform upper layer cleanup.
+ */
+
+static void __exit
+ModExit(void)
+{
+ if (!commOSModExit) {
+ CommOS_Log(("%s: Can't find \'fini\' function for module \'" \
+ COMM_OS_MOD_SHORT_NAME_STRING "\'.\n", __FUNCTION__));
+ return;
+ }
+
+ (*commOSModExit)();
+ CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \
+ "\' has been stopped.\n", __FUNCTION__));
+}
+
+
+module_init(ModInit);
+module_exit(ModExit);
+
+/* Module information. */
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION(COMM_OS_MOD_NAME_STRING);
+MODULE_VERSION(COMM_OS_MOD_VERSION_STRING);
+MODULE_LICENSE("GPL v2");
+/*
+ * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement
+ * with them and mark their kernel modules as externally supported via a
+ * change to the module header. If this isn't done, the module will not load
+ * by default (i.e., neither mkinitrd nor modprobe will accept it).
+ */
+MODULE_INFO(supported, "external");
diff --git a/arch/arm/mvp/commkm/comm_os_mod_ver.h b/arch/arm/mvp/commkm/comm_os_mod_ver.h
new file mode 100644
index 0000000..059854c
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_os_mod_ver.h
@@ -0,0 +1,38 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Version definitions for the Comm module.
+ */
+
+#ifndef _COMM_OS_MOD_VER_H_
+#define _COMM_OS_MOD_VER_H_
+
+#define COMM_OS_MOD_NAME_STRING "VMware communication module"
+#define COMM_OS_MOD_SHORT_NAME comm
+#define COMM_OS_MOD_SHORT_NAME_STRING "comm"
+
+#define COMM_OS_MOD_VERSION 1.0.0.0
+#define COMM_OS_MOD_VERSION_COMMAS 1,0,0,0
+#define COMM_OS_MOD_VERSION_STRING "1.0.0.0"
+
+#endif /* _COM_OS_MOD_VER_H_ */
diff --git a/arch/arm/mvp/commkm/comm_svc.c b/arch/arm/mvp/commkm/comm_svc.c
new file mode 100644
index 0000000..18f62bd
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_svc.c
@@ -0,0 +1,421 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Communication functions based on transport functionality.
+ */
+
+#include "comm_os.h"
+#include "comm_os_mod_ver.h"
+#include "comm_svc.h"
+
+
+/*
+ * Initialization of module entry and exit callbacks expected by module
+ * loading/unloading functions in comm_os.
+ */
+
+static int Init(void *args);
+static void Exit(void);
+
+COMM_OS_MOD_INIT(Init, Exit);
+
+static volatile int running; // Initialized and running.
+
+
+/**
+ * @brief Allocates and initializes comm global state.
+ * Starts input dispatch and aio threads.
+ * @param argsIn arguments
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static int
+Init(void *argsIn)
+{
+ int rc = -1;
+ unsigned int maxChannels = 8;
+ /*
+ * Infinite timeout, 1 polling cycle
+ * see kernel/time.c: msecs_to_jiffies()
+ */
+ unsigned int pollingMillis = (unsigned int)-1;
+ unsigned int pollingCycles = 1;
+ const char *args = argsIn;
+
+ if (args && *args) {
+ /* coverity[secure_coding] */
+ sscanf(args,
+ "max_channels:%u,poll_millis:%u,poll_cycles:%u",
+ &maxChannels, &pollingMillis, &pollingCycles);
+ CommOS_Debug(("%s: arguments [%s].\n", __FUNCTION__, args));
+ }
+
+ rc = Comm_Init(maxChannels);
+ if (rc) {
+ goto out;
+ }
+
+ rc = CommOS_StartIO(COMM_OS_MOD_SHORT_NAME_STRING "-disp",
+ Comm_DispatchAll, pollingMillis, pollingCycles,
+ COMM_OS_MOD_SHORT_NAME_STRING "-aio");
+ if (rc) {
+ unsigned long long timeout = 0;
+
+ Comm_Finish(&timeout); /* Nothing started, guaranteed to succeed. */
+ goto out;
+ }
+ running = 1;
+ rc = 0;
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Attempts to close all channels.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static int
+Halt(void)
+{
+ unsigned int maxTries = 10;
+ int rc = -1;
+
+ if (!running) {
+ rc = 0;
+ goto out;
+ }
+
+ for ( ; maxTries; maxTries--) {
+ unsigned long long timeout = 2000ULL;
+
+ CommOS_Debug(("%s: Attempting to halt...\n", __FUNCTION__));
+ if (!Comm_Finish(&timeout)) {
+ running = 0;
+ rc = 0;
+ break;
+ }
+ }
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Stops the comm_rt module.
+ * If Halt() call successful, stops input dispatch and aio threads.
+ */
+
+static void
+Exit(void)
+{
+ if (!Halt()) {
+ CommOS_StopIO();
+ }
+}
+
+
+/**
+ * @brief Registers an implementation block used when attaching to channels
+ * in response to transport attach events.
+ * @param impl implementation block.
+ * @return 0 if successful, non-zero otherwise.
+ */
+
+int
+CommSvc_RegisterImpl(const CommImpl *impl)
+{
+ return Comm_RegisterImpl(impl);
+}
+
+
+/**
+ * @brief Unregisters an implementation block used when attaching to channels
+ * in response to transport attach events.
+ * @param impl implementation block.
+ */
+
+void
+CommSvc_UnregisterImpl(const CommImpl *impl)
+{
+ Comm_UnregisterImpl(impl);
+}
+
+
+/**
+ * @brief Finds a free entry and initializes it with the information provided.
+ * May be called from BH. It doesn't call potentially blocking functions.
+ * @param transpArgs transport initialization arguments.
+ * @param impl implementation block.
+ * @param inBH non-zero if called in bottom half.
+ * @param[out] newChannel newly allocated channel.
+ * @return zero if successful, non-zero otherwise.
+ * @sideeffects Initializes the communications channel with given parameters
+ */
+
+int
+CommSvc_Alloc(const CommTranspInitArgs *transpArgs,
+ const CommImpl *impl,
+ int inBH,
+ CommChannel *newChannel)
+{
+ return Comm_Alloc(transpArgs, impl, inBH, newChannel);
+}
+
+
+/**
+ * @brief Zombifies a channel. May fail if channel isn't active.
+ * @param channel channel to zombify.
+ * @param inBH non-zero if called in bottom half.
+ * @return zero if channel zombified, non-zero otherwise.
+ */
+
+int
+CommSvc_Zombify(CommChannel channel,
+ int inBH)
+{
+ return Comm_Zombify(channel, inBH);
+}
+
+
+/**
+ * @brief Reports whether a channel is active.
+ * @param channel channel to report on.
+ * @return non-zero if channel active, zero otherwise.
+ */
+
+int
+CommSvc_IsActive(CommChannel channel)
+{
+ return Comm_IsActive(channel);
+}
+
+
+/**
+ * @brief Retrieves a channel's transport initialization arguments.
+ * It doesn't lock, the caller must ensure the channel may be accessed.
+ * @param channel CommChannel structure to get initialization arguments from.
+ * @return initialization arguments used to allocate/attach to channel.
+ */
+
+CommTranspInitArgs
+CommSvc_GetTranspInitArgs(CommChannel channel)
+{
+ return Comm_GetTranspInitArgs(channel);
+}
+
+
+/**
+ * @brief Retrieves upper layer state (pointer). It doesn't lock, the caller
+ * must ensure the channel may be accessed.
+ * @param channel CommChannel structure to get state from.
+ * @return pointer to upper layer state.
+ */
+
+void *
+CommSvc_GetState(CommChannel channel)
+{
+ return Comm_GetState(channel);
+}
+
+
+/**
+ * @brief Writes a fully formatted packet (containing payload data, if
+ * applicable) to the specified channel.
+ *
+ * The operation may block until enough write space is available, but no
+ * more than the specified interval. The operation either writes the full
+ * amount of bytes, or it fails. Warning: callers must _not_ use the
+ * _Lock/_Unlock functions to bracket calls to this function.
+ * @param[in,out] channel channel to write to.
+ * @param packet packet to write.
+ * @param[in,out] timeoutMillis interval in milliseconds to wait.
+ * @return number of bytes written, 0 if it times out, -1 error.
+ * @sideeffects Data may be written to the channel.
+ */
+
+int
+CommSvc_Write(CommChannel channel,
+ const CommPacket *packet,
+ unsigned long long *timeoutMillis)
+{
+ return Comm_Write(channel, packet, timeoutMillis);
+}
+
+
+/**
+ * @brief Writes a packet and associated payload data to the specified channel.
+ *
+ * The operation may block until enough write space is available, but not
+ * more than the specified interval. The operation either writes the full
+ * amount of bytes, or it fails. Users may call this function successively
+ * to write several packets from large {io|k}vecs. If that's the case, the
+ * packet header needs to be updated in between calls, for the different
+ * (total) lengths. Warning: callers must _not_ use the _Lock/_Unlock
+ * functions to bracket calls to this function.
+ * @param[in,out] channel the specified channel
+ * @param packet packet to write
+ * @param[in,out] vec kvec to write from
+ * @param[in,out] vecLen length of kvec
+ * @param[in,out] timeoutMillis interval in milliseconds to wait
+ * @param[in,out] iovOffset must be set to 0 before first call (internal cookie)
+ * @return number of bytes written, 0 if it timed out, -1 error
+ * @sideeffects data may be written to the channel
+ */
+
+int
+CommSvc_WriteVec(CommChannel channel,
+ const CommPacket *packet,
+ struct kvec **vec,
+ unsigned int *vecLen,
+ unsigned long long *timeoutMillis,
+ unsigned int *iovOffset)
+{
+ return Comm_WriteVec(channel, packet, vec, vecLen, timeoutMillis, iovOffset);
+}
+
+
+/**
+ * @brief Releases channel ref count. This function is exported for the upper
+ * layer's 'activateNtf' callback which may be run asynchronously. The
+ * callback is protected from concurrent channel releases until it calls
+ * this function.
+ * @param[in,out] channel CommChannel structure to release.
+ */
+
+void
+CommSvc_Put(CommChannel channel)
+{
+ Comm_Put(channel);
+}
+
+
+/**
+ * @brief Uses the read lock. This function is exported for the upper layer
+ * such that it can order acquisition of a different lock (socket) with
+ * the release of the dispatch lock.
+ * @param[in,out] channel CommChannel structure to unlock.
+ */
+
+void
+CommSvc_DispatchUnlock(CommChannel channel)
+{
+ Comm_DispatchUnlock(channel);
+}
+
+
+/**
+ * @brief Lock the channel.
+ *
+ * Uses the writer lock. This function is exported for the upper layer
+ * to ensure that channel isn't closed while updating the layer state.
+ * It also guarantees that if the lock is taken, the entry is either ACTIVE
+ * or ZOMBIE. Operations using this function are expected to be short,
+ * since unlike the _Write functions, these callers cannot be signaled.
+ * @param[in,out] channel CommChannel structure to lock.
+ * @return zero if successful, -1 otherwise.
+ */
+
+int
+CommSvc_Lock(CommChannel channel)
+{
+ return Comm_Lock(channel);
+}
+
+
+/**
+ * @brief Unlock the channel.
+ *
+ * Uses the writer lock. This function is exported for the upper layer
+ * to ensure that channel isn't closed while updating the layer state.
+ * See Comm_WriteLock for details).
+ * @param[in,out] channel CommChannel structure to unlock.
+ */
+
+void
+CommSvc_Unlock(CommChannel channel)
+{
+ Comm_Unlock(channel);
+}
+
+
+/**
+ * @brief Schedules a work item on the AIO thread(s).
+ * @param[in,out] work work item to be scheduled.
+ * @return zero if successful, -1 otherwise.
+ */
+
+int
+CommSvc_ScheduleAIOWork(CommOSWork *work)
+{
+ return CommOS_ScheduleAIOWork(work);
+}
+
+
+/**
+ * @brief Requests events be posted in-line after the function completes.
+ * @param channel channel object.
+ * @return current number of requests for inline event posting, or -1 on error.
+ */
+
+unsigned int
+CommSvc_RequestInlineEvents(CommChannel channel)
+{
+ return Comm_RequestInlineEvents(channel);
+}
+
+
+/**
+ * @brief Requests events be posted out-of-band after the function completes.
+ * @param channel channel object.
+ * @return current number of requests for inline event posting, or -1 on error.
+ */
+
+unsigned int
+CommSvc_ReleaseInlineEvents(CommChannel channel)
+{
+ return Comm_ReleaseInlineEvents(channel);
+}
+
+
+#if defined(__linux__)
+EXPORT_SYMBOL(CommSvc_RegisterImpl);
+EXPORT_SYMBOL(CommSvc_UnregisterImpl);
+EXPORT_SYMBOL(CommSvc_Alloc);
+EXPORT_SYMBOL(CommSvc_Zombify);
+EXPORT_SYMBOL(CommSvc_IsActive);
+EXPORT_SYMBOL(CommSvc_GetTranspInitArgs);
+EXPORT_SYMBOL(CommSvc_GetState);
+EXPORT_SYMBOL(CommSvc_Write);
+EXPORT_SYMBOL(CommSvc_WriteVec);
+EXPORT_SYMBOL(CommSvc_Put);
+EXPORT_SYMBOL(CommSvc_DispatchUnlock);
+EXPORT_SYMBOL(CommSvc_Lock);
+EXPORT_SYMBOL(CommSvc_Unlock);
+EXPORT_SYMBOL(CommSvc_ScheduleAIOWork);
+EXPORT_SYMBOL(CommSvc_RequestInlineEvents);
+EXPORT_SYMBOL(CommSvc_ReleaseInlineEvents);
+#endif // defined(__linux__)
diff --git a/arch/arm/mvp/commkm/comm_svc.h b/arch/arm/mvp/commkm/comm_svc.h
new file mode 100644
index 0000000..c4f3292
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_svc.h
@@ -0,0 +1,71 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Communication functions exported by the comm_rt module.
+ */
+
+#ifndef _COMM_SVC_H_
+#define _COMM_SVC_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "comm.h"
+
+int CommSvc_RegisterImpl(const CommImpl *impl);
+void CommSvc_UnregisterImpl(const CommImpl *impl);
+int CommSvc_Zombify(CommChannel channel, int inBH);
+int CommSvc_IsActive(CommChannel channel);
+CommTranspInitArgs CommSvc_GetTranspInitArgs(CommChannel channel);
+void *CommSvc_GetState(CommChannel channel);
+void CommSvc_Put(CommChannel channel);
+void CommSvc_DispatchUnlock(CommChannel channel);
+int CommSvc_Lock(CommChannel channel);
+void CommSvc_Unlock(CommChannel channel);
+int CommSvc_ScheduleAIOWork(CommOSWork *work);
+
+int
+CommSvc_Alloc(const CommTranspInitArgs *transpArgs,
+ const CommImpl *impl,
+ int inBH,
+ CommChannel *newChannel);
+
+int
+CommSvc_Write(CommChannel channel,
+ const CommPacket *packet,
+ unsigned long long *timeoutMillis);
+
+int
+CommSvc_WriteVec(CommChannel channel,
+ const CommPacket *packet,
+ struct kvec **vec,
+ unsigned int *vecLen,
+ unsigned long long *timeoutMillis,
+ unsigned int *iovOffset);
+
+unsigned int CommSvc_RequestInlineEvents(CommChannel channel);
+unsigned int CommSvc_ReleaseInlineEvents(CommChannel channel);
+
+#endif // _COMM_SVC_H_
diff --git a/arch/arm/mvp/commkm/comm_transp.h b/arch/arm/mvp/commkm/comm_transp.h
new file mode 100644
index 0000000..6cc58ae
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_transp.h
@@ -0,0 +1,90 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Generic shared memory transport API.
+ */
+
+#ifndef _COMM_TRANSP_H_
+#define _COMM_TRANSP_H_
+
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/*
+ * Common shared memory identifier.
+ * External handle that makes sense to both hypervisor and guest.
+ */
+
+#define COMM_TRANSP_ID_8_ANY ((unsigned char)-1)
+#define COMM_TRANSP_ID_32_ANY ((unsigned int)-1)
+#define COMM_TRANSP_ID_64_ANY ((unsigned long long)-1)
+
+
+typedef struct CommTranspID {
+ union {
+ unsigned char d8[8];
+ unsigned int d32[2];
+ unsigned long long d64;
+ };
+} CommTranspID;
+
+
+/* Basic initialization arguments. */
+
+typedef enum CommTranspInitMode {
+ COMM_TRANSP_INIT_CREATE = 0x0,
+ COMM_TRANSP_INIT_ATTACH = 0x1
+} CommTranspInitMode;
+
+typedef struct CommTranspInitArgs {
+ unsigned int capacity; // Shared memory capacity.
+ unsigned int type; // Type / implementation using this area.
+ CommTranspID id; // ID (name) of shared memory area.
+ CommTranspInitMode mode; // Init mode (above).
+} CommTranspInitArgs;
+
+
+/**
+ * @brief Generate a type id from description (protocol) string. This function
+ * uses djb2, a string hashing algorithm by Dan Bernstein.
+ * (see http://www.cse.yorku.ca/~oz/hash.html)
+ * @param str string to hash
+ * @return 32-bit hash value
+ */
+
+static inline unsigned int
+CommTransp_GetType(const char *str)
+{
+ unsigned int hash = 5381;
+ int c;
+
+ while ((c = *str++)) {
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ }
+ return hash;
+}
+
+#endif // _COMM_TRANSP_H_
diff --git a/arch/arm/mvp/commkm/comm_transp_impl.h b/arch/arm/mvp/commkm/comm_transp_impl.h
new file mode 100644
index 0000000..113cd21
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_transp_impl.h
@@ -0,0 +1,165 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Generic shared memory transport private API.
+ */
+
+#ifndef _COMM_TRANSP_IMPL_H_
+#define _COMM_TRANSP_IMPL_H_
+
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "comm_transp.h"
+
+
+/* Shared memory opaque descriptor/handle. Only meaningful locally. */
+
+typedef struct CommTranspPriv *CommTransp;
+
+
+/* Asynchronous signaling initialization arguments. */
+
+typedef enum CommTranspIOEvent {
+ COMM_TRANSP_IO_DETACH = 0x0,
+ COMM_TRANSP_IO_IN = 0x1,
+ COMM_TRANSP_IO_OUT = 0x2,
+ COMM_TRANSP_IO_INOUT = 0x3
+} CommTranspIOEvent;
+
+typedef struct CommTranspEvent {
+ void (*ioEvent)(CommTransp transp, CommTranspIOEvent event, void *data);
+ void *ioEventData;
+} CommTranspEvent;
+
+
+/*
+ * Mechanism to detect and optionally attach to, created shared memory regions.
+ */
+
+typedef struct CommTranspListener {
+ int (*probe)(CommTranspInitArgs *transpArgs, void *probeData);
+ void *probeData;
+} CommTranspListener;
+
+
+
+/*
+ * Function prototypes.
+ */
+
+int CommTranspEvent_Init(void);
+void CommTranspEvent_Exit(void);
+int CommTranspEvent_Process(CommTranspID *transpID, CommTranspIOEvent event);
+int
+CommTranspEvent_Raise(unsigned int peerEvID,
+ CommTranspID *transpID,
+ CommTranspIOEvent event);
+
+int CommTransp_Init(void);
+void CommTransp_Exit(void);
+
+int CommTransp_Register(const CommTranspListener *listener);
+void CommTransp_Unregister(const CommTranspListener *listener);
+int
+CommTransp_Notify(const CommTranspID *notificationCenterID,
+ CommTranspInitArgs *transpArgs);
+
+int
+CommTransp_Open(CommTransp *transp,
+ CommTranspInitArgs *transpArgs,
+ CommTranspEvent *transpEvent);
+void CommTransp_Close(CommTransp transp);
+
+int CommTransp_EnqueueSpace(CommTransp transp);
+int CommTransp_EnqueueReset(CommTransp transp);
+int CommTransp_EnqueueCommit(CommTransp transp);
+int
+CommTransp_EnqueueSegment(CommTransp transp,
+ const void *buf,
+ unsigned int bufLen);
+
+int CommTransp_DequeueSpace(CommTransp transp);
+int CommTransp_DequeueReset(CommTransp transp);
+int CommTransp_DequeueCommit(CommTransp transp);
+int
+CommTransp_DequeueSegment(CommTransp transp,
+ void *buf,
+ unsigned int bufLen);
+
+unsigned int CommTransp_RequestInlineEvents(CommTransp transp);
+unsigned int CommTransp_ReleaseInlineEvents(CommTransp transp);
+
+
+/**
+ * @brief Enqueues data into the transport object, data is available for
+ * reading immediately.
+ * @param transp handle to the transport object.
+ * @param buf bytes to enqueue.
+ * @param bufLen number of bytes to enqueue.
+ * @return number of bytes enqueued on success, < 0 otherwise.
+ */
+
+static inline int
+CommTransp_EnqueueAtomic(CommTransp transp,
+ const void *buf,
+ unsigned int bufLen)
+{
+ int rc;
+
+ CommTransp_EnqueueReset(transp);
+ rc = CommTransp_EnqueueSegment(transp, buf, bufLen);
+ if (CommTransp_EnqueueCommit(transp)) {
+ rc = -1;
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Dequeues data from the transport object into a buffer.
+ * @param transp handle to the transport object.
+ * @param[out] buf buffer to copy to.
+ * @param bufLen number of bytes to dequeue.
+ * @return number of bytes dequeued on success, < 0 otherwise,
+ */
+
+static inline int
+CommTransp_DequeueAtomic(CommTransp transp,
+ void *buf,
+ unsigned int bufLen)
+{
+ int rc;
+
+ CommTransp_DequeueReset(transp);
+ rc = CommTransp_DequeueSegment(transp, buf, bufLen);
+ if (CommTransp_DequeueCommit(transp)) {
+ rc = -1;
+ }
+ return rc;
+}
+
+#endif // _COMM_TRANSP_IMPL_H_
diff --git a/arch/arm/mvp/commkm/comm_transp_mvp.c b/arch/arm/mvp/commkm/comm_transp_mvp.c
new file mode 100644
index 0000000..f755de9
--- /dev/null
+++ b/arch/arm/mvp/commkm/comm_transp_mvp.c
@@ -0,0 +1,944 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Generic shared memory transport API.
+ */
+#include <linux/wait.h>
+
+#include "comm_os.h"
+#include "comm_transp_impl.h"
+
+#include "mvp_types.h"
+#include "qp.h"
+
+
+/*
+ * Opaque CommTransp structure. See comm_transp.h
+ */
+
+struct CommTranspPriv {
+ QPHandle *qp;
+ CommTranspEvent event;
+ unsigned int peerEvID;
+ unsigned int writeSize;
+ unsigned int readSize;
+ uint32 backRef;
+ CommOSWork work;
+ CommOSAtomic raiseInline;
+};
+
+/*
+ * Transport table object accounting
+ */
+
+typedef struct TranspTableEntry {
+ CommOSAtomic holds;
+ CommTransp transp;
+ CommOSWaitQueue wq;
+} TranspTableEntry;
+
+TranspTableEntry transpTable[QP_MAX_QUEUE_PAIRS];
+static CommOSSpinlock_Define(transpTableLock);
+
+/**
+ * @brief Destroy the transport object
+ * @param transp transport object to destroy
+ * @sideeffects detaches from queue pair
+ */
+
+static void
+DestroyTransp(CommTransp transp)
+{
+ CommTranspID transpID;
+ int32 rc;
+
+ if (!transp) {
+ CommOS_Debug(("Failed to close channel: Bad handle\n"));
+ return;
+ }
+
+ CommOS_Log(("%s: Detaching channel [%u:%u]\n",
+ __FUNCTION__,
+ transp->qp->id.context,
+ transp->qp->id.resource));
+
+ transpID.d32[0] = transp->qp->id.context;
+ transpID.d32[1] = transp->qp->id.resource;
+
+#if !defined(COMM_BUILDING_SERVER)
+ /*
+ * Tell the host to detach, will block in the host
+ * until the host has unmapped memory. Once the
+ * host has unmapped, it is safe to free.
+ */
+ CommTranspEvent_Raise(transp->peerEvID,
+ &transpID,
+ COMM_TRANSP_IO_DETACH);
+#endif
+
+ rc = QP_Detach(transp->qp);
+
+#if defined(COMM_BUILDING_SERVER)
+ /*
+ * Wake up waiters now that unmapping is complete
+ */
+ CommOS_WakeUp(&transpTable[transp->backRef].wq);
+#endif
+
+ CommOS_Kfree(transp);
+ if (rc != QP_SUCCESS) {
+ CommOS_Log(("%s: Failed to detach. rc: %d\n", __FUNCTION__, rc));
+ } else {
+ CommOS_Log(("%s: Channel detached.\n", __FUNCTION__));
+ }
+}
+
+
+/**
+ * @brief Initialize the transport object table
+ */
+
+static void
+TranspTableInit(void)
+{
+ uint32 i;
+ CommOS_SpinLock(&transpTableLock);
+ for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) {
+ CommOS_WriteAtomic(&transpTable[i].holds, -1);
+ transpTable[i].transp = NULL;
+ }
+ CommOS_SpinUnlock(&transpTableLock);
+}
+
+
+/**
+ * @brief Add a transport object into the table
+ * @param transp handle to the transport object
+ * @return 0 on success, -1 otherwise
+ * @sideeffects increments entry refcount
+ */
+
+static inline int32
+TranspTableAdd(CommTransp transp)
+{
+ uint32 i;
+
+ if (!transp) {
+ return -1;
+ }
+
+ CommOS_SpinLock(&transpTableLock);
+ for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) {
+ if ((transpTable[i].transp) == NULL) {
+ transpTable[i].transp = transp;
+ CommOS_WriteAtomic(&transpTable[i].holds, 1);
+ CommOS_WaitQueueInit(&transpTable[i].wq);
+ transp->backRef = i;
+ break;
+ }
+ }
+ CommOS_SpinUnlock(&transpTableLock);
+
+ return 0;
+}
+
+/**
+ * @brief retrieve a transport object and increment its ref count
+ * @param id transport id to retrieve
+ * @return transport object, or NULL if not found
+ * @sideeffects increments entry ref count
+ */
+
+static inline CommTransp
+TranspTableGet(CommTranspID *id)
+{
+ CommTransp transp;
+ uint32 i;
+
+ if (!id) {
+ return NULL;
+ }
+
+ for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) {
+ transp = transpTable[i].transp;
+ if (transp &&
+ (transp->qp->id.context == id->d32[0]) &&
+ (transp->qp->id.resource == id->d32[1])) {
+ CommOS_AddReturnAtomic(&transpTable[i].holds, 1);
+ return transp;
+ }
+ }
+ CommOS_Debug(("%s: couldn't find transport object\n", __FUNCTION__));
+
+ return NULL;
+}
+
+/**
+ * @brief Puts back a previously TranspGet-ed transport object.
+ * @param transp the transport object.
+ * @sideeffects decrements the transport reference count.
+ * frees object if refcount now zero
+ */
+
+static inline void
+TranspTablePut(CommTransp transp)
+{
+ int32 holds;
+ int32 backRef;
+ if (!transp) {
+ return;
+ }
+
+ backRef = transp->backRef;
+ BUG_ON(backRef >= QP_MAX_QUEUE_PAIRS);
+
+ holds = CommOS_SubReturnAtomic(&transpTable[backRef].holds, 1);
+ if (holds > 0) {
+ return;
+ }
+ BUG_ON(holds < 0);
+
+ CommOS_SpinLock(&transpTableLock);
+ CommOS_WriteAtomic(&transpTable[backRef].holds, -1);
+ transpTable[backRef].transp = NULL;
+ CommOS_SpinUnlock(&transpTableLock);
+ DestroyTransp(transp);
+}
+
+
+/**
+ * @brief Puts back a previously TranspGet-ed transport object.
+ * @param transp the transport object.
+ * @sideeffects decrements the transport reference count.
+ * asserts that remaining count > 0
+ */
+
+static inline void
+TranspTablePutNF(CommTransp transp)
+{
+ int32 holds;
+ int32 backRef;
+ if (!transp) {
+ return;
+ }
+
+ backRef = transp->backRef;
+ BUG_ON(backRef >= QP_MAX_QUEUE_PAIRS);
+
+ holds = CommOS_SubReturnAtomic(&transpTable[backRef].holds, 1);
+ BUG_ON(holds <= 0);
+}
+
+
+/**
+ * @brief Raises INOUT event in-line or out-of-band. Note that this function
+ * expects the transport object to be held prior to being called.
+ * @param arg work item of transport object.
+ */
+
+static void
+RaiseEvent(CommOSWork *arg)
+{
+#if !defined(__linux__)
+#error "RaiseEvent() is only supported on linux. Port 'container_of'!"
+#endif
+ CommTransp transp = container_of(arg, struct CommTranspPriv, work);
+ CommTranspID transpID = {{
+ .d32 = {
+ [0] = transp->qp->id.context,
+ [1] = transp->qp->id.resource
+ }
+ }};
+
+ CommTranspEvent_Raise(transp->peerEvID,
+ &transpID,
+ COMM_TRANSP_IO_INOUT);
+ TranspTablePut(transp);
+}
+
+
+/**
+ * @brief Requests events be posted in-line after the function completes.
+ * @param transp transport object.
+ * @return current number of requests for inline event posting.
+ * @sideeffects posts an event on the first transition to in-line processing.
+ */
+
+unsigned int
+CommTransp_RequestInlineEvents(CommTransp transp)
+{
+ unsigned int res = CommOS_AddReturnAtomic(&transp->raiseInline, 1);
+ if (res == 1) {
+ /* On the first (effective) transition, make sure an event is raised. */
+
+ CommOS_AddReturnAtomic(&transpTable[transp->backRef].holds, 1);
+ RaiseEvent(&transp->work);
+ }
+ return res;
+}
+
+
+/**
+ * @brief Requests events be posted out-of-band after the function completes.
+ * @param transp transport object.
+ * @return current number of requests for inline event posting.
+ */
+
+unsigned int
+CommTransp_ReleaseInlineEvents(CommTransp transp)
+{
+ return CommOS_SubReturnAtomic(&transp->raiseInline, 1);
+}
+
+
+/*
+ * Comm Offload server callbacks.
+ */
+
+#if defined(COMM_BUILDING_SERVER)
+
+#define COMM_MAX_LISTENERS QP_MAX_LISTENERS
+
+static int32 NotifyCB(const QPInitArgs *args);
+static void DetachCB(void *data);
+
+static CommOSSpinlock_Define(listenersLock);
+static CommTranspListener listeners[COMM_MAX_LISTENERS];
+static uint32 numListeners = 0;
+
+
+/**
+ * @brief Notify callback when guests attach to queue pairs. Notifies any
+ * registered listeners (e.g. Comm layer).
+ * @param args Initialization arguments used by the guest to initialize
+ * its queue pair
+ * @return 0 on success, <0 otherwise. see qp.h for error codes.
+ */
+
+static int32
+NotifyCB(const QPInitArgs* args)
+{
+ CommTranspInitArgs transpArgs;
+ uint32 i;
+ int32 rc = -1;
+
+ if (!args) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ transpArgs.id.d32[0] = args->id.context;
+ transpArgs.id.d32[1] = args->id.resource;
+ transpArgs.capacity = args->capacity;
+ transpArgs.type = args->type;
+
+ CommOS_SpinLock(&listenersLock);
+ for (i = 0; i < COMM_MAX_LISTENERS; i++) {
+ if (listeners[i].probe &&
+ (listeners[i].probe(&transpArgs, listeners[i].probeData) == 0)) {
+ CommOS_Debug(("%s: Delivered notify event to listener %u\n",
+ __FUNCTION__,
+ i));
+ rc = 0;
+ break;
+ }
+ }
+ CommOS_SpinUnlock(&listenersLock);
+ return rc;
+}
+
+
+/**
+ * @brief Detach callback when guests detach from queue pairs. Notifies
+ * any registered listeners (e.g. CommComm layer).
+ * @param data Transport object passed when the callback was registered
+ */
+
+static void
+DetachCB(void *data)
+{
+ CommTransp transp = data;
+ if (!transp || !(transp->event.ioEvent)) {
+ return;
+ }
+ CommOS_Debug(("%s: Guest detached from [%u:%u]\n",
+ __FUNCTION__,
+ transp->qp->id.context,
+ transp->qp->id.resource));
+ transp->event.ioEvent(transp, COMM_TRANSP_IO_DETACH, transp->event.ioEventData);
+}
+#endif
+
+
+/**
+ * @brief Performs one-time initialization of mvp transport provider.
+ * @return 0 on success, < 0 otherwise.
+ */
+
+int
+CommTransp_Init(void)
+{
+ int32 rc;
+ TranspTableInit();
+
+ rc = CommTranspEvent_Init();
+
+#if defined(COMM_BUILDING_SERVER)
+ if (!rc) {
+ QP_RegisterListener(NotifyCB);
+ }
+#endif
+ return rc;
+}
+
+
+/**
+ * @brief Performs clean-up of mvp transport provider.
+ */
+
+void
+CommTransp_Exit(void)
+{
+ CommTranspEvent_Exit();
+#if defined(COMM_BUILDING_SERVER)
+ QP_UnregisterListener(NotifyCB);
+#endif
+}
+
+#if defined(COMM_BUILDING_SERVER)
+
+/**
+ * @brief Checks for a successful detach from Comm
+ * @param arg1 back reference index for channel in transport table
+ * @param arg2 ignored
+ * @return 1 if detach completed, 0 otherwise
+ */
+
+static int
+DetachCondition(void *arg1, void *arg2)
+{
+ uint32 backRef = (uint32)arg1;
+
+ return (CommOS_ReadAtomic(&transpTable[backRef].holds) == -1);
+}
+#endif
+
+
+/**
+ * @brief Processes a raised signal event. This is a callback function called
+ * from a comm_transp_ev plugin when a signal is received. Delivers an event
+ * to one or more channels. If id->d32[1] == COMM_TRANSP_ID_32_ANY, the event
+ * will be delivered to all registered channels associated with vmID
+ * id->d32[0].
+ * @param id identifies a transport object to signal.
+ * @param event type of event.
+ * @return 0 if delivered to at least one channel, -1 on failure.
+ */
+
+int
+CommTranspEvent_Process(CommTranspID *id,
+ CommTranspIOEvent event)
+{
+ int rc = 0;
+ unsigned int delivered = 0;
+ unsigned int backRef;
+ int i = 0;
+
+ CommTransp transp;
+ uint32 raiseOnAllChannels = (id->d32[1] == COMM_TRANSP_ID_32_ANY);
+ uint32 channels = raiseOnAllChannels ? QP_MAX_QUEUE_PAIRS : 1;
+
+ while (channels--) {
+ if (raiseOnAllChannels) {
+ id->d32[1] = i++;
+ }
+ transp = TranspTableGet(id);
+ if (transp) {
+ if (transp->event.ioEvent) {
+ transp->event.ioEvent(transp, event, transp->event.ioEventData);
+ }
+ backRef = transp->backRef;
+ TranspTablePut(transp);
+
+#if defined(COMM_BUILDING_SERVER)
+ /*
+ * Wait for unmap on IO_DETACH, return to monitor.
+ */
+ if (event == COMM_TRANSP_IO_DETACH) {
+ unsigned long long timeout = 30000;
+
+ rc = CommOS_Wait(&transpTable[backRef].wq,
+ DetachCondition,
+ (void*)backRef,
+ NULL,
+ &timeout);
+ switch (rc) {
+ case 1: // Memory successfully unmapped
+ rc = 0;
+ break;
+ default: // Timed out or other error.
+ return -1;
+ }
+ }
+#endif
+ delivered++;
+ }
+ }
+
+ rc = (delivered > 0) ? 0 : -1;
+ return rc;
+}
+
+
+/**
+ * @brief Register a listener to be notified when guests attach to the Comm
+ * offload server
+ * @param listener the listener to be notified
+ * @return 0 on success, -1 on failure
+ */
+
+int
+CommTransp_Register(const CommTranspListener *listener)
+{
+ int32 rc = -1;
+#if defined(COMM_BUILDING_SERVER)
+ uint32 i;
+
+ if (!listener) {
+ return -1;
+ }
+
+ CommOS_SpinLock(&listenersLock);
+ for (i = 0; i < COMM_MAX_LISTENERS; i++) {
+ if ((listeners[i].probe == NULL) &&
+ (listeners[i].probeData == NULL)) {
+ listeners[i] = *listener;
+ numListeners++;
+ rc = 0;
+ CommOS_Debug(("%s: Registered listener %u\n", __FUNCTION__, i));
+ break;
+ }
+ }
+ CommOS_SpinUnlock(&listenersLock);
+#endif
+ return rc;
+}
+
+
+/**
+ * @brief Unregisters a listener from the transport event notification system
+ * @param listener listener to unregister
+ * @return 0 on success
+ */
+
+void
+CommTransp_Unregister(const CommTranspListener *listener)
+{
+#if defined(COMM_BUILDING_SERVER)
+ uint32 i;
+
+ if (!listener || !listener->probe) {
+ return;
+ }
+
+
+ CommOS_SpinLock(&listenersLock);
+ for (i = 0; i < COMM_MAX_LISTENERS; i++) {
+ if ((listeners[i].probe == listener->probe) &&
+ (listeners[i].probeData == listener->probeData)) {
+ listeners[i].probe = NULL;
+ listeners[i].probeData = NULL;
+ numListeners--;
+ CommOS_Debug(("%s: Unregistered listener %u\n", __FUNCTION__, i));
+ }
+ }
+ CommOS_SpinUnlock(&listenersLock);
+#endif
+}
+
+
+/**
+ * @brief Allocates and initializes a transport object
+ * @param[in,out] transp handle to the transport to allocate and initialize
+ * @param transpArgs initialization arguments (see pvtcpTransp.h)
+ * @param transpEvent event callback to be delivered when events occur (e.g.
+ * detach events)
+ * @return 0 on success, <0 otherwise. See qp.h for error codes.
+ * @sideeffects Allocates memory
+ */
+
+int
+CommTransp_Open(CommTransp *transp,
+ CommTranspInitArgs *transpArgs,
+ CommTranspEvent *transpEvent)
+{
+ int32 rc = -1;
+ QPHandle *qp = NULL;
+ CommTransp transpOut = NULL;
+ QPInitArgs qpInitArgs;
+
+ if (!transp || !transpArgs) {
+ return -1;
+ }
+
+ CommOS_Log(("%s: Attaching to [%u:%u]. Capacity: %u\n",
+ __FUNCTION__,
+ transpArgs->id.d32[1],
+ transpArgs->id.d32[0],
+ transpArgs->capacity));
+
+ qpInitArgs.id.context = transpArgs->id.d32[0];
+ qpInitArgs.id.resource = transpArgs->id.d32[1];
+ qpInitArgs.capacity = transpArgs->capacity;
+ qpInitArgs.type = transpArgs->type;
+
+ if (!(transpOut = CommOS_Kmalloc(sizeof *transpOut))) {
+ rc = -1;
+ goto out;
+ }
+
+ /*
+ * Attach to the queue pair
+ */
+ rc = QP_Attach(&qpInitArgs, &qp);
+ if (rc < 0) {
+ rc = -1;
+ goto out;
+ }
+
+ transpOut->qp = qp;
+
+ /*
+ * Reassign ID so Comm knows what ID was actually given
+ */
+ transpArgs->id.d32[0] = qp->id.context;
+ transpArgs->id.d32[1] = qp->id.resource;
+
+ if (transpEvent) {
+ transpOut->event = *transpEvent;
+ } else {
+ transpOut->event.ioEvent = NULL;
+ transpOut->event.ioEventData = NULL;
+ }
+
+#if defined(COMM_BUILDING_SERVER)
+ CommOS_Debug(("%s: Registering detach CB on id %u...\n",
+ __FUNCTION__, transpArgs->id.d32[1]));
+ QP_RegisterDetachCB(transpOut->qp, DetachCB, transpOut);
+#endif
+
+ transpOut->peerEvID = COMM_TRANSP_ID_32_ANY;
+ transpOut->writeSize = 0;
+ transpOut->readSize = 0;
+ CommOS_InitWork(&transpOut->work, RaiseEvent);
+ CommOS_WriteAtomic(&transpOut->raiseInline, 0);
+
+ if (TranspTableAdd(transpOut)) {
+ CommOS_Log(("%s: Exceeded max limit of transport objects!\n",
+ __FUNCTION__));
+ DestroyTransp(transpOut);
+ rc = -1;
+ goto out;
+ }
+
+ *transp = transpOut;
+ rc = 0;
+
+ CommOS_Log(("%s: Channel attached.\n", __FUNCTION__));
+
+out:
+ if (rc && transpOut) {
+ CommOS_Log(("%s: Failed to attach: %d\n", __FUNCTION__, rc));
+ CommOS_Kfree(transpOut);
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Tear down the transport channel, destroy the object if the refcount
+ * drops to zero
+ * @param transp handle to the transport channel
+ * @sideeffects decrements the entry's refcount
+ */
+
+void
+CommTransp_Close(CommTransp transp) {
+ if (!transp) {
+ return;
+ }
+ CommOS_FlushAIOWork(&transp->work);
+ TranspTablePut(transp);
+}
+
+
+/**
+ * @brief Returns available space for enqueue, in bytes
+ * @param transp handle to the transport object
+ * @return available space in the queue for enqueue operations, <0
+ * on error conditions. see qp.h for error codes.
+ */
+
+int
+CommTransp_EnqueueSpace(CommTransp transp)
+{
+ if (!transp) {
+ return -1;
+ }
+ return QP_EnqueueSpace(transp->qp);
+}
+
+
+/**
+ * @brief Discards any pending enqueues
+ * @param transp handle to the transport object
+ * @return 0 on success, <0 otherwise. see qp.h for error codes
+ */
+
+int
+CommTransp_EnqueueReset(CommTransp transp)
+{
+ if (!transp) {
+ return -1;
+ }
+ transp->writeSize = 0;
+ return QP_EnqueueReset(transp->qp);
+}
+
+
+/**
+ * @brief Enqueues a segment of data into the transport object
+ * @param transp handle to the transport object
+ * @param buf data to enqueue
+ * @param bufLen number of bytes to enqueue
+ * @return number of bytes enqueued on success, <0 otherwise. see qp.h
+ * for error codes
+ */
+
+int
+CommTransp_EnqueueSegment(CommTransp transp,
+ const void *buf,
+ unsigned int bufLen)
+{
+ int rc;
+
+ if (!transp) {
+ return -1;
+ }
+ rc = QP_EnqueueSegment(transp->qp, (void*)buf, bufLen);
+ if (rc >= 0) {
+ transp->writeSize += (unsigned int)rc;
+ } else {
+ transp->writeSize = 0;
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Commits any previous EnqueueSegment operations to the transport
+ * object.
+ * @param transp handle to the transport object.
+ * @return 0 on success, < 0 otherwise.
+ */
+
+int
+CommTransp_EnqueueCommit(CommTransp transp)
+{
+ int rc;
+
+ if (!transp) {
+ return -1;
+ }
+
+ rc = QP_EnqueueCommit(transp->qp);
+ if (rc >= 0) {
+ const unsigned int fudge = 4;
+ int writable = CommTransp_EnqueueSpace(transp);
+
+ if ((writable >= 0) &&
+ ((transp->writeSize + (unsigned int)writable + fudge) >=
+ transp->qp->queueSize)) {
+ /*
+ * If bytes written since last commit + writable space 'almost'
+ * equal write queue size, then signal. The 'almost' fudge factor
+ * accounts for a possibly inaccurate CommTransp_EnqueueSpace()
+ * return value. Most of the time, this is inconsequential. In
+ * rare, borderline occasions, it results in a few extra signals.
+ * The scheme essentially means this: if this is the first packet
+ * to be write-committed, we signal. Otherwise, the remote end is
+ * supposed to keep going for as long as it can read.
+ *
+ */
+
+ BUG_ON(transp->backRef >= QP_MAX_QUEUE_PAIRS);
+ CommOS_AddReturnAtomic(&transpTable[transp->backRef].holds, 1);
+ if (CommOS_ReadAtomic(&transp->raiseInline)) {
+ RaiseEvent(&transp->work);
+ } else if (CommOS_ScheduleAIOWork(&transp->work)) {
+ TranspTablePutNF(transp);
+ }
+ }
+ } else {
+ rc = -1;
+ }
+ transp->writeSize = 0;
+ return rc;
+}
+
+
+/**
+ * @brief Returns any available bytes for dequeue
+ * @param transp handle to the transport object
+ * @return available bytes for dequeue, <0 otherwise. see qp.h for error codes
+ */
+
+int
+CommTransp_DequeueSpace(CommTransp transp)
+{
+ if (!transp) {
+ return -1;
+ }
+ return QP_DequeueSpace(transp->qp);
+}
+
+
+/**
+ * @brief Discards any pending dequeues
+ * @param transp handle to the transport object
+ * @return 0 on success, <0 otherwise, see qp.h for error codes
+ */
+
+int
+CommTransp_DequeueReset(CommTransp transp)
+{
+ if (!transp) {
+ return -1;
+ }
+ transp->readSize = 0;
+ return QP_DequeueReset(transp->qp);
+}
+
+
+/**
+ * @brief Dequeues a segment of data from the consumer queue into
+ * a buffer
+ * @param transp handle to the transport object
+ * @param[out] buf buffer to copy to
+ * @param bufLen number of bytes to dequeue
+ * @return number of bytes dequeued on success, <0 otherwise,
+ * see qp.h for error codes
+ */
+
+int
+CommTransp_DequeueSegment(CommTransp transp,
+ void *buf,
+ unsigned bufLen)
+{
+ int rc;
+
+ if (!transp) {
+ return -1;
+ }
+ rc = QP_DequeueSegment(transp->qp, buf, bufLen);
+ if (rc >= 0) {
+ transp->readSize += (unsigned int)rc;
+ } else {
+ transp->readSize = 0;
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Commits any previous DequeueSegment operations to the
+ * transport object.
+ * @param transp handle to the transport object.
+ * @return 0 on success, < 0 otherwise.
+ */
+
+int
+CommTransp_DequeueCommit(CommTransp transp)
+{
+ int rc;
+
+ if (!transp) {
+ return -1;
+ }
+ rc = QP_DequeueCommit(transp->qp);
+ if (rc >= 0) {
+ int readable = CommTransp_DequeueSpace(transp);
+ const unsigned int limit = transp->qp->queueSize / 2;
+
+ if ((readable >= 0) &&
+ (transp->readSize + (unsigned int)readable >= limit) &&
+ ((unsigned int)readable < limit)) {
+ /*
+ * Minimize the number of likely 'peer write OK' signalling:
+ * only do it, if reading crossed half-way down.
+ *
+ */
+
+ BUG_ON(transp->backRef >= QP_MAX_QUEUE_PAIRS);
+ CommOS_AddReturnAtomic(&transpTable[transp->backRef].holds, 1);
+ if (CommOS_ReadAtomic(&transp->raiseInline)) {
+ RaiseEvent(&transp->work);
+ } else if (CommOS_ScheduleAIOWork(&transp->work)) {
+ TranspTablePut(transp);
+ }
+ }
+ } else {
+ rc = -1;
+ }
+ /* coverity[deref_after_free] */
+ transp->readSize = 0;
+ return rc;
+}
+
+
+/**
+ * @brief Notify any registered listeners for the given queue pair
+ * @param notificationCenterID noop, unused on MVP
+ * @param transpArgs initialization arguments used by the guest for this
+ * channel
+ * @sideeffects the host may attach to the queue pair
+ */
+
+int
+CommTransp_Notify(const CommTranspID *notificationCenterID,
+ CommTranspInitArgs *transpArgs)
+{
+ QPInitArgs args;
+
+ args.id.context = transpArgs->id.d32[0];
+ args.id.resource = transpArgs->id.d32[1];
+ args.capacity = transpArgs->capacity;
+ args.type = transpArgs->type;
+
+ CommOS_Debug(("%s: d32[0]: %u d32[1]: %u\n",
+ __FUNCTION__,
+ transpArgs->id.d32[0],
+ transpArgs->id.d32[1]));
+ QP_Notify(&args);
+ return 0;
+}
diff --git a/arch/arm/mvp/commkm/fatalerror.h b/arch/arm/mvp/commkm/fatalerror.h
new file mode 100644
index 0000000..9676ff3
--- /dev/null
+++ b/arch/arm/mvp/commkm/fatalerror.h
@@ -0,0 +1,126 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief fatal error handlers. They all post fatal errors regardless of build
+ * type.
+ */
+
+#ifndef _FATALERROR_H
+#define _FATALERROR_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mvp_compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum FECode {
+ FECodeMisc, ///< generic FATAL() call of sorts
+ FECodeOOM, ///< FATAL_OOM() call of sorts
+ FECodeAssert, ///< ASSERT() call of sorts
+ FECodeNR, ///< NOT_REACHED() call of sorts
+ FECodeNI, ///< NOT_IMPLEMENTED() call of sorts
+ FECodeNT, ///< NOT_TESTED() call of sorts
+ FECodeCF ///< COMPILE_FAIL() call of sorts
+};
+typedef enum FECode FECode;
+
+#define FATAL() FatalError(__FILE__, __LINE__, FECodeMisc, 0, NULL)
+#define FATAL_IF(x) do { if (UNLIKELY(x)) FATAL(); } while (0)
+#define FATAL_OOM() FatalError(__FILE__, __LINE__, FECodeOOM, 0, NULL)
+#define FATAL_OOM_IF(x) do { if (UNLIKELY(x)) FATAL_OOM(); } while (0)
+
+extern _Bool FatalError_hit;
+
+void NORETURN FatalError(char const *file,
+ int line,
+ FECode feCode,
+ int bugno,
+ char const *fmt,
+ ...) FORMAT(printf,5,6);
+
+#define FATALERROR_COMMON(printFunc, \
+ printFuncV, \
+ file, \
+ line, \
+ feCode, \
+ bugno, \
+ fmt) { \
+ va_list ap; \
+ \
+ printFunc("FatalError: %s:%d, code %d, bugno %d\n", \
+ file, line, feCode, bugno); \
+ if (fmt != NULL) { \
+ va_start(ap, fmt); \
+ printFuncV(fmt, ap); \
+ va_end(ap); \
+ } \
+ }
+
+#if defined IN_HOSTUSER || defined IN_GUESTUSER || defined IN_WORKSTATION
+
+#define FATALERROR_POSIX_USER \
+void \
+FatalError_VErrPrintf(const char *fmt, va_list ap) \
+{ \
+ vfprintf(stderr, fmt, ap); \
+} \
+\
+void \
+FatalError_ErrPrintf(const char *fmt, ...) \
+{ \
+ va_list ap; \
+ va_start(ap, fmt); \
+ FatalError_VErrPrintf(fmt, ap); \
+ va_end(ap); \
+} \
+\
+void NORETURN \
+FatalError(char const *file, \
+ int line, \
+ FECode feCode, \
+ int bugno, \
+ const char *fmt, \
+ ...) \
+{ \
+ FATALERROR_COMMON(FatalError_ErrPrintf, FatalError_VErrPrintf, file, line, feCode, bugno, fmt); \
+ exit(EXIT_FAILURE); \
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/arch/arm/mvp/commkm/include_check.h b/arch/arm/mvp/commkm/include_check.h
new file mode 100644
index 0000000..2eeafe7
--- /dev/null
+++ b/arch/arm/mvp/commkm/include_check.h
@@ -0,0 +1,18 @@
+/*
+ * Linux 2.6.32 and later Kernel module for Empty File Placeholder
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
diff --git a/arch/arm/mvp/commkm/mksck.h b/arch/arm/mvp/commkm/mksck.h
new file mode 100644
index 0000000..e9e10bc
--- /dev/null
+++ b/arch/arm/mvp/commkm/mksck.h
@@ -0,0 +1,153 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#ifndef _MKSCK_H
+#define _MKSCK_H
+
+/**
+ * @file
+ *
+ * @brief The monitor-kernel socket interface definitions.
+ *
+ * The monitor kernel socket interface was created for (what the name
+ * says) communications between the monitor and host processes. On the
+ * monitor side a special API is introduced, see mksck_vmm.h. On the
+ * host side the API is the standard Berkeley socket interface. Host
+ * process to host process or monitor to monitor communication is not
+ * supported.
+ *
+ * A generic address consists of two 16 bit fields: the vm id and the
+ * port id. Both hosts (vmx) and monitors (vmm) get their vm id
+ * automatically. The host vm id is assigned at the time the host
+ * process opens the mvpkm file descriptor, while the monitor vm id is
+ * assigned when the vmx.c:SetupWorldSwitchPage() calls
+ * Mvpkm_SetupIds(). As a vmx may create multiple monitors to service
+ * an MP guest, a vmx vm id may be associated with multiple monitor vm
+ * ids. A monitor id, however, has a single associated vmx host id,
+ * the id of its canonical vmx.
+ *
+ * Sockets on the host get their addresses either by explicit user
+ * call (the bind command) or implicitly by (issuing a send command
+ * first). At an explicit bind the user may omit one or both fields by
+ * providing MKSCK_VMID_UNDEF/MKSCK_PORT_UNDEF respectively. An
+ * implicit bind behaves as if both fields were omitted in an explicit
+ * bind. The default value of the vmid field is the vmid computed from
+ * the thread group id while that of a port is a new number. It is not
+ * invalid to bind a host process socket with a vm id different from
+ * the vmid computed from the tgid.
+ *
+ * Sockets of the monitor are automatically assigned a vmid, that of their
+ * monitor, at the time of their creation. The port id can be assigned by the
+ * user or left to the implementation to assign an unused one (by specifying
+ * MKSCK_PORT_UNDEF at @ref Mksck_Open).
+ *
+ * Host unconnected sockets may receive from any monitor sender, may send to any
+ * monitor socket. A socket can be connected to a peer address, that enables the
+ * use of the send command.
+ *
+ * One of many special predefined port (both host and monitor) is
+ * MKSCK_PORT_MASTER. It is used for initialization.
+ *
+ * Monitor sockets have to send their peer address explicitly (by
+ * Mksck_SetPeer()) or implicitly by receiving first. After the peer
+ * is set, monitor sockets may send or receive only to/from their
+ * peer.
+ */
+
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "vmid.h"
+
+/*
+ * The interface limits the size of transferable packets.
+ */
+#define MKSCK_XFER_MAX 1024
+
+#define MKSCK_ADDR_UNDEF (uint32)0xffffffff
+
+#define MKSCK_PORT_UNDEF (uint16)0xffff
+#define MKSCK_PORT_MASTER (MKSCK_PORT_UNDEF-1)
+#define MKSCK_PORT_HOST_FB (MKSCK_PORT_UNDEF-2)
+#define MKSCK_PORT_BALLOON (MKSCK_PORT_UNDEF-3)
+#define MKSCK_PORT_HOST_HID (MKSCK_PORT_UNDEF-4)
+#define MKSCK_PORT_CHECKPOINT (MKSCK_PORT_UNDEF-5)
+#define MKSCK_PORT_COMM_EV (MKSCK_PORT_UNDEF-6)
+#define MKSCK_PORT_HIGH (MKSCK_PORT_UNDEF-7)
+
+#define MKSCK_VMID_UNDEF VMID_UNDEF
+#define MKSCK_VMID_HIGH (MKSCK_VMID_UNDEF-1)
+
+#define MKSCK_DETACH 3
+
+typedef uint16 Mksck_Port;
+typedef VmId Mksck_VmId;
+
+/**
+ * @brief Page descriptor for typed messages. Each page describes a region of
+ * the machine address space with base mpn and size 2^(12 + order) bytes.
+ */
+typedef struct {
+ uint32 mpn : 20; ///< Base MPN of region described by page
+ uint32 order : 12; ///< Region is 2^(12 + order) bytes.
+} Mksck_PageDesc;
+
+/**
+ * @brief Typed message template macro. Allows us to avoid having two message
+ * types, one with page descriptor vector (for VMM), one without (for
+ * VMX).
+ *
+ * @param type C type of uninterpreted component of the message (following the
+ * page descriptor vector).
+ * @param pages number of page descriptors in vector.
+ */
+#define MKSCK_DESC_TYPE(type,pages) \
+ struct { \
+ type umsg; \
+ Mksck_PageDesc page[pages]; \
+ }
+
+/**
+ * @brief The monitor kernel socket interface address format
+ */
+typedef union {
+ uint32 addr; ///< the address
+ struct { /* The address is decomposed to two shorts */
+ Mksck_Port port; ///< port unique within a vmid
+ Mksck_VmId vmId; ///< unique vmid
+ };
+} Mksck_Address;
+
+static inline uint32
+Mksck_AddrInit(Mksck_VmId vmId, Mksck_Port port)
+{
+ Mksck_Address aa;
+ aa.vmId = vmId;
+ aa.port = port;
+ return aa.addr;
+}
+#endif
diff --git a/arch/arm/mvp/commkm/mksck_sockaddr.h b/arch/arm/mvp/commkm/mksck_sockaddr.h
new file mode 100644
index 0000000..82df240
--- /dev/null
+++ b/arch/arm/mvp/commkm/mksck_sockaddr.h
@@ -0,0 +1,50 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Host user space definitions for mksck sockets.
+ */
+
+#ifndef _MKSCK_SOCKADDR_H_
+#define _MKSCK_SOCKADDR_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mksck.h"
+
+/* no one ever uses DECnet anymore? */
+#define AF_MKSCK AF_DECnet
+#define PF_MKSCK PF_DECnet
+
+/* Address structure used by the host user socket interface. */
+struct sockaddr_mk {
+ sa_family_t mk_family;
+ Mksck_Address mk_addr;
+};
+
+#endif
diff --git a/arch/arm/mvp/commkm/mvp.h b/arch/arm/mvp/commkm/mvp.h
new file mode 100644
index 0000000..a57f8cc
--- /dev/null
+++ b/arch/arm/mvp/commkm/mvp.h
@@ -0,0 +1,48 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief top-level include for all basic includes.
+ * This file should not define anything of its own.
+ */
+
+#ifndef _MVP_H
+#define _MVP_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mvp_compiler.h"
+#include "utils.h"
+#include "mvp_assert.h"
+#include "mvp_types.h"
+#include "platdefx.h"
+
+#endif
diff --git a/arch/arm/mvp/commkm/mvp_assert.h b/arch/arm/mvp/commkm/mvp_assert.h
new file mode 100644
index 0000000..cbc5ed8
--- /dev/null
+++ b/arch/arm/mvp/commkm/mvp_assert.h
@@ -0,0 +1,125 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief ASSERT() and related macros.
+ */
+
+#ifndef _MVP_ASSERT_H
+#define _MVP_ASSERT_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define ASSERT(_x) ASSERT_BUG((_x),0)
+
+#ifndef NDEBUG
+#define ASSERT_BUG(_x,_tkt) do { \
+ if (UNLIKELY(!(_x))) { \
+ FatalError(__FILE__, __LINE__, FECodeAssert, _tkt, NULL); \
+ } \
+} while (0)
+
+#define ASSERTF(_x, ...) do { \
+ if (UNLIKELY(!(_x))) { \
+ FatalError(__FILE__, \
+ __LINE__, \
+ FECodeAssert, \
+ 0, \
+ __VA_ARGS__); \
+ } \
+} while (0)
+#else
+
+#define ASSERT_BUG(_x,_tkt) (void)sizeof((int)(_x))
+#define ASSERTF(_x, ...) ASSERT_BUG(_x, 0)
+
+#endif
+
+/*
+ * Compile-time assertions.
+ *
+ * ASSERT_ON_COMPILE does not use the common
+ * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC)
+ * generate code for it.
+ *
+ * The implementation uses both enum and typedef because the typedef alone is
+ * insufficient; gcc allows arrays to be declared with non-constant expressions
+ * (even in typedefs, where it makes no sense).
+ */
+#ifdef __COVERITY__
+#define ASSERT_ON_COMPILE(e) ASSERT(e)
+#else
+#define ASSERT_ON_COMPILE(e) \
+ do { \
+ enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \
+ typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \
+ } while (0)
+#endif
+
+/*
+ * To put an ASSERT_ON_COMPILE() outside a function, wrap it
+ * in MY_ASSERTS(). The first parameter must be unique in
+ * each .c file where it appears. For example,
+ *
+ * MY_ASSERTS(FS3_INT,
+ * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128);
+ * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE);
+ * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE);
+ * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16);
+ * )
+ *
+ * Caution: ASSERT() within MY_ASSERTS() is silently ignored.
+ * The same goes for anything else not evaluated at compile time.
+ */
+
+#define MY_ASSERTS(name, assertions) \
+ static inline void name(void) { \
+ assertions \
+ }
+
+#define KNOWN_BUG(_tkt)
+
+#define NOT_IMPLEMENTED() NOT_IMPLEMENTED_JIRA(0)
+#define NOT_IMPLEMENTED_JIRA(_tkt,...) FatalError(__FILE__, __LINE__, FECodeNI, _tkt, NULL)
+
+#define NOT_IMPLEMENTED_IF(_x) NOT_IMPLEMENTED_IF_JIRA((_x),0)
+#define NOT_IMPLEMENTED_IF_JIRA(_x,_tkt,...) do { if (UNLIKELY(_x)) NOT_IMPLEMENTED_JIRA(_tkt); } while (0)
+/*
+ * All sites tagged with this are @knownjira{MVP-1855}.
+ */
+#define NOT_IMPLEMENTEDF(...) FatalError(__FILE__, __LINE__, FECodeNI, 0, __VA_ARGS__)
+
+#define NOT_REACHED() FatalError(__FILE__, __LINE__, FECodeNR, 0, NULL)
+
+#include "fatalerror.h"
+#include "nottested.h"
+
+#endif
diff --git a/arch/arm/mvp/commkm/mvp_compiler.h b/arch/arm/mvp/commkm/mvp_compiler.h
new file mode 100644
index 0000000..21af455
--- /dev/null
+++ b/arch/arm/mvp/commkm/mvp_compiler.h
@@ -0,0 +1,56 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Compiler-related definitions and directives.
+ */
+
+#ifndef _MVP_COMPILER_H_
+#define _MVP_COMPILER_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#ifdef __GNUC__
+#include "mvp_compiler_gcc.h"
+#else /* __GNUC__ */
+#include "mvp_compiler_other.h"
+#endif /* __GNUC__ */
+
+/**
+ * @brief Find last set bit.
+ *
+ * @param n unsigned 32-bit integer.
+ *
+ * @return 0 if n == 0 otherwise 32 - the number of leading zeroes in n.
+ */
+#define FLS(n) (32 - CLZ(n))
+
+#endif /// ifndef _MVP_COMPILER_H_
diff --git a/arch/arm/mvp/commkm/mvp_compiler_gcc.h b/arch/arm/mvp/commkm/mvp_compiler_gcc.h
new file mode 100644
index 0000000..fbc96e3
--- /dev/null
+++ b/arch/arm/mvp/commkm/mvp_compiler_gcc.h
@@ -0,0 +1,87 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief common definitions for GCC
+ */
+
+#ifndef _MVP_COMPILER_GCC_H
+#define _MVP_COMPILER_GCC_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @brief Count leading zeroes.
+ *
+ * @param n unsigned 32-bit integer.
+ *
+ * @return 32 if n == 0 otherwise 31 - the bit position of the most significant 1
+ * in n.
+ */
+#ifdef __COVERITY__
+static inline int
+CLZ(unsigned int n)
+{
+ unsigned int r = 0;
+
+ while (n) {
+ r++;
+ n >>= 1;
+ }
+
+ return 32 - r;
+}
+#else
+#define CLZ(n) __builtin_clz(n)
+#endif
+
+#define PACKED __attribute__ ((packed))
+#define ALLOC __attribute__ ((malloc, warn_unused_result))
+#define UNUSED __attribute__ ((unused))
+#define PURE __attribute__ ((pure))
+#define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+#define FORMAT(x,y,z) __attribute__ ((format(x,y,z)))
+#define LIKELY(x) __builtin_expect(!!(x), 1)
+#define UNLIKELY(x) __builtin_expect((x), 0)
+
+/*
+ * For debug builds, we want to omit __attribute__((noreturn)) so that gcc will
+ * keep stack linkages and then we will have useful core dumps. For non-debug
+ * builds, we don't care about the stack frames and want the little bit of
+ * optimization that noreturn gives us.
+ */
+#if defined(__COVERITY__) || !defined(MVP_DEBUG)
+#define NORETURN __attribute__((noreturn))
+#else
+#define NORETURN
+#endif
+
+#endif
diff --git a/arch/arm/mvp/commkm/mvp_types.h b/arch/arm/mvp/commkm/mvp_types.h
new file mode 100644
index 0000000..ba5c04c
--- /dev/null
+++ b/arch/arm/mvp/commkm/mvp_types.h
@@ -0,0 +1,94 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief basic type definitions.
+ * These may need to be conditionalized for different compilers/platforms.
+ */
+
+#ifndef _MVPTYPES_H
+#define _MVPTYPES_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+typedef long long int64;
+
+typedef uint32 CVA; // whatever we are compiling the code as
+typedef uint32 GVA; // guest virtual addresses
+typedef uint32 MVA; // monitor virtual addresses
+typedef uint32 HKVA; // host kernel virtual addresses
+typedef uint32 HUVA; // host user virtual addresses
+typedef uint64 PA; // (guest) physical addresses (40-bit)
+typedef uint32 MA; // (host) machine addresses
+
+typedef uint32 PPN; // PA/PAGE_SIZE
+typedef uint32 MPN; // MA/PAGE_SIZE
+
+typedef uint64 cycle_t;
+
+/**
+ * @brief Page segment.
+ *
+ * Specifies a segment within a single page.
+ */
+typedef struct {
+ uint16 off;
+ uint16 len;
+} PageSeg;
+
+/*
+ * GCC's argument checking for printf-like functions
+ *
+ * fmtPos is the position of the format string argument, beginning at 1
+ * varPos is the position of the variable argument, beginning at 1
+ */
+
+#if defined(__GNUC__)
+# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
+#else
+# define PRINTF_DECL(fmtPos, varPos)
+#endif
+
+#if defined(__GNUC__)
+# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
+#else
+# define SCANF_DECL(fmtPos, varPos)
+#endif
+
+#endif /* _MVPTYPES_H */
diff --git a/arch/arm/mvp/commkm/mvpkm_comm_ev.h b/arch/arm/mvp/commkm/mvpkm_comm_ev.h
new file mode 100644
index 0000000..b220a9b
--- /dev/null
+++ b/arch/arm/mvp/commkm/mvpkm_comm_ev.h
@@ -0,0 +1,53 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief mvpkm kernel hooks for comm event signaling
+ */
+
+#ifndef _MVPKM_COMM_EV_H
+#define _MVPKM_COMM_EV_H
+
+extern int (*CommTranspEvProcess)(CommTranspID* id, CommTranspIOEvent event);
+
+/**
+ * @brief Forward any guest signal requests to the commkm module
+ * @param id transport channel id
+ * @param event comm event type
+ */
+
+static inline void
+Mvpkm_CommEvSignal(CommTranspID *id, CommTranspIOEvent event)
+{
+ if (CommTranspEvProcess) {
+ CommTranspEvProcess(id, event);
+ }
+}
+
+void
+Mvpkm_CommEvRegisterProcessCB(int (*commProcessFunc)(CommTranspID*,
+ CommTranspIOEvent));
+void Mvpkm_CommEvUnregisterProcessCB(void);
+
+
+
+#endif
diff --git a/arch/arm/mvp/commkm/nottested.h b/arch/arm/mvp/commkm/nottested.h
new file mode 100644
index 0000000..c5c1e26
--- /dev/null
+++ b/arch/arm/mvp/commkm/nottested.h
@@ -0,0 +1,54 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief NOT_TESTED() and related.
+ */
+
+#ifndef _NOTTESTED_H
+#define _NOTTESTED_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include <stdbool.h>
+
+#ifdef NOT_TESTED_ENABLED
+#define NotTestedEnabled true
+#else
+#define NotTestedEnabled false
+#endif
+
+#define NOT_TESTED() NOT_TESTED_JIRA(0)
+#define NOT_TESTED_JIRA(_tkt,...) NotTested(_tkt, __FILE__, __LINE__)
+
+void NotTested(int tkt, char const *file, int line);
+
+#endif
diff --git a/arch/arm/mvp/commkm/platdefx.h b/arch/arm/mvp/commkm/platdefx.h
new file mode 100644
index 0000000..42953e6
--- /dev/null
+++ b/arch/arm/mvp/commkm/platdefx.h
@@ -0,0 +1,67 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Basic platform definitions needed various places.
+ */
+
+#ifndef _PLATDEFX_H
+#define _PLATDEFX_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define PAGE_ORDER 12
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (1UL << PAGE_ORDER)
+#endif
+#if PAGE_SIZE != 4096
+#error bad page size PAGE_SIZE
+#endif
+
+#define PA_2_PPN(_pa) ((_pa) / PAGE_SIZE)
+#define PPN_2_PA(_ppn) ((_ppn) * PAGE_SIZE)
+
+#define VMM_DOMAIN 0x0
+#define VMM_DOMAIN_NO_ACCESS 0x3
+#define VMM_DOMAIN_CLIENT 0x1
+#define VMM_DOMAIN_MANAGER 0x4
+
+#define INVALID_CVA (-(CVA)1)
+#define INVALID_GVA (-(GVA)1)
+#define INVALID_MVA (-(MVA)1)
+#define INVALID_HKVA (-(HKVA)1)
+#define INVALID_HUVA (-(HUVA)1)
+
+#define INVALID_MPN (((MPN)-1) >> ARM_L2D_SMALL_ORDER)
+#define INVALID_PPN (((PPN)-1) >> ARM_L2D_SMALL_ORDER)
+
+#endif
diff --git a/arch/arm/mvp/commkm/qp.h b/arch/arm/mvp/commkm/qp.h
new file mode 100644
index 0000000..d4a50ec
--- /dev/null
+++ b/arch/arm/mvp/commkm/qp.h
@@ -0,0 +1,332 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MVP Queue Pairs function and structure declarations
+ *
+ * MVP Queue Pairs:
+ *
+ * Queue pairs are intended to be a generic bulk data transport mechanism
+ * between the guest and host kernels. The queue pair abstraction is based
+ * on two ring buffers (queues) placed on a shared memory region mapped
+ * into both guest and host kernel address spaces.
+ *
+ * NOTE: Queue pairs are SINGLE-READER, SINGLE-WRITER. Any caller is
+ * responsible for multi-reader/writer serialization!!!
+ *
+ * There are a maximum of QP_MAX_QUEUE_PAIRS in the system, with a maximum
+ * size of QP_MAX_CAPACITY per pair. Each queue pair is identified by
+ * an ID.
+ *
+ * Each peer follows a producer-consumer model in which one side is the
+ * producer on one queue, and the other side is the consumer on that queue
+ * (and vice-versa for its pair).
+ *
+ * Data is enqueued and dequeued into the pair in transactional stages,
+ * meaning each enqueue/dequeue can be followed by zero or more
+ * enqueue/dequeues, but the enqueue/dequeue is not visible to the peer
+ * until it has been committed with the *Commit() function.
+ * In PVTCP, for example, this is used to enqueue a short header, then
+ * followed by 'segments' of iovecs, then followed by a commit. This
+ * model prevents a peer from reading the header, expecting a payload,
+ * but not being able to read the payload because it hasn't been
+ * enqueued yet.
+ *
+ * Queue Pair setup:
+ *
+ * Before data can be passed, the guest and host kernel must perform
+ * the following connection handshake:
+ *
+ * 1). A host kernel service registers a listener with the queue pair
+ * subsystem with a callback to be called when guests create
+ * and attach to a shared memory region.
+ *
+ * 2). Guest initiates an QP_Attach() operation to a shared memory region
+ * keyed by ID. This step allocates memory, maps it into the host
+ * address space, and optionally notifies any host services who are
+ * listening for attach requests from the guest (see previous step).
+ * Host listeners are provided with a copy of the initialization
+ * arguments used by the guest (id, size, service type). All registered
+ * listeners are iterated over until one of them handles the attach
+ * request and acknowledges with QP_SUCCESS.
+ *
+ * 3). The registered host callback is called, notifying the host that
+ * the guest has attached.
+ *
+ * 4). The host can now QP_Attach() to the shared memory region with the same
+ * arguments as the guest. The queue pair is now well formed and enqueues
+ * and dequeues can proceed on either side.
+ *
+ * Queue Pair teardown:
+ *
+ * 1). As before, teardowns are initiated by the guest. Hosts can register
+ * a callback to be called upon detach. Guests initiate a teardown
+ * through a call to QP_Detach().
+ *
+ * 2). Registered hosts are notified through the aforementioned callback.
+ * 3). The host service can call QP_Detach() at its own leisure. Memory
+ * is freed, the queue pair is destroyed.
+ *
+ * If at any point the guest unexpectedly shuts down, the host will be
+ * notified at monitor shutdown time. Memory is freed, and the queue
+ * pair is destroyed.
+ *
+ */
+
+#ifndef _QP_H
+#define _QP_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+//#define QP_DEBUG 1
+
+typedef enum QPState {
+ QP_STATE_FREE = 0x1, ///< No peers, not memory-backed
+ QP_STATE_CONNECTED, ///< Both peers attached , memory backed
+ QP_STATE_GUEST_ATTACHED, ///< Guest allocated memory, host not yet attached
+ QP_STATE_MAX // leave this at the end!
+} QPState;
+
+typedef struct QPId {
+ uint32 context;
+ uint32 resource;
+} QPId;
+
+/*
+ * Initialization arguments for each queue pair
+ */
+typedef struct QPInitArgs {
+ QPId id; ///< Shared memory region ID
+ uint32 capacity; ///< Total size of shared region in bytes
+ uint32 type; ///< Type of queue pair (PVTCP, other)...
+} QPInitArgs;
+
+/*
+ * Placed on the shared region, two per region
+ */
+typedef struct QHandle {
+ volatile uint32 head; ///< queue head offset
+ volatile uint32 tail; ///< queue tail offset
+ volatile uint32 phantom_head; ///< queue shadow head offset
+ volatile uint32 phantom_tail; ///< queue shadow tail offset
+ uint8 data[0]; ///< start of data, runs off
+ // the struct
+} QHandle;
+
+/*
+ * Local to each peer
+ */
+typedef struct QPHandle {
+ QPId id; ///< shared memory region ID
+ uint32 capacity; ///< size of region in bytes
+ QHandle *produceQ; ///< producer queue
+ QHandle *consumeQ; ///< consumer queue
+ uint32 queueSize; ///< size of each queue in bytes
+ uint32 type; ///< type of queue pair
+
+ /*
+ * Following fields unused by guest
+ */
+ QPState state;
+ void (*peerDetachCB)(void* data); ///< detach notification callback
+ void *detachData; ///< data for the detach cb
+ struct page **pages; ///< page pointers for shared region
+} QPHandle;
+
+/*
+ * QP Error codes
+ */
+#define QP_SUCCESS 0
+#define QP_ERROR_NO_MEM (-1)
+#define QP_ERROR_INVALID_HANDLE (-2)
+#define QP_ERROR_INVALID_ARGS (-3)
+#define QP_ERROR_ALREADY_ATTACHED (-4)
+
+/*
+ * Hard-coded limits
+ */
+#define QP_MIN_CAPACITY (PAGE_SIZE * 2)
+#define QP_MAX_CAPACITY (1024*1024) // 1M
+#define QP_MAX_QUEUE_PAIRS 32
+#define QP_MAX_ID QP_MAX_QUEUE_PAIRS
+#define QP_MAX_LISTENERS QP_MAX_QUEUE_PAIRS
+#define QP_MAX_PAGES (QP_MAX_CAPACITY/PAGE_SIZE) // 256 pages
+
+#define QP_INVALID_ID 0xFFFFFFFF
+#define QP_INVALID_SIZE 0xFFFFFFFF
+#define QP_INVALID_REGION 0xFFFFFFFF
+#define QP_INVALID_TYPE 0xFFFFFFFF
+
+#ifdef __KERNEL__
+/**
+ * @brief Utility function to sanity check arguments
+ * @param args argument structure to check
+ * @return true if arguments are sane, false otherwise
+ */
+static inline
+_Bool QP_CheckArgs(QPInitArgs *args)
+{
+ if (!args ||
+ !is_power_of_2(args->capacity) ||
+ (args->capacity < QP_MIN_CAPACITY) ||
+ (args->capacity > QP_MAX_CAPACITY) ||
+ !(args->id.resource < QP_MAX_ID || args->id.resource == QP_INVALID_ID) ||
+ (args->type == QP_INVALID_TYPE)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+#endif
+
+
+/**
+ * @brief Utility function to sanity check a queue pair handle
+ * @param qp handle to the queue pair
+ * @return true if the handle is sane, false otherwise
+ */
+static inline
+_Bool QP_CheckHandle(QPHandle *qp)
+{
+#ifdef MVP_DEBUG
+ if (!(qp) ||
+ !(qp->produceQ) ||
+ !(qp->consumeQ) ||
+ (qp->state >= (uint32)QP_STATE_MAX) ||
+ !(qp->queueSize < (QP_MAX_CAPACITY/2))) {
+ return false;
+ } else {
+ return true;
+ }
+#else
+ return true;
+#endif
+}
+
+
+/**
+ * @brief Initializes an invalid handle
+ * @param[in, out] qp handle to the queue pair
+ */
+static inline void
+QP_MakeInvalidQPHandle(QPHandle *qp)
+{
+ if (!qp) {
+ return;
+ }
+
+ qp->id.context = QP_INVALID_ID;
+ qp->id.resource = QP_INVALID_ID;
+ qp->capacity = QP_INVALID_SIZE;
+ qp->produceQ = NULL;
+ qp->consumeQ = NULL;
+ qp->queueSize = QP_INVALID_SIZE;
+ qp->type = QP_INVALID_TYPE;
+ qp->state = QP_STATE_FREE;
+ qp->peerDetachCB = NULL;
+ qp->detachData = NULL;
+}
+
+/*
+ * Host only
+ */
+typedef int32 (*QPListener)(const QPInitArgs*);
+int32 QP_RegisterListener(const QPListener);
+int32 QP_UnregisterListener(const QPListener);
+int32 QP_RegisterDetachCB(QPHandle *qp, void (*callback)(void*), void *data);
+
+
+/*
+ * Host and guest specific implementations, see qp_host.c and qp_guest.c
+ */
+int32 QP_Attach(QPInitArgs *args, QPHandle** qp);
+int32 QP_Detach(QPHandle* qp);
+int32 QP_Notify(QPInitArgs *args);
+
+/*
+ * Common implementation, see qp_common.c
+ */
+int32 QP_EnqueueSpace(QPHandle *qp);
+int32 QP_EnqueueSegment(QPHandle *qp, const void *buf, size_t length);
+int32 QP_EnqueueCommit(QPHandle *qp);
+int32 QP_EnqueueReset(QPHandle *qp);
+
+static inline int32
+QP_EnqueueAtomic(QPHandle *qp, const void *buf, size_t length)
+{
+ int32 rc;
+ QP_EnqueueReset(qp);
+ rc = QP_EnqueueSegment(qp, buf, length);
+ if (rc < 0) {
+ return rc;
+ } else {
+ QP_EnqueueCommit(qp);
+ }
+ return rc;
+}
+
+int32 QP_DequeueSpace(QPHandle *qp);
+int32 QP_DequeueSegment(QPHandle *qp, const void *buf, size_t length);
+int32 QP_DequeueReset(QPHandle *qp);
+int32 QP_DequeueCommit(QPHandle *qp);
+
+static inline int32
+QP_DequeueAtomic(QPHandle *qp, const void *buf, size_t length)
+{
+ int32 rc;
+ QP_DequeueReset(qp);
+ rc = QP_DequeueSegment(qp, buf, length);
+ if (rc < 0) {
+ return rc;
+ } else {
+ QP_DequeueCommit(qp);
+ }
+ return rc;
+}
+
+/*
+ * HVC methods and signatures
+ */
+#define MVP_QP_SIGNATURE 0x53525051 ///< 'QPRS'
+#define MVP_QP_ATTACH (MVP_OBJECT_CUSTOM_BASE + 0) ///< attach to a queue pair
+#define MVP_QP_DETACH (MVP_OBJECT_CUSTOM_BASE + 1) ///< detach from a queue pair
+#define MVP_QP_NOTIFY (MVP_OBJECT_CUSTOM_BASE + 2) ///< notify host of attach
+#define MVP_QP_LAST (MVP_OBJECT_CUSTOM_BASE + 3) ///< Number of methods
+
+/*
+ * Debug macros
+ */
+#ifdef QP_DEBUG
+ #ifdef IN_MONITOR
+ #define QP_DBG(...) Log(__VA_ARGS__)
+ #else
+ #define QP_DBG(...) printk(KERN_INFO __VA_ARGS__)
+ #endif
+#else
+ #define QP_DBG(...)
+#endif
+
+#endif
diff --git a/arch/arm/mvp/commkm/utils.h b/arch/arm/mvp/commkm/utils.h
new file mode 100644
index 0000000..b5f1e18
--- /dev/null
+++ b/arch/arm/mvp/commkm/utils.h
@@ -0,0 +1,172 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief General architecture-independent definitions, typedefs, and macros.
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define MAX_FILENAME 128
+
+// Round address up to given size boundary
+// Note: ALIGN() conflicts with Linux
+
+#define MVP_ALIGN(_v, _n) (((_v) + (_n) - 1) & -(_n))
+
+#define ALIGNVA(_addr, _size) MVP_ALIGN(_addr, _size)
+
+#define alignof(t) offsetof(struct { char c; typeof(t) x; }, x)
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define KB(_X_) ((_X_)*1024U)
+#define MB(_X_) (KB(_X_)*1024)
+#define GB(_X_) (MB(_X_)*1024)
+
+#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
+
+/*
+ * x in [low,high)
+ * args evaluated once
+ */
+#define RANGE(x,low,high) \
+ ({ \
+ typeof(x) _x = (x); \
+ typeof(x) _low = (typeof(x))(low); \
+ typeof(x) _high =(typeof(x))(high); \
+ (_Bool)( (_low <= _x) && (_x < _high)); \
+ })
+
+#define OBJECTS_PER_PAGE(_type) (PAGE_SIZE / sizeof(_type))
+
+#define MA_2_MPN(_ma) ((MPN)((_ma) / PAGE_SIZE))
+#define MPN_2_MA(_mpn) ((MA)((_mpn) * PAGE_SIZE))
+
+#define VA_2_VPN(_va) ((_va) / PAGE_SIZE)
+#define VPN_2_vA(_vpn) ((_vpn) * PAGE_SIZE)
+
+/*
+ * The following convenience macro can be used in a following situation
+ *
+ * send(..., &foo, sizeof(foo)) --> send(..., PTR_N_SIZE(foo))
+ */
+
+#define PTR_N_SIZE(_var) &(_var), sizeof(_var)
+
+
+/*
+ *
+ * BIT-PULLING macros
+ *
+ */
+#define MVP_BIT(val,n) ( ((val)>>(n))&1)
+#define MVP_BITS(val,m,n) (((val)<<(31-(n))) >> ((31-(n))+(m)) )
+#define MVP_EXTRACT_FIELD(w, m, n) MVP_BITS((w), (m), ((m) + (n) - 1))
+#define MVP_MASK(m, n) (MVP_EXTRACT_FIELD(~(uint32)0U, (m), (n)) << (m))
+#define MVP_UPDATE_FIELD(old_val, field_val, m, n) \
+ (((old_val) & ~MVP_MASK((m), (n))) | (MVP_EXTRACT_FIELD((field_val), 0, (n)) << (m)))
+
+/*
+ *
+ * 64BIT-PULLING macros
+ *
+ */
+#define MVP_BITS64(val,m,n) (((val)<<(63-(n))) >> ((63-(n))+(m)) )
+#define MVP_EXTRACT_FIELD64(w, m, n) MVP_BITS64((w), (m), ((m) + (n) - 1))
+#define MVP_MASK64(m, n) (MVP_EXTRACT_FIELD64(~(uint64)0ULL, (m), (n)) << (m))
+#define MVP_UPDATE_FIELD64(old_val, field_val, m, n) \
+ (((old_val) & ~MVP_MASK64((m), (n))) | (MVP_EXTRACT_FIELD64(((uint64)(field_val)), 0ULL, (n)) << (m)))
+
+/*
+ *
+ * BIT-CHANGING macros
+ *
+ */
+#define MVP_SETBIT(val,n) ((val)|=(1<<(n)))
+#define MVP_CLRBIT(val,n) ((val)&=(~(1<<(n))))
+
+/*
+ * Fixed bit-width sign extension.
+ */
+#define MVP_SIGN_EXTEND(val,width) \
+ (((val) ^ (1 << ((width) - 1))) - (1 << ((width) - 1)))
+
+
+/*
+ * Assembler helpers.
+ */
+#define _MVP_HASH #
+#define MVP_HASH() _MVP_HASH
+
+#define _MVP_STRINGIFY(...) #__VA_ARGS__
+#define MVP_STRINGIFY(...) _MVP_STRINGIFY(__VA_ARGS__)
+
+#ifndef __ASSEMBLER__
+
+#include <stddef.h>
+#include <stdbool.h>
+
+/*
+ * Constant equivalents of build-flags.
+ *
+ * Test these when possible instead of using #ifdef so that your code
+ * gets parsed.
+ */
+#ifdef MVP_DEBUG
+static const _Bool mvpDebug = true;
+#else
+static const _Bool mvpDebug = false;
+#endif
+
+#ifdef MVP_STATS
+static const _Bool mvpStats = true;
+#else
+static const _Bool mvpStats = false;
+#endif
+
+#ifdef MVP_DEVEL
+static const _Bool mvpDevel = true;
+#else
+static const _Bool mvpDevel = false;
+#endif
+
+#endif
+
+#endif
diff --git a/arch/arm/mvp/commkm/vmid.h b/arch/arm/mvp/commkm/vmid.h
new file mode 100644
index 0000000..f24a650
--- /dev/null
+++ b/arch/arm/mvp/commkm/vmid.h
@@ -0,0 +1,44 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Guest Communications
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#ifndef _VMID_H
+#define _VMID_H
+
+/**
+ * @file
+ *
+ * @brief The vmid definition
+ */
+
+
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define VMID_UNDEF (uint16)0xffff
+typedef uint16 VmId;
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/COPYING b/arch/arm/mvp/mvpkm/COPYING
new file mode 100644
index 0000000..10828e0
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/COPYING
@@ -0,0 +1,341 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/arch/arm/mvp/mvpkm/Kbuild b/arch/arm/mvp/mvpkm/Kbuild
new file mode 100644
index 0000000..fc2fe96
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/Kbuild
@@ -0,0 +1,24 @@
+# Warning: autogenerated
+obj-m := mvpkm.o
+mvpkm-objs := check_kconfig.o cpufreq_kernel.o mksck_kernel.o montimer_kernel.o mutex_kernel.o mvpkm_comm_ev.o mvpkm_main.o qp_host_kernel.o qp_common.o mksck_shared.o vfp_switch.o
+
+ccflags-y += -fno-pic -fno-dwarf2-cfi-asm -march=armv7-a -D__linux__
+ccflags-y += -mfpu=neon -DLIB_ARM_VERSION=7 -DIN_MODULE -DGPLED_CODE
+ccflags-y += --std=gnu89 -O2 -g2 -ggdb -mapcs -fno-optimize-sibling-calls -mno-sched-prolog
+ccflags-$(CONFIG_VMWARE_MVP_DEBUG) += -DMVP_DEBUG
+
+asflags-y += -mfpu=neon -DLIB_ARM_VERSION=7 -DIN_MODULE -DGPLED_CODE
+asflags-y += -mfloat-abi=softfp
+
+LOWMEMKILLER_PATH := $(srctree)/drivers/staging/android/lowmemorykiller.c
+ifeq ($(wildcard $(LOWMEMKILLER_PATH)),)
+$(error "Unable to find lowmemorykiller.c at $(LOWMEMKILLER_PATH)")
+endif
+LOWMEMKILLER_MD5 := $(shell md5sum $(LOWMEMKILLER_PATH) | cut -f1 -d\ )
+LOWMEMKILLER_SUPPORT := $(srctree)/arch/arm/mvp/mvpkm/lowmemkiller_variant.sh
+LOWMEMKILLER_SHRINK_MD5 := $(shell $(SHELL) $(LOWMEMKILLER_SUPPORT) $(LOWMEMKILLER_PATH) | cut -f1 -d\ )
+LOWMEMKILLER_VARIANT := $(shell $(SHELL) $(LOWMEMKILLER_SUPPORT) $(LOWMEMKILLER_PATH) | cut -f2 -d\ )
+ccflags-y += \
+ -DLOWMEMKILLER_VARIANT=$(LOWMEMKILLER_VARIANT) \
+ -DLOWMEMKILLER_SHRINK_MD5=$(LOWMEMKILLER_SHRINK_MD5) \
+ -DLOWMEMKILLER_MD5=$(LOWMEMKILLER_MD5)
diff --git a/arch/arm/mvp/mvpkm/Makefile b/arch/arm/mvp/mvpkm/Makefile
new file mode 100644
index 0000000..16eb389
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/Makefile
@@ -0,0 +1 @@
+# Warning: autogenerated
diff --git a/arch/arm/mvp/mvpkm/actions.h b/arch/arm/mvp/mvpkm/actions.h
new file mode 100644
index 0000000..0e89892
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/actions.h
@@ -0,0 +1,57 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Bit definitions for instrBActions.
+ */
+
+#ifndef _ACTIONS_H
+#define _ACTIONS_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define L2_ACTION_GDB 0 ///< drop into guest debugger GDB
+#define L2_ACTION_MKSCK 1 ///< scan the mksck pipes for incoming messages
+#define L2_ACTION_ABORT 2 ///< abort the monitor cleanly
+#define L2_ACTION_HALT 3 ///< halt the monitor
+#define L2_ACTION_FIQ 6 ///< the VCPU's FIQ pin is active
+#define L2_ACTION_IRQ 7 ///< the VCPU's IRQ pin is active
+#define L2_ACTION_CKPT 8 ///< do a checkpoint
+#define L2_ACTION_WFI 9 ///< wait for interrupt
+#define L2_ACTION_TIMER 10 ///< timer event
+#define L2_ACTION_BALLOON 11 ///< balloon trigger
+
+#define ACTION_GDB (1 << L2_ACTION_GDB)
+#define ACTION_MKSCK (1 << L2_ACTION_MKSCK)
+#define ACTION_ABORT (1 << L2_ACTION_ABORT)
+#define ACTION_HALT (1 << L2_ACTION_HALT)
+#define ACTION_IRQ (1 << L2_ACTION_IRQ)
+#define ACTION_FIQ (1 << L2_ACTION_FIQ)
+#define ACTION_CKPT (1 << L2_ACTION_CKPT)
+#define ACTION_WFI (1 << L2_ACTION_WFI)
+#define ACTION_TIMER (1 << L2_ACTION_TIMER)
+#define ACTION_BALLOON (1 << L2_ACTION_BALLOON)
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/arm_as_macros.h b/arch/arm/mvp/mvpkm/arm_as_macros.h
new file mode 100644
index 0000000..5a0b7fc
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/arm_as_macros.h
@@ -0,0 +1,91 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Macro definitions meta-ops to be used in assembler files
+ *
+ * This header contains asm macro definitions to be used in asm
+ * files only. This is intended to be the equivalent of arm_gcc_inline.h
+ */
+
+#ifndef _ARM_AS_MACROS_H_
+#define _ARM_AS_MACROS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "coproc_defs.h"
+
+/**
+ * @name The following macros re-arrange the order of the mcr/mrc operands
+ * making it suitable to be used with the macros defined in coproc_defs.h
+ *
+ * @par For example
+ * mcr_p15 DOMAIN_CONTROL, r3
+ * @par replaces
+ * mcr p15, 0, r3, c3, c0, 0
+ * @{
+ */
+.macro mcr_p15 op1, op2, op3, op4, reg, cond=al
+ mcr\cond p15, \op1, \reg, \op2, \op3, \op4
+.endm
+
+.macro mrc_p15 op1, op2, op3, op4, reg, cond=al
+ mrc\cond p15, \op1, \reg, \op2, \op3, \op4
+.endm
+
+.macro mcrr_p15 op1, op2, reg1, reg2
+ mcrr p15, \op1, \reg1, \reg2, \op2
+.endm
+
+.macro mrrc_p15 op1, op2, reg1, reg2
+ mrrc p15, \op1, \reg1, \reg2, \op2
+.endm
+/*@}*/
+
+/**
+ * @name Our toolchain does not include support for the VE instructions yet.
+ * @{
+ */
+.macro hvc imm16
+ .word ARM_INSTR_HVC_A1_ENC(\imm16)
+.endm
+
+.macro eret
+ .word ARM_INSTR_ERET_A1_ENC(ARM_INSTR_COND_AL)
+.endm
+
+.macro msr_ext rm, rn
+ .word ARM_INSTR_MSR_EXT_A1_ENC(ARM_INSTR_COND_AL, \rm, \rn)
+.endm
+
+.macro mrs_ext rd, rm
+ .word ARM_INSTR_MRS_EXT_A1_ENC(ARM_INSTR_COND_AL, \rd, \rm)
+.endm
+/*@}*/
+
+#endif /// ifndef _ARM_AS_MACROS_H_
diff --git a/arch/arm/mvp/mvpkm/arm_defs.h b/arch/arm/mvp/mvpkm/arm_defs.h
new file mode 100644
index 0000000..2c39f6a
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/arm_defs.h
@@ -0,0 +1,54 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Umbrella header file for all ARM-related definitions. By
+ * including this you gain access to all such definitions in
+ * lib/arm and are guaranteed a stable include.
+ */
+
+#ifndef _ARM_DEFS_H_
+#define _ARM_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define ARM_V4 4
+#define ARM_V5 5
+#define ARM_V6 6
+#define ARM_V7 7
+#define ARM_V8 8
+
+#include "coproc_defs.h"
+#include "exc_defs.h"
+#include "instr_defs.h"
+#include "mmu_defs.h"
+#include "lpae_defs.h"
+#include "ve_defs.h"
+#include "psr_defs.h"
+
+#endif /// _ARM_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/arm_gcc_inline.h b/arch/arm/mvp/mvpkm/arm_gcc_inline.h
new file mode 100644
index 0000000..33ffe69
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/arm_gcc_inline.h
@@ -0,0 +1,206 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief GCC inline stubs for ARM assembler instructions.
+ */
+
+#ifndef _ARM_GCC_INLINE_H_
+#define _ARM_GCC_INLINE_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "coproc_defs.h"
+
+/*
+ * Macros for accessing CP10.
+ */
+#define _ARM_CP10_MRCMCR_STR(_op1,_cr1,_cr2,_op2,_var) \
+ " p10, " #_op1 ","#_var"," #_cr1 "," #_cr2 "," #_op2 "\n\t"
+
+#define _ARM_MRC_CP10(_op1,_cr1,_cr2,_op2,_var) \
+ asm volatile ("mrc" _ARM_CP10_MRCMCR_STR(_op1,_cr1,_cr2,_op2,%0) \
+ : "=r" (_var) )
+
+#define ARM_MRC_CP10(_cp_reg,_var) _ARM_MRC_CP10(_cp_reg,_var)
+
+#define _ARM_MCR_CP10(_op1,_cr1,_cr2,_op2,_val) \
+ asm volatile ("mcr" _ARM_CP10_MRCMCR_STR(_op1,_cr1,_cr2,_op2,%0) \
+ : \
+ : "r" (_val) )
+
+#define ARM_MCR_CP10(_cp_reg,_val) _ARM_MCR_CP10(_cp_reg,_val)
+
+
+/*
+ * Macros for accessing CP15.
+ */
+#define _ARM_CP15_MRCMCR_STR(_op1,_cr1,_cr2,_op2,_var) \
+ " p15, " #_op1 ","#_var"," #_cr1 "," #_cr2 "," #_op2 "\n\t"
+
+#define ARM_CP15_MRCMCR_STR(_cp_reg,_var) _ARM_CP15_MRCMCR_STR(_cp_reg,_var)
+
+#ifdef __COVERITY__
+static uint32 __cp15;
+#define _ARM_MRC_CP15(_op1,_cr1,_cr2,_op2,_var) \
+ (_var) = (uint32)__cp15
+#else
+#define _ARM_MRC_CP15(_op1,_cr1,_cr2,_op2,_var) \
+ asm volatile ("mrc" _ARM_CP15_MRCMCR_STR(_op1,_cr1,_cr2,_op2,%0) \
+ : "=r" (_var) \
+ : \
+ : "memory")
+#endif
+
+#define ARM_MRC_CP15(_cp_reg,_var) _ARM_MRC_CP15(_cp_reg,_var)
+
+
+#ifdef __COVERITY__
+#define _ARM_MCR_CP15(_op1,_cr1,_cr2,_op2,_val) \
+ __cp15 = (_val)
+#else
+#define _ARM_MCR_CP15(_op1,_cr1,_cr2,_op2,_val) \
+ asm volatile ("mcr" _ARM_CP15_MRCMCR_STR(_op1,_cr1,_cr2,_op2,%0) \
+ : \
+ : "r" (_val)\
+ : "memory")
+#endif
+
+#define ARM_MCR_CP15(_cp_reg,_val) _ARM_MCR_CP15(_cp_reg,_val)
+
+#define _ARM_MRRC_CP15(_op,_cr,_val1,_val2) \
+ asm volatile ("mrrc p15, " #_op ",%0,%1," #_cr "\n\t" \
+ : "=r" (_val1), "=r" (_val2) \
+ : \
+ : "memory")
+
+#define ARM_MRRC_CP15(_cp_reg,_val1,_val2) _ARM_MRRC_CP15(_cp_reg,_val1,_val2)
+
+#define ARM_MRRC64_CP15(_cp_reg,_val) \
+ _ARM_MRRC_CP15(_cp_reg,_val,*((uint8 *)&(_val) + 4))
+
+#define _ARM_MCRR_CP15(_op,_cr,_val1,_val2) \
+ asm volatile ("mcrr p15, " #_op ",%0,%1," #_cr "\n\t" \
+ : \
+ : "r" (_val1), "r" (_val2) \
+ : "memory")
+
+#define ARM_MCRR_CP15(_cp_reg,_val1,_val2) _ARM_MCRR_CP15(_cp_reg,_val1,_val2)
+
+#define ARM_MCRR64_CP15(_cp_reg,_val) \
+ _ARM_MCRR_CP15(_cp_reg,_val,*((uint8 *)&(_val) + 4))
+
+#define DMB() asm volatile ("dmb" : : : "memory")
+#define DSB() asm volatile ("dsb" : : : "memory")
+#define ISB() asm volatile ("isb" : : : "memory")
+
+/**
+ * @name 64-bit multiplies
+ * @{
+ */
+
+// rdhi:rdlo = rm * rs + rdhi + rdlo
+#define ARM_UMAAL(rdlo,rdhi,rm,rs) asm ("umaal %0,%1,%2,%3" \
+ : "+r" (rdlo), "+r" (rdhi) \
+ : "r" (rm), "r" (rs))
+
+// rdhi:rdlo += rm * rs
+#define ARM_UMLAL(rdlo,rdhi,rm,rs) asm ("umlal %0,%1,%2,%3" \
+ : "+r" (rdlo), "+r" (rdhi) \
+ : "r" (rm), "r" (rs))
+
+// rdhi:rdlo = rm * rs
+#define ARM_UMULL(rdlo,rdhi,rm,rs) asm ("umull %0,%1,%2,%3" \
+ : "=r" (rdlo), "=r" (rdhi) \
+ : "r" (rm), "r" (rs))
+/*@}*/
+
+/**
+ * @brief Disable interrupts (IRQ + FIQ)
+ *
+ * @return CPSR status prior to disabling - suitable for passing to
+ * ARM_RestoreInterrupts() to restore IRQ/FIQ levels to
+ * pre-call values
+ */
+static inline uint32
+ARM_DisableInterrupts(void)
+{
+ register uint32 status;
+
+ asm volatile ("mrs %0, cpsr \n\t"
+ "orr r1, %0, %1 \n\t"
+ "msr cpsr_c, r1 \n\t"
+ : "=&r" (status)
+ : "i" (ARM_PSR_I | ARM_PSR_F)
+ : "r1", "memory");
+
+ return status;
+}
+
+/**
+ * @brief Restore interrupts
+ *
+ * @param status return value from a previous call to ARM_DisableInterrupts()
+ */
+static inline void
+ARM_RestoreInterrupts(uint32 status)
+{
+ asm volatile ("msr cpsr_c, %0 \n\t" : : "r" (status) : "memory");
+}
+
+/**
+ * @brief Read current CPSR value
+ *
+ * @return current CPSR value
+ */
+static inline uint32
+ARM_ReadCPSR(void)
+{
+ uint32 status;
+
+ asm volatile ("mrs %0, cpsr \n\t" : "=r" (status));
+
+ return status;
+}
+
+/**
+ * @brief Read current stack pointer
+ *
+ * @return stack pointer value
+ */
+static inline uint32
+ARM_ReadSP(void)
+{
+ uint32 sp;
+
+ asm volatile ("mov %0, sp \n\t" : "=r" (sp));
+
+ return sp;
+}
+
+#endif /// ifndef _ARM_GCC_INLINE_H_
diff --git a/arch/arm/mvp/mvpkm/arm_inline.h b/arch/arm/mvp/mvpkm/arm_inline.h
new file mode 100644
index 0000000..3689a7f
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/arm_inline.h
@@ -0,0 +1,179 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Inline stubs for ARM assembler instructions.
+ */
+
+#ifndef _ARM_INLINE_H_
+#define _ARM_INLINE_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "arm_types.h"
+#include "arm_defs.h"
+
+/*
+ * Compiler specific include - we get the actual inline assembler macros here.
+ */
+#include "arm_gcc_inline.h"
+
+/*
+ * Some non-compiler specific helper functions for inline assembler macros
+ * included above.
+ */
+
+/**
+ * @brief Predicate giving whether interrupts are currently enabled
+ *
+ * @return TRUE if enabled, FALSE otherwise
+ */
+static inline _Bool
+ARM_InterruptsEnabled(void)
+{
+ return !(ARM_ReadCPSR() & ARM_PSR_I);
+}
+
+/**
+ * @brief Read current TTBR0 base machine address
+ *
+ * @return machine address given by translation table base register 0
+ */
+static inline MA
+ARM_ReadTTBase0(void)
+{
+ MA ttbase;
+
+ ARM_MRC_CP15(TTBASE0_POINTER, ttbase);
+
+ return ttbase & ARM_CP15_TTBASE_MASK;
+}
+
+/**
+ * @brief Read VFP/Adv.SIMD Extension System Register
+ *
+ * @param specReg which VFP/Adv. SIMD Extension System Register
+ *
+ * @return Read value
+ */
+static inline uint32
+ARM_ReadVFPSystemRegister(uint8 specReg)
+{
+ uint32 value = 0;
+
+ /*
+ * VMRS is the instruction used to read VFP System Registers.
+ * VMRS is the new UAL-syntax equivalent for the FMRX instruction.
+ * At the end of the day, all these are just synonyms for MRC
+ * instructions on CP10, as the VFP system registers sit in CP10
+ * and MRC is the Co-processor register read instruction.
+ * We use the primitive MRC synonym for VMRS here as VMRS/FMRX
+ * don't seem to be working when used inside asm volatile blocks,
+ * as, for some reason, the inline assembler seems to be setting
+ * the VFP mode to soft-float. Moreover, we WANT the monitor code
+ * to be compiled with soft-float so that the compiler doesn't use
+ * VFP instructions for the monitor's own use, such as for 64-bit
+ * integer operations, etc., since we pass-through the use of the
+ * underlying hardware's VFP/SIMD state to the guest.
+ */
+
+ switch (specReg) {
+ case ARM_VFP_SYSTEM_REG_FPSID:
+ ARM_MRC_CP10(VFP_FPSID, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_MVFR0:
+ ARM_MRC_CP10(VFP_MVFR0, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_MVFR1:
+ ARM_MRC_CP10(VFP_MVFR1, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPEXC:
+ ARM_MRC_CP10(VFP_FPEXC, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPSCR:
+ ARM_MRC_CP10(VFP_FPSCR, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPINST:
+ ARM_MRC_CP10(VFP_FPINST, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPINST2:
+ ARM_MRC_CP10(VFP_FPINST2, value);
+ break;
+ default:
+ NOT_IMPLEMENTED_JIRA(1849);
+ break;
+ }
+
+ return value;
+}
+
+/**
+ * @brief Write to VFP/Adv.SIMD Extension System Register
+ *
+ * @param specReg which VFP/Adv. SIMD Extension System Register
+ * @param value desired value to be written to the System Register
+ */
+static inline void
+ARM_WriteVFPSystemRegister(uint8 specReg, uint32 value)
+{
+ /*
+ * VMSR is the instruction used to write to VFP System Registers.
+ * VMSR is the new UAL-syntax equivalent for the FMXR instruction.
+ * At the end of the day, all these are just synonyms for MCR
+ * instructions on CP10, as the VFP system registers sit in CP10
+ * and MCR is the Co-processor register write instruction.
+ * We use the primitive MCR synonym for VMSR here as VMSR/FMXR
+ * don't seem to be working when used inside asm volatile blocks,
+ * as, for some reason, the inline assembler seems to be setting
+ * the VFP mode to soft-float. Moreover, we WANT the monitor code
+ * to be compiled with soft-float so that the compiler doesn't use
+ * VFP instructions for the monitor's own use, such as for 64-bit
+ * integer operations, etc., since we pass-through the use of the
+ * underlying hardware's VFP/SIMD state to the guest.
+ */
+
+ switch (specReg) {
+ case ARM_VFP_SYSTEM_REG_FPEXC:
+ ARM_MCR_CP10(VFP_FPEXC, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPSCR:
+ ARM_MCR_CP10(VFP_FPSCR, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPINST:
+ ARM_MCR_CP10(VFP_FPINST, value);
+ break;
+ case ARM_VFP_SYSTEM_REG_FPINST2:
+ ARM_MCR_CP10(VFP_FPINST2, value);
+ break;
+ default:
+ NOT_IMPLEMENTED_JIRA(1849);
+ break;
+ }
+}
+
+#endif /// ifndef _ARM_INLINE_H_
diff --git a/arch/arm/mvp/mvpkm/arm_types.h b/arch/arm/mvp/mvpkm/arm_types.h
new file mode 100644
index 0000000..2075860
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/arm_types.h
@@ -0,0 +1,42 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Umbrella header file for all ARM-related types.
+ */
+
+#ifndef _ARM_TYPES_H_
+#define _ARM_TYPES_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "exc_types.h"
+#include "mmu_types.h"
+#include "lpae_types.h"
+
+#endif /// _ARM_TYPES_H_
diff --git a/arch/arm/mvp/mvpkm/atomic.h b/arch/arm/mvp/mvpkm/atomic.h
new file mode 100644
index 0000000..987860f
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/atomic.h
@@ -0,0 +1,88 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief bus-atomic operators.
+ *
+ * The 'atm' argument is the atomic memory cell being operated on and the
+ * remainder of the arguments are the values being applied to the atomic cell
+ * which is assumed to be located in shared normal memory. The operation is
+ * both atomic and visible to the default share-ability domain upon completion.
+ *
+ * The design of each macro is such that the compiler should check types
+ * correctly. For those macros that return a value, the return type should be
+ * the same as the 'atm' argument (with the exception of ATOMIC_SETIF which
+ * returns an int value of 0 or 1).
+ *
+ * Those names ending in 'M' return the modified value of 'atm'.
+ * Those names ending in 'O' return the original value of 'atm'.
+ * Those names ending in 'V' return void (ie, nothing).
+ */
+
+#ifndef _ATOMIC_H
+#define _ATOMIC_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#include "include_check.h"
+
+/*
+ * Wrap type 't' in an atomic struct.
+ * Eg, 'static ATOMIC(uint8) counter;'.
+ *
+ * The function macros use the atm_Normal member to clone the atom's type
+ * when the volatile semantic is not required. They use the atm_Volatl member
+ * when the volatile semantic is required.
+ */
+#define ATOMIC(t) union { t atm_Normal; t volatile atm_Volatl; }
+
+/*
+ * Static atomic variable initialization.
+ * Eg, 'static ATOMIC(uint8) counter = ATOMIC_INI(35);'.
+ */
+#define ATOMIC_INI(v) { .atm_Normal = v }
+
+/*
+ * Some commonly used atomic types.
+ */
+typedef ATOMIC(int32) AtmSInt32 __attribute__ ((aligned (4)));
+typedef ATOMIC(uint32) AtmUInt32 __attribute__ ((aligned (4)));
+typedef ATOMIC(uint64) AtmUInt64 __attribute__ ((aligned (8)));
+
+/*
+ * Architecture-dependent implementations.
+ */
+#if defined(__COVERITY__)
+#include "atomic_coverity.h"
+#elif defined(__arm__)
+#include "atomic_arm.h"
+#elif defined(__i386) || defined(__x86_64)
+#include "atomic_x86.h"
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/atomic_arm.h b/arch/arm/mvp/mvpkm/atomic_arm.h
new file mode 100644
index 0000000..447aa55
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/atomic_arm.h
@@ -0,0 +1,329 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief bus-atomic operators, ARM implementation.
+ * Do not include directly, include 'atomic.h' instead.
+ * Memory where the atomic reside must be shared.
+ *
+ * These operations assume that the exclusive access monitor is cleared during
+ * abort entry but they do not assume that cooperative scheduling (e.g. Linux
+ * schedule()) clears the monitor and hence the use of "clrex" when required.
+ */
+
+#ifndef _ATOMIC_ARM_H
+#define _ATOMIC_ARM_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#include "include_check.h"
+
+#include "mvp_assert.h"
+
+/**
+ * @brief Atomic Add
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return the original value of 'atm'
+ */
+#define ATOMIC_ADDO(atm,modval) ATOMIC_OPO_PRIVATE(atm,modval,add)
+
+/**
+ * @brief Atomic Add
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return nothing
+ */
+#define ATOMIC_ADDV(atm,modval) ATOMIC_OPV_PRIVATE(atm,modval,add)
+
+/**
+ * @brief Atomic And
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return the original value of 'atm'
+ */
+#define ATOMIC_ANDO(atm,modval) ATOMIC_OPO_PRIVATE(atm,modval,and)
+
+/**
+ * @brief Atomic And
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return nothing
+ */
+#define ATOMIC_ANDV(atm,modval) ATOMIC_OPV_PRIVATE(atm,modval,and)
+
+/**
+ * @brief Retrieve an atomic value
+ * @param atm atomic cell to operate on
+ * @return the value of 'atm'
+ */
+#define ATOMIC_GETO(atm) ({ \
+ typeof((atm).atm_Normal) _oldval; \
+ switch (sizeof _oldval) { \
+ case 4: \
+ asm volatile ("ldrex %0, [%1]\n" \
+ "clrex" \
+ : "=&r" (_oldval) \
+ : "r" (&((atm).atm_Volatl))); \
+ break; \
+ case 8: \
+ asm volatile ("ldrexd %0, %H0, [%1]\n" \
+ "clrex" \
+ : "=&r" (_oldval) \
+ : "r" (&((atm).atm_Volatl))); \
+ break; \
+ default: \
+ FATAL(); \
+ } \
+ _oldval; \
+})
+
+/**
+ * @brief Atomic Or
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return the original value of 'atm'
+ */
+#define ATOMIC_ORO(atm,modval) ATOMIC_OPO_PRIVATE(atm,modval,orr)
+
+/**
+ * @brief Atomic Or
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return nothing
+ */
+#define ATOMIC_ORV(atm,modval) ATOMIC_OPV_PRIVATE(atm,modval,orr)
+
+/**
+ * @brief Atomic Conditional Write, ie,
+ * set 'atm' to 'newval' iff it was 'oldval'.
+ * @param atm atomic cell to operate on
+ * @param newval value to possibly write to atomic cell
+ * @param oldval value that atomic cell must equal
+ * @return 0 if failed; 1 if successful
+ */
+#define ATOMIC_SETIF(atm,newval,oldval) ({ \
+ int _failed; \
+ typeof((atm).atm_Normal) _newval = newval; \
+ typeof((atm).atm_Normal) _oldval = oldval; \
+ ASSERT_ON_COMPILE(sizeof _newval == 4); \
+ asm volatile ("1: ldrex %0, [%1] \n" \
+ " cmp %0, %2 \n" \
+ " mov %0, #2 \n" \
+ " IT eq \n" \
+ " strexeq %0, %3, [%1] \n" \
+ " cmp %0, #1 \n" \
+ " beq 1b \n" \
+ " clrex" \
+ : "=&r" (_failed) \
+ : "r" (&((atm).atm_Volatl)), \
+ "r" (_oldval), \
+ "r" (_newval) \
+ : "cc", "memory"); \
+ !_failed; \
+})
+
+
+/**
+ * @brief Atomic Write (unconditional)
+ * @param atm atomic cell to operate on
+ * @param newval value to write to atomic cell
+ * @return the original value of 'atm'
+ */
+#define ATOMIC_SETO(atm,newval) ({ \
+ int _failed; \
+ typeof((atm).atm_Normal) _newval = newval; \
+ typeof((atm).atm_Normal) _oldval; \
+ switch (sizeof _newval) { \
+ case 4: \
+ asm volatile ("1: ldrex %0, [%2]\n" \
+ " strex %1, %3, [%2]\n" \
+ " teq %1, #0\n" \
+ " bne 1b" \
+ : "=&r" (_oldval), \
+ "=&r" (_failed) \
+ : "r" (&((atm).atm_Volatl)), \
+ "r" (_newval) \
+ : "cc", "memory"); \
+ break; \
+ case 8: \
+ asm volatile ("1: ldrexd %0, %H0, [%2]\n" \
+ " strexd %1, %3, %H3, [%2]\n"\
+ " teq %1, #0\n" \
+ " bne 1b" \
+ : "=&r" (_oldval), \
+ "=&r" (_failed) \
+ : "r" (&((atm).atm_Volatl)), \
+ "r" (_newval) \
+ : "cc", "memory"); \
+ break; \
+ default: \
+ FATAL(); \
+ } \
+ _oldval; \
+})
+
+/**
+ * @brief Atomic Write (unconditional)
+ * @param atm atomic cell to operate on
+ * @param newval value to write to atomic cell
+ * @return nothing
+ */
+#define ATOMIC_SETV(atm,newval) do { ATOMIC_SETO((atm),(newval)); } while (0)
+
+/**
+ * @brief Atomic Subtract
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return the original value of 'atm'
+ */
+#define ATOMIC_SUBO(atm,modval) ATOMIC_OPO_PRIVATE(atm,modval,sub)
+
+/**
+ * @brief Atomic Subtract
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @return nothing
+ */
+#define ATOMIC_SUBV(atm,modval) ATOMIC_OPV_PRIVATE(atm,modval,sub)
+
+/**
+ * @brief Atomic Generic Binary Operation
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @param op ARM instruction (add, and, orr, etc)
+ * @return the original value of 'atm'
+ */
+#define ATOMIC_OPO_PRIVATE(atm,modval,op) ({ \
+ int _failed; \
+ typeof((atm).atm_Normal) _modval = modval; \
+ typeof((atm).atm_Normal) _oldval; \
+ typeof((atm).atm_Normal) _newval; \
+ ASSERT_ON_COMPILE(sizeof _modval == 4); \
+ asm volatile ("1: ldrex %0, [%3]\n" \
+ #op " %1, %0, %4\n" \
+ " strex %2, %1, [%3]\n" \
+ " teq %2, #0\n" \
+ " bne 1b" \
+ : "=&r" (_oldval), \
+ "=&r" (_newval), \
+ "=&r" (_failed) \
+ : "r" (&((atm).atm_Volatl)), \
+ "r" (_modval) \
+ : "memory"); \
+ _oldval; \
+})
+
+/**
+ * @brief Atomic Generic Binary Operation
+ * @param atm atomic cell to operate on
+ * @param modval value to apply to atomic cell
+ * @param op ARM instruction (add, and, orr, etc)
+ * @return nothing
+ */
+#define ATOMIC_OPV_PRIVATE(atm,modval,op) do { \
+ int _failed; \
+ typeof((atm).atm_Normal) _modval = modval; \
+ typeof((atm).atm_Normal) _sample; \
+ ASSERT_ON_COMPILE(sizeof _modval == 4); \
+ asm volatile ("1: ldrex %0, [%2]\n" \
+ #op " %0, %3\n" \
+ " strex %1, %0, [%2]\n" \
+ " teq %1, #0\n" \
+ " bne 1b" \
+ : "=&r" (_sample), \
+ "=&r" (_failed) \
+ : "r" (&((atm).atm_Volatl)), \
+ "r" (_modval) \
+ : "memory"); \
+} while (0)
+
+/**
+ * @brief Single-copy atomic word write.
+ *
+ * ARMv7 defines world-aligned word writes to be single-copy atomic. See
+ * A3-26 ARM DDI 0406A.
+ *
+ * @param p word aligned location to write to
+ * @param val word-sized value to write to p
+ */
+#define ATOMIC_SINGLE_COPY_WRITE32(p,val) \
+ do { \
+ ASSERT(sizeof(val) == 4); \
+ ASSERT((MVA)(p) % sizeof(val) == 0); \
+ asm volatile("str %0, [%1]" \
+ : \
+ : "r" (val), "r" (p) \
+ : "memory"); \
+ } while (0);
+
+
+/**
+ * @brief Single-copy atomic word read.
+ *
+ * ARMv7 defines world-aligned word reads to be single-copy atomic. See
+ * A3-26 ARM DDI 0406A.
+ *
+ * @param p word aligned location to read from
+ *
+ * @return word-sized value from p
+ */
+#define ATOMIC_SINGLE_COPY_READ32(p) ({ \
+ ASSERT((MVA)(p) % sizeof(uint32) == 0); \
+ uint32 _val; \
+ asm volatile("ldr %0, [%1]" \
+ : "=r" (_val) \
+ : "r" (p) \
+ ); \
+ _val; \
+})
+
+/**
+ * @brief Single-copy atomic double word write.
+ *
+ * LPAE defines double world-aligned double word writes to be single-copy
+ * atomic. See 6.7 ARM PRD03-GENC-008469 13.0.
+ *
+ * @param p double word aligned location to write to
+ * @param val double word-sized value to write to p
+ */
+#define ATOMIC_SINGLE_COPY_WRITE64(p,val) \
+ do { \
+ ASSERT(sizeof(val) == 8); \
+ ASSERT((MVA)(p) % sizeof(val) == 0); \
+ asm volatile("mov r0, %0 \n" \
+ "mov r1, %1 \n" \
+ "strd r0, r1, [%2]" \
+ : \
+ : "r" ((uint32)(val)), \
+ "r" (((uint64)(val)) >> 32),\
+ "r" (p) \
+ : "r0", "r1", "memory"); \
+ } while (0);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/check_kconfig.c b/arch/arm/mvp/mvpkm/check_kconfig.c
new file mode 100644
index 0000000..bab1b6e
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/check_kconfig.c
@@ -0,0 +1,91 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ * @brief Check for required kernel configuration
+ *
+ * Check to make sure that the kernel options that the MVP hypervisor requires
+ * have been enabled in the kernel that this kernel module is being built
+ * against.
+ */
+#include <linux/version.h>
+
+/*
+ * Minimum kernel version
+ * - network namespace support is only really functional starting in 2.6.29
+ * - Android Gingerbread requires 2.6.35
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+#error "MVP requires a host kernel newer than 2.6.35"
+#endif
+
+/* module loading ability */
+#ifndef CONFIG_MODULES
+#error "MVP requires kernel loadable module support be enabled (CONFIG_MODULES)"
+#endif
+#ifndef CONFIG_MODULE_UNLOAD
+#error "MVP requires kernel module unload support be enabled (CONFIG_MODULE_UNLOAD)"
+#endif
+
+/* sysfs */
+#ifndef CONFIG_SYSFS
+#error "MVP requires sysfs support (CONFIG_SYSFS)"
+#endif
+
+/* network traffic isolation */
+#ifndef CONFIG_NAMESPACES
+#error "MVP networking support requires namespace support (CONFIG_NAMESPACES)"
+#endif
+#ifndef CONFIG_NET_NS
+#error "MVP networking support requires Network Namespace support to be enabled (CONFIG_NET_NS)"
+#endif
+
+/* TCP/IP networking */
+#ifndef CONFIG_INET
+#error "MVP networking requires IPv4 support (CONFIG_INET)"
+#endif
+#ifndef CONFIG_IPV6
+#error "MVP networking requires IPv6 support (CONFIG_IPV6)"
+#endif
+
+/* VPN support */
+#if !defined(CONFIG_TUN) && !defined(CONFIG_TUN_MODULE)
+#error "MVP VPN support requires TUN device support (CONFIG_TUN)"
+#endif
+
+#if !defined(CONFIG_NETFILTER) && !defined(PVTCP_DISABLE_NETFILTER)
+#error "MVP networking support requires netfilter support (CONFIG_NETFILTER)"
+#endif
+
+/* Force /proc/config.gz support for eng/userdebug builds */
+#ifdef MVP_DEBUG
+#if !defined(CONFIG_IKCONFIG) || !defined(CONFIG_IKCONFIG_PROC)
+#error "MVP kernel /proc/config.gz support required for debuggability (CONFIG_IKCONFIG_PROC)"
+#endif
+#endif
+
+/* Sanity check we're only dealing with the memory hotplug + migrate and/or
+ * compaction combo */
+#ifdef CONFIG_MIGRATION
+#if defined(CONFIG_NUMA) || defined(CONFIG_CPUSETS) || defined(CONFIG_MEMORY_FAILURE)
+#error "MVP not tested with migration features other than CONFIG_MEMORY_HOTPLUG and CONFIG_COMPACTION"
+#endif
+#endif
diff --git a/arch/arm/mvp/mvpkm/comm_os.h b/arch/arm/mvp/mvpkm/comm_os.h
new file mode 100644
index 0000000..cf858f6
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/comm_os.h
@@ -0,0 +1,150 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Cross-platform base type definitions and function declarations.
+ * Includes OS-specific base type definitions and function declarations.
+ */
+
+#ifndef _COMM_OS_H_
+#define _COMM_OS_H_
+
+/* For-ever timeout constant (in milliseconds). */
+#define COMM_OS_4EVER_TO ((unsigned long long)(~0UL >> 1))
+
+/* Condition function prototype. Returns 1: true, 0: false, < 0: error code. */
+typedef int (*CommOSWaitConditionFunc)(void *arg1, void *arg2);
+
+/* Dispatch function prototype. Called by input (dispatch) kernel threads. */
+typedef unsigned int (*CommOSDispatchFunc)(void);
+
+/* Module initialization and exit callback functions. */
+extern int (*commOSModInit)(void *args);
+extern void (*commOSModExit)(void);
+
+/* Macro to assign Init and Exit callbacks. */
+#define COMM_OS_MOD_INIT(init, exit) \
+ int (*commOSModInit)(void *args) = init; \
+ void (*commOSModExit)(void) = exit
+
+
+/*
+ * OS-specific implementations must provide the following:
+ * 1. Types:
+ * CommOSAtomic
+ * CommOSSpinlock
+ * CommOSMutex
+ * CommOSWaitQueue
+ * CommOSWork
+ * CommOSWorkFunc
+ * CommOSList
+ * CommOSModule
+ * struct kvec
+ *
+ * 2. Definition, initializers:
+ * CommOSSpinlock_Define()
+ *
+ * 3. Functions:
+ * void CommOS_Debug(const char *format, ...);
+ * void CommOS_Log(const char *format, ...);
+ * void CommOS_WriteAtomic(CommOSAtomic *atomic, int val);
+ * int CommOS_ReadAtomic(CommOSAtomic *atomic);
+ * int CommOS_AddReturnAtomic(CommOSAtomic *atomic, int val);
+ * int CommOS_SubReturnAtomic(CommOSAtomic *atomic, int val);
+ * void CommOS_SpinlockInit(CommOSSpinlock *lock);
+ * void CommOS_SpinLockBH(CommOSSpinlock *lock);
+ * int CommOS_SpinTrylockBH(CommOSSpinlock *lock);
+ * void CommOS_SpinUnlockBH(CommOSSpinlock *lock);
+ * void CommOS_SpinLock(CommOSSpinlock *lock);
+ * int CommOS_SpinTrylock(CommOSSpinlock *lock);
+ * void CommOS_SpinUnlock(CommOSSpinlock *lock);
+ * void CommOS_MutexInit(CommOSMutex *mutex);
+ * void CommOS_MutexLock(CommOSMutex *mutex);
+ * int CommOS_MutexLockUninterruptible(CommOSMutex *mutex);
+ * int CommOS_MutexTrylock(CommOSMutex *mutex);
+ * void CommOS_MutexUnlock(CommOSMutex *mutex);
+ * void CommOS_WaitQueueInit(CommOSWaitQueue *wq);
+ * CommOS_DoWait(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc cond,
+ * void *condArg1,
+ * void *condArg2,
+ * unsigned long long *timeoutMillis,
+ * int interruptible);
+ * int CommOS_Wait(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc func,
+ * void *funcArg1,
+ * void *funcArg2,
+ * unsigned long long *timeoutMillis);
+ * int CommOS_WaitUninterruptible(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc func,
+ * void *funcArg1,
+ * void *funcArg2,
+ * unsigned long long *timeoutMillis);
+ * void CommOS_WakeUp(CommOSWaitQueue *wq);
+ * void *CommOS_KmallocNoSleep(unsigned int size);
+ * void *CommOS_Kmalloc(unsigned int size);
+ * void CommOS_Kfree(void *arg);
+ * void CommOS_Yield(void);
+ * unsigned long long CommOS_GetCurrentMillis(void);
+ * void CommOS_ListInit(CommOSList *list);
+ * int CommOS_ListEmpty(CommOSList *list);
+ * void CommOS_ListAdd(CommOSList *list, CommOSList *listElem);
+ * void CommOS_ListAddTail(CommOSList *list, CommOSList *listElem);
+ * void int CommOS_ListDel(CommOSList *listElem);
+ * Macros:
+ * CommOS_ListForEach(*list, *item, itemListFieldName);
+ * CommOS_ListForEachSafe(*list, *item, *tmp, itemListFieldName);
+ * void CommOS_ListSplice(CommOSList *list, CommOSList *listToAdd);
+ * void CommOS_ListSpliceTail(CommOSList *list, CommOSList *listToAdd);
+ * CommOSModule CommOS_ModuleSelf(void);
+ * int CommOS_ModuleGet(CommOSModule module);
+ * void CommOS_ModulePut(CommOSModule module);
+ * void CommOS_MemBarrier(void);
+ *
+ * These cannot be defined here: a) non-pointer type definitions need size
+ * information, and b) functions may or may not be inlined, or macros may
+ * be used instead.
+ */
+
+
+#ifdef __linux__
+#include "comm_os_linux.h"
+#else
+#error "Unsupported OS"
+#endif
+
+/* Functions to start and stop the dispatch and aio kernel threads. */
+void CommOS_StopIO(void);
+void CommOS_ScheduleDisp(void);
+void CommOS_InitWork(CommOSWork *work, CommOSWorkFunc func);
+int CommOS_ScheduleAIOWork(CommOSWork *work);
+void CommOS_FlushAIOWork(CommOSWork *work);
+
+int
+CommOS_StartIO(const char *dispatchTaskName,
+ CommOSDispatchFunc dispatchHandler,
+ unsigned int interval,
+ unsigned int maxCycles,
+ const char *aioTaskName);
+
+
+#endif /* _COMM_OS_H_ */
diff --git a/arch/arm/mvp/mvpkm/comm_os_linux.h b/arch/arm/mvp/mvpkm/comm_os_linux.h
new file mode 100644
index 0000000..c9d4f26
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/comm_os_linux.h
@@ -0,0 +1,699 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Contains linux-specific type definitions and function declarations
+ */
+
+#ifndef _COMM_OS_LINUX_H_
+#define _COMM_OS_LINUX_H_
+
+#include <linux/types.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#error "Kernel versions lower than 2.6.20 are not supported"
+#endif
+
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+
+/*
+ * Type definitions.
+ */
+
+typedef atomic_t CommOSAtomic;
+typedef spinlock_t CommOSSpinlock;
+typedef struct mutex CommOSMutex;
+typedef wait_queue_head_t CommOSWaitQueue;
+typedef struct delayed_work CommOSWork;
+typedef void (*CommOSWorkFunc)(CommOSWork *work);
+typedef struct list_head CommOSList;
+typedef struct module *CommOSModule;
+
+
+/*
+ * Initializers.
+ */
+
+#define CommOSSpinlock_Define DEFINE_SPINLOCK
+
+
+#define COMM_OS_DOLOG(...) printk(KERN_INFO __VA_ARGS__)
+
+
+/**
+ * @brief Logs given arguments in debug builds.
+ */
+
+#if defined(COMM_OS_DEBUG)
+ #define CommOS_Debug(args) COMM_OS_DOLOG args
+#else
+ #define CommOS_Debug(args)
+#endif
+
+
+/**
+ * @brief Logs given arguments.
+ */
+
+#define CommOS_Log(args) COMM_OS_DOLOG args
+
+
+/**
+ * @brief Logs function name and location.
+ */
+
+#if defined(COMM_OS_TRACE)
+#define TRACE(ptr) \
+ do { \
+ CommOS_Debug(("%p:%s: at [%s:%d] with arg ptr [0x%p].\n", current, \
+ __FUNCTION__, __FILE__, __LINE__, (ptr))); \
+ } while (0)
+#else
+#define TRACE(ptr)
+#endif
+
+
+/**
+ * @brief Write atomic variable
+ * @param[in,out] atomic variable to write
+ * @param val new value
+ */
+
+static inline void
+CommOS_WriteAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ atomic_set(atomic, val);
+}
+
+
+/**
+ * @brief Reads atomic variable
+ * @param atomic variable to read
+ * @return value
+ */
+
+static inline int
+CommOS_ReadAtomic(CommOSAtomic *atomic)
+{
+ return atomic_read(atomic);
+}
+
+
+/**
+ * @brief Atomically add value to atomic variable, return new value.
+ * @param[in,out] atomic variable
+ * @param val value to add
+ * @return new value
+ */
+
+static inline int
+CommOS_AddReturnAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ return atomic_add_return(val, atomic);
+}
+
+
+/**
+ * @brief Atomically substract value from atomic variable, return new value.
+ * @param[in,out] atomic variable
+ * @param val value to substract
+ * @return new value
+ */
+
+static inline int
+CommOS_SubReturnAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ return atomic_sub_return(val, atomic);
+}
+
+
+/**
+ * @brief Initializes a given lock.
+ * @param[in,out] lock lock to initialize
+ */
+
+static inline void
+CommOS_SpinlockInit(CommOSSpinlock *lock)
+{
+ spin_lock_init(lock);
+}
+
+
+/**
+ * @brief Locks given lock and disables bottom half processing.
+ * @param[in,out] lock lock to lock
+ */
+
+static inline void
+CommOS_SpinLockBH(CommOSSpinlock *lock)
+{
+ spin_lock_bh(lock);
+}
+
+
+/**
+ * @brief Attempts to lock the given lock and disable BH processing.
+ * @param[in,out] lock lock to lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_SpinTrylockBH(CommOSSpinlock *lock)
+{
+ return !spin_trylock_bh(lock);
+}
+
+
+/**
+ * @brief Unlocks given lock and re-enables BH processing.
+ * @param[in,out] lock lock to unlock
+ */
+
+static inline void
+CommOS_SpinUnlockBH(CommOSSpinlock *lock)
+{
+ spin_unlock_bh(lock);
+}
+
+
+/**
+ * @brief Locks the given lock.
+ * @param[in,out] lock lock to lock
+ */
+
+static inline void
+CommOS_SpinLock(CommOSSpinlock *lock)
+{
+ spin_lock(lock);
+}
+
+
+/**
+ * @brief Attempts to lock the given lock.
+ * @param[in,out] lock lock to try-lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_SpinTrylock(CommOSSpinlock *lock)
+{
+ return !spin_trylock(lock);
+}
+
+
+/**
+ * @brief Unlocks given lock.
+ * @param[in,out] lock lock to unlock
+ */
+
+static inline void
+CommOS_SpinUnlock(CommOSSpinlock *lock)
+{
+ spin_unlock(lock);
+}
+
+
+/**
+ * @brief Initializes given mutex.
+ * @param[in,out] mutex mutex to initialize
+ */
+
+static inline void
+CommOS_MutexInit(CommOSMutex *mutex)
+{
+ mutex_init(mutex);
+}
+
+
+/**
+ * @brief Acquires mutex.
+ * @param[in,out] mutex mutex to lock
+ * @return zero if successful, non-zero otherwise (interrupted)
+ */
+
+static inline int
+CommOS_MutexLock(CommOSMutex *mutex)
+{
+ return mutex_lock_interruptible(mutex);
+}
+
+
+/**
+ * @brief Acquires mutex in uninterruptible mode.
+ * @param[in,out] mutex mutex to lock
+ */
+
+static inline void
+CommOS_MutexLockUninterruptible(CommOSMutex *mutex)
+{
+ mutex_lock(mutex);
+}
+
+
+/**
+ * @brief Attempts to acquire given mutex.
+ * @param[in,out] mutex mutex to try-lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_MutexTrylock(CommOSMutex *mutex)
+{
+ return !mutex_trylock(mutex);
+}
+
+
+/**
+ * @brief Releases a given mutex.
+ * @param[in,out] mutex mutex to unlock
+ */
+
+static inline void
+CommOS_MutexUnlock(CommOSMutex *mutex)
+{
+ mutex_unlock(mutex);
+}
+
+
+/**
+ * @brief Initializes a wait queue.
+ * @param[in,out] wq workqueue to initialize
+ */
+
+static inline void
+CommOS_WaitQueueInit(CommOSWaitQueue *wq)
+{
+ init_waitqueue_head(wq);
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * - a signal is pending
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @param interruptible enable/disable signal pending check
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, if a signal is pending or other error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_DoWait(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis,
+ int interruptible)
+{
+ int rc;
+ DEFINE_WAIT(wait);
+ long timeout;
+#if defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ long tmpTimeout;
+ long retTimeout;
+ const unsigned int interval = 50;
+#endif
+
+ if (!timeoutMillis) {
+ return -1;
+ }
+ if ((rc = cond(condArg1, condArg2)) != 0) {
+ return rc;
+ }
+
+#if defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ timeout = msecs_to_jiffies(interval < *timeoutMillis ?
+ interval : (unsigned int)*timeoutMillis);
+ retTimeout = msecs_to_jiffies((unsigned int)(*timeoutMillis));
+
+ for (; retTimeout >= 0; ) {
+ prepare_to_wait(wq, &wait,
+ (interruptible?TASK_INTERRUPTIBLE:TASK_UNINTERRUPTIBLE));
+ if ((rc = cond(condArg1, condArg2))) {
+ break;
+ }
+ if (interruptible && signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if ((tmpTimeout = schedule_timeout(timeout))) {
+ retTimeout -= (timeout - tmpTimeout);
+ } else {
+ retTimeout -= timeout;
+ }
+ if (retTimeout < 0) {
+ retTimeout = 0;
+ }
+ }
+ finish_wait(wq, &wait);
+ if (rc == 0) {
+ rc = cond(condArg1, condArg2);
+ if (rc && (retTimeout == 0)) {
+ retTimeout = 1;
+ }
+ }
+ *timeoutMillis = (unsigned long long)jiffies_to_msecs(retTimeout);
+#else // !defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ timeout = msecs_to_jiffies((unsigned int)(*timeoutMillis));
+
+ for (;;) {
+ prepare_to_wait(wq, &wait,
+ (interruptible?TASK_INTERRUPTIBLE:TASK_UNINTERRUPTIBLE));
+ if ((rc = cond(condArg1, condArg2)) != 0) {
+ break;
+ }
+ if (interruptible && signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if ((timeout = schedule_timeout(timeout)) == 0) {
+ rc = 0;
+ break;
+ }
+ }
+ finish_wait(wq, &wait);
+ if (rc == 0) {
+ rc = cond(condArg1, condArg2);
+ if (rc && (timeout == 0)) {
+ timeout = 1;
+ }
+ }
+ *timeoutMillis = (unsigned long long)jiffies_to_msecs(timeout);
+#endif
+
+ return rc;
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * - a signal is pending
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, if a signal is pending or other error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_Wait(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis)
+{
+ return CommOS_DoWait(wq, cond, condArg1, condArg2, timeoutMillis, 1);
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_WaitUninterruptible(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis)
+{
+ return CommOS_DoWait(wq, cond, condArg1, condArg2, timeoutMillis, 0);
+}
+
+
+/**
+ * @brief Wakes up task(s) waiting on the given wait queue.
+ * @param[in,out] wq wait queue.
+ */
+
+static inline void
+CommOS_WakeUp(CommOSWaitQueue *wq)
+{
+ wake_up(wq);
+}
+
+
+/**
+ * @brief Allocates kernel memory of specified size; does not sleep.
+ * @param size size to allocate.
+ * @return Address of allocated memory or NULL if the allocation fails.
+ */
+
+static inline void *
+CommOS_KmallocNoSleep(unsigned int size)
+{
+ return kmalloc(size, GFP_ATOMIC);
+}
+
+
+/**
+ * @brief Allocates kernel memory of specified size; may sleep.
+ * @param size size to allocate.
+ * @return Address of allocated memory or NULL if the allocation fails.
+ */
+
+static inline void *
+CommOS_Kmalloc(unsigned int size)
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+
+/**
+ * @brief Frees previously allocated kernel memory.
+ * @param obj object to free.
+ */
+
+static inline void
+CommOS_Kfree(void *obj)
+{
+ if (obj) {
+ kfree(obj);
+ }
+}
+
+
+/**
+ * @brief Yields the current cpu to other runnable tasks.
+ */
+
+static inline void
+CommOS_Yield(void)
+{
+ cond_resched();
+}
+
+
+/**
+ * @brief Gets the current time in milliseconds.
+ * @return Current time in milliseconds, with precision of at most one tick.
+ */
+
+static inline unsigned long long
+CommOS_GetCurrentMillis(void)
+{
+ return (unsigned long long)jiffies_to_msecs(jiffies);
+}
+
+
+/**
+ * @brief Initializes given list.
+ * @param list list to initialize.
+ */
+
+static inline void
+CommOS_ListInit(CommOSList *list)
+{
+ INIT_LIST_HEAD(list);
+}
+
+
+/**
+ * @brief Tests if list is empty.
+ * @param list list to test.
+ * @return non-zero if empty, zero otherwise.
+ */
+
+#define CommOS_ListEmpty(list) list_empty((list))
+
+
+/**
+ * @brief Adds given element to beginning of list.
+ * @param list list to add to.
+ * @param elem element to add.
+ */
+
+#define CommOS_ListAdd(list, elem) list_add((elem), (list))
+
+
+/**
+ * @brief Adds given element to end of list.
+ * @param list list to add to.
+ * @param elem element to add.
+ */
+
+#define CommOS_ListAddTail(list, elem) list_add_tail((elem), (list))
+
+
+/**
+ * @brief Deletes given element from its list.
+ * @param elem element to delete.
+ */
+
+#define CommOS_ListDel(elem) \
+ do { \
+ list_del((elem)); \
+ INIT_LIST_HEAD((elem)); \
+ } while (0)
+
+
+/**
+ * @brief Iterates over a list.
+ * @param list list to iterate over.
+ * @param[out] item stores next element.
+ * @param itemListFieldName name in the item structure storing the list head.
+ */
+
+#define CommOS_ListForEach(list, item, itemListFieldName) \
+ list_for_each_entry((item), (list), itemListFieldName)
+
+
+/**
+ * @brief Iterates safely over a list.
+ * @param list list to iterate over.
+ * @param[out] item stores next element. May be deleted in the loop.
+ * @param[out] tmpItem saves iteration element.
+ * @param itemListFieldName name in the item structure storing the list head.
+ */
+
+#define CommOS_ListForEachSafe(list, item, tmpItem, itemListFieldName) \
+ list_for_each_entry_safe((item), (tmpItem), (list), itemListFieldName)
+
+
+/**
+ * @brief Combines two lists, adds second list to beginning of first one.
+ * @param list list to add to.
+ * @param list2 list to add.
+ */
+
+#define CommOS_ListSplice(list, list2) list_splice((list2), (list))
+
+
+/**
+ * @brief Combines two lists, adds second list to end of first one.
+ * @param list list to add to.
+ * @param list2 list to add.
+ */
+
+#define CommOS_ListSpliceTail(list, list2) list_splice_tail((list2), (list))
+
+
+/**
+ * @brief Gets current module handle.
+ * @return module handle.
+ */
+
+static inline CommOSModule
+CommOS_ModuleSelf(void)
+{
+ return THIS_MODULE;
+}
+
+
+/**
+ * @brief Retains module.
+ * @param[in,out] module to retain.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+CommOS_ModuleGet(CommOSModule module)
+{
+ int rc = 0;
+
+ if (!module) {
+ goto out;
+ }
+ if (!try_module_get(module)) {
+ rc = -1;
+ }
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Releases module.
+ * @param[in,out] module to release.
+ */
+
+static inline void
+CommOS_ModulePut(CommOSModule module)
+{
+ if (module) {
+ module_put(module);
+ }
+}
+
+
+/**
+ * @brief Inserts r/w memory barrier.
+ */
+
+#define CommOS_MemBarrier smp_mb
+
+#endif /* _COMM_OS_LINUX_H_ */
diff --git a/arch/arm/mvp/mvpkm/comm_transp.h b/arch/arm/mvp/mvpkm/comm_transp.h
new file mode 100644
index 0000000..a90eb40
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/comm_transp.h
@@ -0,0 +1,90 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Generic shared memory transport API.
+ */
+
+#ifndef _COMM_TRANSP_H_
+#define _COMM_TRANSP_H_
+
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/*
+ * Common shared memory identifier.
+ * External handle that makes sense to both hypervisor and guest.
+ */
+
+#define COMM_TRANSP_ID_8_ANY ((unsigned char)-1)
+#define COMM_TRANSP_ID_32_ANY ((unsigned int)-1)
+#define COMM_TRANSP_ID_64_ANY ((unsigned long long)-1)
+
+
+typedef struct CommTranspID {
+ union {
+ unsigned char d8[8];
+ unsigned int d32[2];
+ unsigned long long d64;
+ };
+} CommTranspID;
+
+
+/* Basic initialization arguments. */
+
+typedef enum CommTranspInitMode {
+ COMM_TRANSP_INIT_CREATE = 0x0,
+ COMM_TRANSP_INIT_ATTACH = 0x1
+} CommTranspInitMode;
+
+typedef struct CommTranspInitArgs {
+ unsigned int capacity; // Shared memory capacity.
+ unsigned int type; // Type / implementation using this area.
+ CommTranspID id; // ID (name) of shared memory area.
+ CommTranspInitMode mode; // Init mode (above).
+} CommTranspInitArgs;
+
+
+/**
+ * @brief Generate a type id from description (protocol) string. This function
+ * uses djb2, a string hashing algorithm by Dan Bernstein.
+ * (see http://www.cse.yorku.ca/~oz/hash.html)
+ * @param str string to hash
+ * @return 32-bit hash value
+ */
+
+static inline unsigned int
+CommTransp_GetType(const char *str)
+{
+ unsigned int hash = 5381;
+ int c;
+
+ while ((c = *str++)) {
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ }
+ return hash;
+}
+
+#endif // _COMM_TRANSP_H_
diff --git a/arch/arm/mvp/mvpkm/comm_transp_impl.h b/arch/arm/mvp/mvpkm/comm_transp_impl.h
new file mode 100644
index 0000000..6438ac9
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/comm_transp_impl.h
@@ -0,0 +1,165 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Generic shared memory transport private API.
+ */
+
+#ifndef _COMM_TRANSP_IMPL_H_
+#define _COMM_TRANSP_IMPL_H_
+
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "comm_transp.h"
+
+
+/* Shared memory opaque descriptor/handle. Only meaningful locally. */
+
+typedef struct CommTranspPriv *CommTransp;
+
+
+/* Asynchronous signaling initialization arguments. */
+
+typedef enum CommTranspIOEvent {
+ COMM_TRANSP_IO_DETACH = 0x0,
+ COMM_TRANSP_IO_IN = 0x1,
+ COMM_TRANSP_IO_OUT = 0x2,
+ COMM_TRANSP_IO_INOUT = 0x3
+} CommTranspIOEvent;
+
+typedef struct CommTranspEvent {
+ void (*ioEvent)(CommTransp transp, CommTranspIOEvent event, void *data);
+ void *ioEventData;
+} CommTranspEvent;
+
+
+/*
+ * Mechanism to detect and optionally attach to, created shared memory regions.
+ */
+
+typedef struct CommTranspListener {
+ int (*probe)(CommTranspInitArgs *transpArgs, void *probeData);
+ void *probeData;
+} CommTranspListener;
+
+
+
+/*
+ * Function prototypes.
+ */
+
+int CommTranspEvent_Init(void);
+void CommTranspEvent_Exit(void);
+int CommTranspEvent_Process(CommTranspID *transpID, CommTranspIOEvent event);
+int
+CommTranspEvent_Raise(unsigned int peerEvID,
+ CommTranspID *transpID,
+ CommTranspIOEvent event);
+
+int CommTransp_Init(void);
+void CommTransp_Exit(void);
+
+int CommTransp_Register(const CommTranspListener *listener);
+void CommTransp_Unregister(const CommTranspListener *listener);
+int
+CommTransp_Notify(const CommTranspID *notificationCenterID,
+ CommTranspInitArgs *transpArgs);
+
+int
+CommTransp_Open(CommTransp *transp,
+ CommTranspInitArgs *transpArgs,
+ CommTranspEvent *transpEvent);
+void CommTransp_Close(CommTransp transp);
+
+int CommTransp_EnqueueSpace(CommTransp transp);
+int CommTransp_EnqueueReset(CommTransp transp);
+int CommTransp_EnqueueCommit(CommTransp transp);
+int
+CommTransp_EnqueueSegment(CommTransp transp,
+ const void *buf,
+ unsigned int bufLen);
+
+int CommTransp_DequeueSpace(CommTransp transp);
+int CommTransp_DequeueReset(CommTransp transp);
+int CommTransp_DequeueCommit(CommTransp transp);
+int
+CommTransp_DequeueSegment(CommTransp transp,
+ void *buf,
+ unsigned int bufLen);
+
+unsigned int CommTransp_RequestInlineEvents(CommTransp transp);
+unsigned int CommTransp_ReleaseInlineEvents(CommTransp transp);
+
+
+/**
+ * @brief Enqueues data into the transport object, data is available for
+ * reading immediately.
+ * @param transp handle to the transport object.
+ * @param buf bytes to enqueue.
+ * @param bufLen number of bytes to enqueue.
+ * @return number of bytes enqueued on success, < 0 otherwise.
+ */
+
+static inline int
+CommTransp_EnqueueAtomic(CommTransp transp,
+ const void *buf,
+ unsigned int bufLen)
+{
+ int rc;
+
+ CommTransp_EnqueueReset(transp);
+ rc = CommTransp_EnqueueSegment(transp, buf, bufLen);
+ if (CommTransp_EnqueueCommit(transp)) {
+ rc = -1;
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Dequeues data from the transport object into a buffer.
+ * @param transp handle to the transport object.
+ * @param[out] buf buffer to copy to.
+ * @param bufLen number of bytes to dequeue.
+ * @return number of bytes dequeued on success, < 0 otherwise,
+ */
+
+static inline int
+CommTransp_DequeueAtomic(CommTransp transp,
+ void *buf,
+ unsigned int bufLen)
+{
+ int rc;
+
+ CommTransp_DequeueReset(transp);
+ rc = CommTransp_DequeueSegment(transp, buf, bufLen);
+ if (CommTransp_DequeueCommit(transp)) {
+ rc = -1;
+ }
+ return rc;
+}
+
+#endif // _COMM_TRANSP_IMPL_H_
diff --git a/arch/arm/mvp/mvpkm/coproc_defs.h b/arch/arm/mvp/mvpkm/coproc_defs.h
new file mode 100644
index 0000000..26218cf
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/coproc_defs.h
@@ -0,0 +1,351 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Constant definitions for ARM CP15 coprocessor registers.
+ *
+ * Derived from tweety hypervisor/src/armv6/trango_macros.inc file
+ */
+
+#ifndef _COPROC_DEFS_H_
+#define _COPROC_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @name CP10 registers.
+ *
+ * MCR/MRC format: @code #define <name> <opcode_1>, <CRn>, <CRm>, <opcode_2> @endcode
+ * @{
+ */
+#define VFP_FPSID 7, c0, c0, 0
+#define VFP_MVFR0 7, c7, c0, 0
+#define VFP_MVFR1 7, c6, c0, 0
+#define VFP_FPEXC 7, c8, c0, 0
+#define VFP_FPSCR 7, c1, c0, 0
+#define VFP_FPINST 7, c9, c0, 0
+#define VFP_FPINST2 7, c10, c0, 0
+/*@}*/
+
+
+/**
+ * @name CP15 registers.
+ *
+ * MCR/MRC format: @code #define <name> <opcode_1>, <CRn>, <CRm>, <opcode_2> @endcode
+ * MCRR format: @code #define <name> <opcode>, <CRm>@endcode
+ * @{
+ */
+#define ID_CODE 0, c0, c0, 0
+#define CACHE_TYPE 0, c0, c0, 1
+#define MPIDR 0, c0, c0, 5
+#define CACHE_SIZE_ID 1, c0, c0, 0
+#define CACHE_LEVEL_ID 1, c0, c0, 1
+#define CACHE_SIZE_SELECTION 2, c0, c0, 0
+#define MEM_MODEL_FEATURE_0 0, c0, c1, 4
+#define CONTROL_REGISTER 0, c1, c0, 0
+#define TTBASE0_POINTER 0, c2, c0, 0
+#define TTBASE1_POINTER 0, c2, c0, 1
+#define TTCONTROL 0, c2, c0, 2
+#define DOMAIN_CONTROL 0, c3, c0, 0
+#define DATA_FAULT_STATUS 0, c5, c0, 0
+#define INST_FAULT_STATUS 0, c5, c0, 1
+#define AUX_DATA_FAULT_STATUS 0, c5, c1, 0
+#define AUX_INST_FAULT_STATUS 0, c5, c1, 1
+#define DATA_FAULT_ADDRESS 0, c6, c0, 0
+#define INST_FAULT_ADDRESS 0, c6, c0, 2
+#define WAIT_FOR_INTERRUPT 0, c7, c0, 4
+#define PHYSICAL_ADDRESS 0, c7, c4, 0
+#define ICACHE_INVALIDATE_POU 0, c7, c5, 0
+#define ICACHE_INVALIDATE_MVA_POU 0, c7, c5, 1
+#define ICACHE_INVALIDATE_INDEX 0, c7, c5, 2
+#define BTAC_INVALIDATE 0, c7, c5, 6
+#define BTAC_INVALIDATE_MVA 0, c7, c5, 7
+#define DCACHE_INVALIDATE 0, c7, c6, 0
+#define DCACHE_INVALIDATE_MVA_POC 0, c7, c6, 1
+#define DCACHE_INVALIDATE_INDEX 0, c7, c6, 2
+#define UCACHE_INVALIDATE 0, c7, c7, 0
+#define V2P_CURRENT_PRIV_READ 0, c7, c8, 0
+#define V2P_CURRENT_PRIV_WRITE 0, c7, c8, 1
+#define V2P_CURRENT_USER_READ 0, c7, c8, 2
+#define V2P_CURRENT_USER_WRITE 0, c7, c8, 3
+#define V2P_OTHER_PRIV_READ 0, c7, c8, 4
+#define V2P_OTHER_PRIV_WRITE 0, c7, c8, 5
+#define V2P_OTHER_USER_READ 0, c7, c8, 6
+#define V2P_OTHER_USER_WRITE 0, c7, c8, 7
+#define DCACHE_CLEAN 0, c7, c10, 0
+#define DCACHE_CLEAN_MVA_POC 0, c7, c10, 1
+#define DCACHE_CLEAN_INDEX 0, c7, c10, 2
+#define DCACHE_CLEAN_MVA_POU 0, c7, c11, 1
+#define DCACHE_CLEAN_INVALIDATE 0, c7, c14, 0
+#define DCACHE_CLEAN_INVALIDATE_MVA_POC 0, c7, c14, 1
+#define DCACHE_CLEAN_INVALIDATE_INDEX 0, c7, c14, 2
+#define ITLB_INVALIDATE_ALL 0, c8, c5, 0
+#define ITLB_INVALIDATE_SINGLE 0, c8, c5, 1
+#define ITLB_INVALIDATE_ASID 0, c8, c5, 2
+#define DTLB_INVALIDATE_ALL 0, c8, c6, 0
+#define DTLB_INVALIDATE_SINGLE 0, c8, c6, 1
+#define DTLB_INVALIDATE_ASID 0, c8, c6, 2
+#define UTLB_INVALIDATE_ALL 0, c8, c7, 0
+#define UTLB_INVALIDATE_SINGLE 0, c8, c7, 1
+#define UTLB_INVALIDATE_ASID 0, c8, c7, 2
+#define TLB_LOCKDOWN 0, c10, c0, 0
+#define PRIMARY_REGION_REMAP 0, c10, c2, 0
+#define MAIR0 PRIMARY_REGION_REMAP
+#define NORMAL_MEMORY_REMAP 0, c10, c2, 1
+#define MAIR1 NORMAL_MEMORY_REMAP
+#define VECTOR_BASE 0, c12, c0, 0
+#define INTERRUPT_STATUS 0, c12, c1, 0
+#define CONTEXT_ID 0, c13, c0, 1
+#define TID_USER_RW 0, c13, c0, 2
+#define TID_USER_RO 0, c13, c0, 3
+#define TID_PRIV_RW 0, c13, c0, 4
+#define CLEAR_FAULT_IN_EFSR 7, c15, c0, 1
+#define VBAR 0, c12, c0, 0
+
+/*
+ * ARMv7 performance counters' registers (MVP related)
+ * - ARM Architecture Reference Manual v7-A and v7-R: DDI0406B
+ * - Cortex-A8 TRM, rev.r1p1: DDI0344B
+ */
+#define PERF_MON_CONTROL_REGISTER 0, c9, c12, 0
+#define CYCLE_COUNT 0, c9, c13, 0
+#define PERF_MON_COUNT_SET 0, c9, c12, 1
+#define PERF_MON_COUNT_CLR 0, c9, c12, 2
+#define PERF_MON_FLAG_RDCLR 0, c9, c12, 3
+#define PERF_MON_EVENT_SELECT 0, c9, c12, 5
+#define PERF_MON_EVENT_TYPE 0, c9, c13, 1
+#define PERF_MON_EVENT_COUNT 0, c9, c13, 2
+#define PERF_MON_INTEN_SET 0, c9, c14, 1
+#define PERF_MON_INTEN_CLR 0, c9, c14, 2
+
+#define COPROC_ACCESS_CONTROL 0, c1, c0, 2
+#define NON_SECURE_ACCESS_CONTROL 0, c1, c1, 2
+
+#define HYP_CFG 4, c1, c1, 0
+#define HYP_DEBUG_CONTROL 4, c1, c1, 1
+#define HYP_COPROC_TRAP 4, c1, c1, 2
+#define HYP_SYS_TRAP 4, c1, c1, 3
+#define VIRT_TCR 4, c2, c1, 2
+#define HYP_SYNDROME 4, c5, c2, 0
+#define HYP_DATA_FAULT_ADDRESS 4, c6, c0, 0
+#define HYP_INST_FAULT_ADDRESS 4, c6, c0, 2
+#define HYP_IPA_FAULT_ADDRESS 4, c6, c0, 4
+#define UTLB_INVALIDATE_ALL_HYP 4, c8, c7, 0
+#define UTLB_INVALIDATE_SINGLE_HYP 4, c8, c7, 1
+#define UTLB_INVALIDATE_ALL_NS_NON_HYP 4, c8, c7, 4
+
+#define EXT_TTBR0 0, c2
+#define EXT_TTBR1 1, c2
+#define HYP_TTBR 4, c2
+#define VIRT_TTBR 6, c2
+#define EXT_PHYSICAL_ADDRESS 0, c7
+/*@}*/
+
+/**
+ * @name CP15 configuration control register bits.
+ * @{
+ */
+#define ARM_CP15_CNTL_M (1 << 0)
+#define ARM_CP15_CNTL_A (1 << 1)
+#define ARM_CP15_CNTL_C (1 << 2)
+#define ARM_CP15_CNTL_B (1 << 7)
+#define ARM_CP15_CNTL_Z (1 << 11)
+#define ARM_CP15_CNTL_I (1 << 12)
+#define ARM_CP15_CNTL_V (1 << 13)
+#define ARM_CP15_CNTL_U (1 << 22)
+#define ARM_CP15_CNTL_VE (1 << 24)
+#define ARM_CP15_CNTL_EE (1 << 25)
+#define ARM_CP15_CNTL_TRE (1 << 28)
+#define ARM_CP15_CNTL_AFE (1 << 29)
+#define ARM_CP15_CNTL_TE (1 << 30)
+
+/*@}*/
+
+/**
+ * @brief Initial System Control Register (SCTLR) value.
+ *
+ * Magic described on B3-97 ARM DDI 0406B, it's the power-on
+ * value, e.g. caches/MMU/alignment checking/TEX remap etc. disabled.
+ */
+#define ARM_CP15_CNTL_INIT 0x00c50078
+
+/**
+ * @name System control coprocessor primary registers.
+ * Each primary register is backed by potentially multiple
+ * physical registers in the vCPU CP15 register file.
+ * @{
+ */
+#define ARM_CP15_CRN_ID 0 ///< Processor ID, cache, TCM and TLB type
+#define ARM_CP15_CRN_CNTL 1 ///< System configuration bits
+#define ARM_CP15_CRN_PT 2 ///< Page table control
+#define ARM_CP15_CRN_DACR 3 ///< Domain access control
+#define ARM_CP15_CRN_F_STATUS 5 ///< Fault status
+#define ARM_CP15_CRN_F_ADDR 6 ///< Fault address
+#define ARM_CP15_CRN_CACHE 7 ///< Cache/write buffer control
+#define ARM_CP15_CRN_TLB 8 ///< TLB control
+#define ARM_CP15_CRN_REMAP 10 ///< Memory Remap registers
+#define ARM_CP15_CRN_SER 12 ///< Security Extension registers
+#define ARM_CP15_CRN_PID 13 ///< Process ID
+#define ARM_CP15_CRN_TIMER 14 ///< Architecture timers
+
+#define ARM_CP15_CRM_INVALIDATE_D_CACHE_RANGE 6
+#define ARM_CP15_CRM_CLEAN_AND_INVALIDATE_D_CACHE_RANGE 14
+/*@}*/
+
+/**
+ * @name ARMv7 performance counter control/status register bits (MVP related)
+ * INTEN: counters overflow interrupt enable
+ * CNTEN: counters enable
+ * @{
+ */
+#define ARMV7_PMNC_E (1 << 0)
+#define ARMV7_PMNC_INTEN_P0 (1 << 0)
+#define ARMV7_PMNC_INTEN_P1 (1 << 1)
+#define ARMV7_PMNC_INTEN_P2 (1 << 2)
+#define ARMV7_PMNC_INTEN_P3 (1 << 3)
+#define ARMV7_PMNC_INTEN_C (1 << 31)
+#define ARMV7_PMNC_INTEN_MASK 0x8000000f
+#define ARMV7_PMNC_CNTEN_P0 (1 << 0)
+#define ARMV7_PMNC_CNTEN_P1 (1 << 1)
+#define ARMV7_PMNC_CNTEN_P2 (1 << 2)
+#define ARMV7_PMNC_CNTEN_P3 (1 << 3)
+#define ARMV7_PMNC_CNTEN_C (1 << 31)
+#define ARMV7_PMNC_FLAG_P0 (1 << 0)
+#define ARMV7_PMNC_FLAG_P1 (1 << 1)
+#define ARMV7_PMNC_FLAG_P2 (1 << 2)
+#define ARMV7_PMNC_FLAG_P3 (1 << 3)
+#define ARMV7_PMNC_FLAG_C (1 << 31)
+/*@}*/
+
+/**
+ * @name TTBR masks.
+ * See B4.9.2 ARM DDI 0100I and B3.12.24 ARM DDI 0406A.
+ * @{
+ */
+#define ARM_CP15_TTBASE_MASK MVP_MASK(14, 18)
+#define ARM_CP15_TTBASE_SPLIT_MASK(ttbcrn) MVP_MASK(14-ttbcrn, 18+ttbcrn)
+#define ARM_CP15_TTATTRIB_MASK MVP_MASK(0, 6)
+/*@}*/
+
+/**
+ * @name ARM fault status register encoding/decoding.
+ * See B4.6 and B4.9.6 in ARM DDI 0100I.
+ * @{
+ */
+#define ARM_CP15_FSR_STATUS_POS 0
+#define ARM_CP15_FSR_STATUS_POS2 10
+#define ARM_CP15_FSR_DOMAIN_POS 4
+#define ARM_CP15_FSR_WR_POS 11
+
+#define ARM_CP15_FSR_STATUS_LEN 4
+#define ARM_CP15_FSR_DOMAIN_LEN 4
+
+#define ARM_CP15_FSR_STATUS_DEBUG_EVENT 0x2
+#define ARM_CP15_FSR_STATUS_ALIGNMENT 0x1
+#define ARM_CP15_FSR_STATUS_ICACHE_MAINT 0x4
+#define ARM_CP15_FSR_STATUS_TRANSLATION_SECT 0x5
+#define ARM_CP15_FSR_STATUS_TRANSLATION_PAGE 0x7
+#define ARM_CP15_FSR_STATUS_DOMAIN_SECT 0x9
+#define ARM_CP15_FSR_STATUS_DOMAIN_PAGE 0xb
+#define ARM_CP15_FSR_STATUS_PERMISSION_SECT 0xd
+#define ARM_CP15_FSR_STATUS_PERMISSION_PAGE 0xf
+#define ARM_CP15_FSR_STATUS_ACCESS_FLAG_SECT 0x3
+#define ARM_CP15_FSR_STATUS_ACCESS_FLAG_PAGE 0x6
+#define ARM_CP15_FSR_STATUS_SYNC_EXT_ABORT 0x8
+#define ARM_CP15_FSR_STATUS_ASYNC_EXT_ABORT 0x16
+/*@}*/
+
+/**
+ * @brief Generate ARM fault status register value.
+ *
+ * @param fs status from Table B4-1. Only implemented for fs <= 0xf.
+ * @param domain domain accessed when abort occurred.
+ * @param write write access caused abort.
+ */
+#define ARM_CP15_FSR(fs,domain,write) \
+ (((fs) << ARM_CP15_FSR_STATUS_POS) | \
+ ((domain) << ARM_CP15_FSR_DOMAIN_POS) | \
+ ((write) ? (1 << ARM_CP15_FSR_WR_POS) : 0))
+
+#define ARM_CP15_FSR_STATUS(r) \
+ (MVP_EXTRACT_FIELD((r), ARM_CP15_FSR_STATUS_POS, ARM_CP15_FSR_STATUS_LEN) | \
+ (MVP_BIT((r), ARM_CP15_FSR_STATUS_POS2) << ARM_CP15_FSR_STATUS_LEN))
+#define ARM_CP15_FSR_DOMAIN(r) \
+ MVP_EXTRACT_FIELD((r), ARM_CP15_FSR_DOMAIN_POS, ARM_CP15_FSR_DOMAIN_LEN)
+#define ARM_CP15_FSR_WR(r) \
+ MVP_BIT((r), ARM_CP15_FSR_WR_POS)
+/*@}*/
+
+/*
+ * This should mask out the major and minor revision numbers.
+ * As per http://infocenter.arm.com/help/topic/com.arm.doc.ddi0211k/I65012.html
+ */
+#define ARM_CP15_MAIN_ID_NOREVISION_MASK 0xFF0FFFF0
+
+// 2-8 ARM DDI 0151C
+#define ARM_CP15_MAIN_ID_920_T 0x41129200
+// 3-18 ARM DDI 0211H
+#define ARM_CP15_MAIN_ID_1136J_S 0x4107B362
+
+/* Coprocessor Access Control Register */
+#define CPACR_ASEDIS (1 << 31)
+#define CPACR_D32DIS (1 << 30)
+#define CPACR_CP10_MASK (0x3 << (10*2))
+#define CPACR_CP10_CP11_MASK ( (0x3 << (10*2)) | (0x3 << (11*2)) )
+#define CPACR_CP10_CP11_PRIV_ONLY ( (0x1 << (10*2)) | (0x1 << (11*2)) )
+ /* 2-bit access permission per Co-Proc */
+
+/**
+ * @name ARM VFP/Adv. SIMD Extension System Registers
+ * @{
+ */
+#define ARM_VFP_SYSTEM_REG_FPSID 0x0
+#define ARM_VFP_SYSTEM_REG_FPSCR 0x1
+#define ARM_VFP_SYSTEM_REG_MVFR1 0x6
+#define ARM_VFP_SYSTEM_REG_MVFR0 0x7
+#define ARM_VFP_SYSTEM_REG_FPEXC 0x8
+#define ARM_VFP_SYSTEM_REG_FPINST 0x9
+#define ARM_VFP_SYSTEM_REG_FPINST2 0xa
+
+#define ARM_VFP_SYSTEM_REG_FPEXC_EX (1 << 31)
+#define ARM_VFP_SYSTEM_REG_FPEXC_EN (1 << 30)
+#define ARM_VFP_SYSTEM_REG_FPEXC_FP2V (1 << 28)
+
+#define ARM_VFP_SYSTEM_REG_MVFR0_A_SIMD_BIT (0)
+#define ARM_VFP_SYSTEM_REG_MVFR0_A_SIMD_MASK (0xf << ARM_VFP_SYSTEM_REG_MVFR0_A_SIMD_BIT)
+/*@}*/
+
+/**
+ * @name ARM Multi Processor ID Register (MPIDR) decoding
+ * @{
+ */
+#define ARM_CP15_MPIDR_MP (0x1 << 31)
+#define ARM_CP15_MPIDR_U (0x1 << 30)
+/*@}*/
+
+#endif /// ifndef _COPROC_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/cpufreq_kernel.c b/arch/arm/mvp/mvpkm/cpufreq_kernel.c
new file mode 100644
index 0000000..4ba71f2
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/cpufreq_kernel.c
@@ -0,0 +1,308 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MVP host kernel cpufreq related
+ *
+ * Track CPU frequency changes.
+ */
+
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/rwsem.h>
+#include <linux/smp.h>
+
+#include "mvp.h"
+#include "cpufreq_kernel.h"
+#include "mvp_timer.h"
+
+DEFINE_PER_CPU(struct TscToRate64Cb, tscToRate64);
+
+
+/**
+ * @brief Return current CPU frequency
+ * @param cpu CPU number
+ * @return CPU frequency in Hz
+ *
+ * When CPU_FREQ is not available, it uses hardcoded frequencies.
+ */
+static uint32
+GetCpuFrequency(unsigned int cpu)
+{
+ unsigned int counterKHZ;
+
+#ifdef CONFIG_CPU_FREQ
+ counterKHZ = cpufreq_quick_get(cpu);
+ if (counterKHZ == 0) {
+ counterKHZ = cpufreq_get(cpu);
+ FATAL_IF(counterKHZ == 0);
+ }
+#elif defined(MVP_HOST_BOARD_ve)
+ /**
+ * @knownjira{MVP-143}
+ * We're only using this under the simulator, and it's almost non perceptible to
+ * provide a fixed TSC frequency as the instructions / second executed widely
+ * varies depending over time. While we resolve this issue we can use the
+ * BogoMIPS reported at boot for now.
+ */
+ KNOWN_BUG(MVP-143);
+ counterKHZ = 125e3;
+ printk(KERN_INFO "mvpkm: CPU_FREQ not available, forcing TSC to %d KHz\n", counterKHZ);
+#elif defined(MVP_HOST_BOARD_panda)
+ counterKHZ = 1e6;
+#else
+ /*
+ * If the kernel can't tell us and we have no further host knowledge,
+ * time to die.
+ */
+#error "host TSC frequency unknown."
+#endif
+
+ return counterKHZ * 1000;
+}
+
+/**
+ * @brief Compute TSC to RATE64 ratio
+ * @param cpuFreq TSC frequency in Hz
+ * @param[out] ttr tscToRate64 pointer
+ */
+static void
+TscToRate64(uint32 cpuFreq, struct TscToRate64Cb *ttr)
+{
+ uint32 shift;
+ uint64 mult;
+
+ /*
+ * A little bit of math !
+ *
+ * We need here to convert the TSC value to our RATE64 timebase.
+ *
+ * In other words:
+ *
+ * tsc * MVP_TIMER_RATE64
+ * rate64 = ----------------------
+ * cpuFreq
+ *
+ * But we are limited by CPU performance (does not divide easily), CPU
+ * instruction set, and CPU register file width. To fit performance
+ * requirement, the math becomes:
+ *
+ * rate64 = (cpuFreq * mult) >> shift
+ *
+ * To respect instruction set, both cpuFreq and mult must be 32-bit
+ * numbers. Thus (cpuFreq * mult) will be a 64-bit number.
+ *
+ *
+ * Log2 rate64 = Log2 cpuFreq + Log2 mult - shift
+ *
+ * shift = Log2 mult + Log2 cpuFreq - Log2 rate64
+ *
+ * && Log2 mult < 32
+ *
+ * => shift < 32 + Log2 cpuFreq - Log2 rate64
+ *
+ * rate64 << shift
+ * => mult = ---------------
+ * cpuFreq
+ *
+ * (rate64 << shift) must be a 64-bit number:
+ *
+ * Log2 rate64 + shift < 64
+ *
+ * => shift < 64 - Log2 rate64
+ *
+ * While cpuFreq is lower than 2^32 Hz, we have:
+ *
+ * shift < 32 + Log2 cpuFreq - Log2 rate64 < 64 - Log2 rate64
+ *
+ * As (31 - CLZ32 x) <= Log2 x < (32 - CLZ32 x):
+ *
+ * 31 - CLZ32 cpuFreq <= Log2 cpuFreq &&
+ *
+ * CLZ32 rate64 - 32 < - Log2 rate64
+ *
+ * 31 + CLZ32 rate64 - CLZ32 cpuFreq < 32 + Log2 cpuFreq - Log2 rate64
+ *
+ * As we want shift to be as great as possible:
+ *
+ * => shift = 31 + CLZ32 rate64 - CLZ32 cpuFreq
+ *
+ * rate64 << shift
+ * && mult = ---------------
+ * cpuFreq
+ *
+ *
+ */
+
+ /* CLZ(MVP_TIMER_RATE64) is optimized by compiler in a constant */
+ shift = 31 + CLZ(MVP_TIMER_RATE64) - CLZ(cpuFreq);
+ mult = MVP_TIMER_RATE64;
+ mult <<= shift;
+ do_div(mult, cpuFreq);
+
+ /* verify Log2 mult < 32 */
+ ASSERT(mult < (1ULL<<32));
+
+ /* update global variables */
+ ttr->mult = mult;
+ ttr->shift = shift;
+}
+
+/**
+ * @brief Compute TSC to RATE64 ratio for the current cpu
+ * @param info TSC frequency in Hz
+ * @sideeffect Update local cpu tscToRate64
+ */
+static void
+TscToRate64IPI(void *info)
+{
+ uint32 cpuFreq = (uint32)info;
+
+ TscToRate64(cpuFreq, &__get_cpu_var(tscToRate64));
+}
+
+/**
+ * @brief Handle cpufreq transition notifications.
+ * @param nb Notifier block
+ * @param val Notified event
+ * @param data Linux cpufreq_freqs info
+ * @return NOTIFY_OK
+ *
+ * @note A frequency change can fail in which case PRECHANGE and POSTCHANGE
+ * will not be paired and you get any number of PRECHANGE and maybe never a
+ * POSTCHANGE (i.e. there is not enough battery voltage available to support a
+ * high frequency).
+ * @note This is called once per cpu core that is changing but not always on
+ * the core that is changing.
+ */
+static int
+CpuFreqNotifier(struct notifier_block *nb,
+ unsigned long val,
+ void *data)
+{
+ struct cpufreq_freqs *freq = data;
+ bool updateRequired;
+
+ /* ASSUMPTION: Only freq. increases can fail and that it is ok to tell the
+ * guest a higher frequency than it really is but not the other way around
+ * as that just leads to time "jumping" forward in the guest not backwards.
+ */
+ updateRequired = (val == CPUFREQ_PRECHANGE && freq->new > freq->old) ||
+ (val == CPUFREQ_POSTCHANGE && freq->new < freq->old);
+
+ /* Call TscToRate64() on the correct CPU core so that locking is not
+ * required. This also has the side-effect of forcing any currently running
+ * vCPU's to worldswitch back to the host and correctly update the world
+ * switch page.
+ */
+ if (updateRequired) {
+ uint32 hz = freq->new * 1000;
+ smp_call_function_single(freq->cpu, TscToRate64IPI, (void *)hz, false);
+ }
+
+ return NOTIFY_OK;
+}
+
+/**
+ * @brief Notifier block for cpufreq transitions
+ */
+static struct notifier_block cpuFreqNotifierBlock = {
+ .notifier_call = CpuFreqNotifier
+};
+
+/**
+ * @brief Handle cpuUp notifications.
+ * @param nb Notifier block
+ * @param action Notified action, e.g., CPU_ONLINE
+ * @param hcpu cpu no
+ * @return NOTIFY_OK
+ */
+static int
+CpuUpNotifier(struct notifier_block *nb,
+ unsigned long action,
+ void *hcpu)
+{
+ long cpu = (long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ /* The new CPU core is not yet executing normal tasks, so it is safe
+ * to update it's scaling factors from a different core. */
+ TscToRate64(GetCpuFrequency(cpu), &per_cpu(tscToRate64, cpu));
+ break;
+ default:
+ /*
+ * Ignore all other action notifications,
+ * such as CPU_UP_PREPARE, CPU_UP_CANCELED,
+ * CPU_DOWN_PREPARE, CPU_DOWN_FAILED,
+ * CPU_DYING, CPU_DEAD, CPU_POST_DEAD, etc.
+ * as they are irrelevant here.
+ */
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+/**
+ * @brief Notifier block for cpus going online
+ */
+static struct notifier_block cpuUpNotifierBlock = {
+ .notifier_call = CpuUpNotifier
+};
+
+/**
+ * @brief Initialize TSC ratio and register cpufreq transitions.
+ */
+void
+CpuFreq_Init(void)
+{
+ int ret;
+ int cpu;
+
+ /* register callback on frequency change */
+ ret = cpufreq_register_notifier(&cpuFreqNotifierBlock,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ FATAL_IF(ret < 0);
+
+ /* register callback on cpu core online */
+ ret = register_cpu_notifier(&cpuUpNotifierBlock);
+ FATAL_IF(ret < 0);
+
+ /* Make sure that things are correctly initialized. */
+ for_each_online_cpu(cpu) {
+ TscToRate64(GetCpuFrequency(cpu), &per_cpu(tscToRate64, cpu));
+ }
+}
+
+/**
+ * @brief Exit cpufreq, unregister cpufreq transitions
+ */
+void
+CpuFreq_Exit(void)
+{
+ cpufreq_unregister_notifier(&cpuFreqNotifierBlock,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ unregister_cpu_notifier(&cpuUpNotifierBlock);
+}
diff --git a/arch/arm/mvp/mvpkm/cpufreq_kernel.h b/arch/arm/mvp/mvpkm/cpufreq_kernel.h
new file mode 100644
index 0000000..a84b6dd
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/cpufreq_kernel.h
@@ -0,0 +1,47 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The monitor-kernel socket interface kernel-only definitions.
+ */
+
+#ifndef _CPUFREQ_KERNEL_H
+#define _CPUFREQ_KERNEL_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/* Scaling factors to convert CPU clock cycles to Rate64 value */
+struct TscToRate64Cb {
+ uint32 mult;
+ uint32 shift;
+};
+
+/* It is assumed that this is only accessed from the current CPU core and not
+ * "across cores" */
+DECLARE_PER_CPU(struct TscToRate64Cb, tscToRate64);
+
+void CpuFreq_Init(void);
+void CpuFreq_Exit(void);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/exc_defs.h b/arch/arm/mvp/mvpkm/exc_defs.h
new file mode 100644
index 0000000..1d5d063
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/exc_defs.h
@@ -0,0 +1,67 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Exception-related definitions. See A2.6 ARM DDI 0100I.
+ */
+
+#ifndef _EXC_DEFS_H_
+#define _EXC_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define EXC_VECTOR_SIZE 0x20
+
+#define EXC_RESET_VECTOR_OFFSET 0x00
+#define EXC_UNDEFINED_VECTOR_OFFSET 0x04
+#define EXC_SWI_VECTOR_OFFSET 0x08
+#define EXC_PREFETCH_ABORT_VECTOR_OFFSET 0x0c
+#define EXC_DATA_ABORT_VECTOR_OFFSET 0x10
+#define EXC_HYP_VECTOR_OFFSET 0x14
+#define EXC_IRQ_VECTOR_OFFSET 0x18
+#define EXC_FIQ_VECTOR_OFFSET 0x1c
+
+#define EXC_ARM_UNDEFINED_SAVED_PC_OFFSET 4
+#define EXC_ARM_SWI_SAVED_PC_OFFSET 4
+#define EXC_ARM_PREFETCH_ABORT_SAVED_PC_OFFSET 4
+#define EXC_ARM_DATA_ABORT_SAVED_PC_OFFSET 8
+#define EXC_ARM_IRQ_SAVED_PC_OFFSET 4
+#define EXC_ARM_FIQ_SAVED_PC_OFFSET 4
+
+#define EXC_THUMB_UNDEFINED_SAVED_PC_OFFSET 2
+#define EXC_THUMB_SWI_SAVED_PC_OFFSET 2
+#define EXC_THUMB_PREFETCH_ABORT_SAVED_PC_OFFSET 4
+#define EXC_THUMB_DATA_ABORT_SAVED_PC_OFFSET 8
+#define EXC_THUMB_IRQ_SAVED_PC_OFFSET 4
+#define EXC_THUMB_FIQ_SAVED_PC_OFFSET 4
+
+#define EXC_SAVED_PC_OFFSET(exc, cpsr) \
+ (((cpsr) & ARM_PSR_T) ? EXC_THUMB_##exc##_SAVED_PC_OFFSET : \
+ EXC_ARM_##exc##_SAVED_PC_OFFSET)
+
+#endif /// _EXC_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/exc_types.h b/arch/arm/mvp/mvpkm/exc_types.h
new file mode 100644
index 0000000..ba835e5
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/exc_types.h
@@ -0,0 +1,53 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Exception-related types. See A2.6 ARM DDI 0100I.
+ */
+
+#ifndef _EXC_TYPES_H_
+#define _EXC_TYPES_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @brief ARM hardware exception enumeration. EXC_NONE is added to provide
+ * a distinguished value to flag non-exception states.
+ */
+typedef enum {
+ EXC_NONE,
+ EXC_RESET,
+ EXC_UNDEFINED,
+ EXC_SWI,
+ EXC_PREFETCH_ABORT,
+ EXC_DATA_ABORT,
+ EXC_IRQ,
+ EXC_FIQ
+} ARM_Exception;
+
+#endif /// _EXC_TYPES_H_
diff --git a/arch/arm/mvp/mvpkm/exitstatus.h b/arch/arm/mvp/mvpkm/exitstatus.h
new file mode 100644
index 0000000..c53827a
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/exitstatus.h
@@ -0,0 +1,67 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Exit Status values
+ */
+
+#ifndef _EXITSTATUS_H
+#define _EXITSTATUS_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_HOSTUSER
+#include "include_check.h"
+
+
+#define _EXIT_STATUS_DEF \
+ _EXIT_STATUS_ITEM(Success, 0) \
+ _EXIT_STATUS_ITEM(ReturnToHost, 1) \
+ _EXIT_STATUS_ITEM(GuestExit, 2) \
+ _EXIT_STATUS_ITEM(HostRequest, 3) \
+ _EXIT_STATUS_ITEM(VMXFatalError, 4) \
+ _EXIT_STATUS_ITEM(VMMFatalError, 5) \
+ _EXIT_STATUS_ITEM(MVPDFatalError, 6) \
+ _EXIT_STATUS_ITEM(VPNFatalError, 7) \
+ _EXIT_STATUS_ITEM(VMXFindCause, 8)
+
+
+enum ExitStatus {
+#define _EXIT_STATUS_ITEM(name,num) ExitStatus##name = num,
+_EXIT_STATUS_DEF
+#undef _EXIT_STATUS_ITEM
+};
+
+typedef enum ExitStatus ExitStatus;
+
+#ifndef __cplusplus
+static const char * ExitStatusName[] UNUSED = {
+#define _EXIT_STATUS_ITEM(name,num) [ExitStatus##name] = #name,
+_EXIT_STATUS_DEF
+#undef _EXIT_STATUS_ITEM
+};
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/fatalerror.h b/arch/arm/mvp/mvpkm/fatalerror.h
new file mode 100644
index 0000000..58e1f98
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/fatalerror.h
@@ -0,0 +1,126 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief fatal error handlers. They all post fatal errors regardless of build
+ * type.
+ */
+
+#ifndef _FATALERROR_H
+#define _FATALERROR_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mvp_compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum FECode {
+ FECodeMisc, ///< generic FATAL() call of sorts
+ FECodeOOM, ///< FATAL_OOM() call of sorts
+ FECodeAssert, ///< ASSERT() call of sorts
+ FECodeNR, ///< NOT_REACHED() call of sorts
+ FECodeNI, ///< NOT_IMPLEMENTED() call of sorts
+ FECodeNT, ///< NOT_TESTED() call of sorts
+ FECodeCF ///< COMPILE_FAIL() call of sorts
+};
+typedef enum FECode FECode;
+
+#define FATAL() FatalError(__FILE__, __LINE__, FECodeMisc, 0, NULL)
+#define FATAL_IF(x) do { if (UNLIKELY(x)) FATAL(); } while (0)
+#define FATAL_OOM() FatalError(__FILE__, __LINE__, FECodeOOM, 0, NULL)
+#define FATAL_OOM_IF(x) do { if (UNLIKELY(x)) FATAL_OOM(); } while (0)
+
+extern _Bool FatalError_hit;
+
+void NORETURN FatalError(char const *file,
+ int line,
+ FECode feCode,
+ int bugno,
+ char const *fmt,
+ ...) FORMAT(printf,5,6);
+
+#define FATALERROR_COMMON(printFunc, \
+ printFuncV, \
+ file, \
+ line, \
+ feCode, \
+ bugno, \
+ fmt) { \
+ va_list ap; \
+ \
+ printFunc("FatalError: %s:%d, code %d, bugno %d\n", \
+ file, line, feCode, bugno); \
+ if (fmt != NULL) { \
+ va_start(ap, fmt); \
+ printFuncV(fmt, ap); \
+ va_end(ap); \
+ } \
+ }
+
+#if defined IN_HOSTUSER || defined IN_GUESTUSER || defined IN_WORKSTATION
+
+#define FATALERROR_POSIX_USER \
+void \
+FatalError_VErrPrintf(const char *fmt, va_list ap) \
+{ \
+ vfprintf(stderr, fmt, ap); \
+} \
+\
+void \
+FatalError_ErrPrintf(const char *fmt, ...) \
+{ \
+ va_list ap; \
+ va_start(ap, fmt); \
+ FatalError_VErrPrintf(fmt, ap); \
+ va_end(ap); \
+} \
+\
+void NORETURN \
+FatalError(char const *file, \
+ int line, \
+ FECode feCode, \
+ int bugno, \
+ const char *fmt, \
+ ...) \
+{ \
+ FATALERROR_COMMON(FatalError_ErrPrintf, FatalError_VErrPrintf, file, line, feCode, bugno, fmt); \
+ exit(EXIT_FAILURE); \
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/include_check.h b/arch/arm/mvp/mvpkm/include_check.h
new file mode 100644
index 0000000..2eeafe7
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/include_check.h
@@ -0,0 +1,18 @@
+/*
+ * Linux 2.6.32 and later Kernel module for Empty File Placeholder
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
diff --git a/arch/arm/mvp/mvpkm/instr_defs.h b/arch/arm/mvp/mvpkm/instr_defs.h
new file mode 100644
index 0000000..ce6b1c9
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/instr_defs.h
@@ -0,0 +1,426 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief ARM instruction encoding/decoding macros.
+ */
+
+#ifndef _INSTR_DEFS_H_
+#define _INSTR_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "utils.h"
+
+/**
+ * @name ARM register synonyms.
+ * @{
+ */
+#define ARM_REG_R0 0
+#define ARM_REG_R1 1
+#define ARM_REG_R2 2
+#define ARM_REG_R3 3
+#define ARM_REG_R4 4
+#define ARM_REG_R5 5
+#define ARM_REG_R6 6
+#define ARM_REG_R7 7
+#define ARM_REG_R8 8
+#define ARM_REG_R9 9
+#define ARM_REG_R10 10
+#define ARM_REG_FP 11
+#define ARM_REG_IP 12
+#define ARM_REG_SP 13
+#define ARM_REG_LR 14
+#define ARM_REG_PC 15
+/*@}*/
+
+/**
+ * @name Data-processing + load/store instruction register field decoding.
+ *
+ * @note The following constants and masks used to fetch register operands
+ * are meant to be used in strictly the following sets of instructions:
+ * data processing instructions and load/store instructions.
+ * If you want to fetch the RN, RD, RS and RM fields for some other
+ * type of instructions, please verify before using -- you may have
+ * to introduce special constants just for those sets of instructions.
+ * For instance, all the multiply and signed multiply instructions have
+ * RN and RD reversed. So, @b BEWARE !
+ *
+ * @{
+ */
+#define ARM_INSTR_RN_BIT_POS 16
+#define ARM_INSTR_RD_BIT_POS 12
+#define ARM_INSTR_RS_BIT_POS 8
+#define ARM_INSTR_RM_BIT_POS 0
+
+#define ARM_INSTR_RN_LENGTH 4
+#define ARM_INSTR_RD_LENGTH 4
+#define ARM_INSTR_RS_LENGTH 4
+#define ARM_INSTR_RM_LENGTH 4
+
+#define ARM_INSTR_RN(r) \
+ MVP_EXTRACT_FIELD((r), ARM_INSTR_RN_BIT_POS, ARM_INSTR_RN_LENGTH)
+#define ARM_INSTR_RD(r) \
+ MVP_EXTRACT_FIELD((r), ARM_INSTR_RD_BIT_POS, ARM_INSTR_RD_LENGTH)
+#define ARM_INSTR_RS(r) \
+ MVP_EXTRACT_FIELD((r), ARM_INSTR_RS_BIT_POS, ARM_INSTR_RS_LENGTH)
+#define ARM_INSTR_RM(r) \
+ MVP_EXTRACT_FIELD((r), ARM_INSTR_RM_BIT_POS, ARM_INSTR_RM_LENGTH)
+
+#define ARM_INSTR_RN_SHIFT(word) ((word) << ARM_INSTR_RN_BIT_POS)
+#define ARM_INSTR_RD_SHIFT(word) ((word) << ARM_INSTR_RD_BIT_POS)
+#define ARM_INSTR_RS_SHIFT(word) ((word) << ARM_INSTR_RS_BIT_POS)
+#define ARM_INSTR_RM_SHIFT(word) ((word) << ARM_INSTR_RM_BIT_POS)
+
+#define ARM_INSTR_RN_MASK (~(ARM_INSTR_RN_SHIFT(0xf)))
+#define ARM_INSTR_RD_MASK (~(ARM_INSTR_RD_SHIFT(0xf)))
+#define ARM_INSTR_RS_MASK (~(ARM_INSTR_RS_SHIFT(0xf)))
+#define ARM_INSTR_RM_MASK (~(ARM_INSTR_RM_SHIFT(0xf)))
+/*@}*/
+
+/**
+ * @name Condition field -- common bit layout across all ARM instructions.
+ * @{
+ */
+#define ARM_INSTR_COND(instr) (MVP_EXTRACT_FIELD(instr, 28, 4))
+
+#define ARM_INSTR_COND_EQ 0x0 ///< Equal
+#define ARM_INSTR_COND_NE 0x1 ///< Not equal
+#define ARM_INSTR_COND_CS 0x2 ///< Carry set/unsigned higher or same
+#define ARM_INSTR_COND_CC 0x3 ///< Carry clear/unsigned lower
+#define ARM_INSTR_COND_MI 0x4 ///< Minus/negative
+#define ARM_INSTR_COND_PL 0x5 ///< Plus/positive or zero
+#define ARM_INSTR_COND_VS 0x6 ///< Overflow
+#define ARM_INSTR_COND_VC 0x7 ///< No overflow
+#define ARM_INSTR_COND_HI 0x8 ///< Unsigned higher
+#define ARM_INSTR_COND_LS 0x9 ///< Unsigned lower or same
+#define ARM_INSTR_COND_GE 0xa ///< Signed greater than or equal
+#define ARM_INSTR_COND_LT 0xb ///< Signed less than
+#define ARM_INSTR_COND_GT 0xc ///< Signed greater than
+#define ARM_INSTR_COND_LE 0xd ///< Signed less than or equal
+#define ARM_INSTR_COND_AL 0xe ///< Always (unconditional)
+#define ARM_INSTR_COND_NV 0xf ///< Invalid
+/*@}*/
+
+/**
+ * @name Load/store instruction decoding.
+ * @{
+ */
+
+/*
+ * I bit indicating Register(1)/Immediate(0) addressing modes.
+ */
+#define ARM_INSTR_LDST_IBIT(instr) (MVP_BIT(instr, 25))
+
+/*
+ * U bit indicating whether the offset is added to the base (U == 1)
+ * or is subtracted from the base (U == 0).
+ */
+#define ARM_INSTR_LDST_UBIT(instr) (MVP_BIT(instr, 23))
+
+/*
+ * B bit indicating byte(1)/word(0).
+ */
+#define ARM_INSTR_LDST_BBIT(instr) (MVP_BIT(instr, 22))
+
+/*
+ * L bit indicating ld(1)/st(0).
+ */
+#define ARM_INSTR_LDST_LBIT(instr) (MVP_BIT(instr, 20))
+
+/*
+ * Shifter operand.
+ */
+#define ARM_INSTR_LDST_SHIFTER_OPERAND(instr) (MVP_EXTRACT_FIELD(instr, 0, 12))
+
+/*
+ * Immediate offset (12-bits wide) for load/store.
+ */
+#define ARM_INSTR_LDST_IMMEDIATE(instr) (MVP_EXTRACT_FIELD(instr, 0, 12))
+
+/*
+ * Register List for multiple ld/st.
+ */
+#define ARM_INSTR_LDMSTM_REGLIST(instr) (MVP_EXTRACT_FIELD(instr, 0, 16))
+
+/*
+ * Immediate Offset for Miscellaneous ld/st instructions.
+ */
+#define ARM_INSTR_MISC_LDST_IMM_OFFSET(instr) \
+ ((MVP_EXTRACT_FIELD(instr, 8, 4) << 4) | MVP_EXTRACT_FIELD(instr, 0, 4))
+
+/*@}*/
+
+/**
+ * @name Thumb ldrt/strt instruction decoding.
+ * @{
+ */
+
+/*
+ * L bit indicating ld(1)/st(0).
+ */
+#define ARM_THUMB_INSTR_LDST_LBIT(instr) (MVP_BIT(instr, 20))
+
+/*
+ * W bit indicating word(1)/byte(0).
+ */
+#define ARM_THUMB_INSTR_LDST_WBIT(instr) (MVP_BIT(instr, 22))
+
+/*
+ * Immediate offset (8-bits wide) for load/store.
+ */
+#define ARM_THUMB_INSTR_LDST_IMMEDIATE(instr) (MVP_EXTRACT_FIELD(instr, 0, 8))
+
+/*@}*/
+
+/**
+ * @name ARM instruction opcodes.
+ * @{
+ */
+#define ARM_OP_BR_A1 0x0a000000
+#define ARM_OP_BX_A1 0x012fff10
+#define ARM_OP_LDR_LIT_A1 0x051f0000
+#define ARM_OP_MOV_A1 0x01a00000
+#define ARM_OP_MOVW_A2 0x03000000
+#define ARM_OP_MOVT_A1 0x03400000
+#define ARM_OP_MRS_A1 0x01000000
+#define ARM_OP_MSR_T1 0x8000f380
+#define ARM_OP_MSR_A1 0x0120f000
+#define ARM_OP_HVC_A1 0x01400070
+#define ARM_OP_ERET_T1 0x8f00f3de
+#define ARM_OP_ERET_A1 0x0160006e
+
+/*
+ * Set SYSm[5] = 1 for VE MSR/MRS, see p77-78 ARM PRD03-GENC-008353 10.0.
+ */
+#define ARM_OP_MRS_EXT_A1 (ARM_OP_MRS_A1 | (1 << 9))
+#define ARM_OP_MSR_EXT_T1 (ARM_OP_MSR_T1 | (1 << 21))
+#define ARM_OP_MSR_EXT_A1 (ARM_OP_MSR_A1 | (1 << 9))
+
+#define ARM_OP_I 0x02000000
+#define ARM_OP_S 0x00100000
+#define ARM_OP_W 0x00200000
+/*@}*/
+
+/**
+ * @name ARM instruction class - see Figure A3-1 ARM DDI 0100I.
+ * @{
+ */
+#define ARM_INSTR_CLASS(instr) MVP_BITS(instr, 25, 27)
+
+#define ARM_INSTR_CLASS_BRANCH 0x5
+/*@}*/
+
+/**
+ * @name ARM instruction opcode - see Figure A3-1 ARM DDI 0100I. Does not
+ * include extension bits 4-7.
+ * @{
+ */
+#define ARM_INSTR_OPCODE(instr) MVP_EXTRACT_FIELD(instr, 20, 8)
+
+#define ARM_INSTR_OPCODE_EQ(instr1, instr2) \
+ (ARM_INSTR_OPCODE(instr1) == ARM_INSTR_OPCODE(instr2))
+/*@}*/
+
+/**
+ * @brief Extract the offset in a branch instruction - i.e., the least
+ * significant 24 bits sign extended.
+ */
+#define ARM_INSTR_BRANCH_TARGET(inst) (((int32)(inst) << 8) >> 6)
+
+/**
+ * @brief Check if a potential branch target is outside the encodable distance.
+ */
+#define ARM_INSTR_BRANCH_TARGET_OVERFLOWS(v) ((v) + (1 << 25) >= (1<< 26))
+
+/**
+ * @brief Modify branch instruction encoding 'ins' with 'offset' as the
+ * new target.
+ */
+#define ARM_INSTR_BRANCH_UPDATE_OFFSET(ins, offset) \
+ (((ins) & MVP_MASK(24, 8)) | (((offset) >> 2) & MVP_MASK(0, 24)))
+
+/**
+ * @brief B instruction encoding - see A8.6.16 ARM DDI 0406A.
+ */
+#define ARM_INSTR_BR_ENC(cond, offset) \
+ (((cond) << 28) | ARM_OP_BR_A1 | MVP_BITS(((uint32)offset) >> 2, 0, 23))
+
+/**
+ * @brief BX instruction encoding
+ */
+#define ARM_INSTR_BX_ENC(cond, rm) \
+ (((cond) << 28) | ARM_OP_BX_A1 | (rm))
+
+/**
+ * @brief LDR +literal instruction encoding - see ARM8.6.59 DDI 0506A.
+ */
+#define ARM_INSTR_LDR_LIT_ADD_ENC(cond, reg, offset) \
+ (((cond) << 28) | ARM_OP_LDR_LIT_A1 | (1 << 23) | ((reg) << 12) | (offset))
+
+/**
+ * @brief Generate encoding of the instruction mov rd, rn.
+ */
+#define ARM_INSTR_MOV_A1_ENC(cond, rd, rn) \
+ ((((cond) << 28) | ARM_OP_MOV_A1 | ((rd) << 12) | (rn)))
+
+/**
+ * @name Encoding/decoding of MOVT/W instructions.
+ * @{
+ */
+#define ARM_INSTR_MOVTW_IMMED(instr) \
+ (MVP_BITS(instr, 0, 11) | (MVP_BITS(instr, 16, 19) << 12))
+
+#define ARM_INSTR_MOVW_A2_ENC(cond,rd,immed) \
+ (((cond) << 28) | ARM_OP_MOVW_A2 | (MVP_BITS(immed, 12, 15) << 16) | \
+ ((rd) << 12) | MVP_BITS(immed, 0, 11))
+
+#define ARM_INSTR_MOVT_A1_ENC(cond,rd,immed) \
+ (((cond) << 28) | ARM_OP_MOVT_A1 | \
+ (MVP_BITS(((immed) >> 16), 12, 15) << 16) | \
+ ((rd) << 12) | MVP_BITS(((immed) >> 16), 0, 11))
+/*@}*/
+
+/**
+ * @brief BKPT instruction encoding - see A4.1.7 ARM DDI 0100I.
+ */
+#define ARM_INSTR_BKPT_ENC(immed) \
+ (0xe1200070 | \
+ MVP_EXTRACT_FIELD(immed, 0, 4) | \
+ (MVP_EXTRACT_FIELD(immed, 4, 12) << 8))
+
+/**
+ * @name VE instruction encodings - see section 13 ARM PRD03-GENC-008353 10.0.
+ * @{
+ */
+#define ARM_INSTR_HVC_A1_ENC(immed) \
+ ((ARM_INSTR_COND_AL << 28) | ARM_OP_HVC_A1 | \
+ MVP_EXTRACT_FIELD(immed, 0, 4) | \
+ (MVP_EXTRACT_FIELD(immed, 4, 12) << 8))
+
+#define ARM_INSTR_ERET_A1_ENC(cond) \
+ (((cond) << 28) | ARM_OP_ERET_A1)
+
+/*
+ * R=0
+ */
+#define ARM_REG_R8_USR 0
+#define ARM_REG_R9_USR 1
+#define ARM_REG_R10_USR 2
+#define ARM_REG_R11_USR 3
+#define ARM_REG_R12_USR 4
+#define ARM_REG_SP_USR 5
+#define ARM_REG_LR_USR 6
+#define ARM_REG_R8_FIQ 8
+#define ARM_REG_R9_FIQ 9
+#define ARM_REG_R10_FIQ 10
+#define ARM_REG_FP_FIQ 11
+#define ARM_REG_IP_FIQ 12
+#define ARM_REG_SP_FIQ 13
+#define ARM_REG_LR_FIQ 14
+#define ARM_REG_LR_IRQ 16
+#define ARM_REG_SP_IRQ 17
+#define ARM_REG_LR_SVC 18
+#define ARM_REG_SP_SVC 19
+#define ARM_REG_LR_ABT 20
+#define ARM_REG_SP_ABT 21
+#define ARM_REG_LR_UND 22
+#define ARM_REG_SP_UND 23
+#define ARM_REG_LR_MON 28
+#define ARM_REG_SP_MON 29
+#define ARM_REG_ELR_HYP 30
+#define ARM_REG_SP_HYP 31
+
+/*
+ * R=1
+ */
+#define R_EXTEND(x) ((1 << 5) | (x))
+#define ARM_REG_SPSR_FIQ R_EXTEND(ARM_REG_LR_FIQ)
+#define ARM_REG_SPSR_IRQ R_EXTEND(ARM_REG_LR_IRQ)
+#define ARM_REG_SPSR_SVC R_EXTEND(ARM_REG_LR_SVC)
+#define ARM_REG_SPSR_ABT R_EXTEND(ARM_REG_LR_ABT)
+#define ARM_REG_SPSR_UND R_EXTEND(ARM_REG_LR_UND)
+#define ARM_REG_SPSR_MON R_EXTEND(ARM_REG_LR_MON)
+#define ARM_REG_SPSR_HYP R_EXTEND(ARM_REG_ELR_HYP)
+
+#define ARM_INSTR_MSR_EXT_T1_ENC(rm,rn) \
+ (ARM_OP_MSR_EXT_T1 | (MVP_BIT(rm, 5) << 4) | \
+ (MVP_BIT(rm, 4) << 20) | (MVP_EXTRACT_FIELD(rm, 0, 4) << 24) | ((rn) << 0))
+
+#define ARM_INSTR_MSR_EXT_A1_ENC(cond,rm,rn) \
+ (((cond) << 28) | ARM_OP_MSR_EXT_A1 | (MVP_BIT(rm, 5) << 22) | \
+ (MVP_BIT(rm, 4) << 8) | (MVP_EXTRACT_FIELD(rm, 0, 4) << 16) | ((rn) << 0))
+
+#define ARM_INSTR_MRS_EXT_A1_ENC(cond,rd,rm) \
+ (((cond) << 28) | ARM_OP_MRS_EXT_A1 | (MVP_BIT(rm, 5) << 22) | \
+ (MVP_BIT(rm, 4) << 8) | (MVP_EXTRACT_FIELD(rm, 0, 4) << 16) | ((rd) << 12))
+/*@}*/
+
+/**
+ * @name ARM MCR/MRC/MCRR instruction decoding.
+ * @{
+ */
+#define ARM_INSTR_COPROC_CR_LEN 4
+#define ARM_INSTR_COPROC_CR_MAX (1 << ARM_INSTR_COPROC_CR_LEN)
+#define ARM_INSTR_COPROC_OPCODE_LEN 3
+#define ARM_INSTR_COPROC_OPCODE_MAX (1 << ARM_INSTR_COPROC_OPCODE_LEN)
+
+#define ARM_INSTR_COPROC_CRM(instr) MVP_EXTRACT_FIELD(instr, 0, 4)
+#define ARM_INSTR_COPROC_CRN(instr) MVP_EXTRACT_FIELD(instr, 16, 4)
+#define ARM_INSTR_COPROC_OPCODE1(instr) MVP_EXTRACT_FIELD(instr, 21, 3)
+#define ARM_INSTR_COPROC_OPCODE2(instr) MVP_EXTRACT_FIELD(instr, 5, 3)
+#define ARM_INSTR_COPROC_OPCODE(instr) MVP_EXTRACT_FIELD(instr, 4, 4)
+#define ARM_INSTR_COPROC_CPNUM(instr) MVP_EXTRACT_FIELD(instr, 8, 4)
+/*@}*/
+
+/**
+ * @name ARM VMRS/VMSR instruction decoding -- See VMRS (B6.1.14)
+ * and VMSR (B6.1.15) in ARM DDI 0406B.
+ * @{
+ */
+#define ARM_INSTR_IS_VMRS(instr) ((MVP_EXTRACT_FIELD(instr, 0, 12) == 0xa10) && \
+ (ARM_INSTR_OPCODE(instr) == 0xef))
+
+#define ARM_INSTR_IS_VMSR(instr) ((MVP_EXTRACT_FIELD(instr, 0, 12) == 0xa10) && \
+ (ARM_INSTR_OPCODE(instr) == 0xee))
+
+#define ARM_INSTR_VMRS_SPECREG(instr) MVP_EXTRACT_FIELD(instr, 16, 4)
+#define ARM_INSTR_VMRS_RT(instr) MVP_EXTRACT_FIELD(instr, 12, 4)
+
+#define ARM_INSTR_VMSR_SPECREG(instr) MVP_EXTRACT_FIELD(instr, 16, 4)
+#define ARM_INSTR_VMSR_RT(instr) MVP_EXTRACT_FIELD(instr, 12, 4)
+/*@}*/
+
+/**
+ * @name ARM SWP{B} instruction checking.
+ * @{
+ */
+#define ARM_INSTR_IS_SWP(instr) ((instr & 0x0fb00ff0) == 0x01000090)
+/*@}*/
+
+#endif /// _INSTR_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/lowmemkiller_variant.sh b/arch/arm/mvp/mvpkm/lowmemkiller_variant.sh
new file mode 100644
index 0000000..2c9ab50
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/lowmemkiller_variant.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+#
+# Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+#
+# Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published by
+# the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; see the file COPYING. If not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# @brief Script providing the variant of the low memory killer implementation
+# to assist in mvpkm's export of the other_file calculation.
+
+if [ -z "$1" ]
+then
+ echo "Usage: $0 <path to lowmemorykiller.c>"
+ exit 1
+fi
+
+# We look at the relevant section of the lowmem_shrink function here. This
+# pattern is sufficient to distinguish between the known variants without
+# introducing too many false positives for new variants. I.e. we can spot the
+# lines that matter for the other_file calculation. In some cases the
+# lowmemorykiller uses only the other_file calculation instead of max(free,
+# file) - in the cases we've seen this is OK with the balloon policy, since the
+# free term isn't really significant when we get into low memory states anyway.
+
+tmp_file="lmk_md5sum_$RANDOM"
+
+cat $1 | tr -d '\ \t\n\r' > $tmp_file
+sed -i -e 's/.*\(intother_file.*other_file<\).*/;\1/' \
+ -e 's/[;][^;]*other_file[^;]*/#<#&#>#/g' \
+ -e 's/#>#[^#]*//g' $tmp_file
+
+MD5=`md5sum $tmp_file | cut -f1 -d\ `
+
+rm $tmp_file
+
+case $MD5 in
+4af66fafb5e4cbd7b4092e29e071f152|\
+a0f18472eb53e52b38d6f85d4ec66842|\
+590b89af56f57146edffceba60845ad8|\
+fddbb73a58e82ba1966fd862a561c2bd)
+ #/*
+ # * This is the same as the non-exported global_reclaimable_pages() when there
+ # * is no swap.
+ # */
+ #other_file = global_page_state(NR_ACTIVE_FILE) +
+ # global_page_state(NR_INACTIVE_FILE);
+ V=1
+;;
+943372c447dd868845d71781292eae17|\
+14d0cc4189c1f4fd7818c3393cc8c311)
+ # other_file = global_page_state(NR_FILE_PAGES);
+ V=2
+;;
+59f3bb678a855acfea2365b7a904bc5b|\
+df96cbb1784869ac7d017dd343e4e8f2)
+ # other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM);
+ V=3
+;;
+ed03b69361c2881ed1a031c9b9a24d8a|\
+8639aca416d3014d68548d6cb538405b)
+ # other_file = global_page_state(NR_FREE_PAGES) + global_page_state(NR_FILE_PAGES);
+ # (other_free not used, but max(other_free, other_file) = other_file in this
+ # case.
+ V=4
+;;
+*)
+ V=0
+;;
+esac
+
+echo "$MD5 $V"
diff --git a/arch/arm/mvp/mvpkm/lpae_defs.h b/arch/arm/mvp/mvpkm/lpae_defs.h
new file mode 100644
index 0000000..7729268
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/lpae_defs.h
@@ -0,0 +1,92 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Large physical address extension definitions.
+ *
+ * See ARM PRD03-GENC-008469 11.0.
+ */
+#ifndef _LPAE_DEFS_H_
+#define _LPAE_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define ARM_LPAE_PT_ORDER 12
+
+#define ARM_LPAE_PT_SIZE (1 << ARM_LPAE_PT_ORDER)
+#define ARM_LPAE_ENTRY_ORDER 3
+#define ARM_LPAE_PT_ENTRIES_ORDER (ARM_LPAE_PT_ORDER - ARM_LPAE_ENTRY_ORDER)
+#define ARM_LPAE_PT_ENTRIES (1 << ARM_LPAE_PT_ENTRIES_ORDER)
+
+#define ARM_LPAE_L1D_BLOCK_ORDER 30
+#define ARM_LPAE_L2D_BLOCK_ORDER 21
+#define ARM_LPAE_L3D_BLOCK_ORDER 12
+
+#define ARM_LPAE_L1D_BLOCK_BITS (40 - ARM_LPAE_L1D_BLOCK_ORDER)
+#define ARM_LPAE_L2D_BLOCK_BITS (40 - ARM_LPAE_L2D_BLOCK_ORDER)
+#define ARM_LPAE_L3D_BLOCK_BITS (40 - ARM_LPAE_L3D_BLOCK_ORDER)
+
+/*
+ * Currently supporting up to 16GB PA spaces.
+ */
+#define ARM_LPAE_L1PT_INDX(addr) \
+ MVP_EXTRACT_FIELD64(addr, ARM_LPAE_L1D_BLOCK_ORDER, 4)
+#define ARM_LPAE_L2PT_INDX(addr) \
+ MVP_EXTRACT_FIELD64(addr, ARM_LPAE_L2D_BLOCK_ORDER, ARM_LPAE_PT_ENTRIES_ORDER)
+#define ARM_LPAE_L3PT_INDX(addr) \
+ MVP_EXTRACT_FIELD64(addr, ARM_LPAE_L3D_BLOCK_ORDER, ARM_LPAE_PT_ENTRIES_ORDER)
+
+#define ARM_LPAE_L1D_BLOCK_BASE_ADDR(base) ((base) << ARM_LPAE_L1D_BLOCK_ORDER)
+#define ARM_LPAE_L1D_BLOCK_ADDR_BASE(addr) ((addr) >> ARM_LPAE_L1D_BLOCK_ORDER)
+#define ARM_LPAE_L2D_BLOCK_BASE_ADDR(base) ((base) << ARM_LPAE_L2D_BLOCK_ORDER)
+#define ARM_LPAE_L2D_BLOCK_ADDR_BASE(addr) ((addr) >> ARM_LPAE_L2D_BLOCK_ORDER)
+#define ARM_LPAE_L3D_BLOCK_BASE_ADDR(base) ((base) << ARM_LPAE_L3D_BLOCK_ORDER)
+#define ARM_LPAE_L3D_BLOCK_ADDR_BASE(addr) ((addr) >> ARM_LPAE_L3D_BLOCK_ORDER)
+
+#define ARM_LPAE_TABLE_BASE_ADDR(base) ((base) << ARM_LPAE_PT_ORDER)
+#define ARM_LPAE_TABLE_ADDR_BASE(addr) ((addr) >> ARM_LPAE_PT_ORDER)
+
+#define ARM_LPAE_TYPE_INVALID 0
+#define ARM_LPAE_TYPE_TABLE 3
+#define ARM_LPAE_L1D_TYPE_BLOCK 1
+#define ARM_LPAE_L2D_TYPE_BLOCK 1
+#define ARM_LPAE_L3D_TYPE_BLOCK 3
+
+/**
+ * @name Second stage permission model.
+ *
+ * @{
+ */
+#define ARM_LPAE_S2_PERM_NONE 0
+#define ARM_LPAE_S2_PERM_RO 1
+#define ARM_LPAE_S2_PERM_WO 2
+#define ARM_LPAE_S2_PERM_RW 3
+/*@}*/
+
+
+#endif /// ifndef _LPAE_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/lpae_types.h b/arch/arm/mvp/mvpkm/lpae_types.h
new file mode 100644
index 0000000..292f0d9
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/lpae_types.h
@@ -0,0 +1,124 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Large physical address extension types.
+ *
+ * See ARM PRD03-GENC-008469 11.0.
+ */
+#ifndef _LPAE_TYPES_H_
+#define _LPAE_TYPES_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "lpae_defs.h"
+
+/**
+ * @name ARM LPAE page table descriptors. See p7-8 ARM PRD03-GENC-008469 11.0.
+ * @{
+ */
+
+#define LOWER_PAGE_ATTRIBUTES_STAGE1 \
+ uint64 attrIndx : 3; \
+ uint64 ns : 1; \
+ uint64 ap : 2; \
+ uint64 sh : 2; \
+ uint64 af : 1; \
+ uint64 ng : 1;
+
+#define LOWER_PAGE_ATTRIBUTES_STAGE2 \
+ uint64 memAttr : 4; \
+ uint64 hap : 2; \
+ uint64 sh : 2; \
+ uint64 af : 1; \
+ uint64 sbzL : 1;
+
+#define UPPER_PAGE_ATTRIBUTES_STAGE1 \
+ uint64 contig : 1; \
+ uint64 pxn : 1; \
+ uint64 xn : 1; \
+ uint64 sw : 4; \
+ uint64 ignU : 5;
+
+#define UPPER_PAGE_ATTRIBUTES_STAGE2 \
+ uint64 contig : 1; \
+ uint64 sbzU : 1; \
+ uint64 xn : 1; \
+ uint64 sw : 4; \
+ uint64 ignU : 5;
+
+
+#define ARM_LPAE_DESC_TYPE(lvl,blen,sbzpad) \
+ typedef union { \
+ uint64 u; \
+ \
+ struct { \
+ uint64 type : 2;\
+ uint64 ign : 62; \
+ } x; \
+ \
+ struct { \
+ uint64 type : 2;\
+ LOWER_PAGE_ATTRIBUTES_STAGE1 \
+ sbzpad \
+ uint64 base : blen; \
+ uint64 sbz : 12; \
+ UPPER_PAGE_ATTRIBUTES_STAGE1 \
+ } blockS1; \
+ \
+ struct { \
+ uint64 type : 2;\
+ LOWER_PAGE_ATTRIBUTES_STAGE2 \
+ sbzpad \
+ uint64 base : blen; \
+ uint64 sbz : 12; \
+ UPPER_PAGE_ATTRIBUTES_STAGE2 \
+ } blockS2; \
+ \
+ struct { \
+ uint64 type : 2;\
+ uint64 ign0 : 10; \
+ uint64 base : 28; \
+ uint64 sbz : 12; \
+ uint64 ign1 : 7; \
+ uint64 pxn : 1; \
+ uint64 xn : 1; \
+ uint64 ap : 2; \
+ uint64 ns : 1; \
+ } table; \
+ \
+ } ARM_LPAE_L##lvl##D;
+
+
+ARM_LPAE_DESC_TYPE(1, ARM_LPAE_L1D_BLOCK_BITS, uint64 sbzP : 18;)
+ARM_LPAE_DESC_TYPE(2, ARM_LPAE_L2D_BLOCK_BITS, uint64 sbzP : 9;)
+ARM_LPAE_DESC_TYPE(3, ARM_LPAE_L3D_BLOCK_BITS, )
+
+/*@}*/
+
+#endif /// ifndef _LPAE_TYPES_H_
diff --git a/arch/arm/mvp/mvpkm/mksck.h b/arch/arm/mvp/mvpkm/mksck.h
new file mode 100644
index 0000000..aac00f7
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mksck.h
@@ -0,0 +1,153 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#ifndef _MKSCK_H
+#define _MKSCK_H
+
+/**
+ * @file
+ *
+ * @brief The monitor-kernel socket interface definitions.
+ *
+ * The monitor kernel socket interface was created for (what the name
+ * says) communications between the monitor and host processes. On the
+ * monitor side a special API is introduced, see mksck_vmm.h. On the
+ * host side the API is the standard Berkeley socket interface. Host
+ * process to host process or monitor to monitor communication is not
+ * supported.
+ *
+ * A generic address consists of two 16 bit fields: the vm id and the
+ * port id. Both hosts (vmx) and monitors (vmm) get their vm id
+ * automatically. The host vm id is assigned at the time the host
+ * process opens the mvpkm file descriptor, while the monitor vm id is
+ * assigned when the vmx.c:SetupWorldSwitchPage() calls
+ * Mvpkm_SetupIds(). As a vmx may create multiple monitors to service
+ * an MP guest, a vmx vm id may be associated with multiple monitor vm
+ * ids. A monitor id, however, has a single associated vmx host id,
+ * the id of its canonical vmx.
+ *
+ * Sockets on the host get their addresses either by explicit user
+ * call (the bind command) or implicitly by (issuing a send command
+ * first). At an explicit bind the user may omit one or both fields by
+ * providing MKSCK_VMID_UNDEF/MKSCK_PORT_UNDEF respectively. An
+ * implicit bind behaves as if both fields were omitted in an explicit
+ * bind. The default value of the vmid field is the vmid computed from
+ * the thread group id while that of a port is a new number. It is not
+ * invalid to bind a host process socket with a vm id different from
+ * the vmid computed from the tgid.
+ *
+ * Sockets of the monitor are automatically assigned a vmid, that of their
+ * monitor, at the time of their creation. The port id can be assigned by the
+ * user or left to the implementation to assign an unused one (by specifying
+ * MKSCK_PORT_UNDEF at @ref Mksck_Open).
+ *
+ * Host unconnected sockets may receive from any monitor sender, may send to any
+ * monitor socket. A socket can be connected to a peer address, that enables the
+ * use of the send command.
+ *
+ * One of many special predefined port (both host and monitor) is
+ * MKSCK_PORT_MASTER. It is used for initialization.
+ *
+ * Monitor sockets have to send their peer address explicitly (by
+ * Mksck_SetPeer()) or implicitly by receiving first. After the peer
+ * is set, monitor sockets may send or receive only to/from their
+ * peer.
+ */
+
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "vmid.h"
+
+/*
+ * The interface limits the size of transferable packets.
+ */
+#define MKSCK_XFER_MAX 1024
+
+#define MKSCK_ADDR_UNDEF (uint32)0xffffffff
+
+#define MKSCK_PORT_UNDEF (uint16)0xffff
+#define MKSCK_PORT_MASTER (MKSCK_PORT_UNDEF-1)
+#define MKSCK_PORT_HOST_FB (MKSCK_PORT_UNDEF-2)
+#define MKSCK_PORT_BALLOON (MKSCK_PORT_UNDEF-3)
+#define MKSCK_PORT_HOST_HID (MKSCK_PORT_UNDEF-4)
+#define MKSCK_PORT_CHECKPOINT (MKSCK_PORT_UNDEF-5)
+#define MKSCK_PORT_COMM_EV (MKSCK_PORT_UNDEF-6)
+#define MKSCK_PORT_HIGH (MKSCK_PORT_UNDEF-7)
+
+#define MKSCK_VMID_UNDEF VMID_UNDEF
+#define MKSCK_VMID_HIGH (MKSCK_VMID_UNDEF-1)
+
+#define MKSCK_DETACH 3
+
+typedef uint16 Mksck_Port;
+typedef VmId Mksck_VmId;
+
+/**
+ * @brief Page descriptor for typed messages. Each page describes a region of
+ * the machine address space with base mpn and size 2^(12 + order) bytes.
+ */
+typedef struct {
+ uint32 mpn : 20; ///< Base MPN of region described by page
+ uint32 order : 12; ///< Region is 2^(12 + order) bytes.
+} Mksck_PageDesc;
+
+/**
+ * @brief Typed message template macro. Allows us to avoid having two message
+ * types, one with page descriptor vector (for VMM), one without (for
+ * VMX).
+ *
+ * @param type C type of uninterpreted component of the message (following the
+ * page descriptor vector).
+ * @param pages number of page descriptors in vector.
+ */
+#define MKSCK_DESC_TYPE(type,pages) \
+ struct { \
+ type umsg; \
+ Mksck_PageDesc page[pages]; \
+ }
+
+/**
+ * @brief The monitor kernel socket interface address format
+ */
+typedef union {
+ uint32 addr; ///< the address
+ struct { /* The address is decomposed to two shorts */
+ Mksck_Port port; ///< port unique within a vmid
+ Mksck_VmId vmId; ///< unique vmid
+ };
+} Mksck_Address;
+
+static inline uint32
+Mksck_AddrInit(Mksck_VmId vmId, Mksck_Port port)
+{
+ Mksck_Address aa;
+ aa.vmId = vmId;
+ aa.port = port;
+ return aa.addr;
+}
+#endif
diff --git a/arch/arm/mvp/mvpkm/mksck_kernel.c b/arch/arm/mvp/mvpkm/mksck_kernel.c
new file mode 100644
index 0000000..6811a68
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mksck_kernel.c
@@ -0,0 +1,2589 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The monitor/kernel socket interface kernel extension.
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/fcntl.h>
+#include <linux/syscalls.h>
+#include <linux/kmod.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include <linux/rcupdate.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/vmalloc.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <net/sock.h>
+
+#include <asm/memory.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "mvp.h"
+#include "actions.h"
+#include "mvpkm_kernel.h"
+#include "mksck_kernel.h"
+#include "mksck_sockaddr.h"
+#include "mutex_kernel.h"
+
+void NORETURN FatalError(char const *file,
+ int line,
+ FECode feCode,
+ int bugno,
+ char const *fmt,
+ ...)
+{
+ /* Lock around printing the error details so that the messages from multiple
+ * threads are not interleaved. */
+ static DEFINE_MUTEX(fatalErrorMutex);
+ mutex_lock(&fatalErrorMutex);
+
+ FATALERROR_COMMON(printk, vprintk, file, line, feCode, bugno, fmt);
+
+ dump_stack();
+
+ /* done printing */
+ mutex_unlock(&fatalErrorMutex);
+
+ /* do_exit below exits the current thread but does not crash the kernel.
+ * Hence the stack dump will actually be readable from other user threads.
+ */
+ do_exit(1);
+}
+
+
+/*
+ * The project uses a new address family: AF_MKSCK. Optimally this address
+ * family were accepted with the Linux community and a permanent number
+ * were assigned. This, however, is a dream only, not even the x86 team
+ * has been able to pull it off.
+ *
+ * Instead we ASSUME that DECnet is dead and re-use it's address family number.
+ * This is what the x86 world is moving too in the latest versions.
+ */
+
+static struct proto mksckProto = {
+ .name = "AF_MKSCK",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof (struct sock),
+};
+
+static int MksckCreate(struct net *net,
+ struct socket *sock,
+ int protocol,
+ int kern);
+
+static struct net_proto_family mksckFamilyOps = {
+ .family = AF_MKSCK,
+ .owner = THIS_MODULE,
+ .create = MksckCreate,
+};
+
+static int MksckFault(struct vm_area_struct *vma, struct vm_fault *vmf);
+
+
+/**
+ * @brief Linux vma operations for receive windows established via Mksck
+ * mmap.
+ */
+static struct vm_operations_struct mksckVMOps = {
+ .fault = MksckFault
+};
+
+/*
+ * List of hosts and guests we know about.
+ */
+static spinlock_t mksckPageListLock;
+static MksckPage *mksckPages[MKSCK_MAX_SHARES];
+
+/*
+ * The following functions form the AF_MKSCK DGRAM operations.
+ */
+static int MksckRelease(struct socket *sock);
+static int MksckBacklogRcv(struct sock *sk, struct sk_buff *skb);
+static void MksckSkDestruct(struct sock *sk);
+static int MksckBind(struct socket *sock,
+ struct sockaddr *addr,
+ int addrLen);
+static int MksckBindGeneric(struct sock *sk,
+ Mksck_Address addr);
+static int MksckDgramRecvMsg(struct kiocb *kiocb,
+ struct socket *sock,
+ struct msghdr *msg,
+ size_t len,
+ int flags);
+static int MksckDgramSendMsg(struct kiocb *kiocb,
+ struct socket *sock,
+ struct msghdr *msg,
+ size_t len);
+static int MksckGetName(struct socket *sock,
+ struct sockaddr *addr,
+ int *addrLen,
+ int peer);
+static unsigned int MksckPoll(struct file *filp,
+ struct socket *sock,
+ poll_table *wait);
+static int MksckDgramConnect(struct socket *sock,
+ struct sockaddr *addr,
+ int addrLen,
+ int flags);
+static int MksckMMap(struct file *file,
+ struct socket *sock,
+ struct vm_area_struct *vma);
+
+static void MksckPageRelease(MksckPage *mksckPage);
+
+static struct proto_ops mksckDgramOps = {
+ .family = AF_MKSCK,
+ .owner = THIS_MODULE,
+ .release = MksckRelease,
+ .bind = MksckBind,
+ .connect = MksckDgramConnect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = MksckGetName,
+ .poll = MksckPoll,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown, /* MksckShutdown, */
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = MksckDgramSendMsg,
+ .recvmsg = MksckDgramRecvMsg,
+ .mmap = MksckMMap,
+ .sendpage = sock_no_sendpage,
+};
+
+
+/**
+ * @brief Initialize the MKSCK protocol
+ *
+ * @return 0 on success, -errno on failure
+ */
+int
+Mksck_Init(void)
+{
+ int err;
+
+ spin_lock_init(&mksckPageListLock);
+
+ /*
+ * Create a slab to allocate socket structs from.
+ */
+ err = proto_register(&mksckProto, 1);
+ if (err != 0) {
+ printk(KERN_INFO
+ "Mksck_Init: Cannot register MKSCK protocol, errno = %d.\n", err);
+ return err;
+ }
+
+ /*
+ * Register the socket family
+ */
+ err = sock_register(&mksckFamilyOps);
+ if (err < 0) {
+ printk(KERN_INFO
+ "Mksck_Init: Could not register address family AF_MKSCK"
+ " (errno = %d).\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+
+/**
+ * @brief De-register the MKSCK protocol
+ */
+void
+Mksck_Exit(void)
+{
+ sock_unregister(mksckFamilyOps.family);
+ proto_unregister(&mksckProto);
+}
+
+
+/**
+ * @brief Create a new MKSCK socket
+ *
+ * @param net network namespace (2.6.24 or above)
+ * @param sock user socket structure
+ * @param protocol protocol to be used
+ * @param kern called from kernel mode
+ *
+ * @return 0 on success, -errno on failure
+ */
+static int
+MksckCreate(struct net *net,
+ struct socket *sock,
+ int protocol,
+ int kern)
+{
+ struct sock *sk;
+ uid_t currentUid = current_euid();
+
+ if (!(currentUid == 0 ||
+ currentUid == Mvpkm_vmwareUid)) {
+ printk(KERN_WARNING
+ "MksckCreate: rejected from process %s tgid=%d, pid=%d euid:%d.\n",
+ current->comm,
+ task_tgid_vnr(current),
+ task_pid_vnr(current),
+ currentUid);
+ return -EPERM;
+ }
+
+ if (!sock) {
+ return -EINVAL;
+ }
+
+ if (protocol) {
+ return -EPROTONOSUPPORT;
+ }
+
+ switch (sock->type) {
+ case SOCK_DGRAM: {
+ sock->ops = &mksckDgramOps;
+ break;
+ }
+ default: {
+ return -ESOCKTNOSUPPORT;
+ }
+ }
+
+ sock->state = SS_UNCONNECTED;
+
+ /*
+ * Most recently (in 2.6.24), sk_alloc() was changed to expect the
+ * network namespace, and the option to zero the sock was dropped.
+ */
+ sk = sk_alloc(net, mksckFamilyOps.family, GFP_KERNEL, &mksckProto);
+
+ if (!sk) {
+ return -ENOMEM;
+ }
+
+ sock_init_data(sock, sk);
+
+ sk->sk_type = SOCK_DGRAM;
+ sk->sk_destruct = MksckSkDestruct;
+ sk->sk_backlog_rcv = MksckBacklogRcv;
+
+ /*
+ * On socket lock...
+ *
+ * A bound socket will have an associated private area, the Mksck
+ * structure part of MksckPage. That area is pointed to by
+ * sk->sk_protinfo. In addition, a connected socket will have the
+ * peer field in its associated area set to point to the associated
+ * private area of the peer socket. A mechanism is needed to ensure
+ * that these private areas area not freed while they are being
+ * accessed within the scope of a function. A simple lock would not
+ * suffice as the interface functions (like MksckDgramRecvMsg())
+ * may block. Hence a reference count mechanism is employed. When
+ * the mentioned references (sk->sk_protinfo and mksck->peer) to
+ * the respective private areas are set a refcount is incremented,
+ * and decremented when the references are deleted.
+ *
+ * The refcounts of areas pointed to by sk->sk_protinfo and
+ * mksck->peer will be decremented under the lock of the socket.
+ * Hence these private areas cannot disappear as long as the socket
+ * lock is held.
+ *
+ * The interface functions will have one of the following
+ * structures:
+ *
+ * simpleFn(sk)
+ * {
+ * lock_sock(sk);
+ * if ((mksck = sk->sk_protinfo)) {
+ * <non-blocking use of mksck>
+ * }
+ * release_sock(sk);
+ * }
+ *
+ * complexFn(sk)
+ * {
+ * lock_sock(sk);
+ * if ((mksck = sk->sk_protinfo)) {
+ * IncRefc(mksck);
+ * }
+ * release_sock(sk);
+ *
+ * if (mksck) {
+ * <use of mksck in a potentially blocking manner>
+ * DecRefc(mksck);
+ * }
+ * }
+ */
+ sk->sk_protinfo = NULL;
+ sock_reset_flag(sk, SOCK_DONE);
+
+ return 0;
+}
+
+
+/**
+ * @brief Delete a MKSCK socket
+ *
+ * @param sock user socket structure
+ *
+ * @return 0 on success, -errno on failure
+ */
+static int
+MksckRelease(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ if (sk) {
+ lock_sock(sk);
+ sock_orphan(sk);
+ release_sock(sk);
+ sock_put(sk);
+ }
+
+ sock->sk = NULL;
+ sock->state = SS_FREE;
+
+ return 0;
+}
+
+
+static int
+MksckBacklogRcv(struct sock *sk, struct sk_buff *skb)
+{
+ /*
+ * We should never get these as we never queue an skb.
+ */
+ printk("MksckBacklogRcv: should never get here\n");
+ return -EIO;
+}
+
+
+/**
+ * @brief Callback at socket destruction
+ *
+ * @param sk pointer to kernel socket structure
+ */
+static void
+MksckSkDestruct(struct sock *sk)
+{
+ Mksck *mksck;
+
+ lock_sock(sk);
+ mksck = sk->sk_protinfo;
+
+ if (mksck != NULL) {
+ sk->sk_protinfo = NULL;
+ Mksck_CloseCommon(mksck);
+ }
+
+ if (sk->sk_user_data != NULL) {
+ sock_kfree_s(sk, sk->sk_user_data, sizeof(int));
+ sk->sk_user_data = NULL;
+ }
+
+ release_sock(sk);
+}
+
+
+/**
+ * @brief Set the local address of a MKSCK socket
+ *
+ * @param sk kernel socket structure
+ * @param addr the new address of the socket
+ *
+ * @return 0 on success, -errno on failure
+ *
+ * If addr.port is undefined a new random port is assigned.
+ * If addr.vmId is undefined then the vmId computed from the tgid is used.
+ * Hence the vmId of a socket does not determine the host all the time.
+ *
+ * Assumed that the socket is locked.
+ * This function is called by explicit set (MksckBind) and implicit (Send).
+ */
+static int
+MksckBindGeneric(struct sock *sk,
+ Mksck_Address addr)
+{
+ int err;
+ Mksck *mksck;
+ MksckPage *mksckPage;
+
+ if (sk->sk_protinfo != NULL) {
+ return -EISCONN;
+ }
+
+ /*
+ * Locate the page for the given host and increment its reference
+ * count so it can't get freed off while we are working on it.
+ */
+ if (addr.vmId == MKSCK_VMID_UNDEF) {
+ mksckPage = MksckPage_GetFromTgidIncRefc();
+ } else {
+ printk(KERN_WARNING "MksckBind: host bind called on vmid 0x%X\n", addr.vmId);
+ mksckPage = MksckPage_GetFromVmIdIncRefc(addr.vmId);
+ }
+
+ if (mksckPage == NULL) {
+ printk(KERN_INFO "MksckBind: no mksckPage for vm 0x%X\n", addr.vmId);
+ return -ENETUNREACH;
+ }
+ addr.vmId = mksckPage->vmId;
+
+ /*
+ * Before we can find an unused socket port on the page we have to
+ * lock the page for exclusive access so another thread can't
+ * allocate the same port.
+ */
+ err = Mutex_Lock(&mksckPage->mutex, MutexModeEX);
+ if (err < 0) {
+ goto outDec;
+ }
+
+ addr.port = MksckPage_GetFreePort(mksckPage, addr.port);
+ if (addr.port == MKSCK_PORT_UNDEF) {
+ err = -EINVAL;
+ goto outUnlockDec;
+ }
+
+ /*
+ * At this point we have the mksckPage locked for exclusive access
+ * and its reference count incremented. Also, addr is completely
+ * filled in with vmId and port that we want to bind.
+ *
+ * Find an available mksck struct on the shared page and initialize
+ * it.
+ */
+ mksck = MksckPage_AllocSocket(mksckPage, addr);
+ if (mksck == NULL) {
+ err = -EMFILE;
+ goto outUnlockDec;
+ }
+
+ /*
+ * Stable, release mutex. Leave mksckPage->refCount incremented so
+ * mksckPage can't be freed until socket is closed.
+ */
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+
+ /*
+ * This is why we start mksck->refCount at 1. When sk_protinfo gets
+ * cleared, we decrement mksck->refCount.
+ */
+ sk->sk_protinfo = mksck;
+
+ PRINTK(KERN_DEBUG "MksckBind: socket bound to %08X\n", mksck->addr.addr);
+
+ return 0;
+
+outUnlockDec:
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+outDec:
+ MksckPage_DecRefc(mksckPage);
+ return err;
+}
+
+
+/**
+ * @brief Test if the socket is already bound to a local address and,
+ * if not, bind it to an unused address.
+ *
+ * @param sk kernel socket structure
+ * @return 0 on success, -errno on failure
+ *
+ * Assumed that the socket is locked.
+ */
+static inline int
+MksckTryBind(struct sock *sk)
+{
+ int err = 0;
+
+ if (!sk->sk_protinfo) {
+ static const Mksck_Address addr = { .addr = MKSCK_ADDR_UNDEF };
+ err = MksckBindGeneric(sk, addr);
+ }
+ return err;
+}
+
+
+
+/**
+ * @brief Set the address of a MKSCK socket (user call)
+ *
+ * @param sock user socket structure
+ * @param addr the new address of the socket
+ * @param addrLen length of the address
+ *
+ * @return 0 on success, -errno on failure
+ */
+static int
+MksckBind(struct socket *sock,
+ struct sockaddr *addr,
+ int addrLen)
+{
+ int err;
+ struct sock *sk = sock->sk;
+ struct sockaddr_mk *addrMk = (struct sockaddr_mk *)addr;
+
+ if (addrLen != sizeof *addrMk) {
+ return -EINVAL;
+ }
+ if (addrMk->mk_family != AF_MKSCK) {
+ return -EAFNOSUPPORT;
+ }
+
+ /*
+ * Obtain the socket lock and call the generic Bind function.
+ */
+ lock_sock(sk);
+ err = MksckBindGeneric(sk, addrMk->mk_addr);
+ release_sock(sk);
+
+ return err;
+}
+
+/**
+ * @brief Lock the peer socket by locating it, incrementing its refc
+ * @param addr the address of the peer socket
+ * @param[out] peerMksckR set to the locked peer socket pointer
+ * upon successful lookup
+ * @return 0 on success, -errno on failure
+ */
+static int
+LockPeer(Mksck_Address addr, Mksck **peerMksckR)
+{
+ int err = 0;
+ MksckPage *peerMksckPage = MksckPage_GetFromVmIdIncRefc(addr.vmId);
+ Mksck *peerMksck;
+
+ /*
+ * Find corresponding destination shared page and increment its
+ * reference count so it can't be freed while we are sending to the
+ * socket. Make sure that the address is indeed an address of a
+ * monitor/guest socket.
+ */
+ if (peerMksckPage == NULL) {
+ printk(KERN_INFO "LockPeer: vmId %x is not in use!\n", addr.vmId);
+ return -ENETUNREACH;
+ }
+ if (!peerMksckPage->isGuest) {
+ MksckPage_DecRefc(peerMksckPage);
+ printk(KERN_INFO "LockPeer: vmId %x does not belong to a guest!\n",
+ addr.vmId);
+ return -ENETUNREACH;
+ }
+
+
+ err = Mutex_Lock(&peerMksckPage->mutex, MutexModeSH);
+ if (err < 0) {
+ MksckPage_DecRefc(peerMksckPage);
+ return err;
+ }
+
+ /*
+ * Find corresponding destination socket on that shared page and
+ * increment its reference count so it can't be freed while we are
+ * trying to send to it.
+ */
+ peerMksck = MksckPage_GetFromAddr(peerMksckPage, addr);
+
+ if (peerMksck) {
+ ATOMIC_ADDV(peerMksck->refCount, 1);
+ *peerMksckR = peerMksck;
+ } else {
+ printk(KERN_INFO "LockPeer: addr %x is not a defined socket!\n",
+ addr.addr);
+ err = -ENETUNREACH;
+ }
+
+ Mutex_Unlock(&peerMksckPage->mutex, MutexModeSH);
+ MksckPage_DecRefc(peerMksckPage);
+ return err;
+}
+
+/**
+ * @brief Set the peer address of a MKSCK socket
+ *
+ * @param sock user socket structure
+ * @param addr the new address of the socket
+ * @param addrLen length of the address
+ * @param flags flags
+ *
+ * @return 0 on success, -errno on failure
+ */
+static int
+MksckDgramConnect(struct socket *sock,
+ struct sockaddr *addr,
+ int addrLen,
+ int flags)
+{
+ struct sock *sk = sock->sk;
+ Mksck *mksck;
+ struct sockaddr_mk *peerAddrMk = (struct sockaddr_mk *)addr;
+ int err = 0;
+
+ if (addrLen != sizeof *peerAddrMk) {
+ printk(KERN_INFO "MksckConnect: wrong address length!\n");
+ return -EINVAL;
+ }
+ if (peerAddrMk->mk_family != AF_MKSCK) {
+ printk(KERN_INFO "MksckConnect: wrong address family!\n");
+ return -EAFNOSUPPORT;
+ }
+
+ lock_sock(sk);
+
+ if ((err = MksckTryBind(sk))) {
+ goto releaseSock;
+ }
+ mksck = sk->sk_protinfo;
+
+ /*
+ * First severe any past peer connections
+ */
+ Mksck_DisconnectPeer(mksck);
+ sock->state = SS_UNCONNECTED;
+
+ /*
+ * Then build new connections ...
+ */
+ if (peerAddrMk->mk_addr.addr != MKSCK_ADDR_UNDEF) {
+ sock->state = SS_CONNECTED;
+ mksck->peerAddr = peerAddrMk->mk_addr;
+ err = LockPeer(mksck->peerAddr, &mksck->peer);
+ PRINTK(KERN_DEBUG "MksckConnect: socket %x is connected to %x!\n",
+ mksck->addr.addr, mksck->peerAddr.addr);
+ }
+
+releaseSock:
+ release_sock(sk);
+
+ return err;
+}
+
+
+/**
+ * @brief returns the address of a MKSCK socket/peer address
+ *
+ * @param sock user socket structure
+ * @param addr the new address of the socket
+ * @param addrLen length of the address
+ * @param peer 1 if the peer address is sought
+ *
+ * @return 0 on success, -errno on failure
+ */
+static int
+MksckGetName(struct socket *sock,
+ struct sockaddr *addr,
+ int *addrLen,
+ int peer)
+{
+ int err;
+ Mksck *mksck;
+ struct sock *sk = sock->sk;
+
+ // MAX_SOCK_ADDR is size of *addr, Linux doesn't export it!
+ // ASSERT_ON_COMPILE(sizeof (struct sockaddr_mk) <= MAX_SOCK_ADDR);
+
+ lock_sock(sk);
+ mksck = sk->sk_protinfo;
+
+ if (mksck == NULL) {
+ if (peer) {
+ err = -ENOTCONN;
+ } else {
+ ((struct sockaddr_mk *)addr)->mk_family = AF_MKSCK;
+ ((struct sockaddr_mk *)addr)->mk_addr.addr = MKSCK_ADDR_UNDEF;
+ *addrLen = sizeof (struct sockaddr_mk);
+ err = 0;
+ }
+ } else if (!peer) {
+ ((struct sockaddr_mk *)addr)->mk_family = AF_MKSCK;
+ ((struct sockaddr_mk *)addr)->mk_addr = mksck->addr;
+ *addrLen = sizeof (struct sockaddr_mk);
+ err = 0;
+ } else if (mksck->peerAddr.addr == MKSCK_ADDR_UNDEF) {
+ err = -ENOTCONN;
+ } else {
+ ((struct sockaddr_mk *)addr)->mk_family = AF_MKSCK;
+ ((struct sockaddr_mk *)addr)->mk_addr = mksck->peerAddr;
+ *addrLen = sizeof (struct sockaddr_mk);
+ err = 0;
+ }
+
+ release_sock(sk);
+
+ return err;
+}
+
+
+/**
+ * @brief VMX polling a receipted packet from VMM.
+ *
+ * @param filp kernel file pointer to poll for
+ * @param sock user socket structure
+ * @param wait kernel polling table where to poll if not null
+ *
+ * @return poll mask state given from socket state.
+ */
+static unsigned int MksckPoll(struct file *filp,
+ struct socket *sock,
+ poll_table *wait)
+{
+ struct sock *sk = sock->sk;
+ unsigned int mask = 0;
+ Mksck *mksck = NULL;
+ uint32 read;
+ int err;
+
+ lock_sock(sk);
+ if ((err = MksckTryBind(sk))) {
+ release_sock(sk);
+ return err;
+ }
+ mksck = sk->sk_protinfo;
+
+ /*
+ * To avoid mksck disappearing right after the release_sock the
+ * refcount needs to be incremented. For more details read the
+ * block comment on locking in MksckCreate.
+ */
+ ATOMIC_ADDV(mksck->refCount, 1);
+ release_sock(sk);
+
+ /*
+ * Wait to make sure this is the only thread trying to access socket.
+ */
+ if ((err = Mutex_Lock(&mksck->mutex, MutexModeEX)) < 0) {
+ /* we might get in this situation if we are signaled
+ (select() may handle this, so leave) */
+ PRINTK(KERN_INFO "MksckPoll: try to abort\n");
+ return mask;
+ }
+
+ /*
+ * See if packet in ring.
+ */
+ read = mksck->read;
+ if (read != mksck->write) {
+ mask |= POLLIN | POLLRDNORM; /* readable, socket is unlocked */
+ /* Note that if we are implementing support for POLLOUT, we SHOULD
+ change this Mutex_Unlock by Mutex_UnlPoll, because there is no
+ obvious knowledge about the sleepy reason that is intended by user */
+ Mutex_Unlock(&mksck->mutex, MutexModeEX);
+ } else {
+ Mutex_UnlPoll(&mksck->mutex, MutexModeEX, MKSCK_CVAR_FILL, filp, wait);
+ }
+
+ /*
+ * Note that locking rules differ a little inside MksckPoll, since we are
+ * not only given a pointer to the struct socket but also a pointer to a
+ * struct file. This means that during the whole operation of this function
+ * and during any pending wait (registered with poll_wait()), the file itself
+ * is reference counted up, and we should rely on that 'upper' reference
+ * counting to prevent from tearing the Mksck down. That holds true since one
+ * never re-bind sockets !
+ */
+ Mksck_DecRefc(mksck);
+ return mask;
+}
+
+/**
+ * @brief Manage a set of Mksck_PageDesc from a message or a stored array.
+ *
+ * @param pd set of Mksck_PageDesc
+ * @param pages Mksck_PageDesc pages count for this management operation
+ * @param incr ternary used to indicate if we want to reference (+1), or
+ * dereference (-1), or count (0) 4k pages
+ *
+ * @return length of bytes processed.
+ */
+static size_t
+MksckPageDescManage(Mksck_PageDesc *pd,
+ uint32 pages,
+ int incr)
+{
+ size_t payloadLen = 0;
+ uint32 i;
+
+ for (i = 0; i < pages && pd[i].mpn != INVALID_MPN; ++i) {
+ uint32 j;
+
+ for (j = 0; j < 1 << pd[i].order; ++j) {
+ struct page *page;
+ MPN currMPN = pd[i].mpn + j;
+
+ /*
+ * The monitor tried to send an invalid MPN, bad.
+ */
+ if (!pfn_valid(currMPN)) {
+ printk("MksckPageDescManage: Invalid MPN %x\n", currMPN);
+ } else {
+ page = pfn_to_page(currMPN);
+
+ if (incr == +1) {
+ get_page(page);
+ }
+ if (incr == -1) {
+ put_page(page);
+ }
+ }
+
+ payloadLen += PAGE_SIZE;
+ }
+ }
+
+ return payloadLen;
+}
+
+/**
+ * @brief Management values to be used as third parameter of MksckPageDescManage
+ */
+#define MANAGE_INCREMENT +1
+#define MANAGE_DECREMENT -1
+#define MANAGE_COUNT 0
+
+
+/**
+ * @brief Map a set of Mksck_PageDesc from a message or a stored array.
+ *
+ * @param pd set of Mksck_PageDesc
+ * @param pages pages count for this mapping
+ * @param iov vectored user virtual addresses of the recv commands
+ * @param iovCount size for iov parameter
+ * @param vma virtual memory area used for the mapping, note that
+ * this is mandatorily required MksckPageDescMap is used
+ * on an indirect PageDesc context (i.e whenever iov is
+ * not computed by the kernel but by ourselves).
+ *
+ * Since find_vma() and vm_insert_page() are used, this function must
+ * be called with current's mmap_sem locked, or inside an MMap operation.
+ *
+ * @return length of bytes mapped.
+ */
+static size_t
+MksckPageDescMap(Mksck_PageDesc *pd,
+ uint32 pages,
+ struct iovec *iov,
+ int iovCount,
+ struct vm_area_struct *vma)
+{
+ size_t payloadLen = 0;
+ uint32 i;
+
+ for (i = 0; i < pages && pd[i].mpn != INVALID_MPN; ++i) {
+ uint32 j;
+
+ for (j = 0; j < 1 << pd[i].order; ++j) {
+ HUVA huva = 0;
+ struct page *page;
+ MPN currMPN = pd[i].mpn + j;
+
+ while (iovCount > 0 && iov->iov_len == 0) {
+ iovCount--;
+ iov++;
+ }
+
+ if (iovCount == 0) {
+ printk("MksckPageDescMap: Invalid iov length\n");
+ goto map_done;
+ }
+
+ huva = (HUVA)iov->iov_base;
+
+ /*
+ * iovecs for receiving the typed component of the message should
+ * have page aligned base and size sufficient for page descriptor's
+ * mappings.
+ */
+ if (huva & (PAGE_SIZE - 1) || iov->iov_len < PAGE_SIZE) {
+ printk("MksckPageDescMap: Invalid huva %x or iov_len %d\n",
+ huva,
+ iov->iov_len);
+ goto map_done;
+ }
+
+ /*
+ * Might be in a new vma...
+ */
+ if (vma == NULL || huva < vma->vm_start || huva >= vma->vm_end) {
+ vma = find_vma(current->mm, huva);
+
+ /*
+ * Couldn't find a matching vma for huva.
+ */
+ if (vma == NULL ||
+ huva < vma->vm_start ||
+ vma->vm_ops != &mksckVMOps) {
+ printk("MksckPageDescMap: Invalid vma\n");
+ goto map_done;
+ }
+ }
+
+ /*
+ * The monitor tried to send an invalid MPN, bad.
+ */
+ if (!pfn_valid(currMPN)) {
+ printk("MksckPageDescMap: Invalid MPN %x\n", currMPN);
+ } else {
+ int rc;
+
+ page = pfn_to_page(currMPN);
+
+ /*
+ * Map into the receive window.
+ */
+ rc = vm_insert_page(vma, huva, page);
+ if (rc) {
+ printk("MksckPageDescMap: Failed to insert %x at %x, error %d\n",
+ currMPN,
+ huva,
+ rc);
+ goto map_done;
+ }
+
+ ASSERT(iov->iov_len >= PAGE_SIZE);
+ iov->iov_base += PAGE_SIZE;
+ iov->iov_len -= PAGE_SIZE;
+ }
+
+ payloadLen += PAGE_SIZE;
+ }
+ }
+
+map_done:
+ return payloadLen;
+}
+
+
+/**
+ * @brief Check if the provided MsgHdr has still room for a receive operation.
+ *
+ * @param msg user buffer
+ * @return 1 if MsgHdr has IO space room in order to receive a mapping, 0 otherwise.
+ */
+static int
+MsgHdrHasAvailableRoom(struct msghdr *msg)
+{
+ struct iovec *vec = msg->msg_iov;
+ uint32 count = msg->msg_iovlen;
+
+ while (count > 0 && vec->iov_len == 0) {
+ count--;
+ vec++;
+ }
+
+ return (count != 0);
+}
+
+
+/**
+ * Whenever a typed message is received from the monitor, we may choose to store
+ * all the page descriptor content in a linked state of descriptors, through the
+ * following information context
+ */
+typedef struct MksckPageDescInfo {
+ struct MksckPageDescInfo *next;
+ uint32 flags;
+ uint32 pages;
+ uint32 mapCounts;
+ Mksck_PageDesc descs[0];
+} MksckPageDescInfo;
+
+static void MksckPageDescSkDestruct(struct sock *sk);
+static int MksckPageDescMMap(struct file *file,
+ struct socket *sock,
+ struct vm_area_struct *vma);
+static int MksckPageDescIoctl(struct socket *sock,
+ unsigned int cmd,
+ unsigned long arg);
+
+/**
+ * @brief Delete a page descriptor container socket
+ *
+ * @param sock user socket structure
+ * @return 0 on success, -errno on failure
+ */
+static int
+MksckPageDescRelease(struct socket *sock)
+{
+ /* This is generic socket release */
+ struct sock *sk = sock->sk;
+
+ if (sk) {
+ lock_sock(sk);
+ sock_orphan(sk);
+ release_sock(sk);
+ sock_put(sk);
+ }
+
+ sock->sk = NULL;
+ sock->state = SS_FREE;
+
+ return 0;
+}
+
+
+/**
+ * Whenever a typed message is received from the monitor, we may choose to store
+ * all the page descriptor content for a future mapping. One shall put a context
+ * usable by host userland, that means trough a file descriptor, and as a secure
+ * implementation we choose to define a strict set of operations that are used
+ * only for that purpose. This set of operation is reduced to leaving the
+ * default "PageDesc(s) accumulating" mode (inside ioctl), mapping the context,
+ * and generic socket destruction.
+ */
+static struct proto_ops mksckPageDescOps = {
+ .family = AF_MKSCK,
+ .owner = THIS_MODULE,
+ .release = MksckPageDescRelease,
+ .bind = sock_no_bind,
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = sock_no_getname,
+ .poll = sock_no_poll,
+ .ioctl = MksckPageDescIoctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = sock_no_sendmsg,
+ .recvmsg = sock_no_recvmsg,
+ .mmap = MksckPageDescMMap,
+ .sendpage = sock_no_sendpage,
+};
+
+
+/**
+ * @brief Create or accumulate to a PageDesc context, backed as a descriptor.
+ *
+ * @param sock user socket structure
+ * @param msg user buffer to receive the file descriptor as ancillary data
+ * @param pd source descriptor part of a message
+ * @param pages pages count for this mapping
+ *
+ * @return error if negative, 0 otherwise
+ *
+ */
+static int
+MksckPageDescToFd(struct socket *sock,
+ struct msghdr *msg,
+ Mksck_PageDesc *pd,
+ uint32 pages)
+{
+ int retval;
+ int newfd;
+ struct socket *newsock;
+ struct sock *newsk;
+ struct sock *sk = sock->sk;
+ MksckPageDescInfo **pmpdi, *mpdi;
+ lock_sock(sk);
+
+ /*
+ * Relation between any mk socket and the PageDesc context is as follow:
+ *
+ * From the mk socket to the PageDesc context:
+ * - sk->sk_user_data is a WEAK LINK, containing only a file descriptor
+ * numerical value such that accumulating is keyed on it.
+ *
+ * From the PageDesc context to the mk socket:
+ * - sk->sk_protinfo contains a MksckPageDescInfo struct.
+ * - sk->sk_user_data is a pointer REF-COUNTED sock_hold() LINK, also it is
+ * rarely dereferenced but usually used to check that the
+ * right socket pair is used. Full dereferencing is used
+ * only to break the described links.
+ */
+ if (sk->sk_user_data) {
+ MksckPageDescInfo *mpdi2;
+
+ /* continue any previous on-going mapping, i.e accumulate */
+ newfd = *((int *)sk->sk_user_data);
+ newsock = sockfd_lookup(newfd, &retval); // promote the weak link
+ if (!newsock) {
+ retval = -EINVAL;
+ goto endProcessingReleaseSock;
+ }
+
+ newsk = newsock->sk;
+ lock_sock(newsk);
+ sockfd_put(newsock);
+
+ if (((struct sock *)newsk->sk_user_data) != sk) {
+ /* One way of going into this situation would be for userland to dup
+ the file descriptor just received, close the original number, and
+ open a new mk socket in the very same spot. The userland code have
+ a lot of way of interacting with the kernel without this driver
+ code to be notified. */
+ retval = -EINVAL;
+ release_sock(newsk);
+ goto endProcessingReleaseSock;
+ }
+
+ mpdi = sock_kmalloc(newsk, sizeof(MksckPageDescInfo) +
+ pages*sizeof(Mksck_PageDesc), GFP_KERNEL);
+ if (IS_ERR(mpdi)) {
+ retval = PTR_ERR(mpdi);
+ release_sock(newsk);
+ goto endProcessingReleaseSock;
+ }
+
+ /* There is no mandatory needs for us to notify userland from
+ the progress in "appending" to the file descriptor, but it
+ would feel strange if the userland would have no mean to
+ tell if the received message was just not thrown away. So, in
+ order to be consistent one fill the ancillary message while
+ "creating" and "appending to" file descriptors. */
+ retval = put_cmsg(msg, SOL_DECNET, 0, sizeof(int), &newfd);
+ if (retval < 0) {
+ goto endProcessingKFreeReleaseSock;
+ }
+
+ release_sock(sk);
+
+ mpdi2 = (MksckPageDescInfo *)newsk->sk_protinfo;
+ while (mpdi2->next) {
+ mpdi2 = mpdi2->next;
+ }
+ pmpdi = &(mpdi2->next);
+
+ } else {
+ /* Create a new socket, new context and a new file descriptor. */
+ retval = sock_create(sk->sk_family, sock->type, 0, &newsock);
+ if (retval < 0) {
+ goto endProcessingReleaseSock;
+ }
+
+ newsk = newsock->sk;
+ lock_sock(newsk);
+ newsk->sk_destruct = &MksckPageDescSkDestruct;
+ newsk->sk_user_data = sk;
+ sock_hold(sk); // keeps a reference to parent mk socket
+ newsock->ops = &mksckPageDescOps;
+
+ mpdi = sock_kmalloc(newsk, sizeof(MksckPageDescInfo) +
+ pages*sizeof(Mksck_PageDesc), GFP_KERNEL);
+ if (IS_ERR(mpdi)) {
+ retval = PTR_ERR(mpdi);
+ goto endProcessingFreeNewSock;
+ }
+
+ sk->sk_user_data = sock_kmalloc(sk, sizeof(int), GFP_KERNEL);
+ if (IS_ERR(sk->sk_user_data)) {
+ retval = PTR_ERR(sk->sk_user_data);
+ sk->sk_user_data = NULL;
+ goto endProcessingKFreeAndNewSock;
+ }
+
+ /* mapping to a file descriptor may fail if a thread is closing
+ in parallel of sock_map_fd/sock_alloc_fd, or kernel memory is full */
+ newfd = sock_map_fd(newsock, O_CLOEXEC);
+ if (newfd < 0) {
+ retval = newfd;
+ sock_kfree_s(sk, sk->sk_user_data, sizeof(int));
+ sk->sk_user_data = NULL;
+ goto endProcessingKFreeAndNewSock;
+ }
+
+ /* notify userland from a new file descriptor, alike AF_UNIX ancillary */
+ retval = put_cmsg(msg, SOL_DECNET, 0, sizeof(int), &newfd);
+ if (retval < 0) {
+ sock_kfree_s(sk, sk->sk_user_data, sizeof(int));
+ sk->sk_user_data = NULL;
+ sock_kfree_s(newsk, mpdi, sizeof(MksckPageDescInfo) +
+ mpdi->pages*sizeof(Mksck_PageDesc));
+ release_sock(newsk);
+ sockfd_put(newsock);
+ sock_release(newsock);
+ put_unused_fd(newfd);
+ goto endProcessingReleaseSock;
+ }
+
+ *(int*)sk->sk_user_data = newfd;
+ release_sock(sk);
+ pmpdi = (MksckPageDescInfo **)(&(newsk->sk_protinfo));
+ }
+
+ mpdi->next = NULL;
+ mpdi->flags = 0;
+ mpdi->mapCounts = 0;
+ mpdi->pages = pages;
+ memcpy(mpdi->descs, pd, pages*sizeof(Mksck_PageDesc));
+
+ *pmpdi = mpdi; // link
+ release_sock(newsk);
+
+ /* increment all reference counters for the pages */
+ MksckPageDescManage(pd, pages, MANAGE_INCREMENT);
+ return 0;
+
+endProcessingKFreeAndNewSock:
+ sock_kfree_s(newsk, mpdi, sizeof(MksckPageDescInfo) +
+ mpdi->pages*sizeof(Mksck_PageDesc));
+endProcessingFreeNewSock:
+ release_sock(newsk);
+ sock_release(newsock);
+ release_sock(sk);
+ return retval;
+
+endProcessingKFreeReleaseSock:
+ sock_kfree_s(newsk, mpdi, sizeof(MksckPageDescInfo) +
+ mpdi->pages*sizeof(Mksck_PageDesc));
+ release_sock(newsk);
+endProcessingReleaseSock:
+ release_sock(sk);
+ return retval;
+}
+
+/**
+ * @brief Callback at socket destruction
+ *
+ * @param sk pointer to kernel socket structure
+ */
+static void
+MksckPageDescSkDestruct(struct sock *sk)
+{
+ struct sock *mkSk = NULL;
+ MksckPageDescInfo *mpdi;
+ lock_sock(sk);
+ mpdi = sk->sk_protinfo;
+ while (mpdi) {
+ MksckPageDescInfo *next = mpdi->next;
+ MksckPageDescManage(mpdi->descs, mpdi->pages,
+ MANAGE_DECREMENT);
+ sock_kfree_s(sk, mpdi, sizeof(MksckPageDescInfo) +
+ mpdi->pages*sizeof(Mksck_PageDesc));
+ mpdi = next;
+ }
+ if (sk->sk_user_data) {
+ mkSk = (struct sock *)sk->sk_user_data;
+ sk->sk_user_data = NULL;
+ }
+ sk->sk_protinfo = NULL;
+ release_sock(sk);
+ /* clean the monki socket that we are holding */
+ if (mkSk) {
+ lock_sock(mkSk);
+ sock_kfree_s(mkSk, mkSk->sk_user_data, sizeof(int));
+ mkSk->sk_user_data = NULL;
+ release_sock(mkSk);
+ sock_put(mkSk); // revert of sock_hold()
+ }
+}
+
+/**
+ * @brief The mmap operation of the PageDesc context file descriptor.
+ *
+ * The mmap command is used to mmap any detached (i.e. no more accumulating)
+ * PageDesc context, full of the content from its parent communication mk
+ * socket. Mapping may be done a specified number of times, so that the
+ * PageDesc context could become useless (as a security restriction).
+ *
+ * Also note that mapping from an offset different from zero is considered
+ * as a userland invalid operation.
+ *
+ * @param file user file structure
+ * @param sock user socket structure
+ * @param vma virtual memory area structure
+ *
+ * @return error code, 0 on success
+ */
+static int
+MksckPageDescMMap(struct file *file,
+ struct socket *sock,
+ struct vm_area_struct *vma)
+{
+ struct sock *sk = sock->sk;
+ MksckPageDescInfo *mpdi;
+ struct iovec iov;
+ unsigned long vm_flags;
+ int freed = 0;
+
+ iov.iov_base = (void*)vma->vm_start;
+ iov.iov_len = vma->vm_end - vma->vm_start;
+
+ lock_sock(sk);
+ mpdi = sk->sk_protinfo;
+
+ // vma->vm_pgoff is checked, since offsetting the map is not supported
+ if (!mpdi || sk->sk_user_data || vma->vm_pgoff) {
+ release_sock(sk);
+ printk(KERN_INFO "MMAP failed for virt %lx size %lx\n",
+ vma->vm_start, vma->vm_end - vma->vm_start);
+ return -EINVAL;
+ }
+
+ vm_flags = mpdi->flags;
+ if ((vma->vm_flags & ~vm_flags) & (VM_READ|VM_WRITE)) {
+ release_sock(sk);
+ return -EACCES;
+ }
+
+ while (mpdi) {
+ MksckPageDescInfo *next = mpdi->next;
+ MksckPageDescMap(mpdi->descs, mpdi->pages, &iov, 1, vma);
+ if (mpdi->mapCounts && !--mpdi->mapCounts) {
+ MksckPageDescManage(mpdi->descs, mpdi->pages,
+ MANAGE_DECREMENT);
+ sock_kfree_s(sk, mpdi, sizeof(MksckPageDescInfo) +
+ mpdi->pages*sizeof(Mksck_PageDesc));
+ freed = 1;
+ }
+ mpdi = next;
+ }
+
+ if (freed) {
+ sk->sk_protinfo = NULL;
+ }
+ vma->vm_ops = &mksckVMOps;
+ release_sock(sk);
+ return 0;
+}
+
+/**
+ * @brief The ioctl operation of the PageDesc context file descriptor.
+ *
+ * The ioctl MKSCK_DETACH command is used to detach the PageDesc context
+ * from its parent communication mk socket. Once done, the context
+ * is able to remap the transferred PageDesc(s) of typed messages accumulated
+ * into the context.
+ *
+ * @param sock user socket structure
+ * @param cmd select which cmd function needs to be performed
+ * @param arg argument for command
+ *
+ * @return error code, 0 on success
+ */
+static int
+MksckPageDescIoctl(struct socket *sock,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ struct sock *monkiSk = NULL;
+ struct sock *sk = sock->sk;
+ MksckPageDescInfo *mpdi;
+ int retval = 0;
+
+ switch (cmd) {
+ /**
+ * ioctl MKSCK_DETACH (in and out):
+ * Detach, compute size and define allowed protection access rights
+ *
+ * [in]: unsigned long flags, similar to prot argument of mmap()
+ * unsigned long number of available further mappings
+ * with 0 meaning unlimited number of mappings
+ * [out]: unsigned long size of the available mappable area
+ */
+ case MKSCK_DETACH: {
+ unsigned long ul[2];
+ lock_sock(sk);
+ mpdi = sk->sk_protinfo;
+ // read unsigned long argument that contains the mmap alike flags
+ if (copy_from_user(ul, (void *)arg, sizeof ul)) {
+ retval = -EFAULT;
+ // check that the file descriptor has a parent and some context there
+ } else if (!mpdi || !sk->sk_user_data) {
+ retval = -EINVAL;
+ } else {
+ /* compute mapping protection bits from argument and size of the
+ * mapping, that is also given back to userland as unsigned long.
+ */
+ uint32 flags = calc_vm_prot_bits(ul[0]);
+ ul[0] = 0;
+ while (mpdi) {
+ MksckPageDescInfo *next = mpdi->next;
+ ul[0] += MksckPageDescManage(mpdi->descs, mpdi->pages,
+ MANAGE_COUNT);
+ mpdi->mapCounts = ul[1];
+ mpdi = next;
+ }
+ if (copy_to_user((void *)arg, ul, sizeof(ul[0]))) {
+ retval = -EFAULT;
+ } else {
+ mpdi = sk->sk_protinfo;
+ mpdi->flags = flags;
+ monkiSk = (struct sock *)sk->sk_user_data;
+ sk->sk_user_data = NULL;
+ }
+ }
+ release_sock(sk);
+ // clean the monki socket that we are holding
+ if ((sk = monkiSk)) {
+ lock_sock(sk);
+ sock_kfree_s(sk, sk->sk_user_data, sizeof(int));
+ sk->sk_user_data = NULL;
+ release_sock(sk);
+ sock_put(sk);
+ }
+ break;
+ }
+ default: {
+ retval = -EINVAL;
+ break;
+ }
+ }
+ return retval;
+}
+
+
+/**
+ * @brief VMX receiving a packet from VMM.
+ *
+ * @param kiocb kernel io control block (unused)
+ * @param sock user socket structure
+ * @param msg user buffer to receive the packet
+ * @param len size of the user buffer
+ * @param flags flags
+ *
+ * @return -errno on failure, else length of untyped portion + total number
+ * of bytes mapped for typed portion.
+ */
+static int
+MksckDgramRecvMsg(struct kiocb *kiocb,
+ struct socket *sock,
+ struct msghdr *msg,
+ size_t len,
+ int flags)
+{
+ int err = 0;
+ struct sock *sk = sock->sk;
+ Mksck *mksck;
+ Mksck_Datagram *dg;
+ struct sockaddr_mk *fromAddr;
+ uint32 read;
+ struct iovec *iov;
+ size_t payloadLen, untypedLen;
+ uint32 iovCount;
+
+ if (flags & MSG_OOB || flags & MSG_ERRQUEUE) {
+ return -EOPNOTSUPP;
+ }
+
+ if ((msg->msg_name != NULL) && (msg->msg_namelen < sizeof *fromAddr)) {
+ return -EINVAL;
+ }
+
+ lock_sock(sk);
+ if ((err = MksckTryBind(sk))) {
+ release_sock(sk);
+ return err;
+ }
+ mksck = sk->sk_protinfo;
+
+ /*
+ * To avoid mksck disappearing right after the release_sock the
+ * refcount needs to be incremented. For more details read the
+ * block comment on locking in MksckCreate.
+ */
+ ATOMIC_ADDV(mksck->refCount, 1);
+ release_sock(sk);
+
+ /*
+ * Get pointer to next packet in ring to be dequeued.
+ */
+ while (1) {
+
+ /*
+ * Wait to make sure this is the only thread trying to access socket.
+ */
+ if ((err = Mutex_Lock(&mksck->mutex, MutexModeEX)) < 0) {
+ goto decRefc;
+ }
+
+ /*
+ * See if packet in ring.
+ */
+ read = mksck->read;
+ if (read != mksck->write) {
+ break;
+ }
+
+ /*
+ * Nothing there, if user wants us not to block then just return EAGAIN.
+ */
+ if (flags & MSG_DONTWAIT) {
+ Mutex_Unlock(&mksck->mutex, MutexModeEX);
+ err = -EAGAIN;
+ goto decRefc;
+ }
+
+ /*
+ * Nothing there, unlock socket and wait for data.
+ */
+ mksck->foundEmpty ++;
+ err = Mutex_UnlSleep(&mksck->mutex, MutexModeEX, MKSCK_CVAR_FILL);
+ if (err < 0) {
+ PRINTK(KERN_INFO "MksckDgramRecvMsg: aborted\n");
+ goto decRefc;
+ }
+ }
+
+ /*
+ * Point to packet in ring.
+ */
+ dg = (void *)&mksck->buff[read];
+
+ /*
+ * Provide the address of the sender.
+ */
+ if (msg->msg_name != NULL) {
+ fromAddr = (void *)msg->msg_name;
+ fromAddr->mk_addr = dg->fromAddr;
+ fromAddr->mk_family = AF_MKSCK;
+ msg->msg_namelen = sizeof *fromAddr;
+ } else {
+ msg->msg_namelen = 0;
+ }
+
+ /*
+ * Copy data from ring buffer to caller's buffer and remove packet from
+ * ring buffer.
+ */
+ iov = msg->msg_iov;
+ iovCount = msg->msg_iovlen;
+ payloadLen = untypedLen =
+ dg->len - dg->pages * sizeof(Mksck_PageDesc) - dg->pad;
+
+ /*
+ * Handle the untyped portion of the message.
+ */
+ if (untypedLen <= len) {
+ err = memcpy_toiovec(iov,
+ dg->data,
+ untypedLen);
+ if (err < 0) {
+ printk("MksckDgramRecvMsg: Failed to memcpy_to_iovec untyped message component "
+ "(buf len %d datagram len %d (untyped %d))\n",
+ len,
+ dg->len,
+ untypedLen);
+ }
+ } else {
+ err = -EINVAL;
+ }
+
+ /*
+ * Map in the typed descriptor.
+ */
+ if (err >= 0 && dg->pages > 0) {
+ Mksck_PageDesc *pd = (Mksck_PageDesc *)(dg->data + untypedLen + dg->pad);
+
+ /*
+ * There are 3 ways of receiving typed messages from the monitor.
+ * - The typed message is mapped directly into a VMA. To indicate this the
+ * userland sets msg_controllen == 0.
+ * - The typed message is mapped directly into a VMA and a file descriptor
+ * created for further mappings on the host (in same userland address
+ * space or an alternate userland address space). In this case
+ * msg_controllen should be set to sizeof(fd).
+ * - The typed message is not mapped directly into a VMA, but a file
+ * descriptor is created for later mapping on the host. In this case
+ * msg_controllen should be set to sizeof(fd) and the supplied iovec
+ * shall not specify a receive window.
+ *
+ * The conjuncts below decide on which of these 3 cases we've encountered.
+ */
+
+ if ((msg->msg_controllen <= 0) ||
+ ((err = MksckPageDescToFd(sock, msg, pd, dg->pages)) != 0) ||
+ (MsgHdrHasAvailableRoom(msg) != 0)) {
+
+ down_write(&current->mm->mmap_sem); // lock for a change of mapping
+ payloadLen += MksckPageDescMap(pd, dg->pages, iov, iovCount, NULL);
+ up_write(&current->mm->mmap_sem);
+ }
+ }
+
+ /*
+ * Now that packet is removed, it is safe to unlock socket so another thread
+ * can do a recv(). We also want to wake someone waiting for room to insert
+ * a new packet.
+ */
+ if ((err >= 0) && Mksck_IncReadIndex(mksck, read, dg)) {
+ Mutex_UnlWake(&mksck->mutex, MutexModeEX, MKSCK_CVAR_ROOM, true);
+ } else {
+ Mutex_Unlock(&mksck->mutex, MutexModeEX);
+ }
+
+ /*
+ * If memcpy error, return error status.
+ * Otherwise, return number of bytes copied.
+ */
+ if (err >= 0) {
+ err = payloadLen;
+ }
+
+decRefc:
+ Mksck_DecRefc(mksck);
+ return err;
+}
+
+
+/**
+ * @brief VMX sending a packet to VMM.
+ *
+ * @param kiocb kernel io control block
+ * @param sock user socket structure
+ * @param msg packet to be transmitted
+ * @param len length of the packet
+ *
+ * @return length of the sent msg on success, -errno on failure
+ */
+static int
+MksckDgramSendMsg(struct kiocb *kiocb,
+ struct socket *sock,
+ struct msghdr *msg,
+ size_t len)
+{
+ int err = 0;
+ struct sock *sk = sock->sk;
+ Mksck *peerMksck;
+ Mksck_Datagram *dg;
+ uint32 needed;
+ uint32 write;
+ Mksck_Address fromAddr;
+
+ if (msg->msg_flags & MSG_OOB) {
+ return -EOPNOTSUPP;
+ }
+
+ if (len > MKSCK_XFER_MAX) {
+ return -EMSGSIZE;
+ }
+
+ /*
+ * In the next locked section peerMksck pointer needs to be set and
+ * its refcount needs to be incremented.
+ */
+ lock_sock(sk);
+ do {
+ Mksck *mksck;
+ Mksck_Address peerAddr =
+ { .addr = (msg->msg_name ?
+ ((struct sockaddr_mk *)msg->msg_name)->mk_addr.addr :
+ MKSCK_ADDR_UNDEF) };
+
+ if ((err = MksckTryBind(sk))) {
+ break;
+ }
+ mksck = sk->sk_protinfo;
+ fromAddr = mksck->addr;
+
+ /*
+ * If the socket is connected, use that address (no sendto for
+ * connected sockets). Otherwise, use the provided address if any.
+ */
+ if ((peerMksck = mksck->peer)) {
+ if (peerAddr.addr != MKSCK_ADDR_UNDEF &&
+ peerAddr.addr != mksck->peerAddr.addr) {
+ err = -EISCONN;
+ break;
+ }
+ /*
+ * To avoid mksckPeer disappearing right after the
+ * release_sock the refcount needs to be incremented. For
+ * more details read the block comment on locking in
+ * MksckCreate.
+ */
+ ATOMIC_ADDV(peerMksck->refCount, 1);
+ } else if (peerAddr.addr == MKSCK_ADDR_UNDEF) {
+ err = -ENOTCONN;
+ } else {
+ /*
+ * LockPeer also increments the refc on the peer.
+ */
+ err = LockPeer(peerAddr, &peerMksck);
+ }
+ } while(0);
+ release_sock(sk);
+
+ if (err) {
+ return err;
+ }
+
+ /*
+ * Get pointer to sufficient empty space in ring buffer.
+ */
+ needed = MKSCK_DGSIZE(len);
+ while (1) {
+ /*
+ * Wait to make sure this is the only thread trying to write to ring.
+ */
+ if ((err = Mutex_Lock(&peerMksck->mutex, MutexModeEX)) < 0) {
+ goto decRefc;
+ }
+
+ /*
+ * Check if socket can receive data.
+ */
+ if (peerMksck->shutDown & MKSCK_SHUT_RD) {
+ err = -ENOTCONN;
+ goto unlockDecRefc;
+ }
+
+ /*
+ * See if there is room for the packet.
+ */
+ write = Mksck_FindSendRoom(peerMksck, needed);
+ if (write != MKSCK_FINDSENDROOM_FULL) {
+ break;
+ }
+
+ /*
+ * No room, unlock socket and maybe wait for room.
+ */
+ if (msg->msg_flags & MSG_DONTWAIT) {
+ err = -EAGAIN;
+ goto unlockDecRefc;
+ }
+
+ peerMksck->foundFull ++;
+ err = Mutex_UnlSleep(&peerMksck->mutex,
+ MutexModeEX,
+ MKSCK_CVAR_ROOM);
+ if (err < 0) {
+ PRINTK(KERN_INFO "MksckDgramSendMsg: aborted\n");
+ goto decRefc;
+ }
+ }
+
+ /*
+ * Point to room in ring and fill in message.
+ */
+ dg = (void *)&peerMksck->buff[write];
+
+ dg->fromAddr = fromAddr;
+ dg->len = len;
+
+ if ((err = memcpy_fromiovec(dg->data, msg->msg_iov, len)) != 0) {
+ goto unlockDecRefc;
+ }
+
+ /*
+ * Increment past message.
+ */
+ Mksck_IncWriteIndex(peerMksck, write, needed);
+
+ /*
+ * Unlock socket and wake someone trying to receive, ie, we filled
+ * in a message.
+ */
+ Mutex_UnlWake(&peerMksck->mutex, MutexModeEX, MKSCK_CVAR_FILL, false);
+
+ /*
+ * Maybe guest is in a general 'wait for interrupt' wait or
+ * grinding away executing guest instructions.
+ *
+ * If it has a receive callback armed for the socket and is
+ * waiting a message, just wake it up. Else send an IPI to the CPU
+ * running the guest so it will interrupt whatever it is doing and
+ * read the message.
+ *
+ * Holding the mksckPage->mutex prevents mksckPage->vmHKVA from
+ * clearing on us.
+ */
+ if (peerMksck->rcvCBEntryMVA != 0) {
+ MksckPage *peerMksckPage = Mksck_ToSharedPage(peerMksck);
+
+ if ((err = Mutex_Lock(&peerMksckPage->mutex, MutexModeSH)) == 0) {
+ uint32 sockIdx = peerMksck->index;
+ MvpkmVM *vm = (MvpkmVM *) peerMksckPage->vmHKVA;
+
+ /*
+ * The destruction of vm and wsp is blocked by the
+ * mksckPage->mutex.
+ */
+ if (vm) {
+ WorldSwitchPage *wsp = vm->wsp;
+
+ ASSERT(sockIdx < 8 * sizeof peerMksckPage->wakeVMMRecv);
+ ATOMIC_ORV(peerMksckPage->wakeVMMRecv, 1U << sockIdx);
+
+ if (wsp) {
+ Mvpkm_WakeGuest(vm, ACTION_MKSCK);
+ }
+ }
+ Mutex_Unlock(&peerMksckPage->mutex, MutexModeSH);
+ }
+ }
+
+ /*
+ * If all are happy tell the caller the number of transferred bytes.
+ */
+ if (!err) {
+ err = len;
+ }
+
+ /*
+ * Now that we are done with target socket, allow it to be freed.
+ */
+decRefc:
+ Mksck_DecRefc(peerMksck);
+ return err;
+
+unlockDecRefc:
+ Mutex_Unlock(&peerMksck->mutex, MutexModeEX);
+ goto decRefc;
+}
+
+
+/**
+ * @brief Page fault handler for receive windows. Since the host process
+ * should not be faulting in this region and only be accessing
+ * memory that has been established via a typed message transfer,
+ * we always signal the fault back to the process.
+ */
+static int
+MksckFault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ return VM_FAULT_SIGBUS;
+}
+
+/**
+ * @brief Establish a region in the host process suitable for use as a
+ * receive window.
+ *
+ * @param file file reference (ignored).
+ * @param sock user socket structure.
+ * @param vma Linux virtual memory area defining the region.
+ *
+ * @return 0 on success, otherwise error code.
+ */
+static int
+MksckMMap(struct file *file, struct socket *sock, struct vm_area_struct *vma)
+{
+ /*
+ * All the hard work is done in MksckDgramRecvMsg. Here we simply mark the
+ * vma as belonging to Mksck.
+ */
+ vma->vm_ops = &mksckVMOps;
+
+ return 0;
+}
+
+/**
+ * @brief This gets called after returning from the monitor.
+ * Since the monitor doesn't directly wake VMX threads when it sends
+ * something to VMX (for efficiency), this routine checks for the
+ * omitted wakes and does them.
+ * @param mksckPage some shared page that the monitor writes packets to, ie
+ * an host shared page
+ */
+void
+Mksck_WakeBlockedSockets(MksckPage *mksckPage)
+{
+ Mksck *mksck;
+ uint32 i, wakeHostRecv;
+
+ wakeHostRecv = mksckPage->wakeHostRecv;
+ if (wakeHostRecv != 0) {
+ mksckPage->wakeHostRecv = 0;
+ for (i = 0; wakeHostRecv != 0; i ++) {
+ if (wakeHostRecv & 1) {
+ mksck = &mksckPage->sockets[i];
+ Mutex_CondSig(&mksck->mutex, MKSCK_CVAR_FILL, true);
+ }
+ wakeHostRecv >>= 1;
+ }
+ }
+}
+
+/**
+ * @brief allocate and initialize a shared page.
+ * @return pointer to shared page.<br>
+ * NULL on error
+ */
+MksckPage *
+MksckPageAlloc(void)
+{
+ uint32 jj;
+ /*
+ * Ask for pages in the virtual kernel space. There is no
+ * requirement to be physically contiguous.
+ */
+ MksckPage *mksckPage = vmalloc(MKSCKPAGE_SIZE);
+
+ if (mksckPage) {
+
+ /*
+ * Initialize its contents. Start refCount at 1 and decrement it
+ * when the worldswitch or VM page gets freed.
+ */
+ memset(mksckPage, 0, MKSCKPAGE_SIZE);
+ ATOMIC_SETV(mksckPage->refCount, 1);
+ mksckPage->portStore = MKSCK_PORT_HIGH;
+
+ Mutex_Init(&mksckPage->mutex);
+ for (jj = 0; jj<MKSCK_SOCKETS_PER_PAGE; jj++) {
+ Mutex_Init(&mksckPage->sockets[jj].mutex);
+ }
+ }
+
+ return mksckPage;
+}
+
+/**
+ * @brief Release the allocated pages.
+ * @param mksckPage the address of the mksckPage to be released
+ */
+static void
+MksckPageRelease(MksckPage *mksckPage)
+{
+ int ii;
+
+ for (ii = 0; ii<MKSCK_SOCKETS_PER_PAGE; ii++) {
+ Mutex_Destroy(&mksckPage->sockets[ii].mutex);
+ }
+ Mutex_Destroy(&mksckPage->mutex);
+
+ vfree(mksckPage);
+}
+
+/**
+ * @brief Using the tgid locate the vmid of this process.
+ * Assumed that mksckPageListLock is held
+ * @return the vmId if page is already allocated,
+ * the first vacant vmid if not yet allocated.<br>
+ * MKSCK_PORT_UNDEF if no slot is vacant
+ */
+static inline Mksck_VmId
+GetHostVmId(void)
+{
+ uint32 jj;
+ Mksck_VmId vmId, vmIdFirstVacant = MKSCK_VMID_UNDEF;
+ MksckPage *mksckPage;
+ uint32 tgid = task_tgid_vnr(current);
+ /*
+ * Assign an unique vmId to the shared page. Start the search from
+ * the vmId that is the result of hashing tgid to 15 bits. As a
+ * used page with a given vmId can occupy only a given slot in the
+ * mksckPages array, it is enough to search through the
+ * MKSCK_MAX_SHARES slots for a vacancy.
+ */
+ for (jj = 0, vmId = MKSCK_TGID2VMID(tgid);
+ jj < MKSCK_MAX_SHARES;
+ jj++, vmId++) {
+ if (vmId > MKSCK_VMID_HIGH) {
+ vmId = 0;
+ }
+ mksckPage = mksckPages[MKSCK_VMID2IDX(vmId)];
+
+ if (mksckPage) {
+ if (mksckPage->tgid == tgid &&
+ !mksckPage->isGuest) {
+ return mksckPage->vmId;
+ }
+
+ } else if (vmIdFirstVacant == MKSCK_VMID_UNDEF) {
+ vmIdFirstVacant = vmId;
+ }
+ }
+ return vmIdFirstVacant;
+}
+
+
+/**
+ * @brief Locate the first empty slot
+ * Assumed that mksckPageListLock is held
+ * @return the first vacant vmid.<br>
+ * MKSCK_PORT_UNDEF if no slot is vacant
+ */
+static inline Mksck_VmId
+GetNewGuestVmId(void)
+{
+ Mksck_VmId vmId;
+
+ for (vmId = 0; vmId < MKSCK_MAX_SHARES; vmId++) {
+ if (!mksckPages[MKSCK_VMID2IDX(vmId)]) {
+ return vmId;
+ }
+ }
+ return MKSCK_VMID_UNDEF;
+}
+
+
+/**
+ * @brief Find shared page for a given idx. The page referred to be the
+ * idx should exist and be locked by the caller.
+ * @param idx index of the page in the array
+ * @return pointer to shared page
+ */
+MksckPage *
+MksckPage_GetFromIdx(uint32 idx)
+{
+ MksckPage *mksckPage = mksckPages[idx];
+ ASSERT(mksckPage);
+ ASSERT(idx<MKSCK_MAX_SHARES);
+ ASSERT(ATOMIC_GETO(mksckPage->refCount));
+ return mksckPage;
+}
+
+/**
+ * @brief find shared page for a given vmId
+ * The vmid should exist and be locked by the caller.
+ * @param vmId vmId to look for, either an host vmId or a guest vmId
+ * @return pointer to shared page
+ */
+MksckPage *
+MksckPage_GetFromVmId(Mksck_VmId vmId)
+{
+ MksckPage *mksckPage = mksckPages[MKSCK_VMID2IDX(vmId)];
+ ASSERT(mksckPage);
+ ASSERT(mksckPage->vmId == vmId);
+ ASSERT(ATOMIC_GETO(mksckPage->refCount));
+ return mksckPage;
+}
+
+
+/**
+ * @brief find shared page for a given vmId
+ * @param vmId vmId to look for, either an host vmId or a guest vmId
+ * @return NULL: no such shared page exists<br>
+ * else: pointer to shared page.
+ * Call Mksck_DecRefc() when done with pointer
+ */
+MksckPage *
+MksckPage_GetFromVmIdIncRefc(Mksck_VmId vmId)
+{
+ MksckPage *mksckPage;
+
+ spin_lock(&mksckPageListLock);
+ mksckPage = mksckPages[MKSCK_VMID2IDX(vmId)];
+
+ if (!mksckPage || (mksckPage->vmId != vmId)) {
+ printk(KERN_INFO "MksckPage_GetFromVmIdIncRefc: vmId %04X not found\n",
+ vmId);
+ mksckPage = NULL;
+ } else {
+ ATOMIC_ADDV(mksckPage->refCount, 1);
+ }
+ spin_unlock(&mksckPageListLock);
+ return mksckPage;
+}
+
+
+/**
+ * @brief find or allocate shared page using tgid
+ * @return NULL: no such shared page exists<br>
+ * else: pointer to shared page.
+ * Call Mksck_DecRefc() when done with pointer
+ */
+MksckPage *
+MksckPage_GetFromTgidIncRefc(void)
+{
+ MksckPage *mksckPage;
+ Mksck_VmId vmId;
+
+ while (1) {
+ spin_lock(&mksckPageListLock);
+ vmId = GetHostVmId();
+
+ if (vmId == MKSCK_VMID_UNDEF) {
+ /*
+ * No vmId has been allocated yet and there is no free slot.
+ */
+ spin_unlock(&mksckPageListLock);
+ return NULL;
+ }
+
+ mksckPage = mksckPages[MKSCK_VMID2IDX(vmId)];
+ if (mksckPage != NULL) {
+ /*
+ * There is a vmid already allocated, increment the refc on it.
+ */
+ ATOMIC_ADDV(mksckPage->refCount, 1);
+ spin_unlock(&mksckPageListLock);
+ return mksckPage;
+ }
+
+ /*
+ * Have to release spinlock to allocate a new page.
+ */
+ spin_unlock(&mksckPageListLock);
+ mksckPage = MksckPageAlloc();
+ if (mksckPage == NULL) {
+ return NULL;
+ }
+
+ /*
+ * Re-lock and make sure no one else allocated while unlocked.
+ * If someone else did allocate, free ours off and use theirs.
+ */
+ spin_lock(&mksckPageListLock);
+ vmId = GetHostVmId();
+ if ((vmId != MKSCK_VMID_UNDEF) &&
+ (mksckPages[MKSCK_VMID2IDX(vmId)] == NULL)) {
+ break;
+ }
+ spin_unlock(&mksckPageListLock);
+ MksckPageRelease(mksckPage);
+ }
+
+ /*
+ * This is a successful new allocation. insert it into the table
+ * and initialize the fields.
+ */
+ mksckPages[MKSCK_VMID2IDX(vmId)] = mksckPage;
+ mksckPage->vmId = vmId;
+ mksckPage->isGuest = false;
+ mksckPage->vmHKVA = 0;
+ mksckPage->tgid = task_tgid_vnr(current);
+ printk(KERN_DEBUG "New host mksck page is allocated: idx %x, vmId %x, tgid %d\n",
+ MKSCK_VMID2IDX(vmId), vmId, mksckPage->tgid);
+
+ spin_unlock(&mksckPageListLock);
+ return mksckPage;
+}
+
+/**
+ * @brief Initialize the VMX provided wsp. Allocate communication page.
+ * @param vm which virtual machine we're running
+ * @return 0 if all OK, error value otherwise
+ */
+int
+Mksck_WspInitialize(MvpkmVM *vm)
+{
+ WorldSwitchPage *wsp = vm->wsp;
+ int err;
+ Mksck_VmId vmId;
+ MksckPage *mksckPage;
+
+ if (wsp->guestId) {
+ err = -EBUSY;
+ } else if (!(mksckPage = MksckPageAlloc())) {
+ err = -ENOMEM;
+ } else {
+ spin_lock(&mksckPageListLock);
+
+ if ((vmId = GetNewGuestVmId()) == MKSCK_VMID_UNDEF) {
+
+ err = -EMFILE;
+ MksckPageRelease(mksckPage);
+
+ printk(KERN_INFO "Mksck_WspInitialize: Cannot allocate vmId\n");
+
+ } else {
+ /*
+ * Now that the mksckPage is all initialized, let others see it.
+ */
+ mksckPages[MKSCK_VMID2IDX(vmId)] = mksckPage;
+ mksckPage->vmId = vmId;
+ mksckPage->isGuest = true;
+ mksckPage->vmHKVA = (HKVA)vm;
+ /* mksckPage->tgid is undefined when isGuest is true */
+
+ wsp->guestId = vmId;
+
+ printk(KERN_DEBUG "New guest mksck page is allocated: idx %x, vmId %x\n",
+ MKSCK_VMID2IDX(vmId), vmId);
+
+ err = 0;
+ }
+
+ /*
+ * All stable, ie, mksckPages[] written, ok to unlock now.
+ */
+ spin_unlock(&mksckPageListLock);
+ }
+
+ return err;
+}
+
+/**
+ * @brief Release the wsp. Clean up after the monitor. Free the
+ * associated communication page.
+ * @param wsp which worldswitch page (VCPU)
+ */
+void
+Mksck_WspRelease(WorldSwitchPage *wsp)
+{
+ int ii;
+ int err;
+ MksckPage *mksckPage = MksckPage_GetFromVmId(wsp->guestId);
+
+ /*
+ * The worldswitch page for a particular VCPU is about to be freed
+ * off, so we know the monitor will never execute again. But the
+ * monitor most likely left some sockets open. Those may have
+ * outbound connections to host sockets that we must close.
+ *
+ * Loop through all possibly open sockets.
+ */
+ uint32 isOpened = wsp->isOpened;
+ Mksck *mksck = mksckPage->sockets;
+ while (isOpened) {
+ if (isOpened & 1) {
+ ASSERT(ATOMIC_GETO(mksck->refCount) != 0);
+ /*
+ * The socket may be connected to a peer (host) socket, so we
+ * have to decrement that target socket's reference
+ * count. Unfortunately, Mksck_DisconnectPeer(mksck) cannot
+ * be called as mksck->peer is an mva not an hkva. Translate
+ * the address first.
+ */
+ if (mksck->peer) {
+ MksckPage *mksckPagePeer = MksckPage_GetFromVmId(mksck->peerAddr.vmId);
+ ASSERT(mksckPagePeer);
+ mksck->peer = MksckPage_GetFromAddr(mksckPagePeer, mksck->peerAddr);
+ ASSERT(mksck->peer);
+ /* mksck->peer is now a hkva */
+ }
+
+ Mksck_CloseCommon(mksck);
+ }
+ isOpened >>= 1;
+ mksck++;
+ }
+
+ /*
+ * A host socket may be in the process of sending to the guest. It
+ * will attempt to wake up the guest using mksckPage->vmHKVA and
+ * mksckPage->vmHKVA->wsp. To assure that the vm and wsp structures
+ * are not disappearing from under the sending thread we lock the
+ * page here.
+ */
+ err = Mutex_Lock(&mksckPage->mutex, MutexModeEX);
+ ASSERT(!err);
+ mksckPage->vmHKVA = 0;
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+ /*
+ * Decrement refcount set by MksckPageAlloc() call in
+ * Mksck_WspInitialize().
+ */
+ MksckPage_DecRefc(mksckPage);
+
+ /*
+ * Decrement refcount set by VMM:Mksck_Init() referring to the local
+ * variable guestMksckPage.
+ */
+ if (wsp->guestPageMapped) {
+ wsp->guestPageMapped = false;
+ MksckPage_DecRefc(mksckPage);
+ }
+
+ /*
+ * Another task is to decrement the reference count on the mksck
+ * pages the monitor accessed. Those pages are listed in the
+ * wsp->isPageMapped list. They were locked by the monitor
+ * calling WSCALL_GET_PAGE_FROM_VMID
+ */
+ for (ii = 0; ii < MKSCK_MAX_SHARES; ii++) {
+ if (wsp->isPageMapped[ii]) {
+ MksckPage *mksckPageOther = MksckPage_GetFromIdx(ii);
+
+ wsp->isPageMapped[ii] = false;
+ MksckPage_DecRefc(mksckPageOther);
+ }
+ }
+}
+
+/**
+ * @brief disconnect from peer by decrementing
+ * peer socket's reference count and clearing the pointer.
+ * @param mksck local socket to check for connection
+ */
+void
+Mksck_DisconnectPeer(Mksck *mksck)
+{
+ Mksck *peerMksck = mksck->peer;
+ if (peerMksck != NULL) {
+ mksck->peer = NULL;
+ mksck->peerAddr.addr = MKSCK_ADDR_UNDEF;
+ Mksck_DecRefc(peerMksck);
+ }
+}
+
+
+/**
+ * @brief decrement shared page reference count, free page if it goes zero.
+ * also do a dmb first to make sure all activity on the struct is
+ * finished before decrementing the ref count.
+ * @param mksckPage shared page
+ */
+void
+MksckPage_DecRefc(MksckPage *mksckPage)
+{
+ uint32 oldRefc;
+
+ DMB();
+ do {
+ while ((oldRefc = ATOMIC_GETO(mksckPage->refCount)) == 1) {
+
+ /*
+ * Find corresponding entry in list of known shared pages and
+ * clear it so we can't open any new sockets on this shared
+ * page, thus preventing its refCount from being incremented.
+ */
+ spin_lock(&mksckPageListLock);
+ if (ATOMIC_SETIF(mksckPage->refCount, 0, 1)) {
+ uint32 ii = MKSCK_VMID2IDX(mksckPage->vmId);
+ ASSERT(ii < MKSCK_MAX_SHARES);
+ ASSERT(mksckPages[ii] == mksckPage);
+ mksckPages[ii] = NULL;
+ spin_unlock(&mksckPageListLock);
+ printk(KERN_DEBUG "%s mksck page is released: idx %x, vmId %x, tgid %d\n",
+ mksckPage->isGuest?"Guest":"Host",
+ ii, mksckPage->vmId, mksckPage->tgid);
+ MksckPageRelease(mksckPage);
+ return;
+ }
+ spin_unlock(&mksckPageListLock);
+ }
+ ASSERT(oldRefc != 0);
+ } while (!ATOMIC_SETIF(mksckPage->refCount, oldRefc - 1, oldRefc));
+}
+
+/**
+ * @brief Lookup if the provided mpn belongs to one of the Mksck pages. Map if found.
+ * @return 0 if all OK, error value otherwise
+ */
+int
+MksckPage_LookupAndInsertPage(struct vm_area_struct *vma,
+ unsigned long address,
+ MPN mpn)
+{
+ int ii, jj;
+ MksckPage **mksckPagePtr = mksckPages;
+
+ spin_lock(&mksckPageListLock);
+ for (jj = MKSCK_MAX_SHARES; jj--; mksckPagePtr++) {
+ if (*mksckPagePtr) {
+ for (ii = 0; ii < MKSCKPAGE_TOTAL; ii++) {
+ if (vmalloc_to_pfn((void*)(((HKVA)*mksckPagePtr) + ii*PAGE_SIZE)) == mpn &&
+ vm_insert_page(vma, address, pfn_to_page(mpn)) == 0) {
+ spin_unlock(&mksckPageListLock);
+ return 0;
+ }
+ }
+ }
+ }
+ spin_unlock(&mksckPageListLock);
+ return -1;
+}
+
+
+/**
+ * @brief Print information on the allocated shared pages
+ *
+ * This function reports (among many other things) on the use of locks
+ * on the mksck page (page lock and individual socket locks). To avoid
+ * the Hiesenberg effect it avoids using locks unless there is a
+ * danger of dereferencing freed memory. In particular, holding
+ * mksckPageListLock ensures that the mksck page is not freed while it
+ * is read. But under very rare conditions this function may report
+ * inconsistent or garbage data.
+ */
+static int
+MksckPageInfoShow(struct seq_file *m, void *private)
+{
+ int ii, jj;
+ uint32 isPageMapped = 0;
+ int err;
+ MvpkmVM *vm;
+
+ /*
+ * Lock is needed to atomize the test and dereference of
+ * mksckPages[ii]
+ */
+ spin_lock(&mksckPageListLock);
+ for (ii = 0; ii < MKSCK_MAX_SHARES; ii++) {
+ MksckPage *mksckPage = mksckPages[ii];
+ if (mksckPage != NULL && mksckPage->isGuest) {
+ /*
+ * After the refcount is incremented mksckPage will not be
+ * freed and it can continued to be dereferenced after the
+ * unlock of mksckPageListLock.
+ */
+ ATOMIC_ADDV(mksckPage->refCount, 1);
+ spin_unlock(&mksckPageListLock);
+
+ /*
+ * To dereference mksckPage->vmHKVA, we need to have the page
+ * lock.
+ */
+ err = Mutex_Lock(&mksckPage->mutex, MutexModeEX);
+ vm = (MvpkmVM *) mksckPage->vmHKVA;
+
+ if (err == 0 && vm && vm->wsp) {
+ for (jj = 0; jj < MKSCK_MAX_SHARES; jj++) {
+ if (vm->wsp->isPageMapped[jj]) isPageMapped |= 1<<jj;
+ }
+ }
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+ /*
+ * Decrement the page refcount and relock the
+ * mksckPageListLock for the next for loop.
+ */
+ MksckPage_DecRefc(mksckPage);
+ spin_lock(&mksckPageListLock);
+ break;
+ }
+ }
+
+ /* mksckPageListLock is still locked, mksckPages[ii] can be dereferenced */
+ for (ii = 0; ii < MKSCK_MAX_SHARES; ii++) {
+ MksckPage *mksckPage = mksckPages[ii];
+ if (mksckPage != NULL) {
+ uint32 lState = ATOMIC_GETO(mksckPage->mutex.state);
+ uint32 isOpened = 0; /* guest has an implicit ref */
+
+ seq_printf(m, "MksckPage[%02d]: { vmId = %4x(%c), refC = %2d%s",
+ ii, mksckPage->vmId,
+ mksckPage->isGuest?'G':'H',
+ ATOMIC_GETO(mksckPage->refCount),
+ (isPageMapped&(1<<ii) ? "*" : ""));
+
+ if (lState) {
+ seq_printf(m, ", lock=%x locked by line %d, unlocked by %d",
+ lState, mksckPage->mutex.line, mksckPage->mutex.lineUnl);
+ }
+
+
+ if (!mksckPage->isGuest) {
+ struct task_struct *target;
+ seq_printf(m, ", tgid = %d", mksckPage->tgid);
+
+ rcu_read_lock();
+
+ target = pid_task(find_vpid(mksckPage->tgid), PIDTYPE_PID);
+ seq_printf(m, "(%s)", target ? target->comm : "no such process");
+
+ rcu_read_unlock();
+ } else {
+ ATOMIC_ADDV(mksckPage->refCount, 1);
+ spin_unlock(&mksckPageListLock);
+
+ err = Mutex_Lock(&mksckPage->mutex, MutexModeEX);
+ vm = (MvpkmVM *) mksckPage->vmHKVA;
+
+ if (err == 0 && vm && vm->wsp) {
+ isOpened = vm->wsp->isOpened;
+ }
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+ MksckPage_DecRefc(mksckPage);
+ spin_lock(&mksckPageListLock);
+ /*
+ * As the mksckPageListLock was unlocked, nothing
+ * prevented the MksckPage_DecRefc from actually freeing
+ * the page. Lets verify that the page is still there.
+ */
+ if (mksckPage != mksckPages[ii]) {
+ seq_printf(m, " released }\n");
+ continue;
+ }
+ }
+ seq_printf(m, ", sockets[] = {");
+
+ for (jj = 0; jj < mksckPage->numAllocSocks; jj++, isOpened >>= 1) {
+ Mksck *mksck = mksckPage->sockets + jj;
+
+ if (ATOMIC_GETO(mksck->refCount)) {
+ uint32 blocked;
+ lState = ATOMIC_GETO(mksck->mutex.state);
+ seq_printf(m, "\n { addr = %8x, refC = %2d%s%s%s",
+ mksck->addr.addr,
+ ATOMIC_GETO(mksck->refCount),
+ (isOpened & 1 ? "*" : ""),
+ (mksck->shutDown & MKSCK_SHUT_RD ? " SHUTD_RD":""),
+ (mksck->shutDown & MKSCK_SHUT_WR ? " SHUTD_WR":""));
+
+ if (mksck->peer) {
+ seq_printf(m, ", peerAddr = %8x",
+ mksck->peerAddr.addr);
+ }
+
+ if (lState) {
+ seq_printf(m, ", lock=%x locked by line %d, unlocked by %d",
+ lState, mksck->mutex.line, mksck->mutex.lineUnl);
+ }
+
+ if ((blocked = ATOMIC_GETO(mksck->mutex.blocked))) {
+ seq_printf(m, ", blocked=%d", blocked);
+ }
+
+ seq_printf(m, " }");
+ }
+ }
+ seq_printf(m, " } }\n");
+ }
+ }
+ spin_unlock(&mksckPageListLock);
+
+ return 0;
+}
+
+
+static int
+MksckPageInfoOpen(struct inode *inode, struct file *file)
+{
+ return single_open(file, MksckPageInfoShow, inode->i_private);
+}
+
+static const struct file_operations mksckPageInfoFops = {
+ .open = MksckPageInfoOpen,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *mksckPageDentry = NULL;
+
+void
+MksckPageInfo_Init(void)
+{
+ mksckPageDentry = debugfs_create_file("mksckPage",
+ S_IROTH,
+ NULL,
+ NULL,
+ &mksckPageInfoFops);
+}
+
+void
+MksckPageInfo_Exit(void)
+{
+ if (mksckPageDentry) {
+ debugfs_remove(mksckPageDentry);
+ }
+}
diff --git a/arch/arm/mvp/mvpkm/mksck_kernel.h b/arch/arm/mvp/mvpkm/mksck_kernel.h
new file mode 100644
index 0000000..233b780
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mksck_kernel.h
@@ -0,0 +1,68 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The monitor-kernel socket interface kernel-only definitions.
+ */
+
+#ifndef _MKSCK_KERNEL_H
+#define _MKSCK_KERNEL_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mksck_shared.h"
+
+/*
+ * prototypes
+ */
+int Mksck_Init(void);
+void Mksck_Exit(void);
+void Mksck_WakeBlockedSockets(MksckPage *mksckPage);
+MksckPage *MksckPage_GetFromTgidIncRefc(void);
+MksckPage *MksckPage_GetFromVmIdIncRefc(Mksck_VmId vmId);
+MksckPage *MksckPage_GetFromIdx(uint32 idx);
+void MksckPageInfo_Init(void);
+void MksckPageInfo_Exit(void);
+int Mksck_WspInitialize(MvpkmVM *vm);
+void Mksck_WspRelease(WorldSwitchPage *wsp);
+int MksckPage_LookupAndInsertPage(struct vm_area_struct *vma,
+ unsigned long address,
+ MPN mpn);
+
+/*
+ * Mksck open request must come from this uid.
+ */
+extern uid_t Mvpkm_vmwareUid;
+
+#define MKSCK_DEVEL 0
+
+#if MKSCK_DEVEL
+#define PRINTK printk
+#else
+#define PRINTK if (0) printk
+#endif
+
+#define HOST_CPUID_UNDEF (~0)
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mksck_shared.c b/arch/arm/mvp/mvpkm/mksck_shared.c
new file mode 100644
index 0000000..68c38fc6
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mksck_shared.c
@@ -0,0 +1,343 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#include "mvp.h"
+#include "mksck_shared.h"
+
+/**
+ * @file
+ *
+ * @brief The mksck shared area functions used by the monitor and the
+ * kernel extension.
+ *
+ */
+
+/**
+ * @brief try to locate a socket using an address.
+ * @param mksckPage which shared page to look on.
+ * ASSUMED: locked for shared access
+ * @param addr address to check
+ * @return pointer to mksck page with addr.
+ * NULL if not found
+ */
+Mksck *
+MksckPage_GetFromAddr(MksckPage *mksckPage, Mksck_Address addr)
+{
+ Mksck *mksck = mksckPage->sockets;
+ uint32 ii;
+
+ ASSERT(addr.vmId == mksckPage->vmId);
+
+ for (ii = mksckPage->numAllocSocks; ii--; mksck++) {
+ if ((ATOMIC_GETO(mksck->refCount) != 0) &&
+ (mksck->addr.addr == addr.addr)) {
+ return mksck;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * @brief Close a monitor socket.
+ *
+ * @param mksck pointer to the socket control block
+ */
+void
+Mksck_CloseCommon(Mksck *mksck)
+{
+ /*
+ * If a peer was connected, release the peer.
+ */
+ Mksck_DisconnectPeer(mksck);
+
+ /*
+ * Signal senders that this socket won't be read anymore.
+ */
+ while (Mutex_Lock(&mksck->mutex, MutexModeEX) < 0);
+ mksck->shutDown = MKSCK_SHUT_WR | MKSCK_SHUT_RD;
+ Mutex_UnlWake(&mksck->mutex, MutexModeEX, MKSCK_CVAR_ROOM, true);
+
+ /*
+ * Decrement reference count because it was set to 1 when opened. It could
+ * still be non-zero after this if some other thread is currently sending to
+ * this socket.
+ */
+ Mksck_DecRefc(mksck);
+}
+
+
+/**
+ * @brief decrement socket reference count, free if it goes zero. Also do a
+ * dmb first to make sure all activity on the struct is finished before
+ * decrementing the ref count.
+ * @param mksck socket
+ */
+void
+Mksck_DecRefc(Mksck *mksck)
+{
+ uint32 oldRefc;
+
+ DMB();
+ do {
+ while ((oldRefc = ATOMIC_GETO(mksck->refCount)) == 1) {
+
+ MksckPage *mksckPage = Mksck_ToSharedPage(mksck);
+
+ /*
+ * Socket refcount is going zero on a socket that locks mksckPage in.
+ * Lock shared page exclusive to make sure no one is trying to look
+ * for this socket, thus preventing socket's refcount from being
+ * incremented non-zero once we decrement it to zero.
+ */
+
+ /*
+ * Lock failed probably because of an interrupt. Keep trying
+ * to lock until we succeed.
+ */
+ while (Mutex_Lock(&mksckPage->mutex, MutexModeEX) < 0);
+
+ /*
+ * No one is doing any lookups, so set refcount zero.
+ */
+ if (ATOMIC_SETIF(mksck->refCount, 0, 1)) {
+#if 0
+ /**
+ * @knownjira{MVP-1349}
+ * The standard Log is not yet implemented in the kernel space.
+ */
+ KNOWN_BUG(MVP-1349);
+ PRINTK(KERN_INFO "Mksck_DecRefc: %08X shutDown %u, foundEmpty %u,"
+ " foundFull %u, blocked %u\n",
+ mksck->addr.addr, mksck->shutDown,
+ mksck->foundEmpty, mksck->foundFull,
+ ATOMIC_GETO(mksck->mutex.blocked));
+#endif
+
+ /*
+ * Sockets can't have connected peers by the time their
+ * refc hits 0. The owner should have cleaned that up by
+ * now.
+ */
+ ASSERT(mksck->peer == 0);
+
+ /*
+ * Successfully set to zero, release mutex and decrement
+ * shared page ref count as it was incremented when the
+ * socket was opened. This may free the shared page.
+ */
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+ MksckPage_DecRefc(mksckPage);
+ return;
+ }
+
+ /*
+ * Someone incremented refcount just before we locked the mutex, so
+ * try it all again.
+ */
+ Mutex_Unlock(&mksckPage->mutex, MutexModeEX);
+ }
+
+ /*
+ * Not going zero or doesn't lock mksckPage, simple decrement.
+ */
+ ASSERT(oldRefc != 0);
+ } while (!ATOMIC_SETIF(mksck->refCount, oldRefc - 1, oldRefc));
+}
+
+
+/**
+ * @brief Find an unused port.
+ * @param mksckPage which shared page to look in.
+ * Locked for exclusive access
+ * @param port if not MKSCK_PORT_UNDEF test only this port
+ * @return port allocated or MKSCK_PORT_UNDEF if none was found
+ */
+Mksck_Port
+MksckPage_GetFreePort(MksckPage *mksckPage, Mksck_Port port)
+{
+ Mksck_Address addr = { .addr = Mksck_AddrInit(mksckPage->vmId, port) };
+ uint32 ii;
+
+ if (port == MKSCK_PORT_UNDEF) {
+ for (ii = 0; ii<MKSCK_SOCKETS_PER_PAGE; ii++) {
+
+ /*
+ * Find an unused local socket number.
+ */
+ addr.port = mksckPage->portStore--;
+ if (!addr.port) {
+
+ /*
+ * Wrapped around, reset portStore
+ */
+ mksckPage->portStore = MKSCK_PORT_HIGH;
+ }
+
+ if (!MksckPage_GetFromAddr(mksckPage, addr)) {
+ return addr.port;
+ }
+ }
+
+ } else if (!MksckPage_GetFromAddr(mksckPage, addr)) {
+ return addr.port;
+ }
+
+ return MKSCK_PORT_UNDEF;
+}
+
+/**
+ * @brief Find an unused slot in the sockets[] array and allocate it.
+ * @param mksckPage which shared page to look in.
+ * Locked for exclusive access
+ * @param addr what local address to assign to the socket
+ * @return NULL: no slots available <br>
+ * else: pointer to allocated socket
+ */
+Mksck *
+MksckPage_AllocSocket(MksckPage *mksckPage, Mksck_Address addr)
+{
+ Mksck *mksck;
+ uint32 i;
+
+ for (i = 0; (offsetof(MksckPage, sockets[i+1]) <= MKSCKPAGE_SIZE) &&
+ (i < 8 * sizeof mksckPage->wakeHostRecv) &&
+ (i < 8 * sizeof mksckPage->wakeVMMRecv); i ++) {
+ mksck = &mksckPage->sockets[i];
+ if (ATOMIC_GETO(mksck->refCount) == 0) {
+ ATOMIC_SETV(mksck->refCount, 1);
+ mksck->addr = addr;
+ mksck->peerAddr.addr = MKSCK_ADDR_UNDEF;
+ mksck->peer = NULL;
+ mksck->index = i;
+ mksck->write = 0;
+ mksck->read = 0;
+ mksck->shutDown = 0;
+ mksck->foundEmpty = 0;
+ mksck->foundFull = 0;
+ ATOMIC_SETV(mksck->mutex.blocked, 0);
+ mksck->rcvCBEntryMVA = 0;
+ mksck->rcvCBParamMVA = 0;
+
+ if (mksckPage->numAllocSocks < ++ i) {
+ mksckPage->numAllocSocks = i;
+ }
+
+ return mksck;
+ }
+ }
+ return NULL;
+}
+
+
+/**
+ * @brief increment read index over the packet just read
+ * @param mksck socket packet was read from.
+ * Locked for exclusive access
+ * @param read current value of mksck->read
+ * @param dg datagram at current mksck->read
+ * @return with mksck->read updated to next packet <br>
+ * false: buffer not empty <br>
+ * true: buffer now empty
+ */
+_Bool
+Mksck_IncReadIndex(Mksck *mksck, uint32 read, Mksck_Datagram *dg)
+{
+ ASSERT(read == mksck->read);
+ ASSERT((void *)dg == (void *)&mksck->buff[read]);
+
+ read += MKSCK_DGSIZE(dg->len);
+ if ((read > mksck->write) && (read >= mksck->wrap)) {
+ ASSERT(read == mksck->wrap);
+ read = 0;
+ }
+ mksck->read = read;
+
+ return read == mksck->write;
+}
+
+
+/**
+ * @brief find index in buffer that has enough room for a packet
+ * @param mksck socket message is being sent to.
+ * Locked for exclusive access
+ * @param needed room needed, including dg header and rounded up
+ * @return MKSCK_FINDSENDROOM_FULL: not enough room available <br>
+ * else: index in mksck->buff for packet
+ */
+uint32
+Mksck_FindSendRoom(Mksck *mksck, uint32 needed)
+{
+ uint32 read, write;
+
+ /*
+ * We must leave at least one byte unused so receiver can distinguish full
+ * from empty.
+ */
+ read = mksck->read;
+ write = mksck->write;
+ if (write == read) {
+ if (needed < MKSCK_BUFSIZE) {
+ mksck->read = 0;
+ mksck->write = 0;
+ return 0;
+ }
+ } else if (write < read) {
+ if (write + needed < read) {
+ return write;
+ }
+ } else {
+ if (write + needed < MKSCK_BUFSIZE) {
+ return write;
+ }
+ if ((write + needed == MKSCK_BUFSIZE) && (read > 0)) {
+ return write;
+ }
+ if (needed < read) {
+ mksck->wrap = write;
+ mksck->write = 0;
+ return 0;
+ }
+ }
+
+ return MKSCK_FINDSENDROOM_FULL;
+}
+
+
+/**
+ * @brief increment read index over the packet just written
+ * @param mksck socket packet was written to.
+ * Locked for exclusive access
+ * @param write as returned by @ref Mksck_FindSendRoom
+ * @param needed as passed to @ref Mksck_FindSendRoom
+ * @return with mksck->write updated to next packet
+ */
+void
+Mksck_IncWriteIndex(Mksck *mksck, uint32 write, uint32 needed)
+{
+ ASSERT(write == mksck->write);
+ write += needed;
+ if (write >= MKSCK_BUFSIZE) {
+ ASSERT(write == MKSCK_BUFSIZE);
+ mksck->wrap = MKSCK_BUFSIZE;
+ write = 0;
+ }
+ ASSERT(write != mksck->read);
+ mksck->write = write;
+}
diff --git a/arch/arm/mvp/mvpkm/mksck_shared.h b/arch/arm/mvp/mvpkm/mksck_shared.h
new file mode 100644
index 0000000..2677ec1
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mksck_shared.h
@@ -0,0 +1,189 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The monitor-kernel socket interface shared area definitions.
+ */
+
+#ifndef _MKSCK_SHARED_H
+#define _MKSCK_SHARED_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/*
+ * Allocated MksckPages are stored in an array of size
+ * MKSCK_MAX_SHARES. The vmid and the slot index of a shared page is
+ * not unrelated: vmid = idx%MKSCK_MAX_SHARES.
+ */
+#define MKSCK_MAX_SHARES_LOG2 4 // 16: one per VM + one per VCPU
+#define MKSCK_MAX_SHARES (1U << MKSCK_MAX_SHARES_LOG2)
+#define MKSCK_VMID2IDX(idx) ((idx)%MKSCK_MAX_SHARES)
+#define MKSCK_TGID2VMID(tgid) (((((tgid)<<1)^((tgid)>>15))&0xfffe)|1)
+/*
+ * The size of a shared page determines how many sockets can be open
+ * concurrently.
+ */
+#define MKSCKPAGE_TOTAL 8 // number of shared pages
+#define MKSCKPAGE_SIZE (PAGE_SIZE * MKSCKPAGE_TOTAL)
+#define MKSCK_SOCKETS_PER_PAGE ((MKSCKPAGE_SIZE-offsetof(MksckPage, sockets[0])) / \
+ sizeof(Mksck))
+
+/*
+ * Individual datagrams are aligned on a MKSCK_ALIGNMENT byte boundary
+ * in the data receive area of a socket.
+ */
+#define MKSCK_ALIGNMENT 8 // data packet alignment
+#define MKSCK_ALIGN(x) MVP_ALIGN(x, MKSCK_ALIGNMENT)
+#define MKSCK_DGSIZE(len) offsetof(Mksck_Datagram, data[MKSCK_ALIGN(len)])
+#define MKSCK_BUFSIZE MKSCK_DGSIZE(MKSCK_XFER_MAX + 1)
+
+/*
+ * Conditional variables for sleeping on.
+ */
+#define MKSCK_CVAR_ROOM 0 // senders waiting for room for message
+#define MKSCK_CVAR_FILL 1 // receivers waiting for a message to fetch
+
+#define MKSCK_FINDSENDROOM_FULL 0xFFFFFFFFU
+
+/*
+ * Shutdown bits
+ */
+#define MKSCK_SHUT_WR (1 << 0) // socket can't send data anymore
+#define MKSCK_SHUT_RD (1 << 1) // socket can't receive data anymore
+
+typedef struct Mksck Mksck;
+typedef struct Mksck_Datagram Mksck_Datagram;
+typedef struct MksckPage MksckPage;
+
+#include "atomic.h"
+#include "mksck.h"
+#include "mmu_defs.h"
+#include "mutex.h"
+#include "arm_inline.h"
+
+/**
+ * @brief Monitor-kernel socket datagram structure
+ */
+struct Mksck_Datagram {
+ Mksck_Address fromAddr; ///< source address
+ uint32 len : 16; ///< length of the data
+ uint32 pad : 3; ///< padding between untyped message and mpn
+ ///< array.
+ uint32 pages : 13; ///< number of pages in mpn array
+ uint8 data[1] ///< start of the data
+ __attribute__((aligned(MKSCK_ALIGNMENT)));
+};
+
+/**
+ * @brief one particular socket's shared page data.
+ */
+struct Mksck {
+ AtmUInt32 refCount; ///< when zero, struct is free
+ ///< ... increment only with mksckPage->mutex
+ ///< ... decrement at any time
+ Mksck_Address addr; ///< this socket's address if open
+ ///< ... MKSCK_ADDR_UNDEF if closed
+ ///< ... open only with mksckPage->mutex
+ Mksck_Address peerAddr; ///< peer's address if connected
+ ///< ... MKSCK_ADDR_UNDEF if not
+ struct Mksck *peer; ///< connected peer's ptr or NULL if not
+ ///< ... ptr is MVA for monitor sockets and
+ ///< ... HKVA for sockets of host processes
+ ///< ... holds ref count on target socket
+ uint32 index; ///< index of this socket in page
+
+ ///< empty ring indicated by read == write
+ ///< ring never completely fills, always at
+ ///< least room for one more byte so we can tell
+ ///< empty from full
+
+ uint32 write; ///< index within buff to insert next data
+ ///< ... always < MKSCK_BUFSIZE
+ uint32 read; ///< index within buff to remove next data
+ ///< ... always < MKSCK_BUFSIZE
+ uint32 wrap; ///< current wrapping point
+ ///< ... valid only whenever write < read
+ uint32 shutDown; ///< MKSCK_SHUT_RD, MKSCK_SHUT_WR bitfield
+ uint32 foundEmpty; ///< number of times a receive has blocked
+ uint32 foundFull; ///< number of times a send has blocked
+ Mutex mutex; ///< locks the ring buffer
+ MVA rcvCBEntryMVA; ///< monitor's receive callback entrypoint
+ MVA rcvCBParamMVA; ///< monitor's receive callback parameter
+ uint8 buff[MKSCK_BUFSIZE] ///< data going TO this socket
+ __attribute__((aligned(MKSCK_ALIGNMENT)));
+};
+
+
+/**
+ * @brief the shared page of an address domain (vmId)
+ */
+struct MksckPage {
+ _Bool isGuest; ///< the page belongs to a monitor/guest
+ uint32 tgid; ///< thread group id if isGuest=true
+ ///< undefined otherwise
+ volatile HKVA vmHKVA; ///< host side local data structure for vm
+ AtmUInt32 refCount; ///< page cannot be freed unless this is zero
+ ///< ... increment only with mksckPageListLock
+ ///< ... decrement at any time
+ ///< ... initialized to 1 for wsp->mksckPage* pointers
+ uint32 wakeHostRecv; ///< bitmask of sockets[] to be woken for receive
+ ///< ... access from VCPU thread only
+ AtmUInt32 wakeVMMRecv; ///< likewise for monitor receive callbacks
+ Mutex mutex; ///< locks list of open sockets
+ Mksck_VmId vmId; ///< hostId or guestId these sockets are for
+ Mksck_Port portStore; ///< used to assign ephemeral port numbers
+ uint32 numAllocSocks; ///< number of elements in sockets[] array
+ Mksck sockets[1]; ///< array of sockets (to fill MKSCKPAGE_SIZE)
+};
+
+MksckPage *MksckPage_GetFromVmId(Mksck_VmId vmId);
+Mksck_Port MksckPage_GetFreePort(MksckPage *mksckPage, Mksck_Port port);
+Mksck *MksckPage_GetFromAddr(MksckPage *mksckPage, Mksck_Address addr);
+Mksck *MksckPage_AllocSocket(MksckPage *mksckPage, Mksck_Address addr);
+void MksckPage_DecRefc(MksckPage *mksckPage);
+
+void Mksck_DecRefc(Mksck *mksck);
+void Mksck_CloseCommon(Mksck *mksck);
+_Bool Mksck_IncReadIndex(Mksck *mksck, uint32 read, Mksck_Datagram *dg);
+uint32 Mksck_FindSendRoom(Mksck *mksck, uint32 needed);
+void Mksck_IncWriteIndex(Mksck *mksck, uint32 write, uint32 needed);
+void Mksck_DisconnectPeer(Mksck *mksck);
+
+
+/**
+ * @brief determine which shared page a given socket is on
+ * Note that this process does not rely on any directory.
+ * @param mksck pointer to socket
+ * @return pointer to shared page
+ */
+static inline MksckPage *
+Mksck_ToSharedPage(Mksck *mksck)
+{
+ return (MksckPage*)((char*)(mksck - mksck->index)
+ - offsetof(MksckPage, sockets));
+}
+#endif
diff --git a/arch/arm/mvp/mvpkm/mksck_sockaddr.h b/arch/arm/mvp/mvpkm/mksck_sockaddr.h
new file mode 100644
index 0000000..e99d1f5
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mksck_sockaddr.h
@@ -0,0 +1,50 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Host user space definitions for mksck sockets.
+ */
+
+#ifndef _MKSCK_SOCKADDR_H_
+#define _MKSCK_SOCKADDR_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mksck.h"
+
+/* no one ever uses DECnet anymore? */
+#define AF_MKSCK AF_DECnet
+#define PF_MKSCK PF_DECnet
+
+/* Address structure used by the host user socket interface. */
+struct sockaddr_mk {
+ sa_family_t mk_family;
+ Mksck_Address mk_addr;
+};
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mmu_defs.h b/arch/arm/mvp/mvpkm/mmu_defs.h
new file mode 100644
index 0000000..340b91b
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mmu_defs.h
@@ -0,0 +1,218 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MMU-related definitions.
+ */
+
+#ifndef _MMU_DEFS_H_
+#define _MMU_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @name ARM address space identifier.
+ * @{
+ */
+#define ARM_ASID_BITS 8
+#define ARM_ASID_NUM (1 << ARM_ASID_BITS)
+#define ARM_ASID_MASK (ARM_ASID_NUM - 1)
+/*@}*/
+
+/**
+ * @name ARM level 1 and 2 page table sizes.
+ * @{
+ */
+#define ARM_L1PT_ORDER 14
+#define ARM_L2PT_FINE_ORDER 12
+#define ARM_L2PT_COARSE_ORDER 10
+
+#define ARM_L1D_SECTION_ORDER 20
+#define ARM_L1D_SUPERSECTION_ORDER 24
+
+#define ARM_L2D_SMALL_ORDER 12
+#define ARM_L2D_LARGE_ORDER 16
+
+#define ARM_L1PT_SIZE (1 << ARM_L1PT_ORDER)
+#define ARM_L2PT_FINE_SIZE (1 << ARM_L2PT_FINE_ORDER)
+#define ARM_L2PT_COARSE_SIZE (1 << ARM_L2PT_COARSE_ORDER)
+
+#define ARM_L1D_SECTION_SIZE (1 << ARM_L1D_SECTION_ORDER)
+#define ARM_L1D_SUPERSECTION_SIZE (1 << ARM_L1D_SUPERSECTION_ORDER)
+
+#define ARM_L2D_SMALL_SIZE (1 << ARM_L2D_SMALL_ORDER)
+#define ARM_L2D_LARGE_SIZE (1 << ARM_L2D_LARGE_ORDER)
+
+#define ARM_L2PT_COARSE_PER_PAGE (PAGE_SIZE / ARM_L2PT_COARSE_SIZE)
+
+#define ARM_L1PT_ENTRIES (ARM_L1PT_SIZE / sizeof(ARM_L1D))
+#define ARM_L2PT_FINE_ENTRIES (ARM_L2PT_FINE_SIZE / sizeof(ARM_L2D))
+#define ARM_L2PT_COARSE_ENTRIES (ARM_L2PT_COARSE_SIZE / sizeof(ARM_L2D))
+/*@}*/
+
+/**
+ * @brief Level 1 descriptor type field values.
+ * @{
+ */
+#define ARM_L1D_TYPE_INVALID 0
+#define ARM_L1D_TYPE_COARSE 1
+#define ARM_L1D_TYPE_SECTION 2
+#define ARM_L1D_TYPE_SUPERSECTION 2
+/*@}*/
+
+/**
+ * @name Decomposition of virtual addresses for page table indexing.
+ * @{
+ */
+#define ARM_L1PT_INDX(addr) MVP_EXTRACT_FIELD((addr), 20, 12)
+#define ARM_L2PT_COARSE_INDX(addr) MVP_EXTRACT_FIELD((addr), 12, 8)
+/*@}*/
+
+/**
+ * @name Mapping from the VA/PA/MA of a LxD entry to its table index.
+ * @{
+ */
+#define ARM_L1D_PTR_INDX(l1dp) MVP_BITS((uint32)(l1dp), 2, ARM_L1PT_ORDER - 1)
+#define ARM_L2D_PTR_INDX(l2dp) MVP_BITS((uint32)(l2dp), 2, ARM_L2PT_COARSE_ORDER - 1)
+/*@}*/
+
+/**
+ * @name L1D base index <-> MA.
+ * @{
+ */
+#define ARM_L1D_BASE_ADDR(base) ((base) << ARM_L1PT_ORDER)
+#define ARM_L1D_ADDR_BASE(addr) ((addr) >> ARM_L1PT_ORDER)
+/*@}*/
+
+/**
+ * @brief Which 1 MB section of a 16 MB supersection does the given addr lie in?
+ */
+#define ARM_SUPER_SECTION_INDEX(addr) MVP_EXTRACT_FIELD((addr), 20, 4)
+
+/**
+ * @name L1D entry base <-> either MA or MA of a second-level table.
+ * @{
+ */
+#define ARM_L1D_SUPERSECTION_BASE_ADDR(base) ((base) << ARM_L1D_SUPERSECTION_ORDER)
+#define ARM_L1D_SUPERSECTION_ADDR_BASE(addr) ((addr) >> ARM_L1D_SUPERSECTION_ORDER)
+#define ARM_L1D_SECTION_BASE_ADDR(base) ((base) << ARM_L1D_SECTION_ORDER)
+#define ARM_L1D_SECTION_ADDR_BASE(addr) ((addr) >> ARM_L1D_SECTION_ORDER)
+#define ARM_L1D_COARSE_BASE_ADDR(base) ((base) << ARM_L2PT_COARSE_ORDER)
+#define ARM_L1D_COARSE_ADDR_BASE(addr) ((addr) >> ARM_L2PT_COARSE_ORDER)
+#define ARM_L1D_FINE_BASE_ADDR(base) ((base) << ARM_L2PT_FINE_ORDER)
+#define ARM_L1D_FINE_ADDR_BASE(addr) ((addr) >> ARM_L2PT_FINE_ORDER)
+/*@}*/
+
+/*
+ * The number of L1 page directory pages the service the entire
+ * virtual space
+ */
+#define ARM_L1PT_PAGES (1<<(ARM_L1PT_ORDER - PAGE_ORDER))
+
+
+/**
+ * @name Level 2 descriptor type field values.
+ * @{
+ */
+#define ARM_L2D_TYPE_INVALID 0
+#define ARM_L2D_TYPE_LARGE 0
+#define ARM_L2D_TYPE_SMALL 1
+#define ARM_L2D_XTYPE_LARGE 1
+#define ARM_L2D_XTYPE_SMALL 2
+#define ARM_L2D_XTYPE_SMALL_NX 3
+/*@}*/
+
+/**
+ * @name Small/Large L2D (in coarse table) base <-> MA conversion.
+ * @{
+ */
+#define ARM_L2D_LARGE_BASE_ADDR(base) ((base) << ARM_L2D_LARGE_ORDER)
+#define ARM_L2D_LARGE_ADDR_BASE(addr) ((addr) >> ARM_L2D_LARGE_ORDER)
+#define ARM_L2D_SMALL_BASE_ADDR(base) ((base) << ARM_L2D_SMALL_ORDER)
+#define ARM_L2D_SMALL_ADDR_BASE(addr) ((addr) >> ARM_L2D_SMALL_ORDER)
+
+#define ARM_L2D_SMALL_PAGE_NUMBER(addr) ARM_L2D_SMALL_ADDR_BASE(addr)
+#define ARM_L2D_SMALL_PAGE_OFFSET(addr) ((addr) & (PAGE_SIZE - 1))
+/* @}*/
+
+/**
+ * @brief ARM page table descriptor access permissions for the AP field.
+ * @{
+ */
+#define ARM_PERM_NONE 0
+#define ARM_PERM_PRIV_RW 1
+#define ARM_PERM_USER_RO 2
+#define ARM_PERM_USER_RW 3
+/*@}*/
+
+/**
+ * @name Simplified access permission model introduced in ARMv7.
+ *
+ * AP[0] is an access flag, AP[2:1] are one of the following.
+ *
+ * @{
+ */
+#define ARM_SIMPLE_PERM_KERN_RW 0
+#define ARM_SIMPLE_PERM_USER_RW 1
+#define ARM_SIMPLE_PERM_KERN_RO 2
+#define ARM_SIMPLE_PERM_USER_RO 3
+
+#define ARM_SIMPLE_PERM_AP_KERN 1
+#define ARM_SIMPLE_PERM_AP_USER 3
+
+#define ARM_SIMPLE_PERM_APX_RW 0
+#define ARM_SIMPLE_PERM_APX_RO 1
+
+#define ARM_SIMPLE_PERM_AP(x) ((MVP_BIT(x, 0) << 1) | 1)
+#define ARM_SIMPLE_PERM_APX(x) MVP_BIT(x, 1)
+/*@}*/
+
+/**
+ * @name ARM domains.
+ * @{
+ */
+#define ARM_DOMAINS 16
+
+#define ARM_DOMAIN_NOACCESS 0
+#define ARM_DOMAIN_CLIENT 1
+#define ARM_DOMAIN_RESERVED 2
+#define ARM_DOMAIN_MANAGER 3
+/*@}*/
+
+#define ARM_DOMAIN_INDEX(dacr,dom) MVP_EXTRACT_FIELD((dacr), 2*(dom), 2)
+#define ARM_DOMAIN_ACCESS(dom,access) ((access) << (2*(dom)))
+
+/*
+ * Cache-related definitions.
+ */
+#define ARM_CACHE_LEVELS_MAX 8
+#define ARM_CACHE_LINE_SIZE_MAX 2048
+
+#endif /// _MMU_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/mmu_types.h b/arch/arm/mvp/mvpkm/mmu_types.h
new file mode 100644
index 0000000..da8a6fa
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mmu_types.h
@@ -0,0 +1,226 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MMU-related types.
+ */
+
+#ifndef _MMU_TYPES_H_
+#define _MMU_TYPES_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mmu_defs.h"
+
+/**
+ * @brief ARM level 1 page table descriptor. See B3-8 ARM DDI 0406B.
+ */
+typedef union {
+ uint32 u;
+
+ struct {
+ uint32 type : 2;
+ uint32 xx : 30;
+ } x;
+
+ struct {
+ uint32 type : 2;
+ uint32 sbz1 : 1;
+ uint32 ns : 1;
+ uint32 sbz2 : 1;
+ uint32 domain : 4;
+ uint32 imp : 1;
+ uint32 base : 22;
+ } coarse;
+
+ struct {
+ uint32 type : 2;
+ uint32 cb : 2;
+ uint32 xn : 1;
+ uint32 domain : 4;
+ uint32 imp : 1;
+ uint32 ap : 2;
+ uint32 tex : 3;
+ uint32 apx : 1;
+ uint32 s : 1;
+ uint32 ng : 1;
+ uint32 sbz : 1;
+ uint32 ns : 1;
+ uint32 base : 12;
+ } section;
+
+ struct {
+ uint32 type : 2;
+ uint32 cb : 2;
+ uint32 xn : 1;
+ uint32 xbase2 : 4;
+ uint32 imp : 1;
+ uint32 ap : 2;
+ uint32 tex : 3;
+ uint32 apx : 1;
+ uint32 s : 1;
+ uint32 ng : 1;
+ uint32 sbo : 1;
+ uint32 ns : 1;
+ uint32 xbase1 : 4;
+ uint32 base : 8;
+ } supersection;
+} ARM_L1D;
+
+/**
+ * @brief ARM level 2 page table descriptor. See B3-10 ARM DDI 0406B.
+ */
+typedef union {
+ uint32 u;
+
+ struct {
+ uint32 type : 2;
+ uint32 cb : 2;
+ uint32 xx : 28;
+ } x;
+
+ struct {
+ uint32 type : 2;
+ uint32 cb : 2;
+ uint32 ap : 2;
+ uint32 sbz : 3;
+ uint32 apx : 1;
+ uint32 s : 1;
+ uint32 ng : 1;
+ uint32 tex : 3;
+ uint32 xn : 1;
+ uint32 base : 16;
+ } large;
+
+ struct {
+ uint32 xn : 1;
+ uint32 type : 1;
+ uint32 cb : 2;
+ uint32 ap : 2;
+ uint32 tex : 3;
+ uint32 apx : 1;
+ uint32 s : 1;
+ uint32 ng : 1;
+ uint32 base : 20;
+ } small;
+} ARM_L2D;
+
+/**
+ * @brief Get the simplified access permissions from a small L2 descriptor.
+ *
+ * @param l2D value of L2 descriptor.
+ *
+ * @return Simplified access permissions.
+ */
+static inline uint8
+ARM_L2DSimpleAP(ARM_L2D l2D)
+{
+ ASSERT(l2D.small.type == ARM_L2D_TYPE_SMALL);
+ return (l2D.small.apx << 1) | (l2D.small.ap >> 1);
+}
+
+/**
+ * @brief Permissions for a page - intermediate format.
+ */
+typedef struct {
+ uint8 ap : 2;
+ uint8 apx : 1;
+ uint8 xn : 1;
+} ARM_AccessPerms;
+
+/**
+ * @brief ARM domain (0-15).
+ */
+typedef uint8 ARM_Domain;
+
+/**
+ * @brief ARM Domain Access Control Register, see B4.9.4 ARM DDI 0100I.
+ */
+typedef uint32 ARM_DACR;
+
+/**
+ * @brief ARM address space identifier.
+ * 8-bits with an "invalid ASID" value
+ * representation.
+ */
+typedef uint32 ARM_ASID;
+
+#define ARM_INVALID_ASID ((uint32)(-1))
+
+/**
+ * @brief Page shareability property.
+ *
+ * LPAE encoding, see p8 ARM PRD03-GENC-008469 11.0.
+ */
+typedef enum {
+ ARM_SHARE_ATTR_NONE,
+ ARM_SHARE_ATTR_RESERVED,
+ ARM_SHARE_ATTR_OUTER,
+ ARM_SHARE_ATTR_INNER,
+} PACKED ARM_ShareAttr;
+
+/**
+ * @brief Page cacheability property (TEX Remap disabled).
+ *
+ * ARM C/B bits, see B4.4.1 ARM DDI 0100I.
+ */
+typedef enum {
+ ARM_CB_UNBUFFERED = 0,
+ ARM_CB_UNCACHED = 1,
+ ARM_CB_WRITETHROUGH = 2,
+ ARM_CB_WRITEBACK = 3
+} PACKED ARM_CB;
+
+/**
+ * @brief Normal page cacheability property (TEX Remap enabled).
+ *
+ * NMRR encoding, see B3-146 ARM DDI 0406B.
+ */
+typedef enum {
+ ARM_CACHE_ATTR_NORMAL_NONE,
+ ARM_CACHE_ATTR_NORMAL_WB_WALLOC,
+ ARM_CACHE_ATTR_NORMAL_WT,
+ ARM_CACHE_ATTR_NORMAL_WB
+} PACKED ARM_CacheAttrNormal;
+
+/**
+ * @brief Normal page memory attributes.
+ *
+ * Captures the general case of distinct inner/outer cacheability/shareability.
+ * See A3-30 ARM DDI 0406B for a discussion of shareability domains and
+ * cacheability attributes.
+ */
+typedef struct {
+ ARM_ShareAttr share;
+ ARM_CacheAttrNormal innerCache;
+ ARM_CacheAttrNormal outerCache;
+} ARM_MemAttrNormal;
+
+#endif /// _MMU_TYPES_H_
diff --git a/arch/arm/mvp/mvpkm/montimer_kernel.c b/arch/arm/mvp/mvpkm/montimer_kernel.c
new file mode 100644
index 0000000..e2f8ef8
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/montimer_kernel.c
@@ -0,0 +1,102 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MVP host kernel implementation of monitor timers
+ *
+ * The monitor sends requests that are simply a 64-bit absolute time that it
+ * wants a reply. If it changes its mind, it simply sends a different 64-bit
+ * absolute time. It is tolerant of us replying too soon, so if we miss the
+ * update to a later time, it doesn't matter, the monitor will re-send the
+ * request for the later time. The only time we should miss an update to a
+ * sooner time is when we are about to send the reply to the old time anyway,
+ * in which case the monitor sees a reply as quickly as we can generate them,
+ * so no harm there either.
+ */
+
+#include <linux/module.h>
+#include <linux/hrtimer.h>
+
+#include "mvp.h"
+#include "mvp_timer.h"
+#include "actions.h"
+#include "mvpkm_kernel.h"
+
+/**
+ * @brief Linux timer callback
+ * @param timer The linux timer raised
+ * @return Status to not restart the timer
+ */
+static enum hrtimer_restart
+MonitorTimerCB(struct hrtimer *timer)
+{
+ MvpkmVM *vm = container_of(timer, MvpkmVM, monTimer.timer);
+ Mvpkm_WakeGuest(vm, ACTION_TIMER);
+ return HRTIMER_NORESTART;
+}
+
+/**
+ * @brief Initialize vm associated timer
+ * @param vm which virtual machine we're running
+ */
+void
+MonitorTimer_Setup(MvpkmVM *vm)
+{
+ MonTimer *monTimer = &vm->monTimer;
+ monTimer->vm = vm;
+
+ hrtimer_init(&monTimer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ monTimer->timer.function = MonitorTimerCB;
+}
+
+/**
+ * @brief New timer request from monitor
+ * @param monTimer Monitor timer
+ * @param when64 Timer target value
+ */
+void
+MonitorTimer_Request(MonTimer *monTimer, uint64 when64)
+{
+ if (when64) {
+ ktime_t kt;
+
+ /*
+ * Simple conversion, assuming RATE64 is 1e+9
+ */
+ kt = ns_to_ktime(when64);
+ ASSERT_ON_COMPILE(MVP_TIMER_RATE64 == 1000000000);
+
+ /*
+ * Start the timer. If it was already active, it will remove
+ * the previous expiration time. Linux handles correctly timer
+ * with deadline in the past, and forces a safety minimal delta
+ * for closer timer deadlines.
+ */
+ hrtimer_start(&monTimer->timer, kt, HRTIMER_MODE_ABS);
+ } else {
+ /*
+ * Cancel a pending request. If there is none, this will do nothing.
+ * If it's too late, monitor tolerance will forgive us.
+ */
+ hrtimer_cancel(&monTimer->timer);
+ }
+}
diff --git a/arch/arm/mvp/mvpkm/montimer_kernel.h b/arch/arm/mvp/mvpkm/montimer_kernel.h
new file mode 100644
index 0000000..6817a83
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/montimer_kernel.h
@@ -0,0 +1,47 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The monitor-kernel socket interface kernel-only definitions.
+ */
+
+#ifndef _MONITOR_TIMER_KERNEL_H
+#define _MONITOR_TIMER_KERNEL_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include <linux/hrtimer.h>
+
+/**
+ * @brief Monitor Timer structure
+ */
+typedef struct {
+ struct MvpkmVM *vm; ///< Associated vm
+ struct hrtimer timer; ///< Linux timer
+} MonTimer;
+
+void MonitorTimer_Setup(struct MvpkmVM *vm);
+void MonitorTimer_Request(MonTimer *monTimer, uint64 when64);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/monva_common.h b/arch/arm/mvp/mvpkm/monva_common.h
new file mode 100644
index 0000000..de3dd1a
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/monva_common.h
@@ -0,0 +1,106 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Constant definitions that describing the monitor memory layout
+ * (common to both LPV and VE monitors).
+ *
+ */
+
+#ifndef _MONVA_COMMON_H_
+#define _MONVA_COMMON_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mmu_defs.h"
+#include "mmu_types.h"
+
+/*
+ * The monitor occupies a hole in the guest virtual address space.
+ * The following macros define that hole.
+ */
+
+#define MONITOR_VA_START ((MVA)0xE8000000)
+#define MONITOR_VA_LEN 0x03000000
+
+/*
+ * Worldswitch page gets mapped right after the stack guard.
+ */
+#define MONITOR_VA_WORLDSWITCH \
+ ((MVA)(MONITOR_VA_START + 3 * PAGE_SIZE))
+
+#define MONITOR_VA_WORLDSWITCH_CODE \
+ (MONITOR_VA_WORLDSWITCH + PAGE_SIZE)
+
+#define MONITOR_VA_UART \
+ (MONITOR_VA_WORLDSWITCH_CODE + PAGE_SIZE)
+
+/**
+ * @brief Type of physmem region mapping that we want the VMX to know about.
+ * Helps to identify Guest page allocations.
+ */
+typedef enum {
+ MEMREGION_MAINMEM = 1,
+ MEMREGION_MODULE = 2,
+ MEMREGION_WSP = 3,
+ MEMREGION_MONITOR_MISC = 4,
+ MEMREGION_DEFAULT = 0
+} PACKED PhysMem_RegionType;
+
+typedef struct MonVA { /* Note that this struct is VE only */
+ MA l2BaseMA; ///< MA of monitor L2 page table page
+ MVA excVec; ///< Monitor exception vector virtual address
+} MonVA;
+
+/**
+ * @brief Monitor VA mapping type, device or memory.
+ *
+ * These values are used to index HMAIR0 in the VE monitor - do not change
+ * without making the required update to HMAIR0.
+ */
+typedef enum {
+ MVA_MEMORY = 0,
+ MVA_DEVICE = 1
+} MVAType;
+
+/**
+ * @name Monitor types, used in VMX, Mvpkm and monitors.
+ *
+ * This is not a C enumeration, as we may want to use the values in CPP macros.
+ *
+ * @{
+ */
+#define MONITOR_TYPE_LPV 0
+#define MONITOR_TYPE_VE 1
+#define MONITOR_TYPE_UNKNOWN 0xf
+
+typedef uint32 MonitorType;
+/*@}*/
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mutex.h b/arch/arm/mvp/mvpkm/mutex.h
new file mode 100644
index 0000000..30de97d
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mutex.h
@@ -0,0 +1,107 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Common mutex definitions.
+ */
+
+#ifndef _MUTEX_H
+#define _MUTEX_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define MUTEX_CVAR_MAX 2 ///< maximum number of condition variables supported
+ ///< on a given mutex
+
+typedef enum MutexMode MutexMode;
+typedef struct HKWaitQ HKWaitQ;
+typedef struct Mutex Mutex;
+
+/**
+ * @brief modes for locking
+ */
+enum MutexMode {
+ MutexModeSH = 1, ///< minimum value that can be saved in low
+ ///< 16 bits of 'state', ie, it won't allow
+ ///< any other EXs in there without overflowing.
+ ///< it also will block if there are already
+ ///< 0xFFFF other shared accesses, but it should
+ ///< be of little consequence.
+
+ MutexModeEX = 0xFFFF ///< maximum value that can be saved in low
+ ///< 16 bits of 'state', ie, it won't allow
+ ///< any other EXs or SHs in there without
+ ///< overflowing, thus causing a block.
+};
+
+#include "atomic.h"
+
+typedef union Mutex_State {
+ uint32 state; ///< for atomic setting/reading
+ struct {
+ uint16 mode; ///< the sum of mode values of MutexMode
+ uint16 blck; ///< The number of threads blocked
+ };
+} Mutex_State;
+
+/**
+ * @brief shareable mutex struct.
+ */
+struct Mutex {
+ HKVA mtxHKVA; ///< mutex's host kernel virtual address
+ AtmUInt32 state; ///< low 16 bits: # of granted shared accessors
+ ///< or FFFF if granted exclusive
+ ///< high 16 bits: # of blocked threads
+ AtmUInt32 waiters; ///< number of threads on all condWaitQs
+ ///< ... increment only with mutex locked EX
+ ///< ... decrement any time
+ AtmUInt32 blocked; ///< number times blocked (stats only)
+ HKVA lockWaitQ; ///< threads blocked for mutex to be unlocked
+ HKVA cvarWaitQs[MUTEX_CVAR_MAX]; ///< condition variables
+ /*
+ * Padding to keep binary compatibility @see{MVP-1876}
+ * These padding bytes can be used for debugging.
+ */
+ int line;
+ int lineUnl;
+ uint32 pad3;
+ uint32 pad4;
+ uint32 pad5;
+ uint32 pad6;
+};
+
+#define Mutex_Lock(a, b) Mutex_LockLine(a, b, __FILE__, __LINE__)
+#define Mutex_Unlock(a, b) Mutex_UnlockLine(a, b, __LINE__)
+#define Mutex_UnlSleep(a, b, c) Mutex_UnlSleepLine(a, b, c, __FILE__, __LINE__)
+#define Mutex_UnlSleepTest(a, b, c, d, e) Mutex_UnlSleepTestLine(a, b, c, d, e, __FILE__, __LINE__)
+int Mutex_LockLine(Mutex *mutex, MutexMode mode, const char *file, int line);
+void Mutex_UnlockLine(Mutex *mutex, MutexMode mode, int line);
+int Mutex_UnlSleepLine(Mutex *mutex, MutexMode mode, uint32 cvi, const char *file, int line);
+int Mutex_UnlSleepTestLine(Mutex *mutex, MutexMode mode, uint32 cvi, AtmUInt32 *test, uint32 mask, const char *file, int line);
+void Mutex_UnlWake(Mutex *mutex, MutexMode mode, uint32 cvi, _Bool all);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mutex_kernel.c b/arch/arm/mvp/mvpkm/mutex_kernel.c
new file mode 100644
index 0000000..7b76bfcf
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mutex_kernel.c
@@ -0,0 +1,480 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The host kernel mutex functions. These mutexes can be located in
+ * shared address space with the monitor.
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/string.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/hardirq.h>
+
+#include "mvp.h"
+
+#include "arm_inline.h"
+#include "coproc_defs.h"
+#include "mutex_kernel.h"
+
+#define POLL_IN_PROGRESS_FLAG (1<<(30-MUTEX_CVAR_MAX))
+
+#define INITWAITQ(waitQ) do { \
+ init_waitqueue_head((wait_queue_head_t *)(waitQ)); \
+} while (0)
+
+#define WAKEUPALL(waitQ) do { \
+ wake_up_all((wait_queue_head_t *)(waitQ)); \
+} while (0)
+
+#define WAKEUPONE(waitQ) do { \
+ wake_up((wait_queue_head_t *)(waitQ)); \
+} while (0)
+
+/**
+ * @brief initialize mutex
+ * @param[in,out] mutex mutex to initialize
+ */
+void
+Mutex_Init(Mutex *mutex)
+{
+ wait_queue_head_t *wq;
+ int i;
+
+ wq = kcalloc(MUTEX_CVAR_MAX + 1, sizeof(wait_queue_head_t), 0);
+ FATAL_IF(wq == NULL);
+
+ memset(mutex, 0, sizeof *mutex);
+ mutex->mtxHKVA = (HKVA)mutex;
+ mutex->lockWaitQ = (HKVA)&wq[0];
+ INITWAITQ(mutex->lockWaitQ);
+ for (i = 0; i < MUTEX_CVAR_MAX; i ++) {
+ mutex->cvarWaitQs[i] = (HKVA)&wq[i + 1];
+ INITWAITQ(mutex->cvarWaitQs[i]);
+ }
+}
+
+/**
+ * @brief Check if it is ok to sleep
+ * @param file the file of the caller code
+ * @param line the line number of the caller code
+ */
+static void
+MutexCheckSleep(const char *file, int line)
+{
+#ifdef MVP_DEVEL
+ static unsigned long prev_jiffy; /* ratelimiting: 1/s */
+
+#ifdef CONFIG_PREEMPT
+ if (preemptible() && !irqs_disabled()) {
+ return;
+ }
+#else
+ if (!irqs_disabled()) {
+ return;
+ }
+#endif
+ if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) {
+ return;
+ }
+ prev_jiffy = jiffies;
+ printk(KERN_ERR
+ "BUG: sleeping function called from invalid context at %s:%d\n",
+ file, line);
+ printk(KERN_ERR
+ "irqs_disabled(): %d, preemtible(): %d, pid: %d, name: %s\n",
+ irqs_disabled(),
+ preemptible(),
+ current->pid, current->comm);
+ dump_stack();
+#endif
+}
+
+/**
+ * @brief destroy mutex
+ * @param[in,out] mutex mutex to destroy
+ */
+void
+Mutex_Destroy(Mutex *mutex)
+{
+ kfree((void*)mutex->lockWaitQ);
+}
+
+/**
+ * @brief Lock the mutex. Also does a data barrier after locking so the
+ * locking is complete before any shared data is accessed.
+ * @param[in,out] mutex which mutex to lock
+ * @param mode mutex lock mode
+ * @param file the file of the caller code
+ * @param line the line number of the code that called this function
+ * @return rc = 0: mutex now locked by caller<br>
+ * < 0: interrupted
+ */
+int
+Mutex_LockLine(Mutex *mutex, MutexMode mode, const char *file, int line)
+{
+ Mutex_State newState, oldState;
+
+ MutexCheckSleep(file, line);
+
+ /*
+ * If uncontended, just set new lock state and return success status.
+ * If contended, mark state saying there is a waiting thread to wake.
+ */
+ do {
+lock_start:
+ /*
+ * Get current state and calculate what new state would be.
+ * New state adds 1 for shared and 0xFFFF for exclusive.
+ * If the 16 bit field overflows, there is contention.
+ */
+ oldState.state = ATOMIC_GETO(mutex->state);
+ newState.mode = oldState.mode + mode;
+ newState.blck = oldState.blck;
+
+ /*
+ * So we are saying there is no contention if new state
+ * indicates no overflow.
+ *
+ * On fairness: The test here allows a new-comer thread to grab
+ * the lock even if there is a blocked thread. For example 2
+ * threads repeatedly obtaining shared access can starve a third
+ * wishing to obtain an exclusive lock. Currently this is only a
+ * hypothetical situation as mksck use exclusive lock only and
+ * the code never has more than 2 threads using the same mutex.
+ */
+ if ((uint32)newState.mode >= (uint32)mode) {
+ if (!ATOMIC_SETIF(mutex->state, newState.state, oldState.state)) {
+ goto lock_start;
+ }
+ DMB();
+ mutex->line = line;
+ mutex->lineUnl = -1;
+ return 0;
+ }
+
+ /*
+ * There is contention, so increment the number of blocking threads.
+ */
+ newState.mode = oldState.mode;
+ newState.blck = oldState.blck + 1;
+ } while (!ATOMIC_SETIF(mutex->state, newState.state, oldState.state));
+
+ /*
+ * Statistics...
+ */
+ ATOMIC_ADDV(mutex->blocked, 1);
+
+ /*
+ * Mutex is contended, state has been updated to say there is a blocking
+ * thread.
+ *
+ * So now we block till someone wakes us up.
+ */
+ do {
+ DEFINE_WAIT(waiter);
+
+ /*
+ * This will make sure we catch any wakes done after we check the lock
+ * state again.
+ */
+ prepare_to_wait((wait_queue_head_t *)mutex->lockWaitQ,
+ &waiter,
+ TASK_INTERRUPTIBLE);
+
+ /*
+ * Now that we will catch wakes, check the lock state again. If now
+ * uncontended, mark it locked, abandon the wait and return success.
+ */
+
+set_new_state:
+ /*
+ * Same as the original check for contention above, except that we
+ * must decrement the number of waiting threads by one
+ * if we are successful in locking the mutex.
+ */
+ oldState.state = ATOMIC_GETO(mutex->state);
+ newState.mode = oldState.mode + mode;
+ newState.blck = oldState.blck - 1;
+ ASSERT(oldState.blck);
+
+ if ((uint32)newState.mode >= (uint32)mode) {
+ if (!ATOMIC_SETIF(mutex->state, newState.state, oldState.state)) {
+ goto set_new_state;
+ }
+ /*
+ * Mutex is no longer contended and we were able to lock it.
+ */
+ finish_wait((wait_queue_head_t *)mutex->lockWaitQ, &waiter);
+ DMB();
+ mutex->line = line;
+ mutex->lineUnl = -1;
+ return 0;
+ }
+
+ /*
+ * Wait for a wake that happens any time after prepare_to_wait()
+ * returned.
+ */
+ WARN(!schedule_timeout(10*HZ), "Mutex_Lock: soft lockup - stuck for 10s!\n");
+ finish_wait((wait_queue_head_t *)mutex->lockWaitQ, &waiter);
+ } while (!signal_pending(current));
+
+ /*
+ * We aren't waiting anymore, so decrement the number of waiting threads.
+ */
+ do {
+ oldState.state = ATOMIC_GETO(mutex->state);
+ newState.mode = oldState.mode;
+ newState.blck = oldState.blck - 1;
+
+ ASSERT(oldState.blck);
+
+ } while (!ATOMIC_SETIF(mutex->state, newState.state, oldState.state));
+
+ return -ERESTARTSYS;
+}
+
+
+/**
+ * @brief Unlock the mutex. Also does a data barrier before unlocking so any
+ * modifications made before the lock gets released will be completed
+ * before the lock is released.
+ * @param mutex as passed to Mutex_Lock()
+ * @param mode as passed to Mutex_Lock()
+ * @param line the line number of the code that called this function
+ */
+void
+Mutex_UnlockLine(Mutex *mutex, MutexMode mode, int line)
+{
+ Mutex_State newState, oldState;
+
+ DMB();
+ do {
+ oldState.state = ATOMIC_GETO(mutex->state);
+ newState.mode = oldState.mode - mode;
+ newState.blck = oldState.blck;
+ mutex->lineUnl = line;
+
+ ASSERT(oldState.mode >= mode);
+ } while (!ATOMIC_SETIF(mutex->state, newState.state, oldState.state));
+
+ /*
+ * If another thread was blocked, then wake it up.
+ */
+ if (oldState.blck) {
+ if (mode == MutexModeSH) {
+ WAKEUPONE(mutex->lockWaitQ);
+ } else {
+ WAKEUPALL(mutex->lockWaitQ);
+ }
+ }
+}
+
+
+/**
+ * @brief Unlock the mutex and sleep. Also does a data barrier before
+ * unlocking so any modifications made before the lock gets released
+ * will be completed before the lock is released.
+ * @param mutex as passed to Mutex_Lock()
+ * @param mode as passed to Mutex_Lock()
+ * @param cvi which condition variable to sleep on
+ * @param file the file of the caller code
+ * @param line the line number of the caller code
+ * @return rc = 0: successfully waited<br>
+ * < 0: error waiting
+ */
+int
+Mutex_UnlSleepLine(Mutex *mutex, MutexMode mode, uint32 cvi, const char *file, int line)
+{
+ return Mutex_UnlSleepTestLine(mutex, mode, cvi, NULL, 0, file, line);
+}
+
+/**
+ * @brief Unlock the mutex and sleep. Also does a data barrier before
+ * unlocking so any modifications made before the lock gets released
+ * will be completed before the lock is released.
+ * @param mutex as passed to Mutex_Lock()
+ * @param mode as passed to Mutex_Lock()
+ * @param cvi which condition variable to sleep on
+ * @param test sleep only if null or pointed atomic value mismatches mask
+ * @param mask bitfield to check test against before sleeping
+ * @param file the file of the caller code
+ * @param line the line number of the caller code
+ * @return rc = 0: successfully waited<br>
+ * < 0: error waiting
+ */
+int
+Mutex_UnlSleepTestLine(Mutex *mutex, MutexMode mode, uint32 cvi, AtmUInt32 *test, uint32 mask, const char *file, int line)
+{
+ DEFINE_WAIT(waiter);
+
+ MutexCheckSleep(file, line);
+
+ ASSERT(cvi < MUTEX_CVAR_MAX);
+
+ /*
+ * Tell anyone who might try to wake us that they need to actually call
+ * WAKEUP***().
+ */
+ ATOMIC_ADDV(mutex->waiters, 1);
+
+ /*
+ * Be sure to catch any wake that comes along just after we unlock the mutex
+ * but before we call schedule().
+ */
+ prepare_to_wait_exclusive((wait_queue_head_t *)mutex->cvarWaitQs[cvi],
+ &waiter,
+ TASK_INTERRUPTIBLE);
+
+ /*
+ * Release the mutex, someone can wake us up now.
+ * They will see mutex->waiters non-zero so will actually do the wake.
+ */
+ Mutex_Unlock(mutex, mode);
+
+ /*
+ * Wait to be woken or interrupted.
+ */
+ if (test == NULL || (ATOMIC_GETO(*test) & mask) == 0) {
+ schedule();
+ }
+ finish_wait((wait_queue_head_t *)mutex->cvarWaitQs[cvi], &waiter);
+
+ /*
+ * Done waiting, don't need a wake any more.
+ */
+ ATOMIC_SUBV(mutex->waiters, 1);
+
+ /*
+ * If interrupted, return error status.
+ */
+ if (signal_pending(current)) {
+ return -ERESTARTSYS;
+ }
+
+ /*
+ * Wait completed, return success status.
+ */
+ return 0;
+}
+
+
+/**
+ * @brief Unlock the mutex and prepare to sleep on a kernel polling table
+ * given as anonymous parameters for poll_wait
+ * @param mutex as passed to Mutex_Lock()
+ * @param mode as passed to Mutex_Lock()
+ * @param cvi which condition variable to sleep on
+ * @param filp which file to poll_wait upon
+ * @param wait which poll_table to poll_wait upon
+ */
+void
+Mutex_UnlPoll(Mutex *mutex, MutexMode mode, uint32 cvi, void *filp, void *wait)
+{
+ ASSERT(cvi < MUTEX_CVAR_MAX);
+
+ /* poll_wait is done with mutex locked to prevent any wake that comes and
+ * defer them just after we unlock the mutex but before kernel polling
+ * tables are used
+ * Note that the kernel is probably avoiding an exclusive wait in that case
+ * and also increments the usage for the file given in filp
+ */
+ poll_wait(filp, (wait_queue_head_t *)mutex->cvarWaitQs[cvi], wait);
+
+ /*
+ * Tell anyone who might try to wake us that they need to actually call
+ * WAKEUP***(). This is done in putting ourselves in a "noisy" mode since
+ * there is no guaranty that we would really sleep, or if we would be
+ * wakening the sleeping thread with that socket or condition. This is
+ * done using a POLL_IN_PROGRESS_FLAG, but unfortunately it has to be
+ * a per-cvi flag, in case we would poll independently on different cvi
+ */
+ DMB();
+ ATOMIC_ORO(mutex->waiters, (POLL_IN_PROGRESS_FLAG << cvi));
+
+ /*
+ * Release the mutex, someone can wake us up now.
+ * They will see mutex->waiters non-zero so will actually do the wake.
+ */
+ Mutex_Unlock(mutex, mode);
+}
+
+
+/**
+ * @brief Unlock the semaphore and wake sleeping threads. Also does a data
+ * barrier before unlocking so any modifications made before the lock
+ * gets released will be completed before the lock is released.
+ * @param mutex as passed to Mutex_Lock()
+ * @param mode as passed to Mutex_Lock()
+ * @param cvi which condition variable to signal
+ * @param all false: wake a single thread<br>
+ * true: wake all threads
+ */
+void
+Mutex_UnlWake(Mutex *mutex, MutexMode mode, uint32 cvi, _Bool all)
+{
+ Mutex_Unlock(mutex, mode);
+ Mutex_CondSig(mutex, cvi, all);
+}
+
+
+/**
+ * @brief Signal condition variable, ie, wake up anyone waiting.
+ * @param mutex mutex that holds the condition variable
+ * @param cvi which condition variable to signal
+ * @param all false: wake a single thread<br>
+ * true: wake all threads
+ */
+void
+Mutex_CondSig(Mutex *mutex, uint32 cvi, _Bool all)
+{
+ uint32 waiters;
+
+ ASSERT(cvi < MUTEX_CVAR_MAX);
+
+ waiters = ATOMIC_GETO(mutex->waiters);
+ if (waiters != 0) {
+ /* Cleanup the effects of Mutex_UnlPoll() but only when it is SMP safe,
+ * considering that atomic and wakeup operations should also do memory
+ * barriers accordingly. This is mandatory otherwise rare SMP races are
+ * even possible, since Mutex_CondSig is called with the associated mutex
+ * unlocked, and that does not prevent from select() to run parallel !
+ */
+ if ((waiters >= POLL_IN_PROGRESS_FLAG) &&
+ !waitqueue_active((wait_queue_head_t *)mutex->cvarWaitQs[cvi])) {
+ ATOMIC_ANDO(mutex->waiters, ~(POLL_IN_PROGRESS_FLAG << cvi));
+ }
+ DMB();
+
+ if (all) {
+ WAKEUPALL(mutex->cvarWaitQs[cvi]);
+ } else {
+ WAKEUPONE(mutex->cvarWaitQs[cvi]);
+ }
+ }
+}
diff --git a/arch/arm/mvp/mvpkm/mutex_kernel.h b/arch/arm/mvp/mvpkm/mutex_kernel.h
new file mode 100644
index 0000000..4bdf0e1
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mutex_kernel.h
@@ -0,0 +1,41 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The host kernel mutex definitions.
+ */
+
+#ifndef _MUTEX_KERNEL_H
+#define _MUTEX_KERNEL_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mutex.h"
+
+void Mutex_Init(Mutex *mutex);
+void Mutex_Destroy(Mutex *mutex);
+void Mutex_CondSig(Mutex *mutex, uint32 cvi, _Bool all);
+void Mutex_UnlPoll(Mutex *mutex, MutexMode mode, uint32 cvi, void *filp, void *wait);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvp.h b/arch/arm/mvp/mvpkm/mvp.h
new file mode 100644
index 0000000..e21b8a0
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp.h
@@ -0,0 +1,48 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief top-level include for all basic includes.
+ * This file should not define anything of its own.
+ */
+
+#ifndef _MVP_H
+#define _MVP_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "mvp_compiler.h"
+#include "utils.h"
+#include "mvp_assert.h"
+#include "mvp_types.h"
+#include "platdefx.h"
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvp_assert.h b/arch/arm/mvp/mvpkm/mvp_assert.h
new file mode 100644
index 0000000..9ee6fc0
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_assert.h
@@ -0,0 +1,125 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief ASSERT() and related macros.
+ */
+
+#ifndef _MVP_ASSERT_H
+#define _MVP_ASSERT_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define ASSERT(_x) ASSERT_BUG((_x),0)
+
+#ifndef NDEBUG
+#define ASSERT_BUG(_x,_tkt) do { \
+ if (UNLIKELY(!(_x))) { \
+ FatalError(__FILE__, __LINE__, FECodeAssert, _tkt, NULL); \
+ } \
+} while (0)
+
+#define ASSERTF(_x, ...) do { \
+ if (UNLIKELY(!(_x))) { \
+ FatalError(__FILE__, \
+ __LINE__, \
+ FECodeAssert, \
+ 0, \
+ __VA_ARGS__); \
+ } \
+} while (0)
+#else
+
+#define ASSERT_BUG(_x,_tkt) (void)sizeof((int)(_x))
+#define ASSERTF(_x, ...) ASSERT_BUG(_x, 0)
+
+#endif
+
+/*
+ * Compile-time assertions.
+ *
+ * ASSERT_ON_COMPILE does not use the common
+ * switch (0) { case 0: case (e): ; } trick because some compilers (e.g. MSVC)
+ * generate code for it.
+ *
+ * The implementation uses both enum and typedef because the typedef alone is
+ * insufficient; gcc allows arrays to be declared with non-constant expressions
+ * (even in typedefs, where it makes no sense).
+ */
+#ifdef __COVERITY__
+#define ASSERT_ON_COMPILE(e) ASSERT(e)
+#else
+#define ASSERT_ON_COMPILE(e) \
+ do { \
+ enum { AssertOnCompileMisused = ((e) ? 1 : -1) }; \
+ typedef char AssertOnCompileFailed[AssertOnCompileMisused]; \
+ } while (0)
+#endif
+
+/*
+ * To put an ASSERT_ON_COMPILE() outside a function, wrap it
+ * in MY_ASSERTS(). The first parameter must be unique in
+ * each .c file where it appears. For example,
+ *
+ * MY_ASSERTS(FS3_INT,
+ * ASSERT_ON_COMPILE(sizeof(FS3_DiskLock) == 128);
+ * ASSERT_ON_COMPILE(sizeof(FS3_DiskLockReserved) == DISK_BLOCK_SIZE);
+ * ASSERT_ON_COMPILE(sizeof(FS3_DiskBlock) == DISK_BLOCK_SIZE);
+ * ASSERT_ON_COMPILE(sizeof(Hardware_DMIUUID) == 16);
+ * )
+ *
+ * Caution: ASSERT() within MY_ASSERTS() is silently ignored.
+ * The same goes for anything else not evaluated at compile time.
+ */
+
+#define MY_ASSERTS(name, assertions) \
+ static inline void name(void) { \
+ assertions \
+ }
+
+#define KNOWN_BUG(_tkt)
+
+#define NOT_IMPLEMENTED() NOT_IMPLEMENTED_JIRA(0)
+#define NOT_IMPLEMENTED_JIRA(_tkt,...) FatalError(__FILE__, __LINE__, FECodeNI, _tkt, NULL)
+
+#define NOT_IMPLEMENTED_IF(_x) NOT_IMPLEMENTED_IF_JIRA((_x),0)
+#define NOT_IMPLEMENTED_IF_JIRA(_x,_tkt,...) do { if (UNLIKELY(_x)) NOT_IMPLEMENTED_JIRA(_tkt); } while (0)
+/*
+ * All sites tagged with this are @knownjira{MVP-1855}.
+ */
+#define NOT_IMPLEMENTEDF(...) FatalError(__FILE__, __LINE__, FECodeNI, 0, __VA_ARGS__)
+
+#define NOT_REACHED() FatalError(__FILE__, __LINE__, FECodeNR, 0, NULL)
+
+#include "fatalerror.h"
+#include "nottested.h"
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvp_balloon.h b/arch/arm/mvp/mvpkm/mvp_balloon.h
new file mode 100644
index 0000000..9df5669
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_balloon.h
@@ -0,0 +1,217 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Common guest/host balloon state machine.
+ */
+#ifndef _MVP_BALLOON_H
+#define _MVP_BALLOON_H
+
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_MODULE
+#include "include_check.h"
+
+/**
+ * @brief Balloon watchdog timeout (in seconds).
+ *
+ * If we don't hear back from the guest balloon driver in this amount of time,
+ * we terminate the guest.
+ *
+ * This can sound arbitrary long but we need to deal with checkpointing. The
+ * watchdog goal is only to not let not-responding VM running for ages.
+ */
+#define BALLOON_WATCHDOG_TIMEOUT_SECS 90
+
+/**
+ * @brief MVP_BALLOON_GET_DELTA return.
+ */
+typedef union {
+ struct {
+ int32 delta : 21; ///< Number/direction balloon adjustment in pages.
+ };
+ uint32 u;
+} Balloon_GetDeltaRet;
+
+/**
+ * @name Guest settings for lowmemorykiller oom_adj and minfree thresholds, as reflected in
+ * the guest's /sys/module/lowmemorykiller/parameters/{minfree,adj}.
+ *
+ * @{
+ */
+
+/**
+ * @brief Android oom_adj levels for the various thresholds.
+ */
+typedef enum {
+ BALLOON_ANDROID_GUEST_OOM_ADJ_FOREGROUND_APP = 0,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_VISIBLE_APP = 1,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_SECONDARY_SERVER = 2,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_BACKUP_APP = 2,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_HOME_APP = 4,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_HIDDEN_APP_MIN = 7,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_CONTENT_PROVIDER = 14,
+ BALLOON_ANDROID_GUEST_OOM_ADJ_EMPTY_APP = 15
+} Balloon_AndroidGuestOOMAdj;
+
+/**
+ * @brief Android low memory killer thresholds (in pages).
+ */
+typedef enum {
+ BALLOON_ANDROID_GUEST_MIN_FREE_FOREGROUND_APP_PAGES = 1536,
+ BALLOON_ANDROID_GUEST_MIN_FREE_VISIBLE_APP_PAGES = 2048,
+ BALLOON_ANDROID_GUEST_MIN_FREE_SECONDARY_SERVER_PAGES = 4096,
+ BALLOON_ANDROID_GUEST_MIN_FREE_BACKUP_APP_PAGES = 4096,
+ BALLOON_ANDROID_GUEST_MIN_FREE_HOME_APP_PAGES = 4096,
+ BALLOON_ANDROID_GUEST_MIN_FREE_HIDDEN_APP_PAGES = 5120,
+ BALLOON_ANDROID_GUEST_MIN_FREE_CONTENT_PROVIDER_PAGES = 5632,
+ BALLOON_ANDROID_GUEST_MIN_FREE_EMPTY_APP_MEM_PAGES = 6144
+} Balloon_AndroidGuestMinFreePages;
+
+/* @} */
+/**
+ * @brief Calculate distance to the point at which Android will terminate
+ * processes.
+ *
+ * In the balloon policy we strive to maintain the low memory killer minfree
+ * value (e.g. max(freePages, filePages)) above the threshold for terminating
+ * empty apps (as per the Android low memory killer's logic). Here we measure
+ * the number of pages we have buffering us from this point.
+ *
+ * We chose the empty app threshold instead instead of the home app threshold,
+ * the threshold we ultimately want to avoid crossing for two reasons:
+ * - We want to avoid any error introduced by the use of max(free, file) when
+ * between the two thresholds from interfering with the errorBackground term
+ * in the balloon policy. If we instead measure the distance to the home app
+ * threshold, we can get into the situation that even when both sides have
+ * balanced background pages and the same low memory distance, different
+ * free/file ratios in the two worlds introduces a further bias.
+ * - It's helpful in avoiding extreme situations where the balloon won't be able
+ * to adapt quickly to leave a buffer. With empty app minfree as the target,
+ * when background pages drops to zero, and both worlds are below the empty
+ * app minfree target, the balloon will stop adjusting, leaving each world to
+ * fend for itself. At this point, the worlds have a maximum of 8192 pages
+ * (using the above logic) until they start killing services and foreground
+ * apps, which seems like a reasonable buffer to have in place. Another way of
+ * putting it is that at this point, we are unsure that rebalancing the
+ * balloon won't harm the side it balances against by eating into its buffer.
+ *
+ * We assume that normally filePages only decreases as a result of freePages
+ * being close to zero, when vmscan reclaiming kicks in. Based on this,
+ * there are two cases when computing the distance.
+ *
+ * - filePages >= emptyAppPages:
+ * freePages + filePages - emptyAppPages
+ * - filePages < emptyAppPages:
+ * MAX(0, freePages - emptyAppPages)
+ *
+ * @param freePages number of free pages.
+ * @param filePages number of pages in the page cache.
+ * @param emptyAppPages number of free/file pages at which the
+ * lowmemorykiller will start killing empty apps.
+ *
+ * @return Low memory distance measure (in pages).
+ */
+static inline uint32
+Balloon_LowMemDistance(uint32 freePages, uint32 filePages, uint32 emptyAppPages)
+{
+ return filePages >= emptyAppPages ?
+ freePages + (filePages - emptyAppPages) :
+ (freePages > emptyAppPages ? freePages - emptyAppPages : 0);
+}
+
+#ifdef __KERNEL__
+/**
+ * @brief Obtain approximation of # anonymous pages belonging to Android
+ * background processes.
+ *
+ * Used to inform balloon policy. Note that this is a coarse approximation only,
+ * since we use RSS. More precise accounting is possible but potentially costly
+ * as it's not available directly in the task struct.
+ *
+ * @param hiddenAppOOMAdj minimum oom_adj for hidden apps.
+ *
+ * @return sum of empty, content provider and hidden app anon resident pages.
+ */
+static uint32
+Balloon_AndroidBackgroundPages(uint32 minHiddenAppOOMAdj)
+{
+ uint32 backgroundPages = 0, nonBackgroundPages = 0;
+ struct task_struct *t;
+
+ /*
+ * Traverse the tasklist to replicate the behavior of the Android low memory
+ * killer.
+ */
+ rcu_read_lock();
+
+ for_each_process(t) {
+ int oom_adj = 0;
+
+ task_lock(t);
+
+ if (t->signal == NULL) {
+ task_unlock(t);
+ continue;
+ } else {
+ oom_adj = t->signal->oom_adj;
+ }
+
+ if (t->mm != NULL) {
+#ifdef BALLOON_DEBUG_PRINT_ANDROID_PAGES
+ printk("Balloon_AndroidBackgroundPages: %d %d %s\n",
+ oom_adj,
+ (int)get_mm_counter(t->mm, MM_ANONPAGES),
+ t->comm);
+#endif
+
+ if (oom_adj >= (int)minHiddenAppOOMAdj) {
+ /*
+ * Unlike the Android low memory killer, we only consider anonymous
+ * memory here, since we already account for file pages in the
+ * balloon policy using global_page_state(NR_FILE_PAGES).
+ */
+ backgroundPages += get_mm_counter(t->mm, MM_ANONPAGES);
+ } else {
+ nonBackgroundPages += get_mm_counter(t->mm, MM_ANONPAGES);
+ }
+ }
+
+ task_unlock(t);
+ }
+
+ rcu_read_unlock();
+
+#ifdef BALLOON_DEBUG_PRINT_ANDROID_PAGES
+ printk("Balloon_AndroidBackgroundPages: non-background pages: %d "
+ "background pages: %d\n",
+ nonBackgroundPages,
+ backgroundPages);
+#endif
+
+ return backgroundPages;
+}
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvp_compiler.h b/arch/arm/mvp/mvpkm/mvp_compiler.h
new file mode 100644
index 0000000..58825a0
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_compiler.h
@@ -0,0 +1,56 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Compiler-related definitions and directives.
+ */
+
+#ifndef _MVP_COMPILER_H_
+#define _MVP_COMPILER_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#ifdef __GNUC__
+#include "mvp_compiler_gcc.h"
+#else /* __GNUC__ */
+#include "mvp_compiler_other.h"
+#endif /* __GNUC__ */
+
+/**
+ * @brief Find last set bit.
+ *
+ * @param n unsigned 32-bit integer.
+ *
+ * @return 0 if n == 0 otherwise 32 - the number of leading zeroes in n.
+ */
+#define FLS(n) (32 - CLZ(n))
+
+#endif /// ifndef _MVP_COMPILER_H_
diff --git a/arch/arm/mvp/mvpkm/mvp_compiler_gcc.h b/arch/arm/mvp/mvpkm/mvp_compiler_gcc.h
new file mode 100644
index 0000000..ab35ebd
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_compiler_gcc.h
@@ -0,0 +1,87 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief common definitions for GCC
+ */
+
+#ifndef _MVP_COMPILER_GCC_H
+#define _MVP_COMPILER_GCC_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @brief Count leading zeroes.
+ *
+ * @param n unsigned 32-bit integer.
+ *
+ * @return 32 if n == 0 otherwise 31 - the bit position of the most significant 1
+ * in n.
+ */
+#ifdef __COVERITY__
+static inline int
+CLZ(unsigned int n)
+{
+ unsigned int r = 0;
+
+ while (n) {
+ r++;
+ n >>= 1;
+ }
+
+ return 32 - r;
+}
+#else
+#define CLZ(n) __builtin_clz(n)
+#endif
+
+#define PACKED __attribute__ ((packed))
+#define ALLOC __attribute__ ((malloc, warn_unused_result))
+#define UNUSED __attribute__ ((unused))
+#define PURE __attribute__ ((pure))
+#define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+#define FORMAT(x,y,z) __attribute__ ((format(x,y,z)))
+#define LIKELY(x) __builtin_expect(!!(x), 1)
+#define UNLIKELY(x) __builtin_expect((x), 0)
+
+/*
+ * For debug builds, we want to omit __attribute__((noreturn)) so that gcc will
+ * keep stack linkages and then we will have useful core dumps. For non-debug
+ * builds, we don't care about the stack frames and want the little bit of
+ * optimization that noreturn gives us.
+ */
+#if defined(__COVERITY__) || !defined(MVP_DEBUG)
+#define NORETURN __attribute__((noreturn))
+#else
+#define NORETURN
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvp_math.h b/arch/arm/mvp/mvpkm/mvp_math.h
new file mode 100644
index 0000000..7017bc8
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_math.h
@@ -0,0 +1,133 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Math library.
+ */
+
+#ifndef _MVP_MATH_H_
+#define _MVP_MATH_H_
+
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_HOSTUSER
+#include "include_check.h"
+
+#include "mvp_compiler_gcc.h"
+
+/**
+ * @brief Compute floor log2 of a given 32-bit unsigned integer.
+ *
+ * @param n 32-bit unsigned integer, n > 0.
+ *
+ * @return floor(log2(n)).
+ */
+#define LOG2(n) \
+( \
+ __builtin_constant_p(n) ? ( \
+ (n) & (1UL << 31) ? 31 : \
+ (n) & (1UL << 30) ? 30 : \
+ (n) & (1UL << 29) ? 29 : \
+ (n) & (1UL << 28) ? 28 : \
+ (n) & (1UL << 27) ? 27 : \
+ (n) & (1UL << 26) ? 26 : \
+ (n) & (1UL << 25) ? 25 : \
+ (n) & (1UL << 24) ? 24 : \
+ (n) & (1UL << 23) ? 23 : \
+ (n) & (1UL << 22) ? 22 : \
+ (n) & (1UL << 21) ? 21 : \
+ (n) & (1UL << 20) ? 20 : \
+ (n) & (1UL << 19) ? 19 : \
+ (n) & (1UL << 18) ? 18 : \
+ (n) & (1UL << 17) ? 17 : \
+ (n) & (1UL << 16) ? 16 : \
+ (n) & (1UL << 15) ? 15 : \
+ (n) & (1UL << 14) ? 14 : \
+ (n) & (1UL << 13) ? 13 : \
+ (n) & (1UL << 12) ? 12 : \
+ (n) & (1UL << 11) ? 11 : \
+ (n) & (1UL << 10) ? 10 : \
+ (n) & (1UL << 9) ? 9 : \
+ (n) & (1UL << 8) ? 8 : \
+ (n) & (1UL << 7) ? 7 : \
+ (n) & (1UL << 6) ? 6 : \
+ (n) & (1UL << 5) ? 5 : \
+ (n) & (1UL << 4) ? 4 : \
+ (n) & (1UL << 3) ? 3 : \
+ (n) & (1UL << 2) ? 2 : \
+ (n) & (1UL << 1) ? 1 : \
+ (n) & (1UL << 0) ? 0 : \
+ 0xffffffff \
+ ) : (uint32)(CLZ(1) - CLZ(n)) \
+)
+
+/**
+ * @brief Multiplicative hash function for 32-bit key and p-bit range. See p229
+ * Introduction to Algorithms, Cormen, Leiserson and Rivest, 1996.
+ *
+ * @param key 32-bit key.
+ * @param p range order, <= 32.
+ *
+ * @return hash value in range [0..2^p)
+ */
+static inline uint32
+Math_MultiplicativeHash(uint32 key, uint32 p)
+{
+ return (key * 2654435769UL) >> (32 - p);
+}
+
+/**
+ * @brief Compute ceiling log2 of a given 32-bit unsigned integer.
+ *
+ * @param n 32-bit unsigned integer, n > 0.
+ *
+ * @return ceiling(log2(n)).
+ */
+static inline uint32 CLOG2(uint32 n)
+{
+ return LOG2(n) + ((n & -n) != n);
+}
+
+
+/**
+ * @brief djb2 String hashing function by Dan Bernstein, see
+ * http://www.cse.yorku.ca/~oz/hash.html
+ * @param str String to hash
+ * @return 32-bit hash value
+ */
+static inline
+uint32 Math_Djb2Hash(uint8 *str)
+{
+ uint32 hash = 5381;
+ int32 c;
+
+ while ((c = *str++)) {
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ }
+
+ return hash;
+}
+
+#endif // ifndef _MVP_MATH_H_
diff --git a/arch/arm/mvp/mvpkm/mvp_timer.h b/arch/arm/mvp/mvpkm/mvp_timer.h
new file mode 100644
index 0000000..0bd073a
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_timer.h
@@ -0,0 +1,72 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief timer definitions
+ */
+
+#ifndef _MVP_TIMER_H
+#define _MVP_TIMER_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @brief timer tick rate as returned by MVPTimer_Now64 as a uint64 and used by
+ * MVPTimer.when64.
+ *
+ * For example 1,000,000 means the counter is in microseconds.
+ *
+ * Current implementation requires MVP_TIMER_RATE64 <= 1,000,000,000 and that
+ * it evenly divide 1,000,000,000. Currently 1,000,000,000 to avoid a multiply
+ * or divide in MVPTimer_Now64.
+ */
+#define MVP_TIMER_RATE64 1000000000
+
+/*
+ * Extract current UNIX-style time_t date/time from the 64-bit time as returned
+ * by MVPTimer_Now64().
+ */
+#define MVP_TIMER_RATE64_TIME_T(time64) ((time_t)((time64) / MVP_TIMER_RATE64))
+
+typedef struct MVPTimer MVPTimer;
+
+/**
+ * @brief timer entry struct
+ */
+struct MVPTimer {
+ MVPTimer *next; ///< next in timers list
+ uint64 when64; ///< absolute expiration
+ void (*entry)(uint64 now64, MVPTimer *timer); ///< callback entrypoint
+ void *param; ///< callback parameter
+};
+
+void MVPTimer_InitVMX(void);
+uint64 MVPTimer_Now64(void);
+void MVPTimer_Start(MVPTimer *timer);
+_Bool MVPTimer_Cancel(MVPTimer *timer);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvp_types.h b/arch/arm/mvp/mvpkm/mvp_types.h
new file mode 100644
index 0000000..035efd7
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_types.h
@@ -0,0 +1,94 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief basic type definitions.
+ * These may need to be conditionalized for different compilers/platforms.
+ */
+
+#ifndef _MVPTYPES_H
+#define _MVPTYPES_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
+
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+typedef long long int64;
+
+typedef uint32 CVA; // whatever we are compiling the code as
+typedef uint32 GVA; // guest virtual addresses
+typedef uint32 MVA; // monitor virtual addresses
+typedef uint32 HKVA; // host kernel virtual addresses
+typedef uint32 HUVA; // host user virtual addresses
+typedef uint64 PA; // (guest) physical addresses (40-bit)
+typedef uint32 MA; // (host) machine addresses
+
+typedef uint32 PPN; // PA/PAGE_SIZE
+typedef uint32 MPN; // MA/PAGE_SIZE
+
+typedef uint64 cycle_t;
+
+/**
+ * @brief Page segment.
+ *
+ * Specifies a segment within a single page.
+ */
+typedef struct {
+ uint16 off;
+ uint16 len;
+} PageSeg;
+
+/*
+ * GCC's argument checking for printf-like functions
+ *
+ * fmtPos is the position of the format string argument, beginning at 1
+ * varPos is the position of the variable argument, beginning at 1
+ */
+
+#if defined(__GNUC__)
+# define PRINTF_DECL(fmtPos, varPos) __attribute__((__format__(__printf__, fmtPos, varPos)))
+#else
+# define PRINTF_DECL(fmtPos, varPos)
+#endif
+
+#if defined(__GNUC__)
+# define SCANF_DECL(fmtPos, varPos) __attribute__((__format__(__scanf__, fmtPos, varPos)))
+#else
+# define SCANF_DECL(fmtPos, varPos)
+#endif
+
+#endif /* _MVPTYPES_H */
diff --git a/arch/arm/mvp/mvpkm/mvp_version.h b/arch/arm/mvp/mvpkm/mvp_version.h
new file mode 100644
index 0000000..31274dd
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvp_version.h
@@ -0,0 +1,116 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief What version is this?
+ *
+ */
+
+#ifndef _MVP_VERSION_H_
+#define _MVP_VERSION_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#define INCLUDE_ALLOW_HOSTUSER
+#include "include_check.h"
+#include "utils.h"
+
+/*
+ * MVP Internal Version Numbering
+ *
+ *
+ * There are 4 different usage areas of version information.
+ *
+ * Version Name. This is a marketing string that is used to sell the
+ * product. The update of this string has legal consequences, it
+ * should be done infrequently. Currently we use "V1.0" like
+ * terms. Developer builds have E.X.P as Version Name.
+ *
+ * Android Version Code. This is an integer associated with
+ * com.vmware.mvp.apk on Google Play (a.k.a Android Market). If our
+ * product is multi-apk (that is, we release individual apks for the
+ * different Android versions) then the Android Version Code must
+ * satisfy certain constrains. Typically the Android API level is
+ * the high order 2 digits.
+ *
+ * Engineering Version Code. During an update process of one of the
+ * 3 components on the handset (MVP, VVP, OEK) compatibility needs
+ * to be verified. The Engineering Version Code is a single number
+ * associated with each of the 4 components and it serves as a basis
+ * of this compatibility test. It reflects time, bigger number is
+ * associated with newer code.
+ *
+ * Git Revision. The git hash is a unique identifier of the
+ * source. If picked up from a log, engineers can go to the code
+ * depos and check out the exact code used for the build. For MVP,
+ * VVP, and OEK this is the main/mvp.git, for HMM it is
+ * main/mdm.git. Note that git hash is not ordered, it cannot be
+ * used to directly determine precedence.
+ *
+ */
+
+#define MVP_VERSION_CODE 16800005
+#define MVP_VERSION_CODE_FORMATSTR "%s_%d"
+#define MVP_VERSION_CODE_FORMATARGSV(V_) MVP_STRINGIFY(1.1.3), (V_)
+#define MVP_VERSION_CODE_FORMATARGS \
+ MVP_VERSION_CODE_FORMATARGSV(MVP_VERSION_CODE)
+
+#define MVP_VERSION_FORMATSTR \
+ MVP_VERSION_CODE_FORMATSTR \
+ " compiled at %s based on revision %s by user %s."
+
+#define MVP_VERSION_FORMATARGS \
+ MVP_VERSION_CODE_FORMATARGS, \
+ __DATE__, \
+ MVP_STRINGIFY(5c995a85564cd060562bdbcd1422709e7a326301), \
+ MVP_STRINGIFY()
+
+#define MvpVersion_Map(map_, version_) \
+ ({ \
+ uint32 ii_; \
+ uint32 versionApi_ = 0; \
+ for (ii_ = 0; ii_ < NELEM(map_); ii_++) { \
+ if (map_[ii_] <= version_) { \
+ versionApi_ = map_[ii_]; \
+ } \
+ } \
+ versionApi_; \
+ })
+
+/*
+ * MVP.apk must communicate to VVP and OEK on many of its APIs. To
+ * ensure compatibility, it is mandated that any VVP and OEK version
+ * younger than the minimums defined below can be serviced on all of
+ * the various APIs.
+ *
+ * During the deprecation process, first a marketing decision is made
+ * that the limit below can be raised. After the new minimums are
+ * determined, they must be entered here. Then the various APIs can
+ * remove code that has been obsoleted before the new minimum versions.
+ */
+#define VVP_VERSION_CODE_MIN 0x0100020e
+#define OEK_VERSION_CODE_MIN 0x01000001
+
+#endif /* _MVP_VERSION_H_ */
diff --git a/arch/arm/mvp/mvpkm/mvpkm_comm_ev.c b/arch/arm/mvp/mvpkm/mvpkm_comm_ev.c
new file mode 100644
index 0000000..cb0ce26
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvpkm_comm_ev.c
@@ -0,0 +1,60 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief mvpkm kernel hooks for Comm event signaling
+ */
+
+#include <linux/module.h>
+#include "comm_transp_impl.h"
+
+int (*CommTranspEvProcess)(CommTranspID* id, CommTranspIOEvent event);
+
+
+/**
+ * @brief Register a processing callback for the host when a signal
+ * is received from the guest. Supports only a single comm "service"
+ * on the host.
+ * @param commProcessFunc function pointer to process a signal
+ */
+
+void
+Mvpkm_CommEvRegisterProcessCB(int (*commProcessFunc)(CommTranspID*,
+ CommTranspIOEvent))
+{
+ CommTranspEvProcess = commProcessFunc;
+}
+
+/**
+ * @brief Unregister the processing callback for the host when a signal
+ * is received from the guest.
+ */
+
+void
+Mvpkm_CommEvUnregisterProcessCB(void)
+{
+ CommTranspEvProcess = NULL;
+}
+
+
+EXPORT_SYMBOL(Mvpkm_CommEvRegisterProcessCB);
+EXPORT_SYMBOL(Mvpkm_CommEvUnregisterProcessCB);
diff --git a/arch/arm/mvp/mvpkm/mvpkm_comm_ev.h b/arch/arm/mvp/mvpkm/mvpkm_comm_ev.h
new file mode 100644
index 0000000..2e3c960
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvpkm_comm_ev.h
@@ -0,0 +1,53 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief mvpkm kernel hooks for comm event signaling
+ */
+
+#ifndef _MVPKM_COMM_EV_H
+#define _MVPKM_COMM_EV_H
+
+extern int (*CommTranspEvProcess)(CommTranspID* id, CommTranspIOEvent event);
+
+/**
+ * @brief Forward any guest signal requests to the commkm module
+ * @param id transport channel id
+ * @param event comm event type
+ */
+
+static inline void
+Mvpkm_CommEvSignal(CommTranspID *id, CommTranspIOEvent event)
+{
+ if (CommTranspEvProcess) {
+ CommTranspEvProcess(id, event);
+ }
+}
+
+void
+Mvpkm_CommEvRegisterProcessCB(int (*commProcessFunc)(CommTranspID*,
+ CommTranspIOEvent));
+void Mvpkm_CommEvUnregisterProcessCB(void);
+
+
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvpkm_kernel.h b/arch/arm/mvp/mvpkm/mvpkm_kernel.h
new file mode 100644
index 0000000..19ba6ce
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvpkm_kernel.h
@@ -0,0 +1,83 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#ifndef _MVPKM_KERNEL_H
+#define _MVPKM_KERNEL_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include <linux/rwsem.h>
+#include <linux/kobject.h>
+#include <linux/rbtree.h>
+
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+
+#include "atomic.h"
+#include "montimer_kernel.h"
+#include "worldswitch.h"
+
+/**
+ * @file
+ *
+ * @brief The kernel level driver.
+ */
+
+struct MvpkmVM {
+ struct kobject kobj; ///< used to hook into sysfs
+ struct kset *devicesKSet; ///< kset to list virtual device entries
+ struct kset *miscKSet; ///< kset to list miscellaneous entries
+ _Bool haveKObj; ///< used to properly release instance
+ struct rb_root lockedRoot; ///< locked page RB tree root
+ struct rw_semaphore lockedSem; ///< linked list rw semaphore
+ AtmUInt32 usedPages; ///< number of MEMREGION_MAINMEM pages
+ _Bool isMonitorInited; ///< Has SetupMonitor been called already?
+ WorldSwitchPage *wsp; ///< worldswitch page
+ wait_queue_head_t wfiWaitQ; ///< guest VCPU is waiting-for-interrupt
+ struct rw_semaphore wspSem; /*< prevents entries the WFI
+ wait Q from disappearing
+ underneath us in
+ MvpkmShrink. */
+ MonTimer monTimer; /*< monitor timers, there
+ should be one of these
+ per VCPU */
+ MPN stubPageMPN; /*< stub page to be used for
+ unmappable pages */
+ struct vm_struct *wspHkvaArea; ///< VM area struct for wspHkvaArea
+ HKVA wspHKVADummyPage;///< Dummy page used for backing wspHkvaArea
+#ifdef CONFIG_HAS_WAKELOCK
+ struct wake_lock wakeLock; ///< guest running wake lock
+#endif
+ struct rw_semaphore monThreadTaskSem;/*< prevents monThreadTask from
+ disappearing underneath us */
+ struct task_struct *monThreadTask;
+ struct timer_list balloonWDTimer; /// Balloon watchdog timer
+ _Bool balloonWDEnabled; /// Balloon watchdog enabled?
+};
+
+typedef struct MvpkmVM MvpkmVM;
+
+void Mvpkm_WakeGuest(MvpkmVM *vm, int why);
+struct kset *Mvpkm_FindVMNamedKSet(int vmID, const char *name);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvpkm_main.c b/arch/arm/mvp/mvpkm/mvpkm_main.c
new file mode 100644
index 0000000..61df1a1
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvpkm_main.c
@@ -0,0 +1,2690 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief The kernel level driver.
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/fcntl.h>
+#include <linux/syscalls.h>
+#include <linux/kmod.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/miscdevice.h>
+#include <linux/poll.h>
+#include <linux/smp.h>
+#include <linux/capability.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/sysfs.h>
+#include <linux/pid.h>
+#include <linux/highmem.h>
+#include <linux/syscalls.h>
+
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/wakelock.h>
+#endif
+
+#include <net/sock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/memory.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "mvp.h"
+#include "mvp_version.h"
+#include "mvpkm_types.h"
+#include "mvpkm_private.h"
+#include "mvpkm_kernel.h"
+#include "actions.h"
+#include "wscalls.h"
+#include "arm_inline.h"
+#include "tsc.h"
+#include "mksck_kernel.h"
+#include "mmu_types.h"
+#include "mvp_timer.h"
+#include "qp.h"
+#include "qp_host_kernel.h"
+#include "cpufreq_kernel.h"
+#include "mvpkm_comm_ev.h"
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER
+#include "mvp_balloon.h"
+#endif
+
+
+/*********************************************************************
+ *
+ * Definition of the file operations
+ *
+ *********************************************************************/
+static _Bool LockedListAdd(MvpkmVM *vm,
+ __u32 mpn,
+ __u32 order,
+ PhysMem_RegionType forRegion);
+static _Bool LockedListDel(MvpkmVM *vm, __u32 mpn);
+static void LockedListUnlockAll(MvpkmVM *vm);
+static _Bool LockedListLookup(MvpkmVM *vm, __u32 mpn);
+static int SetupMonitor(MvpkmVM *vm);
+static int RunMonitor(MvpkmVM *vm);
+static MPN AllocZeroedFreePages(MvpkmVM *vm,
+ uint32 order,
+ _Bool highmem,
+ PhysMem_RegionType forRegion,
+ HKVA *hkvaRet);
+static HKVA MapWSPHKVA(MvpkmVM *vm, HkvaMapInfo *mapInfo);
+static void UnmapWSPHKVA(MvpkmVM *vm);
+static int MvpkmWaitForInt(MvpkmVM *vm, _Bool suspend);
+static void ReleaseVM(MvpkmVM *vm);
+
+/*
+ * Mksck open request must come from this uid. It must be root until
+ * it is set via an ioctl from mvpd.
+ */
+uid_t Mvpkm_vmwareUid = 0;
+EXPORT_SYMBOL(Mvpkm_vmwareUid);
+
+/*
+ * Minimum hidden app oom_adj, provided by mvpd, since we can't get it directly
+ * from the lowmemorykiller module.
+ */
+static int minHiddenAppOOMAdj;
+
+/*
+ * vCPU cpu affinity to let monitor/guest run on some CPUs only (when possible)
+ */
+static DECLARE_BITMAP(vcpuAffinity, NR_CPUS);
+
+/*********************************************************************
+ *
+ * Sysfs nodes
+ *
+ *********************************************************************/
+/*
+ * kobject for our sysfs representation, used for global nodes.
+ */
+static struct kobject *mvpkmKObj;
+
+/*
+ * kobject for the balloon exports.
+ */
+static struct kobject *balloonKObj;
+
+/**
+ * @brief sysfs show function for global version attribute.
+ *
+ * @param kobj reference to kobj nested in MvpkmVM struct.
+ * @param attr kobj_attribute reference, not used.
+ * @param buf PAGE_SIZEd buffer to write to.
+ *
+ * @return number of characters printed (not including trailing null character).
+ */
+static ssize_t
+version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, MVP_VERSION_FORMATSTR "\n", MVP_VERSION_FORMATARGS);
+}
+
+static struct kobj_attribute versionAttr = __ATTR_RO(version);
+
+/**
+ * @brief sysfs show function for global background_pages attribute.
+ *
+ * Used by vmx balloon policy controller to gauge the amount of freeable
+ * anonymous memory.
+ *
+ * @param kobj reference to kobj nested in MvpkmVM struct.
+ * @param attr kobj_attribute reference, not used.
+ * @param buf PAGE_SIZEd buffer to write to.
+ *
+ * @return number of characters printed (not including trailing null character).
+ */
+static ssize_t
+background_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+#ifndef CONFIG_ANDROID_LOW_MEMORY_KILLER
+ return snprintf(buf, PAGE_SIZE, "0\n");
+#else
+ return snprintf(buf, PAGE_SIZE, "%d\n", Balloon_AndroidBackgroundPages(minHiddenAppOOMAdj));
+#endif
+}
+
+static struct kobj_attribute backgroundAttr = __ATTR_RO(background);
+
+/**
+ * @brief sysfs show function to export the other_file calculation in
+ * lowmemorykiller.
+ *
+ * It's helpful, in the balloon controller, to know what the lowmemorykiller
+ * module is using to know when the system has crossed a minfree threshold.
+ * Since there exists a number of different other_file calculations in various
+ * lowmemorykiller patches (@see{MVP-1674}), and the module itself doesn't
+ * provide a clean export of this figure, we provide it on a case-by-case basis
+ * for the various supported hosts here.
+ *
+ * @param kobj reference to kobj nested in MvpkmVM struct.
+ * @param attr kobj_attribute reference, not used.
+ * @param buf PAGE_SIZEd buffer to write to.
+ *
+ * @return number of characters printed (not including trailing null character).
+ */
+static ssize_t
+other_file_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ int32 other_file = 0;
+
+#ifndef LOWMEMKILLER_VARIANT
+#define LOWMEMKILLER_VARIANT 0
+#endif
+
+#ifndef LOWMEMKILLER_MD5
+#define LOWMEMKILLER_MD5 0
+#endif
+
+#ifndef LOWMEMKILLER_SHRINK_MD5
+#define LOWMEMKILLER_SHRINK_MD5 0
+#endif
+
+ /*
+ * The build system hashes the lowmemorykiller section related to the
+ * other_file calculation in the kernel source for us, here we have to
+ * provide the code.
+ */
+#if LOWMEMKILLER_VARIANT == 1
+ /*
+ * This is the same as the non-exported global_reclaimable_pages() when there
+ * is no swap.
+ */
+ other_file = global_page_state(NR_ACTIVE_FILE) +
+ global_page_state(NR_INACTIVE_FILE);
+#elif LOWMEMKILLER_VARIANT == 2
+ other_file = global_page_state(NR_FILE_PAGES);
+#elif LOWMEMKILLER_VARIANT == 3
+ other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM);
+#elif LOWMEMKILLER_VARIANT == 4
+ /*
+ * Here free/file pages are fungible and max(free, file) isn't used, but we
+ * can continue to use max(free, file) since max(free, file) = other_file in
+ * this case.
+ */
+ other_file = global_page_state(NR_FREE_PAGES) + global_page_state(NR_FILE_PAGES);
+#elif defined(NONANDROID)
+ /*
+ * Non-Android host platforms don't have ballooning enabled.
+ */
+#else
+ /*
+ * If you get this message, you need to run 'make lowmem-info' and inspect
+ * lowmemorykiller.c. If the "other_file = ..." calculation in lowmem_shrink
+ * appears above, simply add the "Shrink#" to an existing entry in
+ * lowmemkiller-variant.sh, pointing to the variant number above. Otherwise,
+ * provide a new entry above and variant number, with the appropriate
+ * other_file calculation and update lowmemkiller-variant.sh accordingly.
+ */
+//#warning "Unknown lowmemorykiller variant in hosted/module/mvpkm_main.c, falling back on default (see other_file_show for the remedy)"
+ /*
+ * Fall back on default - this may bias strangely for/against the host, but
+ * nothing catastrophic should result.
+ */
+ other_file = global_page_state(NR_FILE_PAGES);
+#endif
+
+#define _STRINGIFY(x) #x
+#define STRINGIFY(x) _STRINGIFY(x)
+ return snprintf(buf,
+ PAGE_SIZE,
+ "%d %d %s %s\n",
+ other_file,
+ LOWMEMKILLER_VARIANT,
+ STRINGIFY(LOWMEMKILLER_MD5),
+ STRINGIFY(LOWMEMKILLER_SHRINK_MD5));
+#undef _STRINGIFY
+#undef STRINGIFY
+}
+
+static struct kobj_attribute otherFileAttr = __ATTR_RO(other_file);
+
+/*
+ * kset for our sysfs representation, used for per-VM nodes.
+ */
+static struct kset *mvpkmKSet;
+
+static ssize_t MvpkmAttrShow(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf);
+static ssize_t MvpkmAttrStore(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf,
+ size_t count);
+
+static void MvpkmKObjRelease(struct kobject *kobj)
+ __attribute__ ((optimize ("-fomit-frame-pointer")));
+
+
+/**
+ * @brief Releases the vm structure containing the kobject.
+ *
+ * @param kobj the vm's kobject.
+ */
+
+static void
+MvpkmKObjRelease(struct kobject *kobj)
+{
+ MvpkmVM *vm = container_of(kobj, MvpkmVM, kobj);
+
+ ReleaseVM(vm);
+
+ module_put(THIS_MODULE);
+}
+
+
+/**
+ * @name mvpkm ktype attribute structures for locked_pages.
+ *
+ * @{
+ */
+static struct sysfs_ops mvpkmSysfsOps = {
+ .show = MvpkmAttrShow,
+ .store = MvpkmAttrStore
+};
+
+static struct attribute mvpkmLockedPagesAttr = {
+ .name = "locked_pages",
+ .mode = 0444,
+};
+
+static struct attribute mvpkmBalloonWatchdogAttr = {
+ .name = "balloon_watchdog",
+ .mode = 0666
+};
+
+static struct attribute mvpkmMonitorAttr = {
+ .name = "monitor",
+ .mode = 0400,
+};
+
+static struct attribute *mvpkmDefaultAttrs[] = {
+ &mvpkmLockedPagesAttr,
+ &mvpkmBalloonWatchdogAttr,
+ &mvpkmMonitorAttr,
+ NULL,
+};
+
+static struct kobj_type mvpkmKType = {
+ .sysfs_ops = &mvpkmSysfsOps,
+ .release = MvpkmKObjRelease,
+ .default_attrs = mvpkmDefaultAttrs,
+};
+/*@}*/
+
+/*
+ * As it is not very common for host kernels to have SYS_HYPERVISOR enabled and
+ * you have to "hack" a Kconfig file to enable it, just include the
+ * functionality inline if it is not enabled.
+ */
+#ifndef CONFIG_SYS_HYPERVISOR
+struct kobject *hypervisor_kobj;
+EXPORT_SYMBOL_GPL(hypervisor_kobj);
+#endif
+
+
+/*
+ * kobject and kset utilities.
+ */
+
+extern struct kobject *kset_find_obj(struct kset *, const char *)
+ __attribute__((weak));
+
+
+/**
+ * @brief Finds a kobject in a kset. The actual implementation is copied from
+ * kernel source in lib/kobject.c. Although the symbol is extern-declared,
+ * it is not EXPORT_SYMBOL-ed. We use a weak reference in case the symbol
+ * might be exported in future kernel versions.
+ *
+ * @param kset set to search.
+ * @param name object name.
+ *
+ * @return retained kobject if found, NULL otherwise.
+ */
+
+struct kobject *
+kset_find_obj(struct kset *kset,
+ const char *name)
+{
+ struct kobject *k;
+ struct kobject *ret = NULL;
+
+ spin_lock(&kset->list_lock);
+ list_for_each_entry(k, &kset->list, entry) {
+ if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
+ ret = kobject_get(k);
+ break;
+ }
+ }
+ spin_unlock(&kset->list_lock);
+ return ret;
+}
+
+
+/**
+ * @brief Finds one of the VM's pre-defined ksets.
+ *
+ * @param vmID a VM ID.
+ * @param name name of one of the VM's pre-defined ksets.
+ *
+ * @return retained kset if found, NULL otherwise.
+ */
+
+struct kset *
+Mvpkm_FindVMNamedKSet(int vmID,
+ const char *name)
+{
+ MvpkmVM *vm;
+ struct kobject *kobj;
+ char vmName[32] = {}; /* Large enough to hold externally-formatted int32. */
+ struct kset *res = NULL;
+
+ if (!mvpkmKSet) {
+ return NULL;
+ }
+
+ snprintf(vmName, sizeof vmName, "%d", vmID);
+ vmName[sizeof vmName - 1] = '\0'; /* Always null-terminate, no overflow. */
+
+ kobj = kset_find_obj(mvpkmKSet, vmName);
+ if (!kobj) {
+ return NULL;
+ }
+
+ vm = container_of(kobj, MvpkmVM, kobj);
+
+ if (!strcmp(name, "devices")) {
+ res = kset_get(vm->devicesKSet);
+ } else if (!strcmp(name, "misc")) {
+ res = kset_get(vm->miscKSet);
+ }
+
+ kobject_put(kobj);
+ return res;
+}
+
+EXPORT_SYMBOL(Mvpkm_FindVMNamedKSet);
+
+
+
+/*********************************************************************
+ *
+ * Standard Linux miscellaneous device registration
+ *
+ *********************************************************************/
+
+MODULE_LICENSE("GPL"); // for kallsyms_lookup_name
+
+static int MvpkmFault(struct vm_area_struct *vma, struct vm_fault *vmf);
+
+
+/**
+ * @brief Linux vma operations for /dev/mem-like kernel module mmap. We
+ * enforce the restriction that only MPNs that have been allocated
+ * to the opened VM may be mapped and also increment the reference
+ * count (via vm_insert_page), so that even if the memory is later
+ * freed by the VM, host process vma's containing the MPN can't
+ * compromise the system.
+ *
+ * However, only trusted host processes (e.g. the vmx) should be allowed
+ * to use this interface, since you can mmap the monitor's code/data/
+ * page tables etc. with it. Untrusted host processes are limited to
+ * typed messages for sharing memory with the monitor. Unix file system
+ * access permissions are the intended method of restricting access.
+ * Unfortunately, today _any_ host process utilizing Mksck requires
+ * access to mvpkm to setup its Mksck pages and obtain socket info via
+ * ioctls - we probably should be exporting two devices, one for trusted
+ * and one for arbitrary host processes to avoid this confusion of
+ * concerns.
+ */
+static struct vm_operations_struct mvpkmVMOps = {
+ .fault = MvpkmFault
+};
+
+/*
+ * Generic kernel module file ops. These functions will be registered
+ * at the time the kernel module is loaded.
+ */
+static long MvpkmUnlockedIoctl(struct file *filep,
+ unsigned int cmd,
+ unsigned long arg);
+static int MvpkmOpen(struct inode *inode, struct file *filp);
+static int MvpkmRelease(struct inode *inode, struct file *filp);
+static int MvpkmMMap(struct file *file, struct vm_area_struct *vma);
+
+/**
+ * @brief the file_operation structure contains the callback functions
+ * that are registered with Linux to handle file operations on
+ * the mvpkm device.
+ *
+ * The structure contains other members that the mvpkm device
+ * does not use. Those members are auto-initialized to NULL.
+ *
+ * WARNING, this structure has changed after Linux kernel 2.6.19:
+ * readv/writev are changed to aio_read/aio_write (neither is used here).
+ */
+static const struct file_operations mvpkmFileOps = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = MvpkmUnlockedIoctl,
+ .open = MvpkmOpen,
+ .release = MvpkmRelease,
+ .mmap = MvpkmMMap
+};
+
+/**
+ * @brief The mvpkm device identifying information to be used to register
+ * the device with the Linux kernel.
+ */
+static struct miscdevice mvpkmDev = {
+ .minor = 165,
+ .name = "mvpkm",
+ .fops = &mvpkmFileOps
+};
+
+/**
+ * Mvpkm is loaded by mvpd and only mvpd will be allowed to open
+ * it. There is a very simple way to verify that: record the process
+ * id (thread group id) at the time the module is loaded and test it
+ * at the time the module is opened.
+ */
+static struct pid *initTgid;
+
+
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER
+/**
+ * @name Slab shrinker for triggering balloon adjustment.
+ *
+ * @note shrinker us used as a trigger for guest balloon.
+ *
+ * @{
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+static int MvpkmShrink(struct shrinker *this, struct shrink_control *sc);
+#else
+static int MvpkmShrink(struct shrinker *this, int nrToScan, gfp_t gfpMask);
+#endif
+
+static struct shrinker mvpkmShrinker = {
+ .shrink = MvpkmShrink,
+ .seeks = DEFAULT_SEEKS
+};
+/*@}*/
+#endif
+
+module_param_array(vcpuAffinity, ulong, NULL, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(vcpuAffinity, "vCPU affinity");
+
+
+/**
+ * @brief Initialize the mvpkm device, register it with the Linux kernel.
+ *
+ * @return A zero is returned on success and a negative errno code for failure.
+ * (Same as the return policy of misc_register(9).)
+ */
+
+static int __init
+MvpkmInit(void)
+{
+ int err = 0;
+ _Bool mksckInited = false;
+ _Bool cpuFreqInited = false;
+
+ printk(KERN_INFO "Mvpkm: " MVP_VERSION_FORMATSTR "\n", MVP_VERSION_FORMATARGS);
+ printk(KERN_INFO "Mvpkm: loaded from process %s tgid=%d, pid=%d\n",
+ current->comm,
+ task_tgid_vnr(current),
+ task_pid_vnr(current));
+
+ if (bitmap_empty(vcpuAffinity, NR_CPUS)) {
+ bitmap_copy(vcpuAffinity, cpumask_bits(cpu_possible_mask), NR_CPUS);
+ }
+
+ if ((err = misc_register(&mvpkmDev))) {
+ return -ENOENT;
+ }
+
+ if ((err = Mksck_Init())) {
+ goto error;
+ } else {
+ mksckInited = true;
+ }
+
+ QP_HostInit();
+
+ CpuFreq_Init();
+ cpuFreqInited = true;
+
+ /*
+ * Reference mvpd (module loader) tgid struct, so that we can avoid
+ * attacks based on pid number wraparound.
+ */
+ initTgid = get_pid(task_tgid(current));
+
+#ifndef CONFIG_SYS_HYPERVISOR
+ hypervisor_kobj = kobject_create_and_add("hypervisor", NULL);
+ if (!hypervisor_kobj) {
+ err = -ENOMEM;
+ goto error;
+ }
+#endif
+
+ if (!(mvpkmKObj = kobject_create_and_add("mvp", hypervisor_kobj)) ||
+ !(balloonKObj = kobject_create_and_add("lowmem", mvpkmKObj)) ||
+ !(mvpkmKSet = kset_create_and_add("vm", NULL, mvpkmKObj))) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ if ((err = sysfs_create_file(mvpkmKObj, &versionAttr.attr))) {
+ goto error;
+ }
+
+ if ((err = sysfs_create_file(balloonKObj, &backgroundAttr.attr))) {
+ goto error;
+ }
+
+ if ((err = sysfs_create_file(balloonKObj, &otherFileAttr.attr))) {
+ goto error;
+ }
+
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER
+ register_shrinker(&mvpkmShrinker);
+#endif
+
+ MksckPageInfo_Init();
+
+ return 0;
+
+error:
+ if (mvpkmKSet) {
+ kset_unregister(mvpkmKSet);
+ }
+
+ if (balloonKObj) {
+ kobject_del(balloonKObj);
+ kobject_put(balloonKObj);
+ }
+
+ if (mvpkmKObj) {
+ kobject_del(mvpkmKObj);
+ kobject_put(mvpkmKObj);
+ }
+
+#ifndef CONFIG_SYS_HYPERVISOR
+ if (hypervisor_kobj) {
+ kobject_del(hypervisor_kobj);
+ kobject_put(hypervisor_kobj);
+ }
+#endif
+
+ if (cpuFreqInited) {
+ CpuFreq_Exit();
+ }
+
+ if (mksckInited) {
+ Mksck_Exit();
+ }
+
+ if (initTgid) {
+ put_pid(initTgid);
+ }
+
+ misc_deregister(&mvpkmDev);
+ return err;
+}
+
+/**
+ * @brief De-register the mvpkm device with the Linux kernel.
+ */
+void
+MvpkmExit(void)
+{
+ PRINTK(KERN_INFO "MvpkmExit called !\n");
+
+ MksckPageInfo_Exit();
+
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER
+ unregister_shrinker(&mvpkmShrinker);
+#endif
+
+ kset_unregister(mvpkmKSet);
+ kobject_del(balloonKObj);
+ kobject_put(balloonKObj);
+ kobject_del(mvpkmKObj);
+ kobject_put(mvpkmKObj);
+#ifndef CONFIG_SYS_HYPERVISOR
+ kobject_del(hypervisor_kobj);
+ kobject_put(hypervisor_kobj);
+#endif
+
+ CpuFreq_Exit();
+
+ Mksck_Exit();
+
+ put_pid(initTgid);
+
+ misc_deregister(&mvpkmDev);
+}
+
+/*
+ * The standard module registration macros of Linux.
+ */
+module_init(MvpkmInit);
+module_exit(MvpkmExit);
+
+module_param_named(minHiddenAppOOMAdj, minHiddenAppOOMAdj, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(minHiddenAppOOMAdj, "minimum hidden app oom_adj, as per lowmemorykiller");
+
+#ifdef CONFIG_ANDROID_LOW_MEMORY_KILLER
+/**
+ * @brief Balloon watchdog timeout callback.
+ *
+ * Terminate the VM since it's not responsive.
+ *
+ * @param data vm reference representation.
+ */
+static void
+WatchdogCB(unsigned long data)
+{
+ MvpkmVM *vm = (MvpkmVM *)data;
+
+ printk("Balloon watchdog expired (%d s)!\n", BALLOON_WATCHDOG_TIMEOUT_SECS);
+
+ Mvpkm_WakeGuest(vm, ACTION_ABORT);
+}
+
+/**
+ * @brief Slab shrinker.
+ *
+ * Called by Linux kernel when we're under memory pressure. We treat all locked
+ * pages as a slab for this purpose, similar to the Android low memory killer.
+ *
+ * @param this reference to registered shrinker for callback context.
+ * @param nrToScan number of entries to scan. If 0 then just return the number
+ * of present entries. We ignore the value of nrToScan when > 1
+ * since the shrinker is a trigger to readjust guest balloons,
+ * where the actual balloon size is determined in conjunction
+ * with the guest.
+ * @param gfpMask ignored.
+ *
+ * @return number of locked pages.
+ */
+static int
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+MvpkmShrink(struct shrinker *this, struct shrink_control *sc)
+#else
+MvpkmShrink(struct shrinker *this, int nrToScan, gfp_t gfpMask)
+#endif
+{
+ uint32 locked = 0;
+ struct kobject *k;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
+ int nrToScan = sc->nr_to_scan;
+#endif
+
+ spin_lock(&mvpkmKSet->list_lock);
+
+ list_for_each_entry(k, &mvpkmKSet->list, entry) {
+ MvpkmVM *vm = container_of(k, MvpkmVM, kobj);
+
+ locked += ATOMIC_GETO(vm->usedPages);
+
+ /*
+ * Try and grab the WSP semaphore - if we fail, we must be VM setup or
+ * teardown, no point trying to wake the guest.
+ */
+ if (nrToScan > 0 &&
+ down_read_trylock(&vm->wspSem)) {
+
+ if (vm->wsp) {
+ Mvpkm_WakeGuest(vm, ACTION_BALLOON);
+
+ /*
+ * Balloon watchdog.
+ */
+ if (vm->balloonWDEnabled) {
+ struct timer_list *t = &vm->balloonWDTimer;
+
+ if (!timer_pending(t)) {
+ t->data = (unsigned long)vm;
+ t->function = WatchdogCB;
+ t->expires = jiffies + BALLOON_WATCHDOG_TIMEOUT_SECS * HZ;
+ add_timer(t);
+ }
+ }
+ }
+
+ up_read(&vm->wspSem);
+ }
+ }
+
+ spin_unlock(&mvpkmKSet->list_lock);
+
+ return locked;
+}
+#endif
+
+
+/**
+ * @brief The open file operation. Initializes the vm specific structure.
+ */
+int
+MvpkmOpen(struct inode *inode, struct file *filp)
+{
+ MvpkmVM *vm;
+
+ if (initTgid != task_tgid(current)) {
+ printk(KERN_ERR "%s: MVPKM can be opened only from MVPD (process %d).\n",
+ __FUNCTION__, pid_vnr(initTgid));
+ return -EPERM;
+ }
+ printk(KERN_DEBUG "%s: Allocating an MvpkmVM structure from process %s tgid=%d, pid=%d\n",
+ __FUNCTION__,
+ current->comm,
+ task_tgid_vnr(current),
+ task_pid_vnr(current));
+
+ vm = kmalloc(sizeof(MvpkmVM), GFP_KERNEL);
+ if (!vm) {
+ return -ENOMEM;
+ }
+
+ memset(vm, 0, sizeof *vm);
+
+ init_timer(&vm->balloonWDTimer);
+ init_rwsem(&vm->lockedSem);
+ init_rwsem(&vm->wspSem);
+ init_rwsem(&vm->monThreadTaskSem);
+ vm->monThreadTask = NULL;
+ vm->isMonitorInited = false;
+
+ filp->private_data = vm;
+
+ if (!Mvpkm_vmwareUid) {
+ Mvpkm_vmwareUid = current_euid();
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Releases a VMs resources
+ * @param vm vm to release
+ */
+static void
+ReleaseVM(MvpkmVM *vm)
+{
+ del_timer_sync(&vm->balloonWDTimer);
+
+ down_write(&vm->wspSem);
+
+ if (vm->isMonitorInited) {
+ MonitorTimer_Request(&vm->monTimer, 0);
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_destroy(&vm->wakeLock);
+#endif
+ Mksck_WspRelease(vm->wsp);
+ vm->wsp = NULL;
+ }
+
+ up_write(&vm->wspSem);
+
+ LockedListUnlockAll(vm);
+
+ UnmapWSPHKVA(vm);
+
+ /*
+ * All sockets potentially connected to sockets of this vm's vmId will fail
+ * at send now. DGRAM sockets are note required to tear down connection
+ * explicitly.
+ */
+
+ kfree(vm);
+}
+
+/**
+ * @brief The release file operation. Releases the vm specific
+ * structure including all the locked pages.
+ *
+ * @param inode Unused
+ * @param filp which VM we're dealing with
+ * @return 0
+ */
+int
+MvpkmRelease(struct inode *inode, struct file *filp)
+{
+ MvpkmVM *vm = filp->private_data;
+
+ /*
+ * Tear down any queue pairs associated with this VM
+ */
+ if (vm->isMonitorInited) {
+ ASSERT(vm->wsp);
+ QP_DetachAll(vm->wsp->guestId);
+ }
+
+ /*
+ * Release the VM's ksets.
+ */
+
+ kset_unregister(vm->miscKSet);
+ kset_unregister(vm->devicesKSet);
+
+ if (vm->haveKObj) {
+ /*
+ * Release the VM's kobject.
+ * 'vm' will be kfree-d in its kobject's release function.
+ */
+
+ kobject_del(&vm->kobj);
+ kobject_put(&vm->kobj);
+ } else {
+ ReleaseVM(vm);
+ }
+
+ filp->private_data = NULL;
+
+ printk(KERN_INFO "%s: Released MvpkmVM structure from process %s tgid=%d, pid=%d\n",
+ __FUNCTION__,
+ current->comm,
+ task_tgid_vnr(current),
+ task_pid_vnr(current));
+
+ return 0;
+}
+
+/**
+ * @brief Page fault handler for /dev/mem-like regions (see mvpkmVMOps
+ * block comment).
+ */
+static int
+MvpkmFault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ unsigned long address = (unsigned long)vmf->virtual_address;
+ MPN mpn = vmf->pgoff;
+ MvpkmVM *vm = vma->vm_file->private_data;
+
+
+ /*
+ * Only insert pages belonging to the VM. The check is slow, O(n) in the
+ * number of MPNs associated with the VM, but it doesn't matter - the mmap
+ * interface should only be used by trusted processes at initialization
+ * time and for debugging.
+ *
+ * The mpn can be either in the memory reserved the monitor or mvpd
+ * through the regular mechanisms or it could be a mksck page.
+ */
+ if (!pfn_valid(mpn)) {
+ printk(KERN_ERR "MvpkmMMap: Failed to insert %x @ %lx, mpn invalid\n",
+ mpn,
+ address);
+ } else if (LockedListLookup(vm, mpn)) {
+ if (vm_insert_page(vma, address, pfn_to_page(mpn)) == 0) {
+ return VM_FAULT_NOPAGE;
+ }
+
+ printk(KERN_ERR "MvpkmMMap: Failed to insert %x @ %lx \n",
+ mpn,
+ address);
+ } else if (MksckPage_LookupAndInsertPage(vma, address, mpn) == 0) {
+ return VM_FAULT_NOPAGE;
+ }
+
+ if (vm->stubPageMPN) {
+ if (vm_insert_page(vma, address, pfn_to_page(vm->stubPageMPN)) == 0) {
+ printk(KERN_INFO "MvpkmMMap: mapped the stub page at %x @ %lx \n",
+ mpn,
+ address);
+ return VM_FAULT_NOPAGE;
+ }
+
+ printk(KERN_ERR "MvpkmMMap: Could not insert stub page %x @ %lx \n",
+ mpn,
+ address);
+
+ }
+
+ return VM_FAULT_SIGBUS;
+}
+
+/**
+ * @brief sysfs show function for per-VM locked_pages attribute.
+ *
+ * @param kobj reference to kobj nested in MvpkmVM struct.
+ * @param attr attribute reference.
+ * @param buf PAGE_SIZEd buffer to write to.
+ *
+ * @return number of characters printed (not including trailing null character).
+ */
+static ssize_t
+MvpkmAttrShow(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ if (attr == &mvpkmLockedPagesAttr) {
+ MvpkmVM *vm = container_of(kobj, MvpkmVM, kobj);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", ATOMIC_GETO(vm->usedPages));
+ } else if (attr == &mvpkmMonitorAttr) {
+ MvpkmVM *vm = container_of(kobj, MvpkmVM, kobj);
+
+ return snprintf(buf,
+ PAGE_SIZE,
+ "hostActions %x callno %d\n",
+ ATOMIC_GETO(vm->wsp->hostActions),
+ WSP_Params(vm->wsp)->callno);
+ } else {
+ return -EPERM;
+ }
+}
+
+/**
+ * @brief sysfs store function for per-VM locked_pages attribute.
+ *
+ * @param kobj reference to kobj nested in MvpkmVM struct.
+ * @param attr attribute reference.
+ * @param buf PAGE_SIZEd buffer to write to.
+ * @param buf input buffer.
+ * @param count input buffer length.
+ *
+ * @return number of bytes consumed or negative error code.
+ */
+static ssize_t
+MvpkmAttrStore(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ if (attr == &mvpkmBalloonWatchdogAttr) {
+ MvpkmVM *vm = container_of(kobj, MvpkmVM, kobj);
+
+ /*
+ * Enable balloon watchdog on first write. This includes all ballooning
+ * capable guest.
+ */
+ vm->balloonWDEnabled = true;
+ del_timer_sync(&vm->balloonWDTimer);
+
+ return 1;
+ } else {
+ return -EPERM;
+ }
+}
+
+/**
+ * @brief Map machine address space region into host process.
+ *
+ * @param file file reference (ignored).
+ * @param vma Linux virtual memory area defining the region.
+ *
+ * @return 0 on success, otherwise error code.
+ */
+static int
+MvpkmMMap(struct file *file, struct vm_area_struct *vma)
+{
+ vma->vm_ops = &mvpkmVMOps;
+
+ return 0;
+}
+
+#ifdef CONFIG_ARM_LPAE
+/**
+ * @brief Determine host cacheability/shareability attributes.
+ *
+ * Used to ensure monitor/guest shared mappings are consistent with
+ * those of host user/kernel.
+ *
+ * @param[out] attribMAN when setting up the HW monitor this provides the
+ * attributes in the generic ARM_MemAttrNormal form,
+ * suitable for configuring the monitor and guest's
+ * [H]MAIR0 and setting the shareability attributes of
+ * the LPAE descriptors.
+ */
+static void
+DetermineMemAttrLPAE(ARM_MemAttrNormal *attribMAN)
+{
+ /*
+ * We use set_pte_ext to sample what {S,TEX,CB} bits Linux is using for
+ * normal kernel/user L2D mappings. These bits should be consistent both
+ * with each other and what we use in the monitor since we share various
+ * pages with both host processes, the kernel module and monitor, and the
+ * ARM ARM requires that synonyms have the same cacheability attributes,
+ * see end of A3.5.{4,7} ARM DDI 0406A.
+ */
+ HKVA hkva = __get_free_pages(GFP_KERNEL, 0);
+
+ ARM_LPAE_L3D *pt = (ARM_LPAE_L3D *)hkva;
+ ARM_LPAE_L3D *kernL3D = &pt[0], *userL3D = &pt[1];
+ uint32 attr, mair0, mair1;
+
+ set_pte_ext((pte_t *)kernL3D, pfn_pte(0, PAGE_KERNEL), 0);
+ set_pte_ext((pte_t *)userL3D, pfn_pte(0, PAGE_NONE), 0);
+
+ printk(KERN_INFO
+ "DetermineMemAttr: Kernel L3D AttrIndx=%x SH=%x\n",
+ kernL3D->blockS1.attrIndx,
+ kernL3D->blockS1.sh);
+
+ printk(KERN_INFO
+ "DetermineMemAttr: User L3D AttrIndx=%x SH=%x\n",
+ userL3D->blockS1.attrIndx,
+ userL3D->blockS1.sh);
+
+ ASSERT(kernL3D->blockS1.attrIndx == userL3D->blockS1.attrIndx);
+ ASSERT(kernL3D->blockS1.sh == userL3D->blockS1.sh);
+
+ switch (kernL3D->blockS1.sh) {
+ case 0: {
+ attribMAN->share = ARM_SHARE_ATTR_NONE;
+ break;
+ }
+ case 2: {
+ attribMAN->share = ARM_SHARE_ATTR_OUTER;
+ break;
+ }
+ case 3: {
+ attribMAN->share = ARM_SHARE_ATTR_INNER;
+ break;
+ }
+ default: {
+ FATAL();
+ }
+ }
+
+ ARM_MRC_CP15(MAIR0, mair0);
+ ARM_MRC_CP15(MAIR1, mair1);
+
+ attr = MVP_EXTRACT_FIELD(kernL3D->blockS1.attrIndx >= 4 ? mair1 : mair0,
+ 8 * (kernL3D->blockS1.attrIndx % 4),
+ 8);
+
+ /*
+ * See B4-1615 ARM DDI 0406C-2c for magic.
+ */
+#define MAIR_ATTR_2_CACHE_ATTR(x, y) \
+ switch (x) { \
+ case 2: { \
+ (y) = ARM_CACHE_ATTR_NORMAL_WT; \
+ break; \
+ } \
+ case 3: { \
+ (y) = ARM_CACHE_ATTR_NORMAL_WB; \
+ break; \
+ } \
+ default: { \
+ FATAL(); \
+ } \
+ }
+
+ MAIR_ATTR_2_CACHE_ATTR(MVP_EXTRACT_FIELD(attr, 2, 2), attribMAN->innerCache);
+ MAIR_ATTR_2_CACHE_ATTR(MVP_EXTRACT_FIELD(attr, 6, 2), attribMAN->outerCache);
+
+#undef MAIR_ATTR_2_CACHE_ATTR
+
+ printk(KERN_INFO
+ "DetermineMemAttr: innerCache %x outerCache %x share %x\n",
+ attribMAN->innerCache,
+ attribMAN->outerCache,
+ attribMAN->share);
+
+ free_pages(hkva, 0);
+}
+
+#else
+
+/**
+ * @brief Determine host cacheability/shareability attributes.
+ *
+ * Used to ensure monitor/guest shared mappings are consistent with
+ * those of host user/kernel.
+ *
+ * @param[out] attribL2D when setting up the LPV monitor a template L2D
+ * containing cacheability attributes {S, TEX,CB} used by
+ * host kernel for normal memory mappings. These may be
+ * used directly for monitor/guest mappings, since both
+ * worlds share a common {TRE, PRRR, NMRR}.
+ * @param[out] attribMAN when setting up TTBR0 in the LPV monitor and the page
+ * tables for the HW monitor this provides the attributes
+ * in the generic ARM_MemAttrNormal form, suitable for
+ * configuring TTBR0 + the monitor and guest's [H]MAIR0
+ * and setting the shareability attributes of the LPAE
+ * descriptors.
+ */
+static void
+DetermineMemAttrNonLPAE(ARM_L2D *attribL2D, ARM_MemAttrNormal *attribMAN)
+{
+ /*
+ * We use set_pte_ext to sample what {S,TEX,CB} bits Linux is using for
+ * normal kernel/user L2D mappings. These bits should be consistent both
+ * with each other and what we use in the monitor since we share various
+ * pages with both host processes, the kernel module and monitor, and the
+ * ARM ARM requires that synonyms have the same cacheability attributes,
+ * see end of A3.5.{4,7} ARM DDI 0406A.
+ */
+ HKVA hkva = __get_free_pages(GFP_KERNEL, 0);
+ uint32 sctlr;
+ ARM_L2D *pt = (ARM_L2D *)hkva;
+ ARM_L2D *kernL2D = &pt[0], *userL2D = &pt[1];
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
+ /*
+ * Linux uses the magic 2048 offset in set_pte_ext. See include/asm/pgtable.h
+ * for PAGE_NONE and PAGE_KERNEL semantics.
+ */
+ const uint32 set_pte_ext_offset = 2048;
+#else
+ /*
+ * Linux 2.6.38 switched the order of Linux vs hardware page tables.
+ * See mainline d30e45eeabefadc6039d7f876a59e5f5f6cb11c6.
+ */
+ const uint32 set_pte_ext_offset = 0;
+#endif
+
+ set_pte_ext((pte_t *)(kernL2D + set_pte_ext_offset/sizeof(ARM_L2D)),
+ pfn_pte(0, PAGE_KERNEL),
+ 0);
+ set_pte_ext((pte_t *)(userL2D + set_pte_ext_offset/sizeof(ARM_L2D)),
+ pfn_pte(0, PAGE_NONE),
+ 0);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+ /*
+ * Linux 2.6.38 switched the order of Linux vs hardware page tables.
+ * See mainline d30e45eeabefadc6039d7f876a59e5f5f6cb11c6.
+ */
+ kernL2D += 2048/sizeof(ARM_L2D);
+ userL2D += 2048/sizeof(ARM_L2D);
+#endif
+
+ printk(KERN_INFO
+ "DetermineMemAttr: Kernel L2D TEX=%x CB=%x S=%x\n",
+ kernL2D->small.tex,
+ kernL2D->small.cb,
+ kernL2D->small.s);
+
+ printk(KERN_INFO
+ "DetermineMemAttr: User L2D TEX=%x CB=%x S=%x\n",
+ userL2D->small.tex,
+ userL2D->small.cb,
+ userL2D->small.s);
+
+ ASSERT((kernL2D->small.tex & 1) == (userL2D->small.tex & 1));
+ ASSERT(kernL2D->small.cb == userL2D->small.cb);
+ ASSERT(kernL2D->small.s == userL2D->small.s);
+
+ *attribL2D = *kernL2D;
+
+ /*
+ * We now decode TEX remap and obtain the more generic form for use in
+ * the LPV monitor's TTBR0 initialization and the HW monitor.
+ */
+
+ ARM_MRC_CP15(CONTROL_REGISTER, sctlr);
+
+ if (sctlr & ARM_CP15_CNTL_TRE) {
+ uint32 prrr, nmrr, indx, type, innerCache, outerCache, outerShare,
+ share;
+
+ printk(KERN_INFO
+ "DetermineMemAttr: TEX remapping enabled\n");
+
+ ARM_MRC_CP15(PRIMARY_REGION_REMAP, prrr);
+ ARM_MRC_CP15(NORMAL_MEMORY_REMAP, nmrr);
+
+ printk(KERN_INFO
+ "DetermineMemAttr: PRRR=%x NMRR=%x\n",
+ prrr,
+ nmrr);
+
+ /*
+ * Decode PRRR/NMRR below. See B3.7 ARM DDI 0406B for register
+ * encodings, tables and magic numbers.
+ */
+
+ indx = (MVP_BIT(kernL2D->small.tex, 0) << 2) | kernL2D->small.cb;
+
+ /*
+ * Only normal memory makes sense here.
+ */
+ type = MVP_EXTRACT_FIELD(prrr, 2 * indx, 2);
+ ASSERT(type == 2);
+
+ innerCache = MVP_EXTRACT_FIELD(nmrr, 2 * indx, 2);
+ outerCache = MVP_EXTRACT_FIELD(nmrr, 16 + 2 * indx, 2);
+ outerShare = !MVP_BIT(prrr, 24 + indx);
+ share = MVP_BIT(prrr, 18 + kernL2D->small.s);
+
+ printk(KERN_INFO
+ "DetermineMemAttr: type %x innerCache %x outerCache %x"
+ " share %x outerShare %x\n",
+ type,
+ innerCache,
+ outerCache,
+ share,
+ outerShare);
+
+ if (share) {
+ if (outerShare) {
+ attribMAN->share = ARM_SHARE_ATTR_OUTER;
+ } else {
+ attribMAN->share = ARM_SHARE_ATTR_INNER;
+ }
+ } else {
+ attribMAN->share = ARM_SHARE_ATTR_NONE;
+ }
+
+ attribMAN->innerCache = innerCache;
+ attribMAN->outerCache = outerCache;
+ } else {
+ NOT_IMPLEMENTED_JIRA(1849);
+ }
+
+ free_pages(hkva, 0);
+}
+#endif
+
+/**
+ * @brief The ioctl file operation.
+ *
+ * The ioctl command is the main communication method between the
+ * vmx and the mvpkm kernel module.
+ *
+ * @param filp which VM we're dealing with
+ * @param cmd select which cmd function needs to be performed
+ * @param arg argument for command
+ * @return error code, 0 on success
+ */
+long
+MvpkmUnlockedIoctl(struct file *filp,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ MvpkmVM *vm = filp->private_data;
+ int retval = 0;
+
+ switch (cmd) {
+
+
+ case MVPKM_DISABLE_FAULT: {
+ if (!vm->stubPageMPN) {
+ uint32 *ptr;
+
+ vm->stubPageMPN =
+ AllocZeroedFreePages(vm, 0, false, MEMREGION_MAINMEM, (HKVA*)&ptr);
+ if (!vm->stubPageMPN) {
+ break;
+ }
+ ptr[0] = MVPKM_STUBPAGE_BEG;
+ ptr[PAGE_SIZE/sizeof(uint32) - 1] = MVPKM_STUBPAGE_END;
+ }
+ break;
+ }
+
+ /*
+ * Allocate some pinned pages from kernel.
+ * Returns -ENOMEM if no host pages available for allocation.
+ */
+ case MVPKM_LOCK_MPN: {
+ struct MvpkmLockMPN buf;
+
+ if (copy_from_user(&buf, (void *)arg, sizeof buf)) {
+ return -EFAULT;
+ }
+
+ buf.mpn = AllocZeroedFreePages(vm,
+ buf.order,
+ false,
+ buf.forRegion,
+ NULL);
+ if (buf.mpn == 0) {
+ return -ENOMEM;
+ }
+
+ if (copy_to_user((void *)arg, &buf, sizeof buf)) {
+ return -EFAULT;
+ }
+ break;
+ }
+
+ case MVPKM_UNLOCK_MPN: {
+ struct MvpkmLockMPN buf;
+
+ if (copy_from_user(&buf, (void *)arg, sizeof buf)) {
+ return -EFAULT;
+ }
+
+ if (!LockedListDel(vm, buf.mpn)) {
+ return -EINVAL;
+ }
+ break;
+ }
+
+ case MVPKM_MAP_WSPHKVA: {
+ MvpkmMapHKVA mvpkmMapInfo;
+ HkvaMapInfo mapInfo[WSP_PAGE_COUNT];
+
+ if (copy_from_user(&mvpkmMapInfo, (void *)arg, sizeof mvpkmMapInfo)) {
+ return -EFAULT;
+ }
+
+ if (copy_from_user(mapInfo, (void *)mvpkmMapInfo.mapInfo, sizeof mapInfo)) {
+ return -EFAULT;
+ }
+
+ mvpkmMapInfo.hkva = MapWSPHKVA(vm, mapInfo);
+ BUG_ON(mvpkmMapInfo.hkva == 0);
+
+ if (mvpkmMapInfo.forRegion == MEMREGION_WSP) {
+ vm->wsp = (WorldSwitchPage *) mvpkmMapInfo.hkva;
+ }
+
+ if (copy_to_user((void *)arg, &mvpkmMapInfo, sizeof mvpkmMapInfo)) {
+ return -EFAULT;
+ }
+ break;
+ }
+
+ case MVPKM_RUN_MONITOR: {
+ if (!vm->isMonitorInited) {
+ vm->isMonitorInited = ((retval = SetupMonitor(vm)) == 0);
+ }
+
+ if (vm->isMonitorInited) {
+ retval = RunMonitor(vm);
+ }
+
+ break;
+ }
+
+ case MVPKM_ABORT_MONITOR: {
+ if (!vm->isMonitorInited) {
+ return -EINVAL;
+ }
+
+ ASSERT(vm->wsp != NULL);
+
+ Mvpkm_WakeGuest(vm, ACTION_ABORT);
+ break;
+ }
+
+ case MVPKM_CPU_INFO: {
+ struct MvpkmCpuInfo buf;
+ uint32 mpidr;
+
+#ifdef CONFIG_ARM_LPAE
+ DetermineMemAttrLPAE(&buf.attribMAN);
+ /**
+ * We need to add support to the LPV monitor for LPAE page tables if we
+ * want to use it on a LPAE host, due to the costs involved in
+ * transitioning between LPAE and non-LPAE page tables without Hyp
+ * assistance.
+ *
+ * @knownjira{MVP-2184}
+ */
+ buf.attribL2D.u = 0;
+#else
+ DetermineMemAttrNonLPAE(&buf.attribL2D, &buf.attribMAN);
+#endif
+ /*
+ * Are MP extensions implemented? See B4-1618 ARM DDI 0406C-2c for
+ * magic.
+ */
+ ARM_MRC_CP15(MPIDR, mpidr);
+
+ buf.mpExt = mpidr & ARM_CP15_MPIDR_MP;
+
+ if (copy_to_user((int *)arg, &buf, sizeof(struct MvpkmCpuInfo))) {
+ retval = -EFAULT;
+ }
+ break;
+ }
+
+ default: {
+ retval = -EINVAL;
+ break;
+ }
+ }
+
+ PRINTK(KERN_INFO "returning from IOCTL(%d) retval = %d %s\n",
+ cmd, retval, signal_pending(current)?"(pending signal)":"" );
+
+ return retval;
+}
+
+
+
+/*********************************************************************
+ *
+ * Locked page management
+ *
+ *********************************************************************/
+
+/*
+ * Pages locked by the kernel module are remembered so an unlockAll
+ * operation can be performed when the vmm is closed. The locked page
+ * identifiers are stored in a red-black tree to support O(log n)
+ * removal and search (required for /dev/mem-like mmap).
+ */
+
+/**
+ * @brief Descriptor of a locked page range
+ */
+typedef struct {
+ struct {
+ __u32 mpn : 20; ///< MPN.
+ __u32 order : 6; ///< Size/alignment exponent for page.
+ __u32 forRegion : 6; ///< Annotation to identify guest page allocation
+ } page;
+ struct rb_node rb;
+} LockedPage;
+
+static void FreeLockedPages(LockedPage *lp);
+
+/**
+ * @brief Search for an mpn inside a RB tree of LockedPages. The mpn
+ * will match a LockedPage as long as it is covered by the
+ * entry, i.e. in a non-zero order entry it doesn't have to be
+ * the base MPN.
+ *
+ * This must be called with the relevant vm->lockedSem held.
+ *
+ * @param root RB tree root.
+ * @param mpn MPN to search for.
+ *
+ * @return reference to LockedPage entry if found, otherwise NULL.
+ */
+static LockedPage *
+LockedListSearch(struct rb_root *root, __u32 mpn)
+{
+ struct rb_node *n = root->rb_node;
+
+ while (n) {
+ LockedPage *lp = rb_entry(n, LockedPage, rb);
+
+ if (lp->page.mpn == (mpn & (~0UL << lp->page.order))) {
+ return lp;
+ }
+
+ if (mpn < lp->page.mpn) {
+ n = n->rb_left;
+ } else {
+ n = n->rb_right;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Delete an mpn from the list of locked pages.
+ *
+ * @param vm Mvpkm module control structure pointer
+ * @param mpn MPN to be unlocked and freed for reuse
+ * @return true if list contained MPN and it was deleted from list
+ */
+
+static _Bool
+LockedListDel(MvpkmVM *vm, __u32 mpn)
+{
+ LockedPage *lp;
+
+ down_write(&vm->lockedSem);
+
+ lp = LockedListSearch(&vm->lockedRoot, mpn);
+
+ /*
+ * The MPN should be in the locked pages RB tree and it should be the
+ * base of an entry, i.e. we can't fragment existing allocations for
+ * a VM.
+ */
+ if (lp == NULL || lp->page.mpn != mpn) {
+ up_write(&vm->lockedSem);
+ return false;
+ }
+
+ FreeLockedPages(lp);
+
+ if (lp->page.forRegion == MEMREGION_MAINMEM) {
+ ATOMIC_SUBV(vm->usedPages, 1U << lp->page.order);
+ }
+
+ rb_erase(&lp->rb, &vm->lockedRoot);
+ kfree(lp);
+
+ up_write(&vm->lockedSem);
+
+ return true;
+}
+
+/**
+ * @brief Scan the list of locked pages to see if an MPN matches.
+ *
+ * @param vm Mvpkm module control structure pointer
+ * @param mpn MPN to check
+ *
+ * @return true iff list contains MPN.
+ */
+static _Bool
+LockedListLookup(MvpkmVM *vm, __u32 mpn)
+{
+ LockedPage *lp;
+
+ down_read(&vm->lockedSem);
+
+ lp = LockedListSearch(&vm->lockedRoot, mpn);
+
+ up_read(&vm->lockedSem);
+
+ return lp != NULL;
+}
+
+/**
+ * @brief Add a new mpn to the locked pages RB tree.
+ *
+ * @param vm control structure pointer
+ *
+ * @param mpn mpn of page that was locked with get_user_pages or some sort of
+ * get that is undone by put_page.
+ * The mpn is assumed to be non-zero
+ * @param order size/alignment exponent for page
+ * @param forRegion Annotation for Page pool to identify guest page allocations
+ *
+ * @return false: couldn't allocate internal memory to record mpn in<br>
+ * true: successful.
+ */
+static _Bool
+LockedListAdd(MvpkmVM *vm,
+ __u32 mpn,
+ __u32 order,
+ PhysMem_RegionType forRegion)
+{
+ struct rb_node *parent, **p;
+ LockedPage *tp, *lp = kmalloc(sizeof *lp, GFP_KERNEL);
+
+ if (!lp) {
+ return false;
+ }
+
+ lp->page.mpn = mpn;
+ lp->page.order = order;
+ lp->page.forRegion = forRegion;
+
+ down_write(&vm->lockedSem);
+
+ if (forRegion == MEMREGION_MAINMEM) {
+ ATOMIC_ADDV(vm->usedPages, 1U << order);
+ }
+
+ /*
+ * Insert as a red leaf in the tree (see include/linux/rbtree.h).
+ */
+ p = &vm->lockedRoot.rb_node;
+ parent = NULL;
+
+ while (*p) {
+ parent = *p;
+ tp = rb_entry(parent, LockedPage, rb);
+
+ /*
+ * MPN should not already exist in the tree.
+ */
+ ASSERT(tp->page.mpn != (mpn & (~0UL << tp->page.order)));
+
+ if (mpn < tp->page.mpn) {
+ p = &(*p)->rb_left;
+ } else {
+ p = &(*p)->rb_right;
+ }
+ }
+
+ rb_link_node(&lp->rb, parent, p);
+
+ /*
+ * Restructure tree if necessary (see include/linux/rbtree.h).
+ */
+ rb_insert_color(&lp->rb, &vm->lockedRoot);
+
+ up_write(&vm->lockedSem);
+
+ return true;
+}
+
+/**
+ * @brief Traverse RB locked tree, freeing every entry.
+ *
+ * This must be called with the relevant vm->lockedSem held.
+ *
+ * @param node reference to RB node at root of subtree.
+ */
+static void
+LockedListNuke(struct rb_node *node)
+{
+ while (node) {
+ if (node->rb_left) {
+ node = node->rb_left;
+ } else if (node->rb_right) {
+ node = node->rb_right;
+ } else {
+ /*
+ * We found a leaf, free it and go back to parent.
+ */
+ LockedPage *lp = rb_entry(node, LockedPage, rb);
+
+ if ((node = rb_parent(node))) {
+ if (node->rb_left) {
+ node->rb_left = NULL;
+ } else {
+ node->rb_right = NULL;
+ }
+ }
+
+ FreeLockedPages(lp);
+ kfree(lp);
+ }
+ }
+}
+
+/**
+ * @brief Unlock all pages at vm close time.
+ *
+ * @param vm control structure pointer
+ */
+static void
+LockedListUnlockAll(MvpkmVM *vm)
+{
+
+ down_write(&vm->lockedSem);
+
+ LockedListNuke(vm->lockedRoot.rb_node);
+
+ ATOMIC_SETV(vm->usedPages, 0);
+
+ up_write(&vm->lockedSem);
+}
+
+
+/**
+ * @brief Allocate zeroed free pages
+ *
+ * @param[in] vm which VM the pages are for so they will be freed when the vm
+ * closes
+ * @param[in] order log2(number of contiguous pages to allocate)
+ * @param[in] highmem is it OK to allocate this page in ZONE_HIGHMEM? This
+ * option should only be specified for pages the host kernel
+ * will not need to address directly.
+ * @param[out] hkvaRet where to return host kernel virtual address of the
+ * allocated pages, if non-NULL, and ONLY IF !highmem.
+ * @param forRegion Annotation for Page pool to identify guest page allocations
+ * @return 0: no host memory available<br>
+ * else: starting MPN<br>
+ * *hkvaRet = filled in
+ */
+static MPN
+AllocZeroedFreePages(MvpkmVM *vm,
+ uint32 order,
+ _Bool highmem,
+ PhysMem_RegionType forRegion,
+ HKVA *hkvaRet)
+{
+ MPN mpn;
+ struct page *page;
+
+ if (order > PAGE_ALLOC_COSTLY_ORDER) {
+ printk(KERN_WARNING "Order %d allocation for region %d exceeds the safe "
+ "maximum order %d\n",
+ order,
+ forRegion,
+ PAGE_ALLOC_COSTLY_ORDER);
+ }
+
+ /*
+ * Get some pages for the requested range. They will be physically
+ * contiguous and have the requested alignment. They will also
+ * have a kernel virtual mapping if !highmem.
+ *
+ * We allocate out of ZONE_MOVABLE even though we can't just pick up our
+ * bags. We do this to support platforms that explicitly configure
+ * ZONE_MOVABLE, such as the Qualcomm MSM8960, to enable deep power down of
+ * memory banks. When the kernel attempts to take a memory bank offline, it
+ * will try and place the pages on the isolate LRU - only pages already on an
+ * LRU, such as anon/file, can get there, so it will not be able to
+ * migrate/move our pages (and hence the bank will not be offlined). The
+ * other alternative is to live withing ZONE_NORMAL, and only have available
+ * a small fraction of system memory. Long term we plan on hooking the
+ * offlining callback in mvpkm and perform our own migration with the
+ * cooperation of the monitor, but we don't have dev board to support this
+ * today.
+ *
+ * @knownjira{MVP-3477}
+ */
+ page = alloc_pages(GFP_USER | __GFP_COMP | __GFP_ZERO |
+ (highmem ? __GFP_HIGHMEM | __GFP_MOVABLE : 0),
+ order);
+
+ if (page == NULL) {
+ return 0;
+ }
+
+ /*
+ * Return the corresponding page number.
+ */
+ mpn = page_to_pfn(page);
+ ASSERT(mpn != 0);
+
+ /*
+ * Remember to unlock the pages when the FD is closed.
+ */
+ if (!LockedListAdd(vm, mpn, order, forRegion)) {
+ __free_pages(page, order);
+ return 0;
+ }
+
+ if (hkvaRet) {
+ *hkvaRet = highmem ? 0 : __phys_to_virt(page_to_phys(page));
+ }
+
+ return mpn;
+}
+
+/**
+ * @brief Map already-pinned WSP memory in host kernel virtual address(HKVA)
+ * space. Assumes 2 world switch pages on an 8k boundary.
+ *
+ * @param[in] vm which VM the HKVA Area is to be mapped for
+ * @param[in] mapInfo array of MPNs and execute permission flags to be used in
+ inserting a new contiguous map in HKVA space
+ * @return 0: HKVA space could not be mapped
+ else: HKVA where mapping was inserted
+ */
+static HKVA
+MapWSPHKVA(MvpkmVM *vm, HkvaMapInfo *mapInfo)
+{
+ unsigned int i;
+ struct page **pages = NULL;
+ struct page **pagesPtr;
+ pgprot_t prot;
+ int retval;
+ int allocateCount = WSP_PAGE_COUNT + 1; // Reserve one page for alignment
+ int pageIndex = 0;
+ HKVA dummyPage = (HKVA)NULL;
+ HKVA start;
+ HKVA startSegment;
+ HKVA endSegment;
+
+ /*
+ * Add one page for alignment purposes in case __get_vm_area returns an
+ * unaligned address.
+ */
+ ASSERT(allocateCount == 3);
+ ASSERT_ON_COMPILE(WSP_PAGE_COUNT == 2);
+
+ /*
+ * NOT_IMPLEMENTED if MapHKVA is called more than once.
+ */
+ BUG_ON(vm->wspHkvaArea);
+
+ /*
+ * Reserve virtual address space.
+ */
+ vm->wspHkvaArea = __get_vm_area((allocateCount * PAGE_SIZE), VM_ALLOC, MODULES_VADDR, MODULES_END);
+ if (!vm->wspHkvaArea) {
+ return 0;
+ }
+
+ pages = kmalloc(allocateCount * sizeof(struct page *), GFP_TEMPORARY);
+ if (!pages) {
+ goto err;
+ }
+ pagesPtr = pages;
+
+ /*
+ * Use a dummy page to boundary align the section, if needed.
+ */
+ dummyPage = __get_free_pages(GFP_KERNEL, 0);
+ if (!dummyPage) {
+ goto err;
+ }
+ vm->wspHKVADummyPage = dummyPage;
+
+ /*
+ * Back every entry with the dummy page.
+ */
+ for (i = 0; i < allocateCount; i++) {
+ pages[i] = virt_to_page(dummyPage);
+ }
+
+ /*
+ * World switch pages must not span a 1MB boundary in order to maintain only
+ * a single L2 page table.
+ */
+ start = (HKVA)vm->wspHkvaArea->addr;
+ startSegment = start & ~(ARM_L1D_SECTION_SIZE - 1);
+ endSegment = (start + PAGE_SIZE) & ~(ARM_L1D_SECTION_SIZE - 1);
+ /*
+ * Insert dummy page at pageIndex, if needed.
+ */
+ pageIndex = (startSegment != endSegment);
+
+ /*
+ * Back the rest with the actual world switch pages
+ */
+ for (i = pageIndex; i < pageIndex + WSP_PAGE_COUNT; i++) {
+ pages[i] = pfn_to_page(mapInfo[i - pageIndex].mpn);
+ }
+
+ /*
+ * Given the lack of functionality in the kernel for being able to mark
+ * mappings for a given vm area with different sets of protection bits,
+ * we simply mark the entire vm area as PAGE_KERNEL_EXEC for now
+ * (i.e., union of all the protection bits). Given that the kernel
+ * itself does something similar while loading modules, this should be a
+ * reasonable workaround for now. In the future, we should set the
+ * protection bits to strictly adhere to what has been requested in the
+ * mapInfo parameter.
+ */
+ prot = PAGE_KERNEL_EXEC;
+
+ retval = map_vm_area(vm->wspHkvaArea, prot, &pagesPtr);
+ if (retval < 0) {
+ goto err;
+ }
+
+ kfree(pages);
+
+ return (HKVA)(vm->wspHkvaArea->addr) + pageIndex * PAGE_SIZE;
+
+err:
+ if (dummyPage) {
+ free_pages(dummyPage, 0);
+ vm->wspHKVADummyPage = (HKVA)NULL;
+ }
+
+ if (pages) {
+ kfree(pages);
+ }
+
+ free_vm_area(vm->wspHkvaArea);
+ vm->wspHkvaArea = (HKVA)NULL;
+
+ return 0;
+}
+
+static void
+UnmapWSPHKVA(MvpkmVM *vm)
+{
+ if (vm->wspHkvaArea) {
+ free_vm_area(vm->wspHkvaArea);
+ }
+
+ if (vm->wspHKVADummyPage) {
+ free_pages(vm->wspHKVADummyPage, 0);
+ vm->wspHKVADummyPage = (HKVA)NULL;
+ }
+}
+
+/**
+ * @brief Clean and release locked pages
+ *
+ * @param lp Reference to the locked pages
+ */
+static void
+FreeLockedPages(LockedPage *lp)
+{
+ struct page *page;
+ int count;
+
+ page = pfn_to_page(lp->page.mpn);
+ count = page_count(page);
+
+ if (count == 0) {
+ printk(KERN_ERR "%s: found locked page with 0 reference (mpn %05x)\n",
+ __func__, lp->page.mpn);
+ return;
+ }
+
+ if (count == 1) {
+ int i;
+
+ /*
+ * There is no other user for this page, clean it.
+ *
+ * We don't bother checking if the page was highmem or not, clear_highmem
+ * works for both.
+ * We clear the content of the page, and rely on the fact that the previous
+ * worldswitch has cleaned the potential VIVT I-CACHE.
+ */
+ for (i = 0; i < (1 << lp->page.order); i++) {
+ clear_highpage(page + i);
+ }
+ } else if (lp->page.forRegion != MEMREGION_MAINMEM) {
+ printk(KERN_WARNING "%s: mpn 0x%05x for region %d is still in use\n",
+ __func__, lp->page.mpn, lp->page.forRegion);
+ }
+
+ __free_pages(page, lp->page.order);
+}
+
+/*********************************************************************
+ *
+ * Communicate with monitor
+ *
+ *********************************************************************/
+
+/**
+ * @brief Register a new monitor page.
+ *
+ * @param vm which virtual machine we're running
+ * @return 0: successful<br>
+ * else: -errno
+ */
+static int
+SetupMonitor(MvpkmVM *vm)
+{
+ int retval;
+ WorldSwitchPage *wsp = vm->wsp;
+
+ if (!wsp ||
+ wsp->wspHKVA != (HKVA)wsp) {
+ return -EINVAL;
+ }
+
+ if ((retval = Mksck_WspInitialize(vm))) {
+ return retval;
+ }
+
+ vm->kobj.kset = mvpkmKSet;
+ retval = kobject_init_and_add(&vm->kobj, &mvpkmKType, NULL, "%d", wsp->guestId);
+ if (retval) {
+ goto error;
+ }
+
+ /*
+ * Get a reference to this module such that it cannot be unloaded until
+ * our kobject's release function completes.
+ */
+
+ __module_get(THIS_MODULE);
+ vm->haveKObj = true;
+
+ /*
+ * Caution: From here on, if we fail, we must not call kobject_put()
+ * on vm->kobj since that may / will deallocate 'vm'. Unregistering VM
+ * ksets on failures, is fine and should be done for proper ref counting.
+ */
+
+ vm->devicesKSet = kset_create_and_add("devices", NULL, &vm->kobj);
+ if (!vm->devicesKSet) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ vm->miscKSet = kset_create_and_add("misc", NULL, &vm->kobj);
+ if (!vm->miscKSet) {
+ kset_unregister(vm->devicesKSet);
+ vm->devicesKSet = NULL;
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ down_write(&vm->wspSem);
+
+ /*
+ * The VE monitor needs to issue a SMC to bootstrap Hyp mode.
+ */
+ if (wsp->monType == MONITOR_TYPE_VE) {
+ /*
+ * Here we assemble the monitor's HMAIR0 based on wsp->memAttr. We map
+ * from the inner/outer normal page cacheability attributes obtained
+ * from DetermineCacheabilityAttribs to the format required in 4.2.8
+ * ARM PRD03-GENC-008469 13.0 (see this document for the magic numbers).
+ *
+ * Where a choice is available, we opt for read and/or write allocation.
+ */
+ static const uint32 normalCacheAttr2MAIR[4] = { 0x4, 0xf, 0xa, 0xe };
+
+ uint32 hmair0 =
+ ((normalCacheAttr2MAIR[wsp->memAttr.innerCache] |
+ (normalCacheAttr2MAIR[wsp->memAttr.outerCache] << 4))
+ << 8 * MVA_MEMORY) |
+ (0x4 << 8 * MVA_DEVICE);
+
+ /*
+ * See B4.1.74 ARM DDI 0406C-2c for the HTCR magic.
+ */
+ uint32 htcr =
+ 0x80000000 |
+ (wsp->memAttr.innerCache << 8) |
+ (wsp->memAttr.outerCache << 10) |
+ (wsp->memAttr.share << 12);
+
+ /**
+ * @knownjira{MVP-377}
+ * Set HSCTLR to enable MMU and caches. We should really run the
+ * monitor WXN, in non-MVP_DEVEL builds. See
+ * 13.18 ARM PRD03-GENC-008353 11.0 for the magic.
+ */
+ static const uint32 hsctlr = 0x30c5187d;
+
+ register uint32 r0 asm("r0") = wsp->monVA.excVec;
+ register uint32 r1 asm("r1") = wsp->regSave.ve.mHTTBR;
+ register uint32 r2 asm("r2") = htcr;
+ register uint32 r3 asm("r3") = hmair0;
+ register uint32 r4 asm("r4") = hsctlr;
+
+ asm volatile (
+ "smc 0"
+ :
+ : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4)
+ : "memory"
+ );
+ }
+
+ /*
+ * Initialize guest wait-for-interrupt waitqueue.
+ */
+ init_waitqueue_head(&vm->wfiWaitQ);
+
+ MonitorTimer_Setup(vm);
+
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock_init(&vm->wakeLock, WAKE_LOCK_SUSPEND, "mvpkm");
+#endif
+
+ wsp->mvpkmVersion = MVP_VERSION_CODE;
+ up_write(&vm->wspSem);
+ /*
+ * Ensure coherence of monitor loading and page tables.
+ */
+ flush_cache_all();
+ return 0;
+
+error:
+ Mksck_WspRelease(wsp);
+ vm->wsp = NULL;
+ return retval;
+}
+
+/**
+ * @brief dummy function to drop the info parameter
+ * @param info ignored
+ */
+static
+void FlushAllCpuCaches(void *info)
+{
+ flush_cache_all();
+}
+
+/**
+ * @brief return to where monitor called worldswitch
+ *
+ * @param vm which virtual machine we're running
+ * @return 0: successful, just call back when ready<br>
+ * 1: successful, process code in WSP_Params(wsp)->callno<br>
+ * else: -errno
+ */
+static int
+RunMonitor(MvpkmVM *vm)
+{
+ int ii;
+ unsigned long flags;
+ WorldSwitchPage *wsp = vm->wsp;
+ int retval = 0;
+
+ ASSERT(wsp);
+
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_lock(&vm->wakeLock);
+#endif
+
+ /*
+ * Set VCPUThread affinity
+ */
+ if (cpumask_intersects(to_cpumask(vcpuAffinity), cpu_active_mask)) {
+ set_cpus_allowed_ptr(current, to_cpumask(vcpuAffinity));
+ }
+
+ /*
+ * Record the the current task structure, so an ABORT will know,
+ * who to wake.
+ */
+ down_write(&vm->monThreadTaskSem);
+ vm->monThreadTask = get_current();
+ up_write(&vm->monThreadTaskSem);
+
+ /*
+ * Keep going as long as the monitor is in critical section or
+ * there are no pending signals such as SIGINT or SIGKILL. Block
+ * interrupts before checking so any IPI sent will remain pending
+ * if our check just misses detecting the signal.
+ */
+ local_irq_save(flags);
+ while (wsp->critSecCount > 0 ||
+ (!signal_pending(current) &&
+ !(ATOMIC_GETO(wsp->hostActions) & ACTION_ABORT))) {
+ /*
+ * ARMv7 Performance counters are per CPU core and might be disabled over
+ * CPU core sleep if there is nothing else in the system to re-enable
+ * them, so now that we have been allocated a CPU core to run the guest,
+ * enable them and in particular the TSC (CCNT) which is used for monitor
+ * timing between world switches.
+ */
+ {
+ uint32 pmnc;
+ uint32 pmcnt;
+
+ /* make sure that the Performance Counters are enabled */
+ ARM_MRC_CP15(PERF_MON_CONTROL_REGISTER, pmnc);
+ if ((pmnc & (ARM_PMNC_E | ARM_PMNC_D)) != (ARM_PMNC_E)) {
+ pmnc |= ARM_PMNC_E; // Enable TSC
+ pmnc &= ~ARM_PMNC_D; // Disable cycle count divider
+ ARM_MCR_CP15(PERF_MON_CONTROL_REGISTER, pmnc);
+ }
+
+ /* make sure that the CCNT is enabled */
+ ARM_MRC_CP15(PERF_MON_COUNT_SET, pmcnt);
+ if ((pmcnt & ARM_PMCNT_C) != ARM_PMCNT_C) {
+ pmcnt |= ARM_PMCNT_C;
+ ARM_MCR_CP15(PERF_MON_COUNT_SET, pmcnt);
+ }
+ }
+
+ /*
+ * Update TSC to RATE64 ratio
+ */
+ {
+ struct TscToRate64Cb *ttr = &__get_cpu_var(tscToRate64);
+ wsp->tscToRate64Mult = ttr->mult;
+ wsp->tscToRate64Shift = ttr->shift;
+ }
+
+ /*
+ * Save the time of day for the monitor's timer facility. The timing
+ * facility in the vmm needs to compute current time in the host linux's
+ * time representation. It uses the formula:
+ * now = wsp->switchedAt64 + (uint32)(TSC_READ() - wsp->lowerTSC)
+ *
+ * Read the timestamp counter *immediately after* ktime_get() as that
+ * will give the most consistent offset between reading the hardware
+ * clock register in ktime_get() and reading the hardware timestamp
+ * counter with TSC_READ().
+ */
+ ASSERT_ON_COMPILE(MVP_TIMER_RATE64 == NSEC_PER_SEC);
+ {
+ ktime_t now = ktime_get();
+ TSC_READ(wsp->switchedAtTSC);
+ wsp->switchedAt64 = ktime_to_ns(now);
+ }
+
+ /*
+ * Save host FPU contents and load monitor contents.
+ */
+ SWITCH_VFP_TO_MONITOR;
+
+ /*
+ * Call into the monitor to run guest instructions until it wants us to
+ * do something for it. Note that any hardware interrupt request will
+ * cause it to volunteer.
+ */
+ switch (wsp->monType) {
+ case MONITOR_TYPE_LPV: {
+ uint32 hostVBAR;
+
+ ARM_MRC_CP15(VECTOR_BASE, hostVBAR);
+ (*wsp->switchToMonitor)(&wsp->regSave);
+ ARM_MCR_CP15(VECTOR_BASE, hostVBAR);
+ break;
+ }
+ case MONITOR_TYPE_VE: {
+ register uint32 r1 asm("r1") = wsp->regSave.ve.mHTTBR;
+
+ asm volatile (
+ ".word " MVP_STRINGIFY(ARM_INSTR_HVC_A1_ENC(0))
+ : "=r" (r1) : "r" (r1) : "r0", "r2", "memory"
+ );
+ break;
+ }
+ default: FATAL();
+ }
+
+ /*
+ * Save monitor FPU contents and load host contents.
+ */
+ SWITCH_VFP_TO_HOST;
+
+ /*
+ * Re-enable local interrupts now that we are back in the host world
+ */
+ local_irq_restore(flags);
+
+
+ /*
+ * Maybe the monitor wrote some messages to monitor->host sockets.
+ * This will wake the corresponding host threads to receive them.
+ */
+ /**
+ * @todo This lousy loop is in the critical path. It should be changed
+ * to some faster algorithm to wake blocked host sockets.
+ */
+ for (ii = 0; ii < MKSCK_MAX_SHARES; ii++) {
+ if (wsp->isPageMapped[ii]) {
+ Mksck_WakeBlockedSockets(MksckPage_GetFromIdx(ii));
+ }
+ }
+
+ switch (WSP_Params(wsp)->callno) {
+ case WSCALL_ACQUIRE_PAGE: {
+ uint32 i;
+
+ for (i = 0; i < WSP_Params(wsp)->pages.pages; ++i) {
+ MPN mpn = AllocZeroedFreePages(vm,
+ WSP_Params(wsp)->pages.order,
+ true,
+ WSP_Params(wsp)->pages.forRegion,
+ NULL);
+ if (mpn == 0) {
+ printk(KERN_WARNING "WSCALL_ACQUIRE_PAGE: no order %u pages available\n",
+ WSP_Params(wsp)->pages.order);
+ WSP_Params(wsp)->pages.pages = i;
+ break;
+ }
+
+ WSP_Params(wsp)->pages.mpns[i] = mpn;
+ }
+
+ break;
+ }
+ case WSCALL_RELEASE_PAGE: {
+ uint32 i;
+
+ for (i = 0; i < WSP_Params(wsp)->pages.pages; ++i) {
+ if (!LockedListDel(vm, WSP_Params(wsp)->pages.mpns[i])) {
+ WSP_Params(wsp)->pages.pages = i;
+ break;
+ }
+ }
+
+ break;
+ }
+ case WSCALL_MUTEXLOCK: {
+ retval = Mutex_Lock((void *)WSP_Params(wsp)->mutex.mtxHKVA,
+ WSP_Params(wsp)->mutex.mode);
+
+ if (retval < 0) {
+ WSP_Params(wsp)->mutex.ok = false;
+ goto monitorExit;
+ }
+
+ /*
+ * The locking succeeded. From this point on the monitor
+ * is in critical section. Even if an interrupt comes
+ * right here, it must return to the monitor to unlock the
+ * mutex.
+ */
+ wsp->critSecCount++;
+ WSP_Params(wsp)->mutex.ok = true;
+ break;
+ }
+ case WSCALL_MUTEXUNLOCK: {
+ Mutex_Unlock((void *)WSP_Params(wsp)->mutex.mtxHKVA,
+ WSP_Params(wsp)->mutex.mode);
+ break;
+ }
+ case WSCALL_MUTEXUNLSLEEP: {
+ /*
+ * The vcpu has just come back from the monitor. During
+ * the transition interrupts were disabled. Above,
+ * however, interrupts were enabled again and it is
+ * possible that a context switch happened into a thread
+ * (serve_vmx) that instructed the vcpu thread to
+ * abort. After returning to this thread the vcpu may
+ * enter a sleep below never to return from it. To avoid
+ * this deadlock we need to test the abort flag in
+ * Mutex_UnlSleepTest.
+ */
+ retval =
+ Mutex_UnlSleepTest((void *)WSP_Params(wsp)->mutex.mtxHKVA,
+ WSP_Params(wsp)->mutex.mode,
+ WSP_Params(wsp)->mutex.cvi,
+ &wsp->hostActions,
+ ACTION_ABORT);
+ if (retval < 0) {
+ goto monitorExit;
+ }
+ break;
+ }
+ case WSCALL_MUTEXUNLWAKE: {
+ Mutex_UnlWake((void *)WSP_Params(wsp)->mutex.mtxHKVA,
+ WSP_Params(wsp)->mutex.mode,
+ WSP_Params(wsp)->mutex.cvi,
+ WSP_Params(wsp)->mutex.all);
+ break;
+ }
+
+ /*
+ * The monitor wants us to block (allowing other host threads to run)
+ * until an async message is waiting for the monitor to process.
+ *
+ * If MvpkmWaitForInt() returns an error, it should only be if there
+ * is another signal pending (such as SIGINT). So we pretend it
+ * completed normally, as the monitor is ready to be called again (it
+ * will see no messages to process and wait again), and return to user
+ * mode so the signals can be processed.
+ */
+ case WSCALL_WAIT: {
+#ifdef CONFIG_HAS_WAKELOCK
+ if (WSP_Params(wsp)->wait.suspendMode) {
+ /* guest has ok'ed suspend mode, so release SUSPEND wakelock */
+ wake_unlock(&vm->wakeLock);
+ retval = MvpkmWaitForInt(vm, true);
+ wake_lock(&vm->wakeLock);
+ WSP_Params(wsp)->wait.suspendMode = 0;
+ } else {
+ /* guest has asked for WFI not suspend so keep holding SUSPEND
+ * wakelock */
+ retval = MvpkmWaitForInt(vm, false);
+ }
+#else
+ retval = MvpkmWaitForInt(vm, WSP_Params(wsp)->wait.suspendMode);
+#endif
+ if (retval < 0) {
+ goto monitorExit;
+ }
+ break;
+ }
+
+ /*
+ * The only reason the monitor returned was because there was a
+ * pending hardware interrupt. The host serviced and cleared that
+ * interrupt when we enabled interrupts above. Now we call the
+ * scheduler in case that interrupt woke another thread, we want to
+ * allow that thread to run before returning to do more guest code.
+ */
+ case WSCALL_IRQ: {
+ break;
+ }
+
+ case WSCALL_GET_PAGE_FROM_VMID: {
+ MksckPage *mksckPage;
+ mksckPage = MksckPage_GetFromVmIdIncRefc(WSP_Params(wsp)->pageMgmnt.vmId);
+
+ if (mksckPage) {
+ int ii;
+
+ WSP_Params(wsp)->pageMgmnt.found = true;
+ for (ii = 0; ii < MKSCKPAGE_TOTAL; ii++) {
+ WSP_Params(wsp)->pageMgmnt.mpn[ii] =
+ vmalloc_to_pfn( (void*)(((HKVA)mksckPage) + ii*PAGE_SIZE) );
+ }
+
+ ASSERT(!wsp->isPageMapped[MKSCK_VMID2IDX(mksckPage->vmId)]);
+ wsp->isPageMapped[MKSCK_VMID2IDX(mksckPage->vmId)] = true;
+ } else {
+ WSP_Params(wsp)->pageMgmnt.found = false;
+ }
+ break;
+ }
+
+ case WSCALL_REMOVE_PAGE_FROM_VMID: {
+ MksckPage *mksckPage;
+ mksckPage = MksckPage_GetFromVmId(WSP_Params(wsp)->pageMgmnt.vmId);
+ ASSERT(wsp->isPageMapped[MKSCK_VMID2IDX(mksckPage->vmId)]);
+ wsp->isPageMapped[MKSCK_VMID2IDX(mksckPage->vmId)] = false;
+ MksckPage_DecRefc(mksckPage);
+ break;
+ }
+
+ /*
+ * Read current wallclock time.
+ */
+ case WSCALL_READTOD: {
+ struct timeval nowTV;
+ do_gettimeofday(&nowTV);
+ WSP_Params(wsp)->tod.now = nowTV.tv_sec;
+ WSP_Params(wsp)->tod.nowusec = nowTV.tv_usec;
+ break;
+ }
+
+ case WSCALL_LOG: {
+ int len = strlen(WSP_Params(wsp)->log.messg);
+ printk(KERN_INFO
+ "VMM: %s%s",
+ WSP_Params(wsp)->log.messg,
+ (WSP_Params(wsp)->log.messg[len-1] == '\n') ? "" : "\n");
+ break;
+ }
+
+ case WSCALL_ABORT: {
+ retval = WSP_Params(wsp)->abort.status;
+ goto monitorExit;
+ }
+
+ case WSCALL_QP_GUEST_ATTACH: {
+ int32 rc;
+ QPInitArgs args;
+ uint32 base;
+ uint32 nrPages;
+
+ args.id = WSP_Params(wsp)->qp.id;
+ args.capacity = WSP_Params(wsp)->qp.capacity;
+ args.type = WSP_Params(wsp)->qp.type;
+ base = WSP_Params(wsp)->qp.base;
+ nrPages = WSP_Params(wsp)->qp.nrPages;
+
+ rc = QP_GuestAttachRequest(vm, &args, base, nrPages);
+
+ WSP_Params(wsp)->qp.rc = rc;
+ WSP_Params(wsp)->qp.id = args.id;
+ break;
+ }
+
+ case WSCALL_QP_NOTIFY: {
+ QPInitArgs args;
+
+ args.id = WSP_Params(wsp)->qp.id;
+ args.capacity = WSP_Params(wsp)->qp.capacity;
+ args.type = WSP_Params(wsp)->qp.type;
+
+ WSP_Params(wsp)->qp.rc = QP_NotifyListener(&args);
+ break;
+ }
+
+ case WSCALL_MONITOR_TIMER: {
+ MonitorTimer_Request(&vm->monTimer, WSP_Params(wsp)->timer.when64);
+ break;
+ }
+
+ case WSCALL_COMM_SIGNAL: {
+ Mvpkm_CommEvSignal(&WSP_Params(wsp)->commEvent.transpID,
+ WSP_Params(wsp)->commEvent.event);
+ break;
+ }
+
+ case WSCALL_FLUSH_ALL_DCACHES: {
+ /*
+ * Broadcast Flush DCache request to all cores.
+ * Block while waiting for all of them to get done.
+ */
+ on_each_cpu(FlushAllCpuCaches, NULL, 1);
+ break;
+ }
+ default: {
+ retval = -EPIPE;
+ goto monitorExit;
+ }
+ }
+
+ /*
+ * The params.callno callback was handled in kernel mode and completed
+ * successfully. Repeat for another call without returning to user mode,
+ * unless there are signals pending.
+ *
+ * But first, call the Linux scheduler to switch threads if there is
+ * some other thread Linux wants to run now.
+ */
+ if (need_resched()) {
+ schedule();
+ }
+
+ /*
+ * Check if cpus allowed mask has to be updated.
+ * Updating it must be done outside of an atomic context.
+ */
+ if (cpumask_intersects(to_cpumask(vcpuAffinity), cpu_active_mask) &&
+ !cpumask_equal(to_cpumask(vcpuAffinity), &current->cpus_allowed)) {
+ set_cpus_allowed_ptr(current, to_cpumask(vcpuAffinity));
+ }
+
+ local_irq_save(flags);
+ }
+
+ /*
+ * There are signals pending so don't try to do any more monitor/guest
+ * stuff. But since we were at the point of just about to run the monitor,
+ * return success status as user mode can simply call us back to run the
+ * monitor again.
+ */
+ local_irq_restore(flags);
+
+monitorExit:
+ ASSERT(wsp->critSecCount == 0);
+
+ if (ATOMIC_GETO(wsp->hostActions) & ACTION_ABORT) {
+ PRINTK(KERN_INFO "Monitor has ABORT flag set.\n");
+ retval = ExitStatusHostRequest;
+ }
+
+#ifdef CONFIG_HAS_WAKELOCK
+ wake_unlock(&vm->wakeLock);
+#endif
+
+ down_write(&vm->monThreadTaskSem);
+ vm->monThreadTask = NULL;
+ up_write(&vm->monThreadTaskSem);
+
+ return retval;
+}
+
+/**
+ * @brief Guest is waiting for interrupts, sleep if necessary
+ *
+ * @param vm which virtual machine we're running
+ * @param suspend is the guest entering suspend or just WFI?
+ * @return 0: woken up, hostActions should have pending events
+ * -ERESTARTSYS: broke out because other signals are pending
+ *
+ * This function is called in the VCPU context after the world switch to wait
+ * for an incoming message. If any message gets queued to this VCPU, the
+ * sender will wake us up.
+ */
+int
+MvpkmWaitForInt(MvpkmVM *vm, _Bool suspend)
+{
+ WorldSwitchPage *wsp = vm->wsp;
+ wait_queue_head_t *q = &vm->wfiWaitQ;
+
+ if (suspend) {
+ return wait_event_interruptible(*q, ATOMIC_GETO(wsp->hostActions) != 0);
+ } else {
+ int ret;
+ ret = wait_event_interruptible_timeout(*q, ATOMIC_GETO(wsp->hostActions) != 0, 10*HZ);
+ if (ret == 0) {
+ printk("MvpkmWaitForInt: guest stuck for 10s in WFI! (hostActions %08x)\n",
+ ATOMIC_GETO(wsp->hostActions));
+ }
+ return ret > 0 ? 0 : ret;
+ }
+}
+
+
+/**
+ * @brief Force the guest to evaluate its hostActions flag field
+ *
+ * @param vm which guest needs waking
+ * @param why why should be guest be woken up?
+ *
+ * This function updates the hostAction flag field as and wakes up the guest as
+ * required so that it can evaluate it. The guest could be executing guest
+ * code in an SMP system, in that case send an IPI; or it could be sleeping, in
+ * the case wake it up.
+ */
+void
+Mvpkm_WakeGuest(MvpkmVM *vm, int why)
+{
+ ASSERT(why != 0);
+
+ /* set the host action */
+ if (ATOMIC_ORO(vm->wsp->hostActions, why) & why) {
+ /* guest has already been woken up so no need to do it again */
+ return;
+ }
+
+ /*
+ * VCPU is certainly in 'wait for interrupt' wait. Wake it up !
+ */
+#ifdef CONFIG_HAS_WAKELOCK
+ /*
+ * To prevent the system to go in suspend mode before the monitor had a
+ * chance on being scheduled, we will hold the VM wakelock from now.
+ * As the wakelocks are not managed as reference counts, this is not an
+ * an issue to take a wake_lock twice in a row.
+ */
+ wake_lock(&vm->wakeLock);
+#endif
+
+ /*
+ * On a UP system, we ensure the monitor thread isn't blocked.
+ *
+ * On an MP system the other CPU might be running the guest. This
+ * is noop on UP.
+ *
+ * When the guest is running, it is an invariant that monThreadTaskSem is not
+ * held as a write lock, so we should not fail to acquire the lock.
+ * Mvpkm_WakeGuest may be called from an atomic context, so we can't sleep
+ * here.
+ */
+ if (down_read_trylock(&vm->monThreadTaskSem)) {
+ if (vm->monThreadTask) {
+ wake_up_process(vm->monThreadTask);
+ kick_process(vm->monThreadTask);
+ }
+ up_read(&vm->monThreadTaskSem);
+ } else {
+ printk("Unexpected failure to acquire monThreadTaskSem!\n");
+ }
+}
diff --git a/arch/arm/mvp/mvpkm/mvpkm_private.h b/arch/arm/mvp/mvpkm/mvpkm_private.h
new file mode 100644
index 0000000..3dfc8d4
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvpkm_private.h
@@ -0,0 +1,97 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Private interface between user level wrappers and kernel module.
+ * The communication uses the ioctl linux call. The command operand is one
+ * of the MVPKM_xxx macros defined below, the custom operand is a pointer
+ * to the respective structure below.
+ */
+
+
+#ifndef _MVPKMPRIVATE_H
+#define _MVPKMPRIVATE_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include <linux/ioctl.h>
+/*
+ * For details how to create ioctl numbers, see
+ * Documentation/ioctl/ioctl-number.txt. The letter '9' is
+ * unused. The 0xa0-0xaf block is even more unused. Note however, that
+ * ioctl numbers are desired to be unique for debug purposes, they
+ * may conflict.
+ */
+#define MVP_IOCTL_LETTER '9'
+#define MVPKM_DISABLE_FAULT _IO( MVP_IOCTL_LETTER, 0xa0)
+#define MVPKM_LOCK_MPN _IOW(MVP_IOCTL_LETTER, 0xa1, MvpkmLockMPN)
+#define MVPKM_UNLOCK_MPN _IOW(MVP_IOCTL_LETTER, 0xa2, MvpkmLockMPN)
+#define MVPKM_RUN_MONITOR _IO( MVP_IOCTL_LETTER, 0xa3)
+#define MVPKM_CPU_INFO _IOR(MVP_IOCTL_LETTER, 0xa4, MvpkmCpuInfo)
+#define MVPKM_ABORT_MONITOR _IO( MVP_IOCTL_LETTER, 0xa5)
+#define MVPKM_MAP_WSPHKVA _IOW(MVP_IOCTL_LETTER, 0xa7, MvpkmMapHKVA)
+
+#include "mksck.h"
+#include "monva_common.h"
+#include "mvpkm_types.h"
+
+/**
+ * @brief Operand for the MVPKM_LOCK_MPN call
+ */
+typedef struct MvpkmLockMPN {
+ uint32 order; /* IN */
+ PhysMem_RegionType forRegion; /* IN */
+ uint32 mpn; /* OUT */
+} MvpkmLockMPN;
+
+/**
+ * @brief Operand for the MVPKM_MAP_HKVA call
+ */
+typedef struct MvpkmMapHKVA {
+ HkvaMapInfo *mapInfo; /* IN */
+ PhysMem_RegionType forRegion; /* IN */
+ HKVA hkva; /* OUT */
+} MvpkmMapHKVA;
+
+#define WSP_PAGE_COUNT 2
+
+/**
+ * @brief Operand for the MVPKM_CPU_INFO call
+ */
+typedef struct MvpkmCpuInfo {
+ ARM_L2D attribL2D; /* OUT */
+ ARM_MemAttrNormal attribMAN; /* OUT */
+ _Bool mpExt; /* OUT */
+} MvpkmCpuInfo;
+
+/**
+ * @brief These magic numbers mark the beginning and end of the
+ * special page that is mapped into the virtual address space of MVPD
+ * when it's monitor coredumper requests an unavailable page.
+ */
+#define MVPKM_STUBPAGE_BEG 0x78d10c67
+#define MVPKM_STUBPAGE_END 0x8378f3dd
+#endif
diff --git a/arch/arm/mvp/mvpkm/mvpkm_types.h b/arch/arm/mvp/mvpkm/mvpkm_types.h
new file mode 100644
index 0000000..ce23554
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/mvpkm_types.h
@@ -0,0 +1,49 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Types used in the interface between users, user level wrappers,
+ * and the kernel module implementation.
+ */
+
+
+#ifndef _MVPKMTYPES_H
+#define _MVPKMTYPES_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+
+/**
+ * @brief HkvaMapInfo structure describing the mpn and execute permission
+ * flag to use to map a given page in HKVA space
+ */
+typedef struct HkvaMapInfo {
+ uint32 mpn;
+ _Bool write;
+ _Bool exec;
+} HkvaMapInfo;
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/nottested.h b/arch/arm/mvp/mvpkm/nottested.h
new file mode 100644
index 0000000..5226a22
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/nottested.h
@@ -0,0 +1,54 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief NOT_TESTED() and related.
+ */
+
+#ifndef _NOTTESTED_H
+#define _NOTTESTED_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include <stdbool.h>
+
+#ifdef NOT_TESTED_ENABLED
+#define NotTestedEnabled true
+#else
+#define NotTestedEnabled false
+#endif
+
+#define NOT_TESTED() NOT_TESTED_JIRA(0)
+#define NOT_TESTED_JIRA(_tkt,...) NotTested(_tkt, __FILE__, __LINE__)
+
+void NotTested(int tkt, char const *file, int line);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/platdefx.h b/arch/arm/mvp/mvpkm/platdefx.h
new file mode 100644
index 0000000..70fb8d7
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/platdefx.h
@@ -0,0 +1,67 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Basic platform definitions needed various places.
+ */
+
+#ifndef _PLATDEFX_H
+#define _PLATDEFX_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define PAGE_ORDER 12
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE (1UL << PAGE_ORDER)
+#endif
+#if PAGE_SIZE != 4096
+#error bad page size PAGE_SIZE
+#endif
+
+#define PA_2_PPN(_pa) ((_pa) / PAGE_SIZE)
+#define PPN_2_PA(_ppn) ((_ppn) * PAGE_SIZE)
+
+#define VMM_DOMAIN 0x0
+#define VMM_DOMAIN_NO_ACCESS 0x3
+#define VMM_DOMAIN_CLIENT 0x1
+#define VMM_DOMAIN_MANAGER 0x4
+
+#define INVALID_CVA (-(CVA)1)
+#define INVALID_GVA (-(GVA)1)
+#define INVALID_MVA (-(MVA)1)
+#define INVALID_HKVA (-(HKVA)1)
+#define INVALID_HUVA (-(HUVA)1)
+
+#define INVALID_MPN (((MPN)-1) >> ARM_L2D_SMALL_ORDER)
+#define INVALID_PPN (((PPN)-1) >> ARM_L2D_SMALL_ORDER)
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/psr_defs.h b/arch/arm/mvp/mvpkm/psr_defs.h
new file mode 100644
index 0000000..4fa53bc
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/psr_defs.h
@@ -0,0 +1,117 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Constant definitions for ARM CPSR/SPSR registers. See A2.5
+ * ARM DDI 0100I.
+ */
+
+#ifndef _PSR_DEFS_H_
+#define _PSR_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define ARM_PSR_MODE_USER 0x10
+#define ARM_PSR_MODE_FIQ 0x11
+#define ARM_PSR_MODE_IRQ 0x12
+#define ARM_PSR_MODE_SUPERVISOR 0x13
+#define ARM_PSR_MODE_ABORT 0x17
+#define ARM_PSR_MODE_HVC 0x1a
+#define ARM_PSR_MODE_UNDEFINED 0x1b
+#define ARM_PSR_MODE_SYSTEM 0x1f
+
+/* Bit 31: N */
+#define ARM_PSR_N (1 << 31)
+
+/* Bit 30: Z */
+#define ARM_PSR_Z (1 << 30)
+
+/* Bit 29: C */
+#define ARM_PSR_C (1 << 29)
+
+/* Bit 28: V */
+#define ARM_PSR_V (1 << 28)
+
+/* Bit 27: Q */
+#define ARM_PSR_Q (1 << 27)
+
+#define ARM_PSR_COND_FLAGS \
+ (ARM_PSR_N | ARM_PSR_Z | ARM_PSR_C | ARM_PSR_V | ARM_PSR_Q)
+
+/* Bits 26..25: ITSTATE<1..0> */
+#define ARM_PSR_ITSTATE_LOW MVP_MASK(25, 2)
+
+/* Bit 24: J */
+#define ARM_PSR_J (1 << 24)
+
+/* Bits 23..20 are reserved as of ARMv7 */
+#define ARM_PSR_RESERVED MVP_MASK(20, 4)
+
+/* Bits 19..16: GE<3..0> */
+#define ARM_PSR_GE MVP_MASK(16, 4)
+
+/* Bits 15..10: ITSTATE<7..2> */
+#define ARM_PSR_ITSTATE_HIGH MVP_MASK(10, 6)
+#define ARM_PSR_ITSTATE (ARM_PSR_ITSTATE_LOW | ARM_PSR_ITSTATE_HIGH)
+
+/* Bit 9: E */
+#define ARM_PSR_E_POS (9)
+#define ARM_PSR_E (1 << ARM_PSR_E_POS)
+
+/* Bit 8: A */
+#define ARM_PSR_A_POS (8)
+#define ARM_PSR_A (1 << ARM_PSR_A_POS)
+
+/* Bit 7: I */
+#define ARM_PSR_I_POS (7)
+#define ARM_PSR_I (1 << ARM_PSR_I_POS)
+
+/* Bit 6: F */
+#define ARM_PSR_F_POS (6)
+#define ARM_PSR_F (1 << ARM_PSR_F_POS)
+
+/* Bit 5: T */
+#define ARM_PSR_T_POS (5)
+#define ARM_PSR_T (1 << ARM_PSR_T_POS)
+
+/* Bits 4..0: Mode */
+#define ARM_PSR_MODE_MASK 0x1f
+
+#define ARM_PSR_MODE(cpsr) ((cpsr) & ARM_PSR_MODE_MASK)
+#define ARM_PSR_USER_MODE(cpsr) (ARM_PSR_MODE(cpsr) == ARM_PSR_MODE_USER)
+
+
+/*
+ * We shadow the 10 LSBs in the CPSR, with the exception of the T bit, as they
+ * are managed by the VMM on behalf of the guest and are potentially different
+ * than the physical CPSR during DE.
+ */
+#define ARM_PSR_MONITOR_BITS 10
+#define ARM_PSR_MONITOR_MASK (((1 << ARM_PSR_MONITOR_BITS) - 1) & ~ARM_PSR_T)
+
+#endif /// ifndef _PSR_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/qp.h b/arch/arm/mvp/mvpkm/qp.h
new file mode 100644
index 0000000..a8d7ac1
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/qp.h
@@ -0,0 +1,332 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MVP Queue Pairs function and structure declarations
+ *
+ * MVP Queue Pairs:
+ *
+ * Queue pairs are intended to be a generic bulk data transport mechanism
+ * between the guest and host kernels. The queue pair abstraction is based
+ * on two ring buffers (queues) placed on a shared memory region mapped
+ * into both guest and host kernel address spaces.
+ *
+ * NOTE: Queue pairs are SINGLE-READER, SINGLE-WRITER. Any caller is
+ * responsible for multi-reader/writer serialization!!!
+ *
+ * There are a maximum of QP_MAX_QUEUE_PAIRS in the system, with a maximum
+ * size of QP_MAX_CAPACITY per pair. Each queue pair is identified by
+ * an ID.
+ *
+ * Each peer follows a producer-consumer model in which one side is the
+ * producer on one queue, and the other side is the consumer on that queue
+ * (and vice-versa for its pair).
+ *
+ * Data is enqueued and dequeued into the pair in transactional stages,
+ * meaning each enqueue/dequeue can be followed by zero or more
+ * enqueue/dequeues, but the enqueue/dequeue is not visible to the peer
+ * until it has been committed with the *Commit() function.
+ * In PVTCP, for example, this is used to enqueue a short header, then
+ * followed by 'segments' of iovecs, then followed by a commit. This
+ * model prevents a peer from reading the header, expecting a payload,
+ * but not being able to read the payload because it hasn't been
+ * enqueued yet.
+ *
+ * Queue Pair setup:
+ *
+ * Before data can be passed, the guest and host kernel must perform
+ * the following connection handshake:
+ *
+ * 1). A host kernel service registers a listener with the queue pair
+ * subsystem with a callback to be called when guests create
+ * and attach to a shared memory region.
+ *
+ * 2). Guest initiates an QP_Attach() operation to a shared memory region
+ * keyed by ID. This step allocates memory, maps it into the host
+ * address space, and optionally notifies any host services who are
+ * listening for attach requests from the guest (see previous step).
+ * Host listeners are provided with a copy of the initialization
+ * arguments used by the guest (id, size, service type). All registered
+ * listeners are iterated over until one of them handles the attach
+ * request and acknowledges with QP_SUCCESS.
+ *
+ * 3). The registered host callback is called, notifying the host that
+ * the guest has attached.
+ *
+ * 4). The host can now QP_Attach() to the shared memory region with the same
+ * arguments as the guest. The queue pair is now well formed and enqueues
+ * and dequeues can proceed on either side.
+ *
+ * Queue Pair teardown:
+ *
+ * 1). As before, teardowns are initiated by the guest. Hosts can register
+ * a callback to be called upon detach. Guests initiate a teardown
+ * through a call to QP_Detach().
+ *
+ * 2). Registered hosts are notified through the aforementioned callback.
+ * 3). The host service can call QP_Detach() at its own leisure. Memory
+ * is freed, the queue pair is destroyed.
+ *
+ * If at any point the guest unexpectedly shuts down, the host will be
+ * notified at monitor shutdown time. Memory is freed, and the queue
+ * pair is destroyed.
+ *
+ */
+
+#ifndef _QP_H
+#define _QP_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+//#define QP_DEBUG 1
+
+typedef enum QPState {
+ QP_STATE_FREE = 0x1, ///< No peers, not memory-backed
+ QP_STATE_CONNECTED, ///< Both peers attached , memory backed
+ QP_STATE_GUEST_ATTACHED, ///< Guest allocated memory, host not yet attached
+ QP_STATE_MAX // leave this at the end!
+} QPState;
+
+typedef struct QPId {
+ uint32 context;
+ uint32 resource;
+} QPId;
+
+/*
+ * Initialization arguments for each queue pair
+ */
+typedef struct QPInitArgs {
+ QPId id; ///< Shared memory region ID
+ uint32 capacity; ///< Total size of shared region in bytes
+ uint32 type; ///< Type of queue pair (PVTCP, other)...
+} QPInitArgs;
+
+/*
+ * Placed on the shared region, two per region
+ */
+typedef struct QHandle {
+ volatile uint32 head; ///< queue head offset
+ volatile uint32 tail; ///< queue tail offset
+ volatile uint32 phantom_head; ///< queue shadow head offset
+ volatile uint32 phantom_tail; ///< queue shadow tail offset
+ uint8 data[0]; ///< start of data, runs off
+ // the struct
+} QHandle;
+
+/*
+ * Local to each peer
+ */
+typedef struct QPHandle {
+ QPId id; ///< shared memory region ID
+ uint32 capacity; ///< size of region in bytes
+ QHandle *produceQ; ///< producer queue
+ QHandle *consumeQ; ///< consumer queue
+ uint32 queueSize; ///< size of each queue in bytes
+ uint32 type; ///< type of queue pair
+
+ /*
+ * Following fields unused by guest
+ */
+ QPState state;
+ void (*peerDetachCB)(void* data); ///< detach notification callback
+ void *detachData; ///< data for the detach cb
+ struct page **pages; ///< page pointers for shared region
+} QPHandle;
+
+/*
+ * QP Error codes
+ */
+#define QP_SUCCESS 0
+#define QP_ERROR_NO_MEM (-1)
+#define QP_ERROR_INVALID_HANDLE (-2)
+#define QP_ERROR_INVALID_ARGS (-3)
+#define QP_ERROR_ALREADY_ATTACHED (-4)
+
+/*
+ * Hard-coded limits
+ */
+#define QP_MIN_CAPACITY (PAGE_SIZE * 2)
+#define QP_MAX_CAPACITY (1024*1024) // 1M
+#define QP_MAX_QUEUE_PAIRS 32
+#define QP_MAX_ID QP_MAX_QUEUE_PAIRS
+#define QP_MAX_LISTENERS QP_MAX_QUEUE_PAIRS
+#define QP_MAX_PAGES (QP_MAX_CAPACITY/PAGE_SIZE) // 256 pages
+
+#define QP_INVALID_ID 0xFFFFFFFF
+#define QP_INVALID_SIZE 0xFFFFFFFF
+#define QP_INVALID_REGION 0xFFFFFFFF
+#define QP_INVALID_TYPE 0xFFFFFFFF
+
+#ifdef __KERNEL__
+/**
+ * @brief Utility function to sanity check arguments
+ * @param args argument structure to check
+ * @return true if arguments are sane, false otherwise
+ */
+static inline
+_Bool QP_CheckArgs(QPInitArgs *args)
+{
+ if (!args ||
+ !is_power_of_2(args->capacity) ||
+ (args->capacity < QP_MIN_CAPACITY) ||
+ (args->capacity > QP_MAX_CAPACITY) ||
+ !(args->id.resource < QP_MAX_ID || args->id.resource == QP_INVALID_ID) ||
+ (args->type == QP_INVALID_TYPE)) {
+ return false;
+ } else {
+ return true;
+ }
+}
+#endif
+
+
+/**
+ * @brief Utility function to sanity check a queue pair handle
+ * @param qp handle to the queue pair
+ * @return true if the handle is sane, false otherwise
+ */
+static inline
+_Bool QP_CheckHandle(QPHandle *qp)
+{
+#ifdef MVP_DEBUG
+ if (!(qp) ||
+ !(qp->produceQ) ||
+ !(qp->consumeQ) ||
+ (qp->state >= (uint32)QP_STATE_MAX) ||
+ !(qp->queueSize < (QP_MAX_CAPACITY/2))) {
+ return false;
+ } else {
+ return true;
+ }
+#else
+ return true;
+#endif
+}
+
+
+/**
+ * @brief Initializes an invalid handle
+ * @param[in, out] qp handle to the queue pair
+ */
+static inline void
+QP_MakeInvalidQPHandle(QPHandle *qp)
+{
+ if (!qp) {
+ return;
+ }
+
+ qp->id.context = QP_INVALID_ID;
+ qp->id.resource = QP_INVALID_ID;
+ qp->capacity = QP_INVALID_SIZE;
+ qp->produceQ = NULL;
+ qp->consumeQ = NULL;
+ qp->queueSize = QP_INVALID_SIZE;
+ qp->type = QP_INVALID_TYPE;
+ qp->state = QP_STATE_FREE;
+ qp->peerDetachCB = NULL;
+ qp->detachData = NULL;
+}
+
+/*
+ * Host only
+ */
+typedef int32 (*QPListener)(const QPInitArgs*);
+int32 QP_RegisterListener(const QPListener);
+int32 QP_UnregisterListener(const QPListener);
+int32 QP_RegisterDetachCB(QPHandle *qp, void (*callback)(void*), void *data);
+
+
+/*
+ * Host and guest specific implementations, see qp_host.c and qp_guest.c
+ */
+int32 QP_Attach(QPInitArgs *args, QPHandle** qp);
+int32 QP_Detach(QPHandle* qp);
+int32 QP_Notify(QPInitArgs *args);
+
+/*
+ * Common implementation, see qp_common.c
+ */
+int32 QP_EnqueueSpace(QPHandle *qp);
+int32 QP_EnqueueSegment(QPHandle *qp, const void *buf, size_t length);
+int32 QP_EnqueueCommit(QPHandle *qp);
+int32 QP_EnqueueReset(QPHandle *qp);
+
+static inline int32
+QP_EnqueueAtomic(QPHandle *qp, const void *buf, size_t length)
+{
+ int32 rc;
+ QP_EnqueueReset(qp);
+ rc = QP_EnqueueSegment(qp, buf, length);
+ if (rc < 0) {
+ return rc;
+ } else {
+ QP_EnqueueCommit(qp);
+ }
+ return rc;
+}
+
+int32 QP_DequeueSpace(QPHandle *qp);
+int32 QP_DequeueSegment(QPHandle *qp, const void *buf, size_t length);
+int32 QP_DequeueReset(QPHandle *qp);
+int32 QP_DequeueCommit(QPHandle *qp);
+
+static inline int32
+QP_DequeueAtomic(QPHandle *qp, const void *buf, size_t length)
+{
+ int32 rc;
+ QP_DequeueReset(qp);
+ rc = QP_DequeueSegment(qp, buf, length);
+ if (rc < 0) {
+ return rc;
+ } else {
+ QP_DequeueCommit(qp);
+ }
+ return rc;
+}
+
+/*
+ * HVC methods and signatures
+ */
+#define MVP_QP_SIGNATURE 0x53525051 ///< 'QPRS'
+#define MVP_QP_ATTACH (MVP_OBJECT_CUSTOM_BASE + 0) ///< attach to a queue pair
+#define MVP_QP_DETACH (MVP_OBJECT_CUSTOM_BASE + 1) ///< detach from a queue pair
+#define MVP_QP_NOTIFY (MVP_OBJECT_CUSTOM_BASE + 2) ///< notify host of attach
+#define MVP_QP_LAST (MVP_OBJECT_CUSTOM_BASE + 3) ///< Number of methods
+
+/*
+ * Debug macros
+ */
+#ifdef QP_DEBUG
+ #ifdef IN_MONITOR
+ #define QP_DBG(...) Log(__VA_ARGS__)
+ #else
+ #define QP_DBG(...) printk(KERN_INFO __VA_ARGS__)
+ #endif
+#else
+ #define QP_DBG(...)
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/qp_common.c b/arch/arm/mvp/mvpkm/qp_common.c
new file mode 100644
index 0000000..8d121a1
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/qp_common.c
@@ -0,0 +1,337 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MVP Queue Pairs common enqueue and dequeue functions.
+ * Does not include Attach(), and Detach(), as this will be specific
+ * to host/guest
+ * implementations.
+ */
+
+#include <linux/module.h>
+
+#include "mvp_types.h"
+#include "comm_os.h"
+#include "qp.h"
+
+
+/**
+ * @brief Calculate free space in the queue, convenience function
+ * @param head queue head offset
+ * @param tail queue tail offset
+ * @param queueSize size of queue
+ * @return free space in the queue
+ */
+static inline int32
+FreeSpace(uint32 head, uint32 tail, uint32 queueSize) {
+ /* Leave 1 byte free to resolve ambiguity between empty
+ * and full conditions */
+ return (tail >= head) ? (queueSize - (tail - head) - 1) :
+ (head - tail - 1);
+}
+
+
+/**
+ * @brief Returns available space for enqueue, in bytes
+ * @param qp handle to the queue pair
+ * @return available space in bytes in the queue for enqueue operations,
+ * QP_ERROR_INVALID_HANDLE if the handle is malformed
+ */
+int32
+QP_EnqueueSpace(QPHandle *qp)
+{
+ uint32 head;
+ uint32 phantom;
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ head = qp->produceQ->head;
+ phantom = qp->produceQ->phantom_tail;
+
+ if (head >= qp->queueSize ||
+ phantom >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ return FreeSpace(head, phantom, qp->queueSize);
+}
+
+
+/**
+ * @brief Enqueues a segment of data into the producer queue
+ * @param qp handle to the queue pair
+ * @param buf data to enqueue
+ * @param bufSize size in bytes to enqueue
+ * @return number of bytes enqueued on success, appropriate error
+ * code otherwise
+ * @sideeffects May move phantom tail pointer
+ */
+int32
+QP_EnqueueSegment(QPHandle *qp, const void *buf, size_t bufSize)
+{
+ int32 freeSpace;
+ uint32 head;
+ uint32 phantom;
+
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ head = qp->produceQ->head;
+ phantom = qp->produceQ->phantom_tail;
+
+ /*
+ * This check must go after the assignment above,
+ * otherwise a malicious guest could write bogus
+ * offsets to the queue and cause the memcpy to
+ * copy into unpleasant places.
+ */
+ if (head >= qp->queueSize ||
+ phantom >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ freeSpace = FreeSpace(head, phantom, qp->queueSize);
+
+ if (bufSize <= freeSpace) {
+ if (bufSize + phantom < qp->queueSize) {
+ memcpy(qp->produceQ->data + phantom, buf, bufSize);
+ phantom += bufSize;
+ } else {
+ uint32 written = qp->queueSize - phantom;
+ memcpy(qp->produceQ->data + phantom, buf, written);
+ memcpy(qp->produceQ->data, (uint8*)buf + written, bufSize - written);
+ phantom = bufSize - written;
+ }
+ } else {
+ return QP_ERROR_NO_MEM;
+ }
+
+ qp->produceQ->phantom_tail = phantom;
+
+ return bufSize;
+}
+
+
+/**
+ * @brief Commits any previous EnqueueSegment operations to the queue
+ * pair
+ * @param qp handle to the queue pair.
+ * @return QP_SUCCESS on success, appropriate error code otherwise.
+ * @sideeffects May move tail pointer
+ */
+int32
+QP_EnqueueCommit(QPHandle *qp)
+{
+ uint32 phantom;
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ phantom = qp->produceQ->phantom_tail;
+ if (phantom >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ qp->produceQ->tail = phantom;
+ return QP_SUCCESS;
+}
+
+
+/**
+ * @brief Returns any available bytes for dequeue
+ * @param qp handle to the queue pair
+ * @return available bytes for dequeue, appropriate error code
+ * otherwise
+ */
+int32
+QP_DequeueSpace(QPHandle *qp)
+{
+ uint32 tail;
+ uint32 phantom;
+ int32 bytesAvailable;
+
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ tail = qp->consumeQ->tail;
+ phantom = qp->consumeQ->phantom_head;
+
+ if (tail >= qp->queueSize ||
+ phantom >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ bytesAvailable = (tail - phantom);
+ if ((int32)bytesAvailable < 0) {
+ bytesAvailable += qp->queueSize;
+ }
+ return bytesAvailable;
+}
+
+
+/**
+ * @brief Dequeues a segment of data from the consumer queue into
+ * a buffer
+ * @param qp handle to the queue pair
+ * @param[out] buf buffer to copy to
+ * @param bytesDesired number of bytes to dequeue
+ * @return number of bytes dequeued on success, appropriate error
+ * code otherwise
+ * @sideeffects May move phantom head pointer
+ */
+int32
+QP_DequeueSegment(QPHandle *qp, const void *buf, size_t bytesDesired)
+{
+ uint32 tail;
+ uint32 phantom;
+ int32 bytesAvailable = 0;
+
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ tail = qp->consumeQ->tail;
+ phantom = qp->consumeQ->phantom_head;
+
+ /*
+ * This check must go after the assignment above,
+ * otherwise a malicious guest could write bogus
+ * offsets to the queue and cause the memcpy to
+ * copy into unpleasant places.
+ */
+ if (tail >= qp->queueSize ||
+ phantom >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ bytesAvailable = (tail - phantom);
+ if ((int32)bytesAvailable < 0) {
+ bytesAvailable += qp->queueSize;
+ }
+
+ if (bytesDesired <= bytesAvailable) {
+ if (bytesDesired + phantom < qp->queueSize) {
+ memcpy((void*)buf, qp->consumeQ->data + phantom, bytesDesired);
+ phantom += bytesDesired;
+ } else {
+ uint32 written = qp->queueSize - phantom;
+ memcpy((void*)buf, qp->consumeQ->data + phantom, written);
+ memcpy((uint8*)buf + written, qp->consumeQ->data, bytesDesired - written);
+ phantom = bytesDesired - written;
+ }
+ } else {
+ return QP_ERROR_NO_MEM;
+ }
+
+ qp->consumeQ->phantom_head = phantom;
+
+ return bytesDesired;
+}
+
+
+/**
+ * @brief Commits any previous DequeueSegment operations to the queue
+ * pair
+ * @param qp handle to the queue pair
+ * @return QP_SUCCESS on success, QP_ERROR_INVALID_HANDLE if the handle
+ * is malformed
+ * @sideeffects Moves the head pointer
+ */
+int32
+QP_DequeueCommit(QPHandle *qp)
+{
+ uint32 phantom;
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ phantom = qp->consumeQ->phantom_head;
+ if (phantom >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ qp->consumeQ->head = phantom;
+ return QP_SUCCESS;
+}
+
+
+/**
+ * @brief Resets the phantom tail pointer and discards any pending
+ * enqueues
+ * @param qp handle to the queue pair
+ * @return QP_SUCCESS on success, QP_ERROR_INVALID_HANDLE if the handle
+ * is malformed
+ * @sideeffects Resets the phantom tail pointer
+ */
+int32
+QP_EnqueueReset(QPHandle *qp)
+{
+ uint32 tail;
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ tail = qp->produceQ->tail;
+ if (tail >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ qp->produceQ->phantom_tail = tail;
+ return QP_SUCCESS;
+}
+
+/**
+ * @brief Resets the phantom head pointer and discards any pending
+ * dequeues
+ * @param qp handle to the queue pair
+ * @return QP_SUCCESS on success, QP_ERROR_INVALID_HANDLE if the handle
+ * is malformed
+ * @sideeffects Resets the phantom head pointer
+ */
+int32
+QP_DequeueReset(QPHandle *qp)
+{
+ uint32 head;
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ head = qp->consumeQ->head;
+ if (head >= qp->queueSize) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ qp->consumeQ->phantom_head = head;
+ return QP_SUCCESS;
+}
+
+EXPORT_SYMBOL(QP_EnqueueSpace);
+EXPORT_SYMBOL(QP_EnqueueSegment);
+EXPORT_SYMBOL(QP_EnqueueCommit);
+EXPORT_SYMBOL(QP_DequeueSpace);
+EXPORT_SYMBOL(QP_DequeueSegment);
+EXPORT_SYMBOL(QP_DequeueCommit);
+EXPORT_SYMBOL(QP_EnqueueReset);
+EXPORT_SYMBOL(QP_DequeueReset);
diff --git a/arch/arm/mvp/mvpkm/qp_host_kernel.c b/arch/arm/mvp/mvpkm/qp_host_kernel.c
new file mode 100644
index 0000000..c53f315
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/qp_host_kernel.c
@@ -0,0 +1,574 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief MVP host kernel implementation of the queue pairs API
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+
+#include "mvp.h"
+#include "mvpkm_kernel.h"
+#include "qp.h"
+#include "qp_host_kernel.h"
+
+static QPHandle queuePairs[QP_MAX_QUEUE_PAIRS];
+static QPListener listeners[QP_MAX_LISTENERS];
+
+/*
+ * Protect listeners and queuePairs.
+ */
+static DEFINE_MUTEX(qpLock);
+
+#define QPLock() mutex_lock(&qpLock)
+#define QPUnlock() mutex_unlock(&qpLock)
+
+/**
+ * @brief Map a vector of pages into virtually contiguous kernel space
+ * @param vm this vm's vm struct
+ * @param base base machine page number that lists pages to map
+ * @param nrPages number of pages to map
+ * @param[out] qp handle to qp to set up
+ * @param[out] hkva virtual address mapping
+ * @return QP_SUCCESS on success, error code otherwise. Mapped address
+ * is returned in hkva
+ */
+
+static int32
+MapPages(MvpkmVM *vm,
+ MPN base,
+ uint32 nrPages,
+ QPHandle *qp,
+ HKVA *hkva)
+{
+ HKVA *va;
+ uint32 i;
+ uint32 rc;
+ struct page *basepfn = pfn_to_page(base);
+ struct page **pages;
+
+ BUG_ON(!vm); // this would be very bad.
+
+ if (!hkva) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ pages = kmalloc(nrPages * sizeof (MPN), GFP_KERNEL);
+ if (!pages) {
+ return QP_ERROR_NO_MEM;
+ }
+
+ /*
+ * Map in the first page, read out the MPN vector
+ */
+ down_write(&vm->lockedSem);
+ va = kmap(basepfn);
+ if (!va) {
+ rc = QP_ERROR_INVALID_ARGS;
+ kfree(pages);
+ qp->pages = NULL;
+ goto out;
+ }
+
+ /*
+ * Grab references and translate MPNs->PFNs
+ */
+ for (i = 0; i < nrPages; i++) {
+ pages[i] = pfn_to_page(((MPN*)va)[i]);
+ get_page(pages[i]);
+ }
+
+ /*
+ * Clean up the first mapping and remap the entire vector
+ */
+ kunmap(basepfn);
+ va = vmap(pages, nrPages, VM_MAP, PAGE_KERNEL);
+ if (!va) {
+ rc = QP_ERROR_NO_MEM;
+ for (i = 0; i < nrPages; i++) {
+ put_page(pages[i]);
+ }
+ kfree(pages);
+ qp->pages = NULL;
+ goto out;
+ } else {
+ *hkva = (HKVA)va;
+ qp->pages = pages;
+ }
+
+ /*
+ * Let's not leak mpns..
+ */
+ memset(va, 0x0, nrPages * PAGE_SIZE);
+
+ rc = QP_SUCCESS;
+
+out:
+ up_write(&vm->lockedSem);
+ return rc;
+}
+
+/**
+ * @brief Initialize all free queue pair entries and listeners
+ */
+
+void
+QP_HostInit(void)
+{
+ uint32 i;
+
+ for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) {
+ QP_MakeInvalidQPHandle(&queuePairs[i]);
+ }
+
+ for (i = 0; i < QP_MAX_LISTENERS; i++) {
+ listeners[i] = NULL;
+ }
+}
+
+
+/**
+ * @brief Detaches a guest from a queue pair and notifies
+ * any registered listeners through the detach callback
+ * @param id id that guest requested a detach from, detaches all
+ * queue pairs associated with a VM if the resource id == QP_INVALID_ID
+ * @return QP_SUCCESS on success, appropriate error code otherwise
+ */
+
+int32
+QP_GuestDetachRequest(QPId id)
+{
+ QPHandle *qp;
+ uint32 i;
+
+ if (id.resource >= QP_MAX_ID && id.resource != QP_INVALID_ID) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ QPLock();
+
+ /*
+ * Invalidate all queue pairs associated with this VM if
+ * resource == QP_INVALID_ID
+ */
+ if (id.resource == QP_INVALID_ID) {
+ for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) {
+ qp = &queuePairs[i];
+ if (qp->id.context == id.context && qp->peerDetachCB) {
+ qp->peerDetachCB(qp->detachData);
+ }
+ }
+ } else {
+ qp = &queuePairs[id.resource];
+ if (qp->peerDetachCB) {
+ qp->peerDetachCB(qp->detachData);
+ }
+ }
+
+ QPUnlock();
+
+ return QP_SUCCESS;
+}
+
+
+/**
+ * @brief Attaches a guest to shared memory region
+ * @param vm guest to attach
+ * @param args queue pair args structure:
+ * - args->id: id of the region to attach to, if id.resource == QP_INVALID_ID, then
+ * an id is assigned
+ * - args->capacity: total size of the region in bytes
+ * - args->type: type of queue pair (e.g PVTCP)
+ * @param base base machine page number that lists pages to map
+ * @param nrPages number of pages to map
+ * @return QP_SUCCESS on success, appropriate error code otherwise.
+ */
+
+int32
+QP_GuestAttachRequest(MvpkmVM *vm,
+ QPInitArgs *args,
+ MPN base,
+ uint32 nrPages)
+{
+ int32 rc;
+ HKVA hkva = 0;
+ QPHandle *qp;
+ uint32 i;
+
+ if ((!QP_CheckArgs(args)) ||
+ (vm->wsp->guestId != (Mksck_VmId)args->id.context) ||
+ (args->capacity != (nrPages * PAGE_SIZE))) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ QP_DBG("%s: Guest requested attach to [%u:%u] capacity: %u type: %x base: %x nrPages: %u\n",
+ __FUNCTION__,
+ args->id.context,
+ args->id.resource,
+ args->capacity,
+ args->type,
+ base,
+ nrPages);
+
+ QPLock();
+
+ /*
+ * Assign a resource id if id == QP_INVALID_ID
+ */
+ if (args->id.resource == QP_INVALID_ID) {
+ for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) {
+ if (queuePairs[i].state == QP_STATE_FREE) {
+ args->id.resource = i;
+ QP_DBG("%s: Guest requested anonymous region, assigning resource id %u\n",
+ __FUNCTION__, args->id.resource);
+ goto found;
+ }
+ }
+
+ rc = QP_ERROR_NO_MEM;
+ goto out;
+ }
+
+found:
+ qp = queuePairs + args->id.resource;
+
+ if (qp->state != QP_STATE_FREE) {
+ rc = QP_ERROR_ALREADY_ATTACHED;
+ goto out;
+ }
+
+ /*
+ * Brand new queue pair, allocate some memory to back it and
+ * initialize the entry
+ */
+ rc = MapPages(vm, base, nrPages, qp, &hkva);
+ if (rc != QP_SUCCESS) {
+ goto out;
+ }
+
+ /* NB: reversed from the guest */
+ qp->id = args->id;
+ qp->capacity = args->capacity;
+ qp->produceQ = (QHandle*)hkva;
+ qp->consumeQ = (QHandle*)(hkva + args->capacity/2);
+ qp->queueSize = args->capacity/2 - sizeof(QHandle);
+ qp->type = args->type;
+ qp->state = QP_STATE_GUEST_ATTACHED;
+
+ /*
+ * The qp is now assumed to be well-formed
+ */
+ QP_DBG("%s: Guest attached to region [%u:%u] capacity: %u HKVA: %x\n",
+ __FUNCTION__,
+ args->id.context,
+ args->id.resource,
+ args->capacity,
+ (uint32)hkva);
+ rc = QP_SUCCESS;
+
+out:
+ QPUnlock();
+ if (rc != QP_SUCCESS) {
+ QP_DBG("%s: Failed to attach: %u\n", __FUNCTION__, rc);
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Attaches the host to the shared memory region. The guest
+ * MUST have allocated the shmem region already or else this will fail.
+ * @param args structure with the shared memory region id to attach to,
+ * total size of the region in bytes, and type of queue pair (e.g PVTCP)
+ * @param[in, out] qp handle to the queue pair to return
+ * @return QP_SUCCESS on success, appropriate error code otherwise
+ */
+
+int32
+QP_Attach(QPInitArgs *args,
+ QPHandle** qp)
+{
+ uint32 rc;
+
+ if (!qp || !QP_CheckArgs(args)) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ QP_DBG("%s: Attaching to id: [%u:%u] capacity: %u\n",
+ __FUNCTION__,
+ args->id.context,
+ args->id.resource,
+ args->capacity);
+
+ QPLock();
+ *qp = queuePairs + args->id.resource;
+
+ if (!QP_CheckHandle(*qp)) {
+ *qp = NULL;
+ rc = QP_ERROR_INVALID_HANDLE;
+ goto out;
+ }
+
+ if ((*qp)->state == QP_STATE_CONNECTED) {
+ rc = QP_ERROR_ALREADY_ATTACHED;
+ goto out;
+ }
+
+ if ((*qp)->state != QP_STATE_GUEST_ATTACHED) {
+ rc = QP_ERROR_INVALID_HANDLE;
+ goto out;
+ }
+
+ (*qp)->state = QP_STATE_CONNECTED;
+
+ QP_DBG("%s: Attached!\n", __FUNCTION__);
+ rc = QP_SUCCESS;
+
+out:
+ QPUnlock();
+ return rc;
+}
+
+/**
+ * @brief Detaches the host to the shared memory region.
+ * @param[in, out] qp handle to the queue pair
+ * @return QP_SUCCESS on success, appropriate error code otherwise
+ * @sideeffects Frees memory
+ */
+
+int32
+QP_Detach(QPHandle* qp)
+{
+ uint32 rc;
+ uint32 i;
+
+ QPLock();
+ if (!QP_CheckHandle(qp)) {
+ rc = QP_ERROR_INVALID_HANDLE;
+ goto out;
+ }
+
+ QP_DBG("%s: Freeing queue pair [%u:%u]\n",
+ __FUNCTION__,
+ qp->id.context,
+ qp->id.resource);
+
+ BUG_ON(!qp->produceQ);
+ BUG_ON(!qp->pages);
+ BUG_ON((qp->state != QP_STATE_CONNECTED) &&
+ (qp->state != QP_STATE_GUEST_ATTACHED));
+
+ vunmap(qp->produceQ);
+
+ for (i = 0; i < qp->capacity/PAGE_SIZE; i++) {
+ put_page(qp->pages[i]);
+ }
+ kfree(qp->pages);
+
+ QP_DBG("%s: Host detached from [%u:%u]\n",
+ __FUNCTION__,
+ qp->id.context,
+ qp->id.resource);
+
+ QP_MakeInvalidQPHandle(qp);
+ rc = QP_SUCCESS;
+
+out:
+ QPUnlock();
+ return rc;
+}
+
+
+/**
+ * @brief Detaches and destroys all queue pairs associated with a given guest
+ * @param vmID which VM to clean up
+ * @sideeffects Destroys all queue pairs for guest vmID
+ */
+
+void QP_DetachAll(Mksck_VmId vmID) {
+ QPId id = {
+ .context = (uint32)vmID,
+ .resource = QP_INVALID_ID
+ };
+
+ QP_DBG("%s: Detaching all queue pairs from vmId context %u\n", __FUNCTION__, vmID);
+ QP_GuestDetachRequest(id);
+}
+
+/**
+ * @brief Registers a listener into the queue pair system. Callbacks are
+ * called with interrupts disabled and must not sleep.
+ * @param listener listener to be called
+ * @return QP_SUCCESS on success, QP_ERROR_NO_MEM if no more
+ * listeners can be registered
+ */
+
+int32
+QP_RegisterListener(const QPListener listener)
+{
+ uint32 i;
+ int32 rc = QP_ERROR_NO_MEM;
+
+ QPLock();
+ for (i = 0; i < QP_MAX_LISTENERS; i++) {
+ if (!listeners[i]) {
+ listeners[i] = listener;
+ QP_DBG("%s: Registered listener\n", __FUNCTION__);
+ rc = QP_SUCCESS;
+ break;
+ }
+ }
+ QPUnlock();
+
+ return rc;
+}
+
+
+/**
+ * @brief Unregister a listener service from the queue pair system.
+ * @param listener listener to unregister
+ * @return QP_SUCCESS on success, appropriate error code otherwise
+ */
+
+int32
+QP_UnregisterListener(const QPListener listener)
+{
+ uint32 i;
+ int32 rc = QP_ERROR_INVALID_HANDLE;
+
+ QPLock();
+ for (i = 0; i < QP_MAX_LISTENERS; i++) {
+ if (listeners[i] == listener) {
+ listeners[i] = NULL;
+ QP_DBG("%s: Unregistered listener\n", __FUNCTION__);
+ rc = QP_SUCCESS;
+ break;
+ }
+ }
+ QPUnlock();
+
+ return rc;
+}
+
+
+/**
+ * @brief Registers a callback to be called when the guest detaches
+ * from a queue pair. Callbacks are called with interrupts and
+ * must not sleep.
+ * @param qp handle to the queue pair
+ * @param callback callback to be called
+ * @param data data to deliver to the callback
+ * @return QP_SUCCESS on success, appropriate error code otherwise
+ */
+
+int32
+QP_RegisterDetachCB(QPHandle *qp,
+ void (*callback)(void*),
+ void *data)
+{
+ if (!QP_CheckHandle(qp)) {
+ return QP_ERROR_INVALID_HANDLE;
+ }
+
+ if (!callback) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ qp->peerDetachCB = callback;
+ qp->detachData = data;
+ QP_DBG("%s: Registered detach callback\n", __FUNCTION__);
+ return QP_SUCCESS;
+}
+
+
+/**
+ * @brief Noop on the host, only guests can initiate a notify
+ * @param args noop
+ * @return QP_SUCCESS
+ */
+
+
+int32 QP_Notify(QPInitArgs *args) {
+ return QP_SUCCESS;
+}
+
+
+/**
+ * @brief Notify any registered listeners for the given queue pair
+ * @param args initialization arguments used by the guest
+ * @return QP_SUCCESS on success, error otherwise
+ */
+
+int32 QP_NotifyListener(QPInitArgs *args) {
+ int32 i;
+ QPHandle *qp = NULL;
+
+ if (!QP_CheckArgs(args)) {
+ return QP_ERROR_INVALID_ARGS;
+ }
+
+ /*
+ * Iterate over listeners until one of them reports they handled it
+ */
+ QPLock();
+ for (i = 0; i < QP_MAX_LISTENERS; i++) {
+ if (listeners[i]) {
+ QP_DBG("Delivering attach event to listener...\n");
+ if (listeners[i](args) == QP_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ if (i == QP_MAX_LISTENERS) {
+ /*
+ * No listener successfully probed this QP.
+ * The guest DETACH HVC isn't implemented; we need compensate for it
+ * by deallocating the QP here.
+ * This is a workaround which assumes, more-or-less correctly, that
+ * unsuccessful QP probes never lead to subsequent host-attaching.
+ */
+
+ qp = &queuePairs[args->id.resource];
+ }
+
+ QPUnlock();
+
+ if (qp) {
+ QP_Detach(qp);
+ }
+ return QP_SUCCESS;
+}
+
+
+EXPORT_SYMBOL(QP_Attach);
+EXPORT_SYMBOL(QP_Detach);
+EXPORT_SYMBOL(QP_RegisterListener);
+EXPORT_SYMBOL(QP_UnregisterListener);
+EXPORT_SYMBOL(QP_RegisterDetachCB);
+EXPORT_SYMBOL(QP_Notify);
diff --git a/arch/arm/mvp/mvpkm/qp_host_kernel.h b/arch/arm/mvp/mvpkm/qp_host_kernel.h
new file mode 100644
index 0000000..111524a
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/qp_host_kernel.h
@@ -0,0 +1,44 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief QP host function prototypes
+ */
+
+
+#ifndef _QP_HOST_KERNEL_H
+#define _QP_HOST_KERNEL_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+void QP_HostInit(void);
+int32 QP_GuestAttachRequest(MvpkmVM *vm,
+ QPInitArgs *args,
+ MPN base,
+ uint32 nr_pages);
+int32 QP_GuestDetachRequest(QPId id);
+void QP_DetachAll(Mksck_VmId vmID);
+int32 QP_NotifyListener(QPInitArgs *args);
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/tsc.h b/arch/arm/mvp/mvpkm/tsc.h
new file mode 100644
index 0000000..0b3149b
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/tsc.h
@@ -0,0 +1,49 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Time stamp and event counters.
+ */
+
+#ifndef _TSC_H_
+#define _TSC_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "arm_inline.h"
+
+#define ARM_PMNC_E (1 << 0)
+#define ARM_PMNC_D (1 << 3)
+
+#define ARM_PMCNT_C (1 << 31)
+
+#define ARM_PMNC_INVALID_EVENT -1
+
+#define TSC_READ(_reg) ARM_MRC_CP15(CYCLE_COUNT, (_reg))
+#define TSC_WRITE(_reg) ARM_MCR_CP15(CYCLE_COUNT, (_reg))
+
+#endif // ifndef _TSC_H_
diff --git a/arch/arm/mvp/mvpkm/utils.h b/arch/arm/mvp/mvpkm/utils.h
new file mode 100644
index 0000000..1fc56e9
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/utils.h
@@ -0,0 +1,172 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief General architecture-independent definitions, typedefs, and macros.
+ */
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_WORKSTATION
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define MAX_FILENAME 128
+
+// Round address up to given size boundary
+// Note: ALIGN() conflicts with Linux
+
+#define MVP_ALIGN(_v, _n) (((_v) + (_n) - 1) & -(_n))
+
+#define ALIGNVA(_addr, _size) MVP_ALIGN(_addr, _size)
+
+#define alignof(t) offsetof(struct { char c; typeof(t) x; }, x)
+
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define KB(_X_) ((_X_)*1024U)
+#define MB(_X_) (KB(_X_)*1024)
+#define GB(_X_) (MB(_X_)*1024)
+
+#define NELEM(x) (sizeof(x)/sizeof((x)[0]))
+
+/*
+ * x in [low,high)
+ * args evaluated once
+ */
+#define RANGE(x,low,high) \
+ ({ \
+ typeof(x) _x = (x); \
+ typeof(x) _low = (typeof(x))(low); \
+ typeof(x) _high =(typeof(x))(high); \
+ (_Bool)( (_low <= _x) && (_x < _high)); \
+ })
+
+#define OBJECTS_PER_PAGE(_type) (PAGE_SIZE / sizeof(_type))
+
+#define MA_2_MPN(_ma) ((MPN)((_ma) / PAGE_SIZE))
+#define MPN_2_MA(_mpn) ((MA)((_mpn) * PAGE_SIZE))
+
+#define VA_2_VPN(_va) ((_va) / PAGE_SIZE)
+#define VPN_2_vA(_vpn) ((_vpn) * PAGE_SIZE)
+
+/*
+ * The following convenience macro can be used in a following situation
+ *
+ * send(..., &foo, sizeof(foo)) --> send(..., PTR_N_SIZE(foo))
+ */
+
+#define PTR_N_SIZE(_var) &(_var), sizeof(_var)
+
+
+/*
+ *
+ * BIT-PULLING macros
+ *
+ */
+#define MVP_BIT(val,n) ( ((val)>>(n))&1)
+#define MVP_BITS(val,m,n) (((val)<<(31-(n))) >> ((31-(n))+(m)) )
+#define MVP_EXTRACT_FIELD(w, m, n) MVP_BITS((w), (m), ((m) + (n) - 1))
+#define MVP_MASK(m, n) (MVP_EXTRACT_FIELD(~(uint32)0U, (m), (n)) << (m))
+#define MVP_UPDATE_FIELD(old_val, field_val, m, n) \
+ (((old_val) & ~MVP_MASK((m), (n))) | (MVP_EXTRACT_FIELD((field_val), 0, (n)) << (m)))
+
+/*
+ *
+ * 64BIT-PULLING macros
+ *
+ */
+#define MVP_BITS64(val,m,n) (((val)<<(63-(n))) >> ((63-(n))+(m)) )
+#define MVP_EXTRACT_FIELD64(w, m, n) MVP_BITS64((w), (m), ((m) + (n) - 1))
+#define MVP_MASK64(m, n) (MVP_EXTRACT_FIELD64(~(uint64)0ULL, (m), (n)) << (m))
+#define MVP_UPDATE_FIELD64(old_val, field_val, m, n) \
+ (((old_val) & ~MVP_MASK64((m), (n))) | (MVP_EXTRACT_FIELD64(((uint64)(field_val)), 0ULL, (n)) << (m)))
+
+/*
+ *
+ * BIT-CHANGING macros
+ *
+ */
+#define MVP_SETBIT(val,n) ((val)|=(1<<(n)))
+#define MVP_CLRBIT(val,n) ((val)&=(~(1<<(n))))
+
+/*
+ * Fixed bit-width sign extension.
+ */
+#define MVP_SIGN_EXTEND(val,width) \
+ (((val) ^ (1 << ((width) - 1))) - (1 << ((width) - 1)))
+
+
+/*
+ * Assembler helpers.
+ */
+#define _MVP_HASH #
+#define MVP_HASH() _MVP_HASH
+
+#define _MVP_STRINGIFY(...) #__VA_ARGS__
+#define MVP_STRINGIFY(...) _MVP_STRINGIFY(__VA_ARGS__)
+
+#ifndef __ASSEMBLER__
+
+#include <stddef.h>
+#include <stdbool.h>
+
+/*
+ * Constant equivalents of build-flags.
+ *
+ * Test these when possible instead of using #ifdef so that your code
+ * gets parsed.
+ */
+#ifdef MVP_DEBUG
+static const _Bool mvpDebug = true;
+#else
+static const _Bool mvpDebug = false;
+#endif
+
+#ifdef MVP_STATS
+static const _Bool mvpStats = true;
+#else
+static const _Bool mvpStats = false;
+#endif
+
+#ifdef MVP_DEVEL
+static const _Bool mvpDevel = true;
+#else
+static const _Bool mvpDevel = false;
+#endif
+
+#endif
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/ve_defs.h b/arch/arm/mvp/mvpkm/ve_defs.h
new file mode 100644
index 0000000..bd1d975
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/ve_defs.h
@@ -0,0 +1,72 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Virtualization extension definitions.
+ *
+ * See ARM PRD03-GENC-008353 11.0.
+ */
+#ifndef _VE_DEFS_H_
+#define _VE_DEFS_H_
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define ARM_VE_HSR_EC_BIT_POS 26
+#define ARM_VE_HSR_EC_LENGTH 6
+
+#define ARM_VE_HSR_EC_UNKNOWN 0x00
+#define ARM_VE_HSR_EC_WFI_WFE 0x01
+#define ARM_VE_HSR_EC_MCR_MRC_CP15 0x03
+#define ARM_VE_HSR_EC_MCRR_MRRC_CP15 0x04
+#define ARM_VE_HSR_EC_MCR_MRC_CP14 0x05
+#define ARM_VE_HSR_EC_LDC_STC_CP14 0x06
+#define ARM_VE_HSR_EC_HCPTR 0x07
+#define ARM_VE_HSR_EC_MRC_CP10 0x08
+#define ARM_VE_HSR_EC_JAZELLE 0x09
+#define ARM_VE_HSR_EC_BXJ 0x0a
+#define ARM_VE_HSR_EC_MRRC_CP14 0x0c
+#define ARM_VE_HSR_EC_SVC_HYP 0x11
+#define ARM_VE_HSR_EC_HVC 0x12
+#define ARM_VE_HSR_EC_SMC 0x13
+#define ARM_VE_HSR_EC_IABORT_SND 0x20
+#define ARM_VE_HSR_EC_IABORT_HYP 0x21
+#define ARM_VE_HSR_EC_DABORT_SND 0x24
+#define ARM_VE_HSR_EC_DABORT_HYP 0x25
+
+#define ARM_VE_HSR_FS_BIT_POS 0
+#define ARM_VE_HSR_FS_LENGTH 6
+
+#define ARM_VE_HSR_FS_TRANS_L1 0x5
+#define ARM_VE_HSR_FS_TRANS_L2 0x6
+#define ARM_VE_HSR_FS_TRANS_L3 0x7
+
+#define ARM_VE_HSR_FS_PERM_L1 0xd
+#define ARM_VE_HSR_FS_PERM_L2 0xe
+#define ARM_VE_HSR_FS_PERM_L3 0xf
+
+#endif /// ifndef _VE_DEFS_H_
diff --git a/arch/arm/mvp/mvpkm/vfp_switch.S b/arch/arm/mvp/mvpkm/vfp_switch.S
new file mode 100644
index 0000000..49d3987
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/vfp_switch.S
@@ -0,0 +1,216 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#include "arm_defs.h"
+#include "platdefx.h"
+#include "arm_as_macros.h"
+
+/**
+ * @file
+ *
+ * @brief Save and Load VFP entire VFP state.
+ */
+
+ .text
+
+/**
+ * @brief Save VFP context
+ * @param R0 = save area pointer:
+ * .long fpexc,fpscr,fpinst,fpinst2,cpacr,fpexc'
+ * .double d0..d15
+ * .double d16..d31
+ * Note: VFP is left in an enable state regardless of initial state.
+ */
+ .align 4
+ .global SaveVFP
+SaveVFP:
+ /*
+ * Save registers. GCC does not expect us to preserve R0..R3,R12,LR.
+ */
+ stmdb sp!, {r4-r6}
+
+ /*
+ * Save Coproc Access Control register.
+ */
+ mrc_p15 COPROC_ACCESS_CONTROL, r5
+
+ /*
+ * If CP10/11 are disabled, enable them so we can save VFP state.
+ * The host (or guest) may have left data in the data registers that
+ * must be preserved.
+ */
+ orr r2, r5, #CPACR_CP10_CP11_PRIV_ONLY
+ mcr_p15 COPROC_ACCESS_CONTROL, r2
+ isb
+
+ /*
+ * Follow procedure on AppxB-22 ARM DDI0406B to save FPINST[2].
+ * Also enable VFP access with FPEXC_EN.
+ */
+ fmrx r1, fpexc @ get existing FPEXC system register
+ orr r6, r1, #ARM_VFP_SYSTEM_REG_FPEXC_EX|ARM_VFP_SYSTEM_REG_FPEXC_FP2V|ARM_VFP_SYSTEM_REG_FPEXC_EN
+#if !defined(MVP_HOST_CODE_forceon)
+ fmxr fpexc, r6 @ set FPEXC.EX, .FP2V and .EN
+ fmrx r6, fpexc @ read them back
+ tst r6, #ARM_VFP_SYSTEM_REG_FPEXC_EX @ see if either one is valid
+ beq 1000f @ neither, skip it all
+ fmrx r3, FPINST @ FPINST is valid, save it
+ tst r6, #ARM_VFP_SYSTEM_REG_FPEXC_FP2V @ see if FPINST2 is valid
+ beq 1000f
+ fmrx r4, FPINST2 @ FPINST2 is valid, save it
+1000:
+#else
+ mov r6, r1
+#endif
+ fmrx r2, FPSCR @ always save FPSCR system register
+
+ /*
+ * At this point:
+ * R1 = original FPEXC
+ * R2 = FPSCR
+ * R3 = FPINST
+ * R4 = FPINST2
+ * R5 = original CPACR
+ * R6 = FPEXC readback with FPEXC.EX, .FP2V and .EN set
+ * telling us whether FPINST/2 are valid
+ */
+ stmia r0!, {r1-r6}
+
+ /*
+ * Save floating point data registers.
+ */
+ vstmia r0!, {d0-d15} @ Save d0 thru d15
+
+ /**
+ * @todo We should probably just read MVFR0 once at boot/initialization
+ * time and store it in some variable, to save having to do what might
+ * be expensive coprocessor accesses.
+ */
+ fmrx r1, MVFR0 @ Read Media and VFP Feature Register 0
+ and r1, r1, #ARM_VFP_SYSTEM_REG_MVFR0_A_SIMD_MASK @ A_SIMD field
+ cmp r1, #2 @ 32 x 64bit registers?
+ bne 2000f
+ vstmia r0!, {d16-d31}
+2000:
+
+ /*
+ * Restore scratch registers and return.
+ */
+ ldmia sp!, {r4-r6}
+ mov pc, lr
+
+
+/**
+ * @brief Load VFP context
+ * @param R0 = load area pointer:
+ * .long fpexc,fpscr,fpinst,fpinst2,cpacr,fpexc'
+ * .double d0..d15
+ * .double d16..d31
+ * @note VFP is assumed to be in an enabled state on entry.
+ */
+ .align 4
+ .global LoadVFP
+LoadVFP:
+ /*
+ * Save registers. GCC does not expect us to preserve R0..R3,R12,LR.
+ */
+ stmdb sp!, {r4-r6}
+
+ /*
+ * Get status register contents:
+ * R1 = original FPEXC
+ * R2 = FPSCR
+ * R3 = FPINST
+ * R4 = FPINST2
+ * R5 = original CPACR
+ * R6 = FPEXC readback with FPEXC.EX, .FP2V and .EN set
+ * telling us whether FPINST/2 are valid
+ */
+ ldmia r0!, {r1-r6}
+
+ /*
+ * Restore some initial FP status registers.
+ */
+ fmxr fpexc, r6 @ with FPEXC.EX, .FP2V and .EN set
+ fmxr FPSCR, r2 @ always load FPSCR system register
+
+ /*
+ * Follow procedure on AppxB-22 ARM DDI0406B to load FPINST[2].
+ */
+#if !defined(MVP_HOST_CODE_forceon)
+ fmrx r6, fpexc @ initial call might have different bits
+ @ ... because FPEXC.EX, .FP2V and .EN
+ @ are forced set by init code in
+ @ mvpd.c SetupMonitor()
+ tst r6, #ARM_VFP_SYSTEM_REG_FPEXC_EX @ see if either one is valid
+ beq 1000f @ neither, skip it all
+ fmxr FPINST, r3 @ FPINST is valid, save it
+ tst r6, #ARM_VFP_SYSTEM_REG_FPEXC_FP2V @ see if FPINST2 is valid
+ beq 1000f
+ fmxr FPINST2, r4 @ FPINST2 is valid, save it
+1000:
+#endif
+
+ /*
+ * Load floating point data registers.
+ */
+ vldmia r0!, {d0-d15}
+
+ /**
+ * @todo We should probably just read MVFR0 once at boot/initialization
+ * time and store it in some variable, to save having to do what might
+ * be expensive coprocessor accesses.
+ */
+ fmrx r3, MVFR0 @ Read Media and VFP Feature Register 0
+ and r3, r3, #ARM_VFP_SYSTEM_REG_MVFR0_A_SIMD_MASK @ A_SIMD field
+ cmp r3, #2 @ 32 x 64bit registers?
+ bne 2000f
+ vldmia r0!, {d16-d31}
+2000:
+
+ /*
+ * Now that VFP registers are all loaded, we put the restored values
+ * back in the registers, possibly disabling the VFP.
+ */
+ fmxr fpexc, r1 @ with original FPEXC.EX, FPEXC.FP2V
+ @ and FPEXC.EN values
+
+ /*
+ * Load Coproc Access Control CP10/CP11 enable bits, possibly disabling
+ * VFP access.
+ */
+ mrc_p15 COPROC_ACCESS_CONTROL, r0
+ bic r0, r0, #CPACR_CP10_CP11_MASK
+ and r5, r5, #CPACR_CP10_CP11_MASK
+ orr r0, r0, r5
+ mcr_p15 COPROC_ACCESS_CONTROL, r0
+ isb
+
+ /*
+ * Restore scratch registers and return.
+ */
+ ldmia sp!, {r4-r6}
+ mov pc, lr
+
+ .align 4
+ .global GetFPEXC
+GetFPEXC:
+ fmrx r0, fpexc @ get existing FPEXC system register
+ mov pc, lr
diff --git a/arch/arm/mvp/mvpkm/vmid.h b/arch/arm/mvp/mvpkm/vmid.h
new file mode 100644
index 0000000..dd89965
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/vmid.h
@@ -0,0 +1,44 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+#ifndef _VMID_H
+#define _VMID_H
+
+/**
+ * @file
+ *
+ * @brief The vmid definition
+ */
+
+
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_HOSTUSER
+#define INCLUDE_ALLOW_GUESTUSER
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define VMID_UNDEF (uint16)0xffff
+typedef uint16 VmId;
+
+#endif
diff --git a/arch/arm/mvp/mvpkm/worldswitch.h b/arch/arm/mvp/mvpkm/worldswitch.h
new file mode 100644
index 0000000..785f2cd
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/worldswitch.h
@@ -0,0 +1,381 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Definition of the world switch page
+ *
+ * Two pages are maintained to facilitate switching from the vmx to
+ * the monitor - a data and code page. The data page contains:
+ * - the necessary information about itself (its MPN, KVA, ...)
+ * - the saved register file of the other world (including some cp15 regs)
+ * - some information about the monitor's address space (the monVA member)
+ * that needed right after the w.s before any communication channels
+ * could have been established
+ * - a world switch related L2 table of the monitor -- this could be
+ * elsewhere.
+ *
+ * The code page contains:
+ * - the actual switching code that saves/restores the registers
+ *
+ * The world switch data page is mapped into the user, kernel, and the monitor
+ * address spaces. In case of the user and monitor spaces the global variable
+ * wsp points to the world switch page (in the vmx and the monitor
+ * respectively). The kernel address of the world switch page is saved on
+ * the page itself: wspHKVA.
+ *
+ * The kernel virtual address for both code and data pages is mapped into
+ * the monitor's space temporarily at the time of the actual switch. This is
+ * needed to provide a stable code and data page while the L1 page table
+ * base is changing. As the monitor does not need the world switch data page
+ * at its KVA for its internal operation, that map is severed right after the
+ * switching to the monitor and re-established before switching back.
+ */
+#ifndef _WORLDSWITCH_H
+#define _WORLDSWITCH_H
+
+#define INCLUDE_ALLOW_MVPD
+#define INCLUDE_ALLOW_VMX
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/**
+ * @brief Area for saving the monitor/kernel register files.
+ *
+ * The order of the registers in this structure was designed to
+ * facilitate the organization of the switching code. For example
+ * all Supervisor Mode registers are grouped together allowing the
+ * @code
+ * switch to svc,
+ * stm old svc regs
+ * ldm new svc regs
+ * @endcode
+ * code to work using a single base register for both the store and
+ * load area.
+ */
+#define MAX_REGISTER_SAVE_SIZE 464
+
+#ifndef __ASSEMBLER__
+typedef struct {
+ uint32 kSPSR_svc;
+ uint32 kr13_svc;
+ uint32 kr14_svc;
+ uint32 mSPSR_svc;
+ uint32 mR13_svc;
+ uint32 mR14_svc;
+
+ uint32 kSPSR_abt;
+ uint32 kr13_abt;
+ uint32 kr14_abt;
+ uint32 mSPSR_abt;
+ uint32 mR13_abt;
+ uint32 mR14_abt;
+
+ uint32 kSPSR_und;
+ uint32 kr13_und;
+ uint32 kr14_und;
+ uint32 mSPSR_und;
+ uint32 mR13_und;
+ uint32 mR14_und;
+
+ uint32 kSPSR_irq;
+ uint32 kr13_irq;
+ uint32 kr14_irq;
+ uint32 mSPSR_irq;
+ uint32 mR13_irq;
+ uint32 mR14_irq;
+
+ uint32 kSPSR_fiq;
+ uint32 kr8_fiq;
+ uint32 kr9_fiq;
+ uint32 kr10_fiq;
+ uint32 kr11_fiq;
+ uint32 kr12_fiq;
+ uint32 kr13_fiq;
+ uint32 kr14_fiq;
+ uint32 mSPSR_fiq;
+ uint32 mR8_fiq;
+ uint32 mR9_fiq;
+ uint32 mR10_fiq;
+ uint32 mR11_fiq;
+ uint32 mR12_fiq;
+ uint32 mR13_fiq;
+ uint32 mR14_fiq;
+} BankedRegisterSave;
+
+/**
+ * @brief Registers for monitor execution context.
+ */
+typedef struct {
+ uint32 mCPSR;
+ uint32 mR1;
+ uint32 mR4;
+ uint32 mR5;
+ uint32 mR6;
+ uint32 mR7;
+ uint32 mR8;
+ uint32 mR9;
+ uint32 mR10;
+ uint32 mR11;
+ uint32 mSP;
+ uint32 mLR; // =mPC
+} MonitorRegisterSave;
+
+/**
+ * @brief LPV monitor register save/restore.
+ */
+typedef struct {
+ uint32 kR2; // =kCPSR
+ uint32 kR4;
+ uint32 kR5;
+ uint32 kR6;
+ uint32 kR7;
+ uint32 kR8;
+ uint32 kR9;
+ uint32 kR10;
+ uint32 kR11;
+ uint32 kR13;
+ uint32 kR14; // =kPC
+
+ BankedRegisterSave bankedRegs;
+
+ uint32 kCtrlReg;
+ uint32 kTTBR0;
+ uint32 kDACR;
+ uint32 kASID;
+ uint32 kTIDUserRW;
+ uint32 kTIDUserRO;
+ uint32 kTIDPrivRW;
+ uint32 kCSSELR;
+ uint32 kPMNCIntEn;
+ uint32 kPMNCCCCNT;
+ uint32 kPMNCOvFlag;
+ uint32 kOpEnabled;
+ uint32 mCtrlReg;
+ uint32 mTTBR0;
+ uint32 mASID;
+ uint32 mTIDUserRW;
+ uint32 mTIDUserRO;
+ uint32 mTIDPrivRW;
+ uint32 mCSSELR;
+
+ MonitorRegisterSave monRegs;
+} RegisterSaveLPV;
+
+/**
+ * @brief VE monitor register save/restore.
+ */
+typedef struct {
+ uint32 mHTTBR;
+
+ uint32 kR3;
+ uint32 kR4;
+ uint32 kR5;
+ uint32 kR6;
+ uint32 kR7;
+ uint32 kR8;
+ uint32 kR9;
+ uint32 kR10;
+ uint32 kR11;
+ uint32 kR12;
+ uint32 kCPSR;
+ uint32 kRet;
+
+ BankedRegisterSave bankedRegs;
+
+ uint32 kCSSELR;
+ uint32 kCtrlReg;
+ uint32 kTTBR0[2];
+ uint32 kTTBR1[2];
+ uint32 kTTBRC;
+ uint32 kDACR;
+ uint32 kDFSR;
+ uint32 kIFSR;
+ uint32 kAuxDFSR;
+ uint32 kAuxIFSR;
+ uint32 kDFAR;
+ uint32 kIFAR;
+ uint32 kPAR[2];
+ uint32 kPRRR;
+ uint32 kNMRR;
+ uint32 kASID;
+ uint32 kTIDUserRW;
+ uint32 kTIDUserRO;
+ uint32 kTIDPrivRW;
+ uint32 mCSSELR;
+ uint32 mCtrlReg;
+ uint32 mTTBR0[2];
+ uint32 mTTBR1[2];
+ uint32 mTTBRC;
+ uint32 mDACR;
+ uint32 mDFSR;
+ uint32 mIFSR;
+ uint32 mAuxDFSR;
+ uint32 mAuxIFSR;
+ uint32 mDFAR;
+ uint32 mIFAR;
+ uint32 mPAR[2];
+ uint32 mPRRR;
+ uint32 mNMRR;
+ uint32 mASID;
+ uint32 mTIDUserRW;
+ uint32 mTIDUserRO;
+ uint32 mTIDPrivRW;
+
+ uint32 mHCR;
+ uint32 mHDCR;
+ uint32 mHCPTR;
+ uint32 mHSTR;
+ uint32 mVTTBR[2];
+ uint32 mVTCR;
+
+ MonitorRegisterSave monRegs;
+} RegisterSaveVE;
+
+typedef union {
+ unsigned char reserve_space[MAX_REGISTER_SAVE_SIZE];
+ RegisterSaveLPV lpv;
+ RegisterSaveVE ve;
+} RegisterSave;
+
+MY_ASSERTS(REGSAVE,
+ ASSERT_ON_COMPILE(sizeof(RegisterSave) == MAX_REGISTER_SAVE_SIZE);
+)
+
+/**
+ * @brief Area for saving the monitor/kernel VFP state.
+ */
+typedef struct VFPSave {
+ uint32 fpexc, fpscr, fpinst, fpinst2, cpacr, fpexc_;
+
+ uint64 fpregs[32]; // Hardware requires that this must be 8-byte (64-bit)
+ // aligned, however the SaveVFP/LoadVFP code does not
+ // align its pointer before accessing so we don't have
+ // an 'aligned(8)' attribute here. However, the
+ // alignment is checked via asserts in SetupMonitor()
+ // where it initializes the contents.
+
+ // So if the preceding uint32's are changed and fpregs[]
+ // is no longer 8-byte aligned, the assert will fire.
+ // Then the uint32's will have to be fixed AND THE CODE
+ // in SaveVFP/LoadVFP will have to be CHANGED EQUALLY to
+ // compensate, as simply padding the uint32's (or
+ // sticking an aligned(8) attribute here) will leave the
+ // this structure mismatched with the code.
+
+} VFPSave __attribute__((aligned(8)));
+ // Keep the aligned(8) attribute here though so the
+ // VFPSave structures begin on an 8-byte boundary.
+
+typedef struct WorldSwitchPage WorldSwitchPage;
+typedef void (SwitchToMonitor)(RegisterSave *regSave);
+typedef void (SwitchToUser)(RegisterSave *regSaveEnd);
+
+#include "atomic.h"
+#include "monva_common.h"
+#include "mksck_shared.h"
+
+struct WorldSwitchPage {
+ uint32 mvpkmVersion; ///< The version number of mvpkm
+
+ HKVA wspHKVA; ///< host kernel virtual address of this page
+ ARM_L1D wspKVAL1D; ///< The l1D entry at the above location
+
+ SwitchToMonitor*switchToMonitor;///< entrypoint of the switching function
+ SwitchToUser *switchToUser; ///< ditto
+
+ MonVA monVA; ///< monitor virtual address space description
+ union {
+ ARM_L2D monAttribL2D; ///< {S,TEX,CB} attributes for monitor mappings (LPV)
+ ARM_MemAttrNormal memAttr; ///< Normal memory attributes for monitor (VE)
+ };
+
+ MonitorType monType; ///< the type of the monitor. Used by mvpkm
+ _Bool allowInts; ///< true: monitor runs with ints enabled as much as possible (normal)
+ ///< false: monitor runs with ints blocked as much as possible (debug)
+
+ struct {
+ uint64 switchedAt64; ///< approx time CP15 TSC was set to...
+ uint32 switchedAtTSC; ///< CP15 TSC value on entry from monitor
+ uint32 tscToRate64Mult; ///< multiplier to convert TSC_READ()s to our RATE64s
+ uint32 tscToRate64Shift; ///< shift to convert TSC_READ()s to our RATE64s
+ };
+
+ struct {
+ AtmUInt32 hostActions; ///< actions for monitor on instruction boundary
+ Mksck_VmId guestId; ///< vmId of the monitor page
+ };
+
+ struct { ///< Mksck attributes needed by Mksck_WspRelease()
+ uint32 critSecCount; ///< if >0 the monitor is in critical section
+ ///< and expects to regain control
+ _Bool isPageMapped[MKSCK_MAX_SHARES]; ///< host mksckPages known to the monitor
+ _Bool guestPageMapped;///< the guest Mksck page has been mapped in MVA space
+ uint32 isOpened; ///< bitfield indicating which mkscks
+ ///< are open on the guest's mksckPage.
+ /* Note that isOpened is per VM not per VCPU. Also note
+ * that this and other bitfields in the MksckPage structure
+ * limit the number of sockets to 32.
+ */
+ };
+
+#define WSP_PARAMS_SIZE 512
+ uint8 params_[WSP_PARAMS_SIZE]; ///< opaque worldswitch call parameters
+
+ RegisterSave regSave; ///< Save area for the worldswitch code below
+ VFPSave hostVFP; ///< Save areas for monitor/kernel VFP state
+ VFPSave monVFP;
+
+__attribute__((aligned(ARM_L2PT_COARSE_SIZE)))
+ ARM_L2D wspDoubleMap[ARM_L2PT_COARSE_ENTRIES]; ///< maps worldswitch page at its HKVA
+ uint8 secondHalfPadding[ARM_L2PT_COARSE_SIZE];
+};
+
+/*
+ * These asserts duplicate the assert at the beginning of SetL1L2esc.
+ */
+MY_ASSERTS(WSP,
+ ASSERT_ON_COMPILE(offsetof(struct WorldSwitchPage, wspDoubleMap) %
+ ARM_L2PT_COARSE_SIZE == 0);
+)
+
+extern void SaveVFP(VFPSave *);
+extern void LoadVFP(VFPSave *);
+
+#define SWITCH_VFP_TO_MONITOR \
+ do { \
+ SaveVFP(&wsp->hostVFP); \
+ LoadVFP(&wsp->monVFP); \
+ } while(0)
+
+#define SWITCH_VFP_TO_HOST \
+ do { \
+ SaveVFP(&wsp->monVFP); \
+ LoadVFP(&wsp->hostVFP); \
+ } while(0)
+
+#endif /// __ASSEMBLER__
+
+#define OFFSETOF_KR3_REGSAVE_VE_WSP 616
+
+#endif /// _WORLDSWITCH_H
diff --git a/arch/arm/mvp/mvpkm/wscalls.h b/arch/arm/mvp/mvpkm/wscalls.h
new file mode 100644
index 0000000..4864f21
--- /dev/null
+++ b/arch/arm/mvp/mvpkm/wscalls.h
@@ -0,0 +1,165 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP Hypervisor Support
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Worldswitch call parameters
+ */
+
+#ifndef _WSCALLS_H
+#define _WSCALLS_H
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#define WSCALL_ACQUIRE_PAGE 1
+#define WSCALL_FLUSH_ALL_DCACHES 2
+#define WSCALL_IRQ 3
+#define WSCALL_ABORT 4
+#define WSCALL_LOG 5
+#define WSCALL_WAIT 6
+#define WSCALL_MUTEXLOCK 7
+#define WSCALL_MUTEXUNLOCK 8
+#define WSCALL_MUTEXUNLSLEEP 9
+#define WSCALL_MUTEXUNLWAKE 10
+#define WSCALL_GET_PAGE_FROM_VMID 11
+#define WSCALL_REMOVE_PAGE_FROM_VMID 12
+#define WSCALL_RELEASE_PAGE 13
+#define WSCALL_READTOD 14
+#define WSCALL_QP_GUEST_ATTACH 15
+#define WSCALL_MONITOR_TIMER 16
+#define WSCALL_COMM_SIGNAL 17
+#define WSCALL_QP_NOTIFY 18
+/*
+ * MVPKM V0.5.2.0 supports all the calls above. If new API calls are
+ * introduced then make sure that the calling function (probably in
+ * mkhost.c) checks the mvpkm's version stored in wsp->mvpkmVersion
+ * and invokes the wscall only when it is supported.
+ */
+
+#define WSCALL_MAX_CALLNO 20
+
+#define WSCALL_LOG_MAX 256
+
+#define WSCALL_MAX_MPNS 16
+
+#include "exitstatus.h"
+#include "mutex.h"
+#include "mksck_shared.h"
+#include "qp.h"
+#include "comm_transp.h"
+#include "comm_transp_impl.h"
+
+typedef struct WSParams {
+ uint32 callno;
+ union {
+ /**
+ * @brief Used for both WSCALL_ACQUIRE_PAGE and WSCALL_RELEASE_PAGE.
+ */
+ struct {
+ uint16 pages; ///< IN Number of pages
+ uint16 order; /**< IN Size of each page -
+ 2^(12+order) sized and aligned
+ in machine space.
+ (WSCALL_ACQUIRE_PAGE only) */
+ PhysMem_RegionType forRegion; /**< IN Region identifier for pages
+ (WSCALL_ACQUIRE_PAGE only) */
+ MPN mpns[WSCALL_MAX_MPNS]; /**< OUT (on WSCALL_ACQUIRE_PAGE)
+ IN (on WSCALL_RELEASE_PAGE)
+ Vector of page base MPNs. */
+ } pages;
+
+ union {
+ MPN mpn; ///< IN MPN to query refcount.
+ _Bool referenced; ///< OUT Do host page tables contain the MPN?
+ } refCount;
+
+ struct {
+ ExitStatus status; ///< IN the final status of the monitor
+ } abort;
+
+ struct {
+ int level;
+ char messg[WSCALL_LOG_MAX];
+ } log;
+
+ struct {
+ HKVA mtxHKVA; ///< IN mutex's host kernel virt addr
+ MutexMode mode; ///< IN shared or exclusive
+ uint32 cvi; ///< IN condition variable index
+ _Bool all; ///< IN wake all waiting threads?
+ _Bool ok; ///< OUT Mutex_Lock completed
+ } mutex;
+
+ struct {
+ Mksck_VmId vmId; ///< IN translate and lock this vmID
+ _Bool found; /**< OUT true if the lookup was successful,
+ page is found, and refc incremented */
+ MPN mpn[MKSCKPAGE_TOTAL]; ///< OUT array of MPNs of the requested vmId
+ } pageMgmnt;
+
+ struct {
+ unsigned int now; ///< OUT current time-of-day seconds
+ unsigned int nowusec; ///< OUT current time-of-day microseconds
+ } tod;
+
+ struct {
+ QPId id; ///< IN/OUT shared memory id
+ uint32 capacity; ///< IN size of shared region requested
+ uint32 type; ///< IN type of queue pair
+ uint32 base; ///< IN base MPN of PA vector page
+ uint32 nrPages; ///< IN number of pages to map
+ int32 rc; ///< OUT return code
+ } qp;
+
+ struct {
+ CommTranspID transpID;
+ CommTranspIOEvent event;
+ } commEvent;
+
+ struct {
+ uint64 when64; ///< IN timer request
+ } timer;
+
+ struct {
+ _Bool suspendMode; ///< Is the guest in suspend mode?
+ } wait;
+
+ }; ///< anonymous union
+} WSParams;
+
+
+/**
+ * @brief Cast the opaque param_ member of the wsp to WSParams type
+ * @param wsp_ the world switch page structure pointer
+ * @return the cast pointer
+ */
+static inline WSParams* UNUSED
+WSP_Params(WorldSwitchPage *wsp_) {
+ return (WSParams*)(wsp_->params_);
+}
+
+MY_ASSERTS(WSParFn,
+ ASSERT_ON_COMPILE(sizeof(WSParams) <= WSP_PARAMS_SIZE);
+)
+#endif
diff --git a/arch/arm/mvp/pvtcpkm/COPYING b/arch/arm/mvp/pvtcpkm/COPYING
new file mode 100644
index 0000000..10828e0
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/COPYING
@@ -0,0 +1,341 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/arch/arm/mvp/pvtcpkm/Kbuild b/arch/arm/mvp/pvtcpkm/Kbuild
new file mode 100644
index 0000000..d2ec844
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/Kbuild
@@ -0,0 +1,9 @@
+# Warning: autogenerated
+obj-m := pvtcpkm.o
+pvtcpkm-objs := check_kconfig.o pvtcp_off_io_linux.o pvtcp_off_linux.o comm_os_linux.o comm_os_mod_linux.o pvtcp.o pvtcp_off.o pvtcp_off_linux_shim.o
+
+ccflags-y += -fno-pic -fno-dwarf2-cfi-asm -march=armv7-a -D__linux__
+ccflags-y += -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -DPVTCP_BUILDING_SERVER
+ccflags-y += -mfpu=neon -DIN_MODULE -DGPLED_CODE
+ccflags-y += --std=gnu89 -O2 -g2 -ggdb -mapcs -fno-optimize-sibling-calls -mno-sched-prolog
+ccflags-$(CONFIG_VMWARE_MVP_DEBUG) += -DMVP_DEBUG
diff --git a/arch/arm/mvp/pvtcpkm/Makefile b/arch/arm/mvp/pvtcpkm/Makefile
new file mode 100644
index 0000000..16eb389
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/Makefile
@@ -0,0 +1 @@
+# Warning: autogenerated
diff --git a/arch/arm/mvp/pvtcpkm/check_kconfig.c b/arch/arm/mvp/pvtcpkm/check_kconfig.c
new file mode 100644
index 0000000..6fc27a1
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/check_kconfig.c
@@ -0,0 +1,91 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ * @brief Check for required kernel configuration
+ *
+ * Check to make sure that the kernel options that the MVP hypervisor requires
+ * have been enabled in the kernel that this kernel module is being built
+ * against.
+ */
+#include <linux/version.h>
+
+/*
+ * Minimum kernel version
+ * - network namespace support is only really functional starting in 2.6.29
+ * - Android Gingerbread requires 2.6.35
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
+#error "MVP requires a host kernel newer than 2.6.35"
+#endif
+
+/* module loading ability */
+#ifndef CONFIG_MODULES
+#error "MVP requires kernel loadable module support be enabled (CONFIG_MODULES)"
+#endif
+#ifndef CONFIG_MODULE_UNLOAD
+#error "MVP requires kernel module unload support be enabled (CONFIG_MODULE_UNLOAD)"
+#endif
+
+/* sysfs */
+#ifndef CONFIG_SYSFS
+#error "MVP requires sysfs support (CONFIG_SYSFS)"
+#endif
+
+/* network traffic isolation */
+#ifndef CONFIG_NAMESPACES
+#error "MVP networking support requires namespace support (CONFIG_NAMESPACES)"
+#endif
+#ifndef CONFIG_NET_NS
+#error "MVP networking support requires Network Namespace support to be enabled (CONFIG_NET_NS)"
+#endif
+
+/* TCP/IP networking */
+#ifndef CONFIG_INET
+#error "MVP networking requires IPv4 support (CONFIG_INET)"
+#endif
+#ifndef CONFIG_IPV6
+#error "MVP networking requires IPv6 support (CONFIG_IPV6)"
+#endif
+
+/* VPN support */
+#if !defined(CONFIG_TUN) && !defined(CONFIG_TUN_MODULE)
+#error "MVP VPN support requires TUN device support (CONFIG_TUN)"
+#endif
+
+#if !defined(CONFIG_NETFILTER) && !defined(PVTCP_DISABLE_NETFILTER)
+#error "MVP networking support requires netfilter support (CONFIG_NETFILTER)"
+#endif
+
+/* Force /proc/config.gz support for eng/userdebug builds */
+#ifdef MVP_DEBUG
+#if !defined(CONFIG_IKCONFIG) || !defined(CONFIG_IKCONFIG_PROC)
+#error "MVP kernel /proc/config.gz support required for debuggability (CONFIG_IKCONFIG_PROC)"
+#endif
+#endif
+
+/* Sanity check we're only dealing with the memory hotplug + migrate and/or
+ * compaction combo */
+#ifdef CONFIG_MIGRATION
+#if defined(CONFIG_NUMA) || defined(CONFIG_CPUSETS) || defined(CONFIG_MEMORY_FAILURE)
+#error "MVP not tested with migration features other than CONFIG_MEMORY_HOTPLUG and CONFIG_COMPACTION"
+#endif
+#endif
diff --git a/arch/arm/mvp/pvtcpkm/comm.h b/arch/arm/mvp/pvtcpkm/comm.h
new file mode 100644
index 0000000..877731d
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm.h
@@ -0,0 +1,171 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Communication functions based on queue pair transport APIs.
+ *
+ * Comm is a shared memory-based mechanism that facilitates the implementation
+ * of kernel components that require host-to-guest, or guest-to-guest
+ * communication.
+ * This facility assumes the availability of a minimal shared memory queue pair
+ * implementation, such as MVP queue pairs or VMCI queue pairs. The latter must
+ * provide primitives for queue pair creation and destruction, and reading and
+ * writing from/to queue pairs.
+ * Comm assumes that the queue pair (transport) layer is not concerned with
+ * multi-threading, locking or flow control, and does not require such features.
+ */
+
+#ifndef _COMM_H_
+#define _COMM_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "comm_os.h"
+#include "comm_transp.h"
+
+
+/* Default/maximum Comm timeouts (in milliseconds). */
+#define COMM_MAX_TO 60000ULL
+#define COMM_MAX_TO_UNINT (COMM_MAX_TO + 1)
+
+#define COMM_OPF_SET_ERR(flags) ((flags) |= 128)
+#define COMM_OPF_CLEAR_ERR(flags) ((flags) &= 127)
+#define COMM_OPF_TEST_ERR(flags) ((flags) & 128)
+
+#define COMM_OPF_SET_VAL(flags, val) ((flags) |= ((val) & 127))
+#define COMM_OPF_GET_VAL(flags) ((flags) & 127)
+
+/**
+ * Packet (header) structure.
+ * NB: Do not change this structure, especially the first three fields; there
+ * will be consequences. It may be extended, but it's not recommended: all
+ * operations carry this header, so it's better kept in its minimal form.
+ */
+
+typedef struct CommPacket {
+ unsigned int len; // Total length
+ unsigned char flags; // Operation flags
+ unsigned char opCode; // Operation to call
+ unsigned short data16; // Auxiliary data
+ unsigned long long data64;
+ unsigned long long data64ex;
+ union {
+ struct {
+ unsigned int data32;
+ unsigned int data32ex;
+ };
+ unsigned long long data64ex2;
+ };
+} CommPacket;
+
+
+/* Opaque structure representing a communication channel. */
+
+struct CommChannelPriv;
+typedef struct CommChannelPriv *CommChannel;
+
+
+/* Input operations associated with a comm channel. */
+
+typedef void (*CommOperationFunc)(CommChannel channel,
+ void *state,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen);
+
+
+/* Helper macros */
+
+#define COMM_DEFINE_OP(funcName) \
+void \
+funcName(CommChannel channel, \
+ void *state, \
+ CommPacket *packet, \
+ struct kvec *vec, \
+ unsigned int vecLen)
+
+
+/* Comm-based implementations. */
+
+typedef struct CommImpl {
+ struct module *owner;
+ int (*checkArgs)(CommTranspInitArgs *transpArgs);
+ void *(*stateCtor)(CommChannel channel);
+ void (*stateDtor)(void *state);
+ void *(*dataAlloc)(unsigned int dataLen);
+ void (*dataFree)(void *data);
+ const CommOperationFunc *operations;
+ void (*closeNtf)(void *closeNtfData,
+ const CommTranspInitArgs *transpArgs,
+ int inBH);
+ void *closeNtfData;
+ void (*activateNtf)(void *activateNtfData,
+ CommChannel channel);
+ void *activateNtfData;
+ unsigned long long openAtMillis;
+ unsigned long long openTimeoutAtMillis;
+ CommTranspID ntfCenterID;
+} CommImpl;
+
+
+int Comm_Init(unsigned int maxChannels);
+int Comm_Finish(unsigned long long *timeoutMillis);
+int Comm_RegisterImpl(const CommImpl *impl);
+void Comm_UnregisterImpl(const CommImpl *impl);
+int Comm_IsActive(CommChannel channel);
+CommTranspInitArgs Comm_GetTranspInitArgs(CommChannel channel);
+void *Comm_GetState(CommChannel channel);
+int Comm_Dispatch(CommChannel channel);
+unsigned int Comm_DispatchAll(void);
+void Comm_Put(CommChannel channel);
+void Comm_DispatchUnlock(CommChannel channel);
+int Comm_Lock(CommChannel channel);
+void Comm_Unlock(CommChannel channel);
+int Comm_Zombify(CommChannel channel, int inBH);
+
+int
+Comm_Alloc(const CommTranspInitArgs *transpArgs,
+ const CommImpl *impl,
+ int inBH,
+ CommChannel *newChannel);
+
+
+int
+Comm_Write(CommChannel channel,
+ const CommPacket *packet,
+ unsigned long long *timeoutMillis);
+
+int
+Comm_WriteVec(CommChannel channel,
+ const CommPacket *packet,
+ struct kvec **vec,
+ unsigned int *vecLen,
+ unsigned long long *timeoutMillis,
+ unsigned int *iovOffset);
+
+unsigned int Comm_RequestInlineEvents(CommChannel channel);
+unsigned int Comm_ReleaseInlineEvents(CommChannel channel);
+
+#endif // _COMM_H_
diff --git a/arch/arm/mvp/pvtcpkm/comm_os.h b/arch/arm/mvp/pvtcpkm/comm_os.h
new file mode 100644
index 0000000..91305f1
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_os.h
@@ -0,0 +1,150 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Cross-platform base type definitions and function declarations.
+ * Includes OS-specific base type definitions and function declarations.
+ */
+
+#ifndef _COMM_OS_H_
+#define _COMM_OS_H_
+
+/* For-ever timeout constant (in milliseconds). */
+#define COMM_OS_4EVER_TO ((unsigned long long)(~0UL >> 1))
+
+/* Condition function prototype. Returns 1: true, 0: false, < 0: error code. */
+typedef int (*CommOSWaitConditionFunc)(void *arg1, void *arg2);
+
+/* Dispatch function prototype. Called by input (dispatch) kernel threads. */
+typedef unsigned int (*CommOSDispatchFunc)(void);
+
+/* Module initialization and exit callback functions. */
+extern int (*commOSModInit)(void *args);
+extern void (*commOSModExit)(void);
+
+/* Macro to assign Init and Exit callbacks. */
+#define COMM_OS_MOD_INIT(init, exit) \
+ int (*commOSModInit)(void *args) = init; \
+ void (*commOSModExit)(void) = exit
+
+
+/*
+ * OS-specific implementations must provide the following:
+ * 1. Types:
+ * CommOSAtomic
+ * CommOSSpinlock
+ * CommOSMutex
+ * CommOSWaitQueue
+ * CommOSWork
+ * CommOSWorkFunc
+ * CommOSList
+ * CommOSModule
+ * struct kvec
+ *
+ * 2. Definition, initializers:
+ * CommOSSpinlock_Define()
+ *
+ * 3. Functions:
+ * void CommOS_Debug(const char *format, ...);
+ * void CommOS_Log(const char *format, ...);
+ * void CommOS_WriteAtomic(CommOSAtomic *atomic, int val);
+ * int CommOS_ReadAtomic(CommOSAtomic *atomic);
+ * int CommOS_AddReturnAtomic(CommOSAtomic *atomic, int val);
+ * int CommOS_SubReturnAtomic(CommOSAtomic *atomic, int val);
+ * void CommOS_SpinlockInit(CommOSSpinlock *lock);
+ * void CommOS_SpinLockBH(CommOSSpinlock *lock);
+ * int CommOS_SpinTrylockBH(CommOSSpinlock *lock);
+ * void CommOS_SpinUnlockBH(CommOSSpinlock *lock);
+ * void CommOS_SpinLock(CommOSSpinlock *lock);
+ * int CommOS_SpinTrylock(CommOSSpinlock *lock);
+ * void CommOS_SpinUnlock(CommOSSpinlock *lock);
+ * void CommOS_MutexInit(CommOSMutex *mutex);
+ * void CommOS_MutexLock(CommOSMutex *mutex);
+ * int CommOS_MutexLockUninterruptible(CommOSMutex *mutex);
+ * int CommOS_MutexTrylock(CommOSMutex *mutex);
+ * void CommOS_MutexUnlock(CommOSMutex *mutex);
+ * void CommOS_WaitQueueInit(CommOSWaitQueue *wq);
+ * CommOS_DoWait(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc cond,
+ * void *condArg1,
+ * void *condArg2,
+ * unsigned long long *timeoutMillis,
+ * int interruptible);
+ * int CommOS_Wait(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc func,
+ * void *funcArg1,
+ * void *funcArg2,
+ * unsigned long long *timeoutMillis);
+ * int CommOS_WaitUninterruptible(CommOSWaitQueue *wq,
+ * CommOSWaitConditionFunc func,
+ * void *funcArg1,
+ * void *funcArg2,
+ * unsigned long long *timeoutMillis);
+ * void CommOS_WakeUp(CommOSWaitQueue *wq);
+ * void *CommOS_KmallocNoSleep(unsigned int size);
+ * void *CommOS_Kmalloc(unsigned int size);
+ * void CommOS_Kfree(void *arg);
+ * void CommOS_Yield(void);
+ * unsigned long long CommOS_GetCurrentMillis(void);
+ * void CommOS_ListInit(CommOSList *list);
+ * int CommOS_ListEmpty(CommOSList *list);
+ * void CommOS_ListAdd(CommOSList *list, CommOSList *listElem);
+ * void CommOS_ListAddTail(CommOSList *list, CommOSList *listElem);
+ * void int CommOS_ListDel(CommOSList *listElem);
+ * Macros:
+ * CommOS_ListForEach(*list, *item, itemListFieldName);
+ * CommOS_ListForEachSafe(*list, *item, *tmp, itemListFieldName);
+ * void CommOS_ListSplice(CommOSList *list, CommOSList *listToAdd);
+ * void CommOS_ListSpliceTail(CommOSList *list, CommOSList *listToAdd);
+ * CommOSModule CommOS_ModuleSelf(void);
+ * int CommOS_ModuleGet(CommOSModule module);
+ * void CommOS_ModulePut(CommOSModule module);
+ * void CommOS_MemBarrier(void);
+ *
+ * These cannot be defined here: a) non-pointer type definitions need size
+ * information, and b) functions may or may not be inlined, or macros may
+ * be used instead.
+ */
+
+
+#ifdef __linux__
+#include "comm_os_linux.h"
+#else
+#error "Unsupported OS"
+#endif
+
+/* Functions to start and stop the dispatch and aio kernel threads. */
+void CommOS_StopIO(void);
+void CommOS_ScheduleDisp(void);
+void CommOS_InitWork(CommOSWork *work, CommOSWorkFunc func);
+int CommOS_ScheduleAIOWork(CommOSWork *work);
+void CommOS_FlushAIOWork(CommOSWork *work);
+
+int
+CommOS_StartIO(const char *dispatchTaskName,
+ CommOSDispatchFunc dispatchHandler,
+ unsigned int interval,
+ unsigned int maxCycles,
+ const char *aioTaskName);
+
+
+#endif /* _COMM_OS_H_ */
diff --git a/arch/arm/mvp/pvtcpkm/comm_os_linux.c b/arch/arm/mvp/pvtcpkm/comm_os_linux.c
new file mode 100644
index 0000000..61ce929
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_os_linux.c
@@ -0,0 +1,371 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Linux-specific functions/types.
+ */
+
+#include "comm_os.h"
+
+#define DISPATCH_MAX_CYCLES 8192
+
+/* Type definitions */
+
+typedef struct workqueue_struct CommOSWorkQueue;
+
+
+/* Static data */
+
+static volatile int running;
+static int numCpus;
+static CommOSWorkQueue *dispatchWQ;
+static CommOSDispatchFunc dispatch;
+static CommOSWork dispatchWorksNow[NR_CPUS];
+static CommOSWork dispatchWorks[NR_CPUS];
+static unsigned int dispatchInterval = 1;
+static unsigned int dispatchMaxCycles = 2048;
+static CommOSWorkQueue *aioWQ;
+
+
+/**
+ * @brief Initializes a workqueue consisting of per-cpu kernel threads.
+ * @param name workqueue name
+ * @return workqueue handle if successful, NULL otherwise
+ */
+
+static inline CommOSWorkQueue *
+CreateWorkqueue(const char *name)
+{
+ return create_workqueue(name);
+}
+
+
+/**
+ * @brief Destroys a workqueue and stops its threads.
+ * @param[in,out] wq workqueue to destroy.
+ * @return workqueue handle is successful, NULL otherwise.
+ */
+
+static inline void
+DestroyWorkqueue(CommOSWorkQueue *wq)
+{
+ destroy_workqueue(wq);
+}
+
+
+/**
+ * @brief Force execution of a work item.
+ * @param[in,out] work work item to dequeue.
+ */
+
+static inline void
+FlushDelayedWork(CommOSWork *work)
+{
+ flush_delayed_work(work);
+}
+
+
+/**
+ * @brief Enqueue a work item to a workqueue for execution on a given cpu
+ * and after the specified interval.
+ * @param cpu cpu number. If negative, work item is enqueued on current cpu.
+ * @param[in,out] wq target work queue.
+ * @param[in,out] work work item to enqueue.
+ * @param jif delay interval.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+QueueDelayedWorkOn(int cpu,
+ CommOSWorkQueue *wq,
+ CommOSWork *work,
+ unsigned long jif)
+{
+ if (cpu < 0) {
+ return !queue_delayed_work(wq, work, jif) ? -1 : 0;
+ } else {
+ return !queue_delayed_work_on(cpu, wq, work, jif) ? -1 : 0;
+ }
+}
+
+
+/**
+ * @brief Enqueues a work item to a workqueue for execution on the current cpu
+ * and after the specified interval.
+ * @param[in,out] wq target work queue.
+ * @param[in,out] work work item to enqueue.
+ * @param jif delay interval.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+QueueDelayedWork(CommOSWorkQueue *wq,
+ CommOSWork *work,
+ unsigned long jif)
+{
+ return QueueDelayedWorkOn(-1, wq, work, jif);
+}
+
+
+/**
+ * @brief Cancels a queued delayed work item and synchronizes with its
+ * completion.
+ * @param[in,out] work work item to cancel
+ */
+
+static inline void
+WaitForDelayedWork(CommOSWork *work)
+{
+ cancel_delayed_work_sync(work);
+}
+
+
+/**
+ * @brief Discards work items queued to the specified workqueue.
+ * @param[in,out] wq work queue to flush.
+ */
+
+static inline void
+FlushWorkqueue(CommOSWorkQueue *wq)
+{
+ flush_workqueue(wq);
+}
+
+
+/**
+ * @brief Schedules dispatcher threads for immediate execution.
+ */
+
+void
+CommOS_ScheduleDisp(void)
+{
+ CommOSWork *work = &dispatchWorksNow[get_cpu()];
+
+ put_cpu();
+ if (running) {
+ QueueDelayedWork(dispatchWQ, work, 0);
+ }
+}
+
+
+/**
+ * @brief Default delayed work callback function implementation.
+ * Calls the input function specified at initialization.
+ * @param[in,out] work work item.
+ */
+
+static void
+DispatchWrapper(CommOSWork *work)
+{
+ unsigned int misses;
+
+ for (misses = 0; running && (misses < dispatchMaxCycles); ) {
+ /* We run for at most dispatchMaxCycles worth of channel no-ops. */
+
+ if (!dispatch()) {
+ /* No useful work was done, on any of the channels. */
+
+ misses++;
+ if ((misses % 32) == 0) {
+ CommOS_Yield();
+ }
+ } else {
+ misses = 0;
+ }
+ }
+
+ if (running &&
+ (work >= &dispatchWorks[0]) &&
+ (work <= &dispatchWorks[NR_CPUS - 1])) {
+ /*
+ * If still running _and_ this was a regular, time-based run, then
+ * re-arm the timer.
+ */
+
+ QueueDelayedWork(dispatchWQ, work, dispatchInterval);
+ }
+}
+
+
+/**
+ * @brief Initializes work item with specified callback function.
+ * @param[in,out] work work queue to initialize.
+ * @param func work item to initialize the queue with.
+ */
+
+void
+CommOS_InitWork(CommOSWork *work,
+ CommOSWorkFunc func)
+{
+ INIT_DELAYED_WORK(work, (work_func_t)func);
+}
+
+
+/**
+ * @brief Flush execution of a work item
+ * @param{in,out] work work item to dequeue
+ */
+void
+CommOS_FlushAIOWork(CommOSWork *work)
+{
+ if (aioWQ && work) {
+ FlushDelayedWork(work);
+ }
+}
+
+
+/**
+ * @brief Queue a work item to the AIO workqueue.
+ * @param[in,out] work work item to enqueue.
+ * @return zero if work enqueued, non-zero otherwise.
+ */
+
+int
+CommOS_ScheduleAIOWork(CommOSWork *work)
+{
+ if (running && aioWQ && work) {
+ return QueueDelayedWork(aioWQ, work, 0);
+ }
+ return -1;
+}
+
+
+/**
+ * @brief Initializes the base IO system.
+ * @param dispatchTaskName dispatch thread(s) name.
+ * @param dispatchFunc dispatch function.
+ * @param intervalMillis periodic interval in milliseconds to call dispatch.
+ * The floor is 1 jiffy, regardless of how small intervalMillis is
+ * @param maxCycles number of cycles to do adaptive polling before scheduling.
+ * The maximum number of cycles is DISPATCH_MAX_CYCLES.
+ * @param aioTaskName AIO thread(s) name. If NULL, AIO threads aren't started.
+ * @return zero is successful, -1 otherwise.
+ * @sideeffects Dispatch threads, and if applicable, AIO threads are started.
+ */
+
+int
+CommOS_StartIO(const char *dispatchTaskName, // IN
+ CommOSDispatchFunc dispatchFunc, // IN
+ unsigned int intervalMillis, // IN
+ unsigned int maxCycles, // IN
+ const char *aioTaskName) // IN
+{
+ int rc;
+ int cpu;
+
+ if (running) {
+ CommOS_Debug(("%s: I/O tasks already running.\n", __FUNCTION__));
+ return 0;
+ }
+
+ /*
+ * OK, let's test the handler against NULL. Though, the whole concept
+ * of checking for NULL pointers, outside cases where NULL is meaningful
+ * to the implementation, is relatively useless: garbage, random pointers
+ * rarely happen to be all-zeros.
+ */
+
+ if (!dispatchFunc) {
+ CommOS_Log(("%s: a NULL Dispatch handler was passed.\n", __FUNCTION__));
+ return -1;
+ }
+ dispatch = dispatchFunc;
+
+ if (intervalMillis == 0) {
+ intervalMillis = 4;
+ }
+ if ((dispatchInterval = msecs_to_jiffies(intervalMillis)) < 1) {
+ dispatchInterval = 1;
+ }
+ if (maxCycles > DISPATCH_MAX_CYCLES) {
+ dispatchMaxCycles = DISPATCH_MAX_CYCLES;
+ } else if (maxCycles > 0) {
+ dispatchMaxCycles = maxCycles;
+ }
+ CommOS_Debug(("%s: Interval millis %u (jif:%u).\n", __FUNCTION__,
+ intervalMillis, dispatchInterval));
+ CommOS_Debug(("%s: Max cycles %u.\n", __FUNCTION__, dispatchMaxCycles));
+
+ numCpus = num_present_cpus();
+ dispatchWQ = CreateWorkqueue(dispatchTaskName);
+ if (!dispatchWQ) {
+ CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__,
+ dispatchTaskName));
+ return -1;
+ }
+
+ if (aioTaskName) {
+ aioWQ = CreateWorkqueue(aioTaskName);
+ if (!aioWQ) {
+ CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__,
+ aioTaskName));
+ DestroyWorkqueue(dispatchWQ);
+ return -1;
+ }
+ } else {
+ aioWQ = NULL;
+ }
+
+ running = 1;
+ for (cpu = 0; cpu < numCpus; cpu++) {
+ CommOS_InitWork(&dispatchWorksNow[cpu], DispatchWrapper);
+ CommOS_InitWork(&dispatchWorks[cpu], DispatchWrapper);
+ rc = QueueDelayedWorkOn(cpu, dispatchWQ,
+ &dispatchWorks[cpu],
+ dispatchInterval);
+ if (rc != 0) {
+ CommOS_StopIO();
+ return -1;
+ }
+ }
+ CommOS_Log(("%s: Created I/O task(s) successfully.\n", __FUNCTION__));
+ return 0;
+}
+
+
+/**
+ * @brief Stops the base IO system.
+ * @sideeffects Dispatch threads, and if applicable, AIO threads are stopped.
+ */
+
+void
+CommOS_StopIO(void)
+{
+ int cpu;
+
+ if (running) {
+ running = 0;
+ if (aioWQ) {
+ FlushWorkqueue(aioWQ);
+ DestroyWorkqueue(aioWQ);
+ aioWQ = NULL;
+ }
+ FlushWorkqueue(dispatchWQ);
+ for (cpu = 0; cpu < numCpus; cpu++) {
+ WaitForDelayedWork(&dispatchWorksNow[cpu]);
+ WaitForDelayedWork(&dispatchWorks[cpu]);
+ }
+ DestroyWorkqueue(dispatchWQ);
+ dispatchWQ = NULL;
+ CommOS_Log(("%s: I/O tasks stopped.\n", __FUNCTION__));
+ }
+}
diff --git a/arch/arm/mvp/pvtcpkm/comm_os_linux.h b/arch/arm/mvp/pvtcpkm/comm_os_linux.h
new file mode 100644
index 0000000..81ee9d1
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_os_linux.h
@@ -0,0 +1,699 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Contains linux-specific type definitions and function declarations
+ */
+
+#ifndef _COMM_OS_LINUX_H_
+#define _COMM_OS_LINUX_H_
+
+#include <linux/types.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#error "Kernel versions lower than 2.6.20 are not supported"
+#endif
+
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+
+/*
+ * Type definitions.
+ */
+
+typedef atomic_t CommOSAtomic;
+typedef spinlock_t CommOSSpinlock;
+typedef struct mutex CommOSMutex;
+typedef wait_queue_head_t CommOSWaitQueue;
+typedef struct delayed_work CommOSWork;
+typedef void (*CommOSWorkFunc)(CommOSWork *work);
+typedef struct list_head CommOSList;
+typedef struct module *CommOSModule;
+
+
+/*
+ * Initializers.
+ */
+
+#define CommOSSpinlock_Define DEFINE_SPINLOCK
+
+
+#define COMM_OS_DOLOG(...) printk(KERN_INFO __VA_ARGS__)
+
+
+/**
+ * @brief Logs given arguments in debug builds.
+ */
+
+#if defined(COMM_OS_DEBUG)
+ #define CommOS_Debug(args) COMM_OS_DOLOG args
+#else
+ #define CommOS_Debug(args)
+#endif
+
+
+/**
+ * @brief Logs given arguments.
+ */
+
+#define CommOS_Log(args) COMM_OS_DOLOG args
+
+
+/**
+ * @brief Logs function name and location.
+ */
+
+#if defined(COMM_OS_TRACE)
+#define TRACE(ptr) \
+ do { \
+ CommOS_Debug(("%p:%s: at [%s:%d] with arg ptr [0x%p].\n", current, \
+ __FUNCTION__, __FILE__, __LINE__, (ptr))); \
+ } while (0)
+#else
+#define TRACE(ptr)
+#endif
+
+
+/**
+ * @brief Write atomic variable
+ * @param[in,out] atomic variable to write
+ * @param val new value
+ */
+
+static inline void
+CommOS_WriteAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ atomic_set(atomic, val);
+}
+
+
+/**
+ * @brief Reads atomic variable
+ * @param atomic variable to read
+ * @return value
+ */
+
+static inline int
+CommOS_ReadAtomic(CommOSAtomic *atomic)
+{
+ return atomic_read(atomic);
+}
+
+
+/**
+ * @brief Atomically add value to atomic variable, return new value.
+ * @param[in,out] atomic variable
+ * @param val value to add
+ * @return new value
+ */
+
+static inline int
+CommOS_AddReturnAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ return atomic_add_return(val, atomic);
+}
+
+
+/**
+ * @brief Atomically substract value from atomic variable, return new value.
+ * @param[in,out] atomic variable
+ * @param val value to substract
+ * @return new value
+ */
+
+static inline int
+CommOS_SubReturnAtomic(CommOSAtomic *atomic,
+ int val)
+{
+ return atomic_sub_return(val, atomic);
+}
+
+
+/**
+ * @brief Initializes a given lock.
+ * @param[in,out] lock lock to initialize
+ */
+
+static inline void
+CommOS_SpinlockInit(CommOSSpinlock *lock)
+{
+ spin_lock_init(lock);
+}
+
+
+/**
+ * @brief Locks given lock and disables bottom half processing.
+ * @param[in,out] lock lock to lock
+ */
+
+static inline void
+CommOS_SpinLockBH(CommOSSpinlock *lock)
+{
+ spin_lock_bh(lock);
+}
+
+
+/**
+ * @brief Attempts to lock the given lock and disable BH processing.
+ * @param[in,out] lock lock to lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_SpinTrylockBH(CommOSSpinlock *lock)
+{
+ return !spin_trylock_bh(lock);
+}
+
+
+/**
+ * @brief Unlocks given lock and re-enables BH processing.
+ * @param[in,out] lock lock to unlock
+ */
+
+static inline void
+CommOS_SpinUnlockBH(CommOSSpinlock *lock)
+{
+ spin_unlock_bh(lock);
+}
+
+
+/**
+ * @brief Locks the given lock.
+ * @param[in,out] lock lock to lock
+ */
+
+static inline void
+CommOS_SpinLock(CommOSSpinlock *lock)
+{
+ spin_lock(lock);
+}
+
+
+/**
+ * @brief Attempts to lock the given lock.
+ * @param[in,out] lock lock to try-lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_SpinTrylock(CommOSSpinlock *lock)
+{
+ return !spin_trylock(lock);
+}
+
+
+/**
+ * @brief Unlocks given lock.
+ * @param[in,out] lock lock to unlock
+ */
+
+static inline void
+CommOS_SpinUnlock(CommOSSpinlock *lock)
+{
+ spin_unlock(lock);
+}
+
+
+/**
+ * @brief Initializes given mutex.
+ * @param[in,out] mutex mutex to initialize
+ */
+
+static inline void
+CommOS_MutexInit(CommOSMutex *mutex)
+{
+ mutex_init(mutex);
+}
+
+
+/**
+ * @brief Acquires mutex.
+ * @param[in,out] mutex mutex to lock
+ * @return zero if successful, non-zero otherwise (interrupted)
+ */
+
+static inline int
+CommOS_MutexLock(CommOSMutex *mutex)
+{
+ return mutex_lock_interruptible(mutex);
+}
+
+
+/**
+ * @brief Acquires mutex in uninterruptible mode.
+ * @param[in,out] mutex mutex to lock
+ */
+
+static inline void
+CommOS_MutexLockUninterruptible(CommOSMutex *mutex)
+{
+ mutex_lock(mutex);
+}
+
+
+/**
+ * @brief Attempts to acquire given mutex.
+ * @param[in,out] mutex mutex to try-lock
+ * @return zero if successful, non-zero otherwise
+ */
+
+static inline int
+CommOS_MutexTrylock(CommOSMutex *mutex)
+{
+ return !mutex_trylock(mutex);
+}
+
+
+/**
+ * @brief Releases a given mutex.
+ * @param[in,out] mutex mutex to unlock
+ */
+
+static inline void
+CommOS_MutexUnlock(CommOSMutex *mutex)
+{
+ mutex_unlock(mutex);
+}
+
+
+/**
+ * @brief Initializes a wait queue.
+ * @param[in,out] wq workqueue to initialize
+ */
+
+static inline void
+CommOS_WaitQueueInit(CommOSWaitQueue *wq)
+{
+ init_waitqueue_head(wq);
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * - a signal is pending
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @param interruptible enable/disable signal pending check
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, if a signal is pending or other error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_DoWait(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis,
+ int interruptible)
+{
+ int rc;
+ DEFINE_WAIT(wait);
+ long timeout;
+#if defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ long tmpTimeout;
+ long retTimeout;
+ const unsigned int interval = 50;
+#endif
+
+ if (!timeoutMillis) {
+ return -1;
+ }
+ if ((rc = cond(condArg1, condArg2)) != 0) {
+ return rc;
+ }
+
+#if defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ timeout = msecs_to_jiffies(interval < *timeoutMillis ?
+ interval : (unsigned int)*timeoutMillis);
+ retTimeout = msecs_to_jiffies((unsigned int)(*timeoutMillis));
+
+ for (; retTimeout >= 0; ) {
+ prepare_to_wait(wq, &wait,
+ (interruptible?TASK_INTERRUPTIBLE:TASK_UNINTERRUPTIBLE));
+ if ((rc = cond(condArg1, condArg2))) {
+ break;
+ }
+ if (interruptible && signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if ((tmpTimeout = schedule_timeout(timeout))) {
+ retTimeout -= (timeout - tmpTimeout);
+ } else {
+ retTimeout -= timeout;
+ }
+ if (retTimeout < 0) {
+ retTimeout = 0;
+ }
+ }
+ finish_wait(wq, &wait);
+ if (rc == 0) {
+ rc = cond(condArg1, condArg2);
+ if (rc && (retTimeout == 0)) {
+ retTimeout = 1;
+ }
+ }
+ *timeoutMillis = (unsigned long long)jiffies_to_msecs(retTimeout);
+#else // !defined(COMM_OS_LINUX_WAIT_WORKAROUND)
+ timeout = msecs_to_jiffies((unsigned int)(*timeoutMillis));
+
+ for (;;) {
+ prepare_to_wait(wq, &wait,
+ (interruptible?TASK_INTERRUPTIBLE:TASK_UNINTERRUPTIBLE));
+ if ((rc = cond(condArg1, condArg2)) != 0) {
+ break;
+ }
+ if (interruptible && signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+ if ((timeout = schedule_timeout(timeout)) == 0) {
+ rc = 0;
+ break;
+ }
+ }
+ finish_wait(wq, &wait);
+ if (rc == 0) {
+ rc = cond(condArg1, condArg2);
+ if (rc && (timeout == 0)) {
+ timeout = 1;
+ }
+ }
+ *timeoutMillis = (unsigned long long)jiffies_to_msecs(timeout);
+#endif
+
+ return rc;
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * - a signal is pending
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, if a signal is pending or other error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_Wait(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis)
+{
+ return CommOS_DoWait(wq, cond, condArg1, condArg2, timeoutMillis, 1);
+}
+
+
+/**
+ * @brief Puts the caller on a wait queue until either of the following occurs:
+ * - the condition function (predicate) evaluates to TRUE
+ * - the specified timeout interval elapsed
+ * @param[in,out] wq wait queue to put item on
+ * @param cond predicate to test
+ * @param condArg1 argument 1 for cond
+ * @param condArg2 argument 2 for cond
+ * @param[in,out] timeoutMillis timeout interval in milliseconds
+ * @return 1 if condition was met
+ * 0 if the timeout interval elapsed
+ * <0, error set by condition
+ * @sideeffect timeoutMillis is updated to time remaining
+ */
+
+static inline int
+CommOS_WaitUninterruptible(CommOSWaitQueue *wq,
+ CommOSWaitConditionFunc cond,
+ void *condArg1,
+ void *condArg2,
+ unsigned long long *timeoutMillis)
+{
+ return CommOS_DoWait(wq, cond, condArg1, condArg2, timeoutMillis, 0);
+}
+
+
+/**
+ * @brief Wakes up task(s) waiting on the given wait queue.
+ * @param[in,out] wq wait queue.
+ */
+
+static inline void
+CommOS_WakeUp(CommOSWaitQueue *wq)
+{
+ wake_up(wq);
+}
+
+
+/**
+ * @brief Allocates kernel memory of specified size; does not sleep.
+ * @param size size to allocate.
+ * @return Address of allocated memory or NULL if the allocation fails.
+ */
+
+static inline void *
+CommOS_KmallocNoSleep(unsigned int size)
+{
+ return kmalloc(size, GFP_ATOMIC);
+}
+
+
+/**
+ * @brief Allocates kernel memory of specified size; may sleep.
+ * @param size size to allocate.
+ * @return Address of allocated memory or NULL if the allocation fails.
+ */
+
+static inline void *
+CommOS_Kmalloc(unsigned int size)
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+
+/**
+ * @brief Frees previously allocated kernel memory.
+ * @param obj object to free.
+ */
+
+static inline void
+CommOS_Kfree(void *obj)
+{
+ if (obj) {
+ kfree(obj);
+ }
+}
+
+
+/**
+ * @brief Yields the current cpu to other runnable tasks.
+ */
+
+static inline void
+CommOS_Yield(void)
+{
+ cond_resched();
+}
+
+
+/**
+ * @brief Gets the current time in milliseconds.
+ * @return Current time in milliseconds, with precision of at most one tick.
+ */
+
+static inline unsigned long long
+CommOS_GetCurrentMillis(void)
+{
+ return (unsigned long long)jiffies_to_msecs(jiffies);
+}
+
+
+/**
+ * @brief Initializes given list.
+ * @param list list to initialize.
+ */
+
+static inline void
+CommOS_ListInit(CommOSList *list)
+{
+ INIT_LIST_HEAD(list);
+}
+
+
+/**
+ * @brief Tests if list is empty.
+ * @param list list to test.
+ * @return non-zero if empty, zero otherwise.
+ */
+
+#define CommOS_ListEmpty(list) list_empty((list))
+
+
+/**
+ * @brief Adds given element to beginning of list.
+ * @param list list to add to.
+ * @param elem element to add.
+ */
+
+#define CommOS_ListAdd(list, elem) list_add((elem), (list))
+
+
+/**
+ * @brief Adds given element to end of list.
+ * @param list list to add to.
+ * @param elem element to add.
+ */
+
+#define CommOS_ListAddTail(list, elem) list_add_tail((elem), (list))
+
+
+/**
+ * @brief Deletes given element from its list.
+ * @param elem element to delete.
+ */
+
+#define CommOS_ListDel(elem) \
+ do { \
+ list_del((elem)); \
+ INIT_LIST_HEAD((elem)); \
+ } while (0)
+
+
+/**
+ * @brief Iterates over a list.
+ * @param list list to iterate over.
+ * @param[out] item stores next element.
+ * @param itemListFieldName name in the item structure storing the list head.
+ */
+
+#define CommOS_ListForEach(list, item, itemListFieldName) \
+ list_for_each_entry((item), (list), itemListFieldName)
+
+
+/**
+ * @brief Iterates safely over a list.
+ * @param list list to iterate over.
+ * @param[out] item stores next element. May be deleted in the loop.
+ * @param[out] tmpItem saves iteration element.
+ * @param itemListFieldName name in the item structure storing the list head.
+ */
+
+#define CommOS_ListForEachSafe(list, item, tmpItem, itemListFieldName) \
+ list_for_each_entry_safe((item), (tmpItem), (list), itemListFieldName)
+
+
+/**
+ * @brief Combines two lists, adds second list to beginning of first one.
+ * @param list list to add to.
+ * @param list2 list to add.
+ */
+
+#define CommOS_ListSplice(list, list2) list_splice((list2), (list))
+
+
+/**
+ * @brief Combines two lists, adds second list to end of first one.
+ * @param list list to add to.
+ * @param list2 list to add.
+ */
+
+#define CommOS_ListSpliceTail(list, list2) list_splice_tail((list2), (list))
+
+
+/**
+ * @brief Gets current module handle.
+ * @return module handle.
+ */
+
+static inline CommOSModule
+CommOS_ModuleSelf(void)
+{
+ return THIS_MODULE;
+}
+
+
+/**
+ * @brief Retains module.
+ * @param[in,out] module to retain.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static inline int
+CommOS_ModuleGet(CommOSModule module)
+{
+ int rc = 0;
+
+ if (!module) {
+ goto out;
+ }
+ if (!try_module_get(module)) {
+ rc = -1;
+ }
+
+out:
+ return rc;
+}
+
+
+/**
+ * @brief Releases module.
+ * @param[in,out] module to release.
+ */
+
+static inline void
+CommOS_ModulePut(CommOSModule module)
+{
+ if (module) {
+ module_put(module);
+ }
+}
+
+
+/**
+ * @brief Inserts r/w memory barrier.
+ */
+
+#define CommOS_MemBarrier smp_mb
+
+#endif /* _COMM_OS_LINUX_H_ */
diff --git a/arch/arm/mvp/pvtcpkm/comm_os_mod_linux.c b/arch/arm/mvp/pvtcpkm/comm_os_mod_linux.c
new file mode 100644
index 0000000..e196108
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_os_mod_linux.c
@@ -0,0 +1,105 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Linux-specific module loading, unloading functions.
+ */
+
+#include "comm_os.h"
+#include "comm_os_mod_ver.h"
+
+#include <linux/moduleparam.h>
+
+
+/* Module parameters -- passed as one 'name=value'-list string. */
+
+static char modParams[256];
+module_param_string(COMM_OS_MOD_SHORT_NAME, modParams, sizeof modParams, 0644);
+
+
+/**
+ * @brief Module initialization entry point. Calls the commOSModInit
+ * function pointer to perform upper layer initialization.
+ * @return zero if successful, non-zero otherwise.
+ */
+
+static int __init
+ModInit(void)
+{
+ int rc;
+
+ if (!commOSModInit) {
+ CommOS_Log(("%s: Can't find \'init\' function for module \'" \
+ COMM_OS_MOD_SHORT_NAME_STRING "\'.\n", __FUNCTION__));
+ return -1;
+ }
+
+ CommOS_Debug(("%s: Module parameters: [%s].\n", __FUNCTION__, modParams));
+
+ rc = (*commOSModInit)(modParams);
+ if (rc == 0) {
+ CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \
+ "\' has been successfully initialized.\n", __FUNCTION__));
+ } else {
+ CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \
+ "\' could not be initialized [%d].\n", __FUNCTION__, rc));
+ }
+
+ return rc > 0 ? -rc : rc;
+}
+
+
+/**
+ * @brief Module exit function. Calls the commOSModExit function pointer
+ * to perform upper layer cleanup.
+ */
+
+static void __exit
+ModExit(void)
+{
+ if (!commOSModExit) {
+ CommOS_Log(("%s: Can't find \'fini\' function for module \'" \
+ COMM_OS_MOD_SHORT_NAME_STRING "\'.\n", __FUNCTION__));
+ return;
+ }
+
+ (*commOSModExit)();
+ CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \
+ "\' has been stopped.\n", __FUNCTION__));
+}
+
+
+module_init(ModInit);
+module_exit(ModExit);
+
+/* Module information. */
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION(COMM_OS_MOD_NAME_STRING);
+MODULE_VERSION(COMM_OS_MOD_VERSION_STRING);
+MODULE_LICENSE("GPL v2");
+/*
+ * Starting with SLE10sp2, Novell requires that IHVs sign a support agreement
+ * with them and mark their kernel modules as externally supported via a
+ * change to the module header. If this isn't done, the module will not load
+ * by default (i.e., neither mkinitrd nor modprobe will accept it).
+ */
+MODULE_INFO(supported, "external");
diff --git a/arch/arm/mvp/pvtcpkm/comm_os_mod_ver.h b/arch/arm/mvp/pvtcpkm/comm_os_mod_ver.h
new file mode 100644
index 0000000..5e14c62
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_os_mod_ver.h
@@ -0,0 +1,38 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Version definitions for the pvTCP module.
+ */
+
+#ifndef _COMM_OS_MOD_VER_H_
+#define _COMM_OS_MOD_VER_H_
+
+#define COMM_OS_MOD_NAME_STRING "VMware paravirtualized tcp/ip module"
+#define COMM_OS_MOD_SHORT_NAME pvtcp
+#define COMM_OS_MOD_SHORT_NAME_STRING "pvtcp"
+
+#define COMM_OS_MOD_VERSION 1.0.0.0
+#define COMM_OS_MOD_VERSION_COMMAS 1,0,0,0
+#define COMM_OS_MOD_VERSION_STRING "1.0.0.0"
+
+#endif /* _COM_OS_MOD_VER_H_ */
diff --git a/arch/arm/mvp/pvtcpkm/comm_svc.h b/arch/arm/mvp/pvtcpkm/comm_svc.h
new file mode 100644
index 0000000..784ec76
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_svc.h
@@ -0,0 +1,71 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Communication functions exported by the comm_rt module.
+ */
+
+#ifndef _COMM_SVC_H_
+#define _COMM_SVC_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+#include "comm.h"
+
+int CommSvc_RegisterImpl(const CommImpl *impl);
+void CommSvc_UnregisterImpl(const CommImpl *impl);
+int CommSvc_Zombify(CommChannel channel, int inBH);
+int CommSvc_IsActive(CommChannel channel);
+CommTranspInitArgs CommSvc_GetTranspInitArgs(CommChannel channel);
+void *CommSvc_GetState(CommChannel channel);
+void CommSvc_Put(CommChannel channel);
+void CommSvc_DispatchUnlock(CommChannel channel);
+int CommSvc_Lock(CommChannel channel);
+void CommSvc_Unlock(CommChannel channel);
+int CommSvc_ScheduleAIOWork(CommOSWork *work);
+
+int
+CommSvc_Alloc(const CommTranspInitArgs *transpArgs,
+ const CommImpl *impl,
+ int inBH,
+ CommChannel *newChannel);
+
+int
+CommSvc_Write(CommChannel channel,
+ const CommPacket *packet,
+ unsigned long long *timeoutMillis);
+
+int
+CommSvc_WriteVec(CommChannel channel,
+ const CommPacket *packet,
+ struct kvec **vec,
+ unsigned int *vecLen,
+ unsigned long long *timeoutMillis,
+ unsigned int *iovOffset);
+
+unsigned int CommSvc_RequestInlineEvents(CommChannel channel);
+unsigned int CommSvc_ReleaseInlineEvents(CommChannel channel);
+
+#endif // _COMM_SVC_H_
diff --git a/arch/arm/mvp/pvtcpkm/comm_transp.h b/arch/arm/mvp/pvtcpkm/comm_transp.h
new file mode 100644
index 0000000..c46f849
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/comm_transp.h
@@ -0,0 +1,90 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Generic shared memory transport API.
+ */
+
+#ifndef _COMM_TRANSP_H_
+#define _COMM_TRANSP_H_
+
+#define INCLUDE_ALLOW_PV
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_MONITOR
+#define INCLUDE_ALLOW_GPL
+#include "include_check.h"
+
+/*
+ * Common shared memory identifier.
+ * External handle that makes sense to both hypervisor and guest.
+ */
+
+#define COMM_TRANSP_ID_8_ANY ((unsigned char)-1)
+#define COMM_TRANSP_ID_32_ANY ((unsigned int)-1)
+#define COMM_TRANSP_ID_64_ANY ((unsigned long long)-1)
+
+
+typedef struct CommTranspID {
+ union {
+ unsigned char d8[8];
+ unsigned int d32[2];
+ unsigned long long d64;
+ };
+} CommTranspID;
+
+
+/* Basic initialization arguments. */
+
+typedef enum CommTranspInitMode {
+ COMM_TRANSP_INIT_CREATE = 0x0,
+ COMM_TRANSP_INIT_ATTACH = 0x1
+} CommTranspInitMode;
+
+typedef struct CommTranspInitArgs {
+ unsigned int capacity; // Shared memory capacity.
+ unsigned int type; // Type / implementation using this area.
+ CommTranspID id; // ID (name) of shared memory area.
+ CommTranspInitMode mode; // Init mode (above).
+} CommTranspInitArgs;
+
+
+/**
+ * @brief Generate a type id from description (protocol) string. This function
+ * uses djb2, a string hashing algorithm by Dan Bernstein.
+ * (see http://www.cse.yorku.ca/~oz/hash.html)
+ * @param str string to hash
+ * @return 32-bit hash value
+ */
+
+static inline unsigned int
+CommTransp_GetType(const char *str)
+{
+ unsigned int hash = 5381;
+ int c;
+
+ while ((c = *str++)) {
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ }
+ return hash;
+}
+
+#endif // _COMM_TRANSP_H_
diff --git a/arch/arm/mvp/pvtcpkm/include_check.h b/arch/arm/mvp/pvtcpkm/include_check.h
new file mode 100644
index 0000000..2eeafe7
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/include_check.h
@@ -0,0 +1,18 @@
+/*
+ * Linux 2.6.32 and later Kernel module for Empty File Placeholder
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp.c b/arch/arm/mvp/pvtcpkm/pvtcp.c
new file mode 100644
index 0000000..fdfb0d2
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp.c
@@ -0,0 +1,587 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Pvtcp common code.
+ */
+
+#include "pvtcp.h"
+
+
+/*
+ * Operation table.
+ */
+
+CommOperationFunc pvtcpOperations[] = {
+ [PVTCP_OP_FLOW] = PvtcpFlowOp,
+ [PVTCP_OP_IO] = PvtcpIoOp,
+ [PVTCP_OP_CREATE] = PvtcpCreateOp,
+ [PVTCP_OP_RELEASE] = PvtcpReleaseOp,
+ [PVTCP_OP_BIND] = PvtcpBindOp,
+ [PVTCP_OP_LISTEN] = PvtcpListenOp,
+ [PVTCP_OP_ACCEPT] = PvtcpAcceptOp,
+ [PVTCP_OP_CONNECT] = PvtcpConnectOp,
+ [PVTCP_OP_SHUTDOWN] = PvtcpShutdownOp,
+ [PVTCP_OP_SETSOCKOPT] = PvtcpSetSockOptOp,
+ [PVTCP_OP_GETSOCKOPT] = PvtcpGetSockOptOp,
+ [PVTCP_OP_IOCTL] = PvtcpIoctlOp,
+ [PVTCP_OP_INVALID] = NULL
+};
+
+
+/*
+ * Implementation block.
+ */
+
+CommImpl pvtcpImpl = {
+ .owner = NULL,
+ .checkArgs = PvtcpCheckArgs,
+ .stateCtor = PvtcpStateAlloc,
+ .stateDtor = PvtcpStateFree,
+ .dataAlloc = PvtcpBufAlloc,
+ .dataFree = PvtcpBufFree,
+ .operations = pvtcpOperations,
+ .closeNtf = PvtcpCloseNtf,
+ .closeNtfData = &pvtcpImpl,
+ .ntfCenterID = {{
+ .d32[0] = 2U /* x86 host context (vmci, only). */,
+ .d32[1] = 10000 /* Default, not yet reserved, resource (vmci, only). */
+ }}
+};
+
+
+/*
+ * Version array.
+ */
+
+const char *pvtcpVersions[] = {
+ [PVTCP_VERS_1_1] = PVTCP_COMM_IMPL_VERS_1_1,
+ [PVTCP_VERS_1_0] = PVTCP_COMM_IMPL_VERS_1_0
+};
+
+const unsigned int pvtcpVersionsSize =
+ (sizeof pvtcpVersions / sizeof pvtcpVersions[0]);
+
+
+/*
+ * Client (pv) channel to offload side. We choose to define it here, although
+ * it's only applicable to the pv implementation. The reason is that we can
+ * share a common close notification function which does the right thing
+ * depending on the channel configuration.
+ */
+
+CommChannel pvtcpClientChannel;
+
+
+/*
+ * Built-in state interfaces.
+ */
+
+static PvtcpIfConf ifUnbound = {
+ .family = PVTCP_PF_UNBOUND
+};
+const PvtcpIfConf *pvtcpIfUnbound = &ifUnbound;
+
+static PvtcpIfConf ifDeathRow = {
+ .family = PVTCP_PF_DEATH_ROW
+};
+const PvtcpIfConf *pvtcpIfDeathRow = &ifDeathRow;
+
+static PvtcpIfConf ifLoopbackInet4 = {
+ .family = PVTCP_PF_LOOPBACK_INET4
+};
+const PvtcpIfConf *pvtcpIfLoopbackInet4 = &ifLoopbackInet4;
+
+
+/* Functions */
+
+/**
+ * @brief Checks if the IF configuration has reasonable values.
+ * @param conf configuration to check
+ * @return zero if successful, -1 otherwise
+ */
+
+static int
+IfCheck(const PvtcpIfConf *conf)
+{
+ if (!conf ||
+ ((conf->family != PF_INET) &&
+ (conf->family != PF_INET6) &&
+ (conf->family != PVTCP_PF_UNBOUND) &&
+ (conf->family != PVTCP_PF_DEATH_ROW) &&
+ (conf->family != PVTCP_PF_LOOPBACK_INET4))) {
+ return -1;
+ }
+
+ /** @todo Need more checks for IP/netmask format validity. */
+ return 0;
+}
+
+
+/**
+ * @brief Checks if the IF has reasonable values, but restricts types to
+ * AF_INET and AF_INET6
+ * @param conf IF to check
+ * @return zero if successful, -1 otherwise
+ */
+
+static int
+IfRestrictedCheck(const PvtcpIfConf *conf)
+{
+ if (IfCheck(conf) ||
+ ((conf->family != PF_INET) &&
+ (conf->family != PF_INET6))) {
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Finds a netif given a state and a configuration. The configuration
+ * must have already been checked. This function doesn't lock, so it
+ * should not be called when the state, or the netif for the passed
+ * configuration may be deleted.
+ * @param state state to look for.
+ * @param conf configuration to look for.
+ * @return netif matching configuration, or NULL.
+ */
+
+PvtcpIf *
+PvtcpStateFindIf(PvtcpState *state,
+ const PvtcpIfConf *conf)
+{
+ PvtcpIf *netif;
+
+ if (!state) {
+ return NULL;
+ }
+
+ if (conf->family == PVTCP_PF_UNBOUND) {
+ return &state->ifUnbound;
+ }
+
+ if (conf->family == PVTCP_PF_DEATH_ROW) {
+ return &state->ifDeathRow;
+ }
+
+ if (conf->family == PVTCP_PF_LOOPBACK_INET4) {
+ return &state->ifLoopbackInet4;
+ }
+
+ CommOS_ListForEach(&state->ifList, netif, stateLink) {
+ if (netif->conf.family == conf->family) {
+ if ((conf->family == PF_INET &&
+ !memcmp(&netif->conf.addr.in, &conf->addr.in,
+ sizeof conf->addr.in)) ||
+ (conf->family == PF_INET6 &&
+ !memcmp(&netif->conf.addr.in6, &conf->addr.in6,
+ sizeof conf->addr.in6))) {
+ return netif;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+/**
+ * @brief Creates and initializes a new netif for a given channel and with
+ * the specified configuration. Death row and unbound netifs may not
+ * be added using this function.
+ * @param[in,out] channel channel to make a new netif in
+ * @param conf configuration to set netif to
+ * @return 0 if successful, -1 otherwise
+ * @sideeffect May allocate memory
+ */
+
+int
+PvtcpStateAddIf(CommChannel channel,
+ const PvtcpIfConf *conf)
+{
+ int rc = -1;
+ PvtcpState *state;
+ PvtcpIf *netif;
+
+ if (!channel || IfRestrictedCheck(conf)) {
+ return rc;
+ }
+
+ if (CommSvc_Lock(channel)) {
+ return rc; /* channel isn't active. */
+ }
+
+ state = CommSvc_GetState(channel);
+ if (!state) {
+ goto out;
+ }
+
+ if (PvtcpStateFindIf(state, conf)) {
+ goto out; /* Already configured. */
+ }
+
+ netif = CommOS_Kmalloc(sizeof *netif);
+ if (!netif) {
+ goto out;
+ }
+
+ INIT_LIST_HEAD(&netif->stateLink);
+ INIT_LIST_HEAD(&netif->sockList);
+ netif->state = state;
+ netif->conf = *conf;
+ CommOS_ListAddTail(&state->ifList, &netif->stateLink);
+ rc = 0;
+
+out:
+ CommSvc_Unlock(channel);
+ return rc;
+}
+
+
+/**
+ * @brief Removes and potentially deallocates all sockets associated with the
+ * given netif and deallocates the latter.
+ * @param[in,out] netif netif to deallocate
+ * @sideeffect Closes sockets, deallocates memory
+ */
+
+static void
+IfFree(PvtcpIf *netif)
+{
+ PvtcpSock *pvsk;
+ PvtcpSock *tmp;
+
+ if (netif) {
+ CommOS_ListForEachSafe(&netif->sockList, pvsk, tmp, ifLink) {
+ CommOS_ListDel(&pvsk->ifLink);
+ PvtcpReleaseSocket(pvsk);
+ }
+ if ((netif->conf.family != PVTCP_PF_UNBOUND) &&
+ (netif->conf.family != PVTCP_PF_DEATH_ROW) &&
+ (netif->conf.family != PVTCP_PF_LOOPBACK_INET4)) {
+ CommOS_ListDel(&netif->stateLink);
+ CommOS_Kfree(netif);
+ }
+ }
+}
+
+
+/**
+ * @brief Closes all sockets associated with, and deallocates the netif
+ * in the given channel and with the specified configuration.
+ * Death row and unbound netifs may not be removed using this function.
+ * @param[in,out] channel channel to remove from
+ * @param conf configuration specified
+ * @return zero if successful, error code otherwise
+ * @sideeffect Closes sockets, deallocates memory
+ */
+
+void
+PvtcpStateRemoveIf(CommChannel channel,
+ const PvtcpIfConf *conf)
+{
+ PvtcpState *state;
+ PvtcpIf *netif;
+
+ if (!channel || IfRestrictedCheck(conf)) {
+ return;
+ }
+
+ if (CommSvc_Lock(channel)) {
+ return; /* channel isn't active. */
+ }
+
+ state = CommSvc_GetState(channel);
+ if (state && (netif = PvtcpStateFindIf(state, conf))) {
+ if (netif->state == state) {
+ IfFree(netif);
+ }
+ }
+
+ CommSvc_Unlock(channel);
+}
+
+
+/**
+ * @brief Adds a socket to an existing netif. If the socket is already on a
+ * different netif, it is removed from that netif.
+ * It locks the must-be-active channel. We use that lock to guard
+ * against concurrent removal of the netif.
+ * @param[in,out] channel channel to add to
+ * @param conf specified configuration
+ * @param[in,out] sock socket to add
+ * @return zero if successful, -1 otherwise
+ */
+
+int
+PvtcpStateAddSocket(CommChannel channel,
+ const PvtcpIfConf *conf,
+ PvtcpSock *sock)
+{
+ int rc = -1;
+ PvtcpState *state;
+ PvtcpIf *netif;
+
+ if (!channel || !sock || (sock->channel != channel) || IfCheck(conf)) {
+ return rc;
+ }
+
+ if (CommSvc_Lock(channel)) {
+ return rc; /* channel isn't active. */
+ }
+
+ state = CommSvc_GetState(channel);
+ if (!state) {
+ goto out;
+ }
+
+ netif = PvtcpStateFindIf(state, conf);
+ if (!netif) {
+ goto out;
+ }
+
+ CommOS_ListDel(&sock->ifLink);
+ sock->netif = netif;
+ CommOS_ListAddTail(&netif->sockList, &sock->ifLink);
+ rc = 0;
+
+out:
+ CommSvc_Unlock(channel);
+ return rc;
+}
+
+
+/**
+ * @brief Removes a socket from its netif.
+ * It locks the must-be-active channel. We use that lock to guard
+ * against concurrent removal of the netif.
+ * @param[in,out] channel channel to remove from
+ * @param[in,out] sock socket to remove
+ * @return zero if successful, -1 otherwise
+ */
+
+int
+PvtcpStateRemoveSocket(CommChannel channel,
+ PvtcpSock *sock)
+{
+ if (!channel || !sock ||
+ (sock->channel && (sock->channel != channel))) {
+ return -1;
+ }
+
+ if (CommSvc_Lock(channel)) {
+ return -1; /* channel isn't active. */
+ }
+
+ CommOS_ListDel(&sock->ifLink);
+ sock->channel = NULL;
+ sock->state = NULL;
+ sock->netif = NULL;
+
+ CommSvc_Unlock(channel);
+ return 0;
+}
+
+
+/**
+ * @brief State constructor called when a channel is created. The netifs
+ * 'death row' and 'unbound' are always initialized.
+ * @param[in,out] channel channel to initialize
+ * @return pointer to a new state structure or NULL
+ * @sideeffect Allocates memory
+ */
+
+void *
+PvtcpStateAlloc(CommChannel channel)
+{
+ PvtcpState *state;
+
+ state = CommOS_Kmalloc(sizeof *state);
+ if (state) {
+ state->channel = channel;
+ INIT_LIST_HEAD(&state->ifList);
+
+ /* Initialize always-present netifs. */
+ INIT_LIST_HEAD(&state->ifDeathRow.stateLink); /* Irrelevant */
+ INIT_LIST_HEAD(&state->ifDeathRow.sockList);
+ state->ifDeathRow.state = state;
+ state->ifDeathRow.conf.family = PVTCP_PF_DEATH_ROW;
+
+ INIT_LIST_HEAD(&state->ifUnbound.stateLink); /* Irrelevant */
+ INIT_LIST_HEAD(&state->ifUnbound.sockList);
+ state->ifUnbound.state = state;
+ state->ifUnbound.conf.family = PVTCP_PF_UNBOUND;
+
+ INIT_LIST_HEAD(&state->ifLoopbackInet4.stateLink); /* Irrelevant */
+ INIT_LIST_HEAD(&state->ifLoopbackInet4.sockList);
+ state->ifLoopbackInet4.state = state;
+ state->ifLoopbackInet4.conf.family = PVTCP_PF_LOOPBACK_INET4;
+
+ state->namespace = NULL;
+ state->mask = ((unsigned int)channel << 4) ^ (unsigned int)state;
+#if defined(__linux__)
+ state->id = ((unsigned long long)random32() << 32) |
+ (unsigned long long)random32();
+#else
+ state->id = (unsigned long long)state;
+#endif
+ }
+ return state;
+}
+
+
+/**
+ * @brief State destructor called when a channel is closed.
+ * The caller (Comm) guarantees proper locking.
+ * @param arg pointer to state structure
+ * @sideeffect Destroys all netifs and their sockets, deallocates memory
+ */
+
+void
+PvtcpStateFree(void *arg)
+{
+ PvtcpState *state = arg;
+ PvtcpIf *netif;
+ PvtcpIf *tmp;
+
+ if (state) {
+ CommOS_ListForEachSafe(&state->ifList, netif, tmp, stateLink) {
+ IfFree(netif);
+ }
+ /* coverity[address_free] */
+ IfFree(&state->ifLoopbackInet4);
+ /* coverity[address_free] */
+ IfFree(&state->ifUnbound);
+ /* coverity[address_free] */
+ IfFree(&state->ifDeathRow);
+ CommOS_Kfree(state);
+ }
+}
+
+
+/**
+ * @brief Checks transport arguments.
+ * @param transpArgs transport arguments.
+ * @return zero if successful, < 0 otherwise.
+ */
+
+int
+PvtcpCheckArgs(CommTranspInitArgs *transpArgs)
+{
+ int rc = -1;
+ const unsigned int minCapacity =
+ (PVTCP_SOCK_BUF_SIZE + sizeof(CommPacket)) * 2;
+ unsigned int versionIndex = pvtcpVersionsSize;
+
+ if (transpArgs->capacity < minCapacity) {
+ return rc;
+ }
+
+ while (versionIndex--) {
+ if (transpArgs->type == CommTransp_GetType(pvtcpVersions[versionIndex])) {
+ /* If a match, overwrite the hash with the actual version (index). */
+
+ transpArgs->type = versionIndex;
+ rc = 0;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+
+/**
+ * @brief Called after a channel is freed.
+ * @param ntfData callback data from implementation block.
+ * @param transpArgs transport arguments of closed channel.
+ * @param inBH whether called in bottom half.
+ */
+
+void
+PvtcpCloseNtf(void *ntfData,
+ const CommTranspInitArgs *transpArgs,
+ int inBH)
+{
+ CommImpl *impl = (CommImpl *)ntfData;
+
+ pvtcpClientChannel = NULL;
+ CommOS_Log(("%s: Channel was reset!\n", __FUNCTION__));
+
+ /*
+ * If the impl. block owner is NULL, we're pv client: we attempt to
+ * reopen the channel in a few seconds.
+ */
+
+ if (impl && !impl->owner && !inBH) {
+ CommOS_Log(("%s: Attempting to re-initialize channel.\n", __FUNCTION__));
+ impl->openAtMillis = CommOS_GetCurrentMillis();
+ impl->openTimeoutAtMillis =
+ CommOS_GetCurrentMillis() + PVTCP_CHANNEL_OPEN_TIMEOUT;
+ if (CommSvc_Alloc(transpArgs, impl, inBH, &pvtcpClientChannel)) {
+ CommOS_Log(("%s: Failed to initialize channel!\n", __FUNCTION__));
+ }
+ }
+}
+
+
+/**
+ * @brief Initializes the Pvtcp socket common fields.
+ * @param pvsk pvtcp socket.
+ * @param channel Comm channel this socket is associated with.
+ * @return 0 if successful, -1 otherwise.
+ */
+
+int
+PvtcpSockInit(PvtcpSock *pvsk,
+ CommChannel channel)
+{
+ PvtcpState *state;
+ int rc = -1;
+
+ if (pvsk && channel && (state = CommSvc_GetState(channel))) {
+ /* Must _not_ zero out pvsk! */
+
+ CommOS_MutexInit(&pvsk->inLock);
+ CommOS_MutexInit(&pvsk->outLock);
+ CommOS_SpinlockInit(&pvsk->stateLock);
+ CommOS_ListInit(&pvsk->ifLink);
+ CommOS_InitWork(&pvsk->work, PvtcpProcessAIO);
+ pvsk->netif = NULL;
+ pvsk->state = state;
+ pvsk->stateID = state->id;
+ pvsk->channel = channel;
+ pvsk->peerSock = PVTCP_PEER_SOCK_NULL;
+ pvsk->peerSockSet = 0;
+ CommOS_WriteAtomic(&pvsk->deltaAckSize,
+ (1 << PVTCP_SOCK_SMALL_ACK_ORDER));
+ CommOS_WriteAtomic(&pvsk->rcvdSize, 0);
+ CommOS_WriteAtomic(&pvsk->sentSize, 0);
+ CommOS_WriteAtomic(&pvsk->queueSize, 0);
+ CommOS_ListInit(&pvsk->queue);
+ pvsk->rpcReply = NULL;
+ pvsk->rpcStatus = 0;
+ pvsk->err = 0;
+ rc = 0;
+ }
+ return rc;
+}
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp.h b/arch/arm/mvp/pvtcpkm/pvtcp.h
new file mode 100644
index 0000000..7f4f2f5
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp.h
@@ -0,0 +1,458 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Pvtcp common APIs.
+ */
+
+#ifndef _PVTCP_H_
+#define _PVTCP_H_
+
+/*
+ * Pvtcp state store ipv4 and ipv6 address structures.
+ * Platform-specific headers where these are defined, must be included here.
+ * Implementation-related header files should not be included in this file.
+ *
+ * NOTE: Pvtcp is not an API and none of its functions are exported.
+ */
+
+#if defined(__linux__)
+#include <linux/in.h>
+#include <linux/in6.h>
+#else
+#error "Unsupported OS."
+#endif
+
+#include "comm_svc.h"
+
+/* Max time to wait for a channel to be created. */
+#define PVTCP_CHANNEL_OPEN_TIMEOUT 2000
+
+/* Max payload size. Used to allocate offload per-cpu bounce buffers. */
+#define PVTCP_SOCK_BUF_SIZE (8 << 10) /* 8K */
+
+#define PVTCP_SOCK_DGRAM_BUF_SIZE PVTCP_SOCK_BUF_SIZE
+#define PVTCP_SOCK_STREAM_BUF_SIZE PVTCP_SOCK_BUF_SIZE
+
+/* Dgram payloads include a pseudo (udp/ip) header. */
+typedef struct PvtcpDgramPseudoHeader {
+ unsigned long long d0;
+ unsigned long long d1;
+ unsigned long long d2;
+ unsigned long long d3;
+} PvtcpDgramPseudoHeader;
+
+
+/*
+ * Flow control constants for pv/offload sockets.
+ * We are defining a receive size model: 1) small, 2) medium, 3)large.
+ * This seems sufficient in addressing most target environments, but more
+ * models may be defined. A smaller minimum model (1) cannot be defined.
+ *
+ * Short description of socket-level flow control. This applies to both
+ * dgram and stream sockets, in both directions. It follows that, with regard
+ * to 'comm' writes, dgram and stream writes are: a) lossless and b) ordered.
+ *
+ * 0. Both sides (offload, pv) of a socket maintain (almost) mirror values
+ * of input/output queue sizes. We say 'almost', because they're allowed
+ * to conservatively converge in time.
+ * 1. Senders never write out to the shmem channel, and destined to a socket
+ * (be it offload or pv), more bytes than that socket can hold/enqueue.
+ * This is based on socket fields storing information mentioned above.
+ * The upper limit is PVTCP_SOCK_RCVSIZE and cannot be exceeded under
+ * any circumstances.
+ * 2. There is a 'safe' limit value (per socket) which can be tested prior
+ * to writing one more max-sized packet to that socket.
+ * This value is PVTCP_SOCK_SAFE_RCVSIZE.
+ * 3. There is also a notion of 'large' acks, which controls the frequency of
+ * reporting socket queue size changes when bytes are consumed from it.
+ * When a sender is about to write out (to the channel, for a given socket)
+ * in excess of PVTCP_SOCK_LARGE_ACK_WM bytes, it sets, in the packet
+ * header flag field, the PVTCP_SOCK_LARGE_ACK_ORDER value. The other end
+ * updates its 'delta ack' value accordingly (1 << flag value).
+ * 4. As bytes are consumed (again, at either end), the operation or function,
+ * will send a size ack packet with the consumed size since the last ack,
+ * _iff_ that size is larger than, or equal to the 'delta ack' value.
+ * If an ack was sent, the 'delta ack' is decreased by half, to a minimum
+ * indicated by PVTCP_SOCK_SMALL_ACK_ORDER.
+ * Note that concurrently setting the 'delta ack' to its high value
+ * because of condition 3) above, is fine since the sender already has,
+ * or is about to put pressure on the socket.
+ */
+
+#if !defined(PVTCP_SOCK_RCVSIZE_MODEL)
+ #define PVTCP_SOCK_RCVSIZE_MODEL 1
+#endif
+
+#if PVTCP_SOCK_RCVSIZE_MODEL == 1
+ #define PVTCP_SOCK_LARGE_ACK_WM (64 << 10) /* 64K */
+ #define PVTCP_SOCK_LARGE_ACK_ORDER 15
+ #define PVTCP_SOCK_SMALL_ACK_ORDER 11
+ #define PVTCP_SOCK_SAFE_RCVSIZE (128 << 10) /* 128K */
+#elif PVTCP_SOCK_RCVSIZE_MODEL == 2
+ #define PVTCP_SOCK_LARGE_ACK_WM (128 << 10) /* 128K */
+ #define PVTCP_SOCK_LARGE_ACK_ORDER 16
+ #define PVTCP_SOCK_SMALL_ACK_ORDER 12
+ #define PVTCP_SOCK_SAFE_RCVSIZE (256 << 10) /* 256K */
+#elif PVTCP_SOCK_RCVSIZE_MODEL == 3
+ #define PVTCP_SOCK_LARGE_ACK_WM (128 << 10) /* 128K */
+ #define PVTCP_SOCK_LARGE_ACK_ORDER 16
+ #define PVTCP_SOCK_SMALL_ACK_ORDER 12
+ #define PVTCP_SOCK_SAFE_RCVSIZE (512 << 10) /* 512K */
+#else
+ #error "Invalid PVTCP_SOCK_RCVSIZE_MODEL (one of 1, 2, 3)"
+#endif
+
+#define PVTCP_SOCK_RCVSIZE \
+ (PVTCP_SOCK_SAFE_RCVSIZE + \
+ PVTCP_SOCK_BUF_SIZE + sizeof (PvtcpDgramPseudoHeader))
+
+
+/*
+ * Operation codes
+ */
+
+enum PvtcpOpCodes {
+ PVTCP_OP_FLOW = 0,
+ PVTCP_OP_IO,
+ PVTCP_OP_CREATE,
+ PVTCP_OP_RELEASE,
+ PVTCP_OP_BIND,
+ PVTCP_OP_LISTEN,
+ PVTCP_OP_ACCEPT,
+ PVTCP_OP_CONNECT,
+ PVTCP_OP_SHUTDOWN,
+ PVTCP_OP_SETSOCKOPT,
+ PVTCP_OP_GETSOCKOPT,
+ PVTCP_OP_IOCTL,
+ PVTCP_OP_INVALID
+};
+
+#define PVTCP_FLOW_OP_INVALID_SIZE 0xffffffff
+
+
+/*
+ * Operation functions
+ */
+
+COMM_DEFINE_OP(PvtcpFlowOp);
+COMM_DEFINE_OP(PvtcpIoOp);
+COMM_DEFINE_OP(PvtcpCreateOp);
+COMM_DEFINE_OP(PvtcpReleaseOp);
+COMM_DEFINE_OP(PvtcpBindOp);
+COMM_DEFINE_OP(PvtcpListenOp);
+COMM_DEFINE_OP(PvtcpAcceptOp);
+COMM_DEFINE_OP(PvtcpConnectOp);
+COMM_DEFINE_OP(PvtcpShutdownOp);
+COMM_DEFINE_OP(PvtcpSetSockOptOp);
+COMM_DEFINE_OP(PvtcpGetSockOptOp);
+COMM_DEFINE_OP(PvtcpIoctlOp);
+
+
+/*
+ * Pvtcp/Comm type and supported versions.
+ */
+
+#define PVTCP_COMM_IMPL_TYPE "com.vmware.comm.protocol.pvTCP@"
+
+#define PVTCP_COMM_IMPL_VERS_1_0 (PVTCP_COMM_IMPL_TYPE "1.0")
+#define PVTCP_COMM_IMPL_VERS_1_1 (PVTCP_COMM_IMPL_TYPE "1.1")
+
+typedef enum {
+ PVTCP_VERS_1_0 = 0,
+ PVTCP_VERS_1_1
+} PvtcpVersion;
+
+extern const char *pvtcpVersions[];
+extern const unsigned int pvtcpVersionsSize;
+
+
+/*
+ * State interface markers
+ */
+
+#define PVTCP_PF_UNBOUND 0x0
+#define PVTCP_PF_DEATH_ROW 0xffffffff
+#define PVTCP_PF_LOOPBACK_INET4 (PVTCP_PF_DEATH_ROW - 1)
+
+
+/*
+ * Interface and interface configuration structures.
+ */
+
+typedef struct PvtcpIfConf {
+ int family; // Values:
+ // unbound (PVTCP_PF_UNBOUND)
+ // deathRow (PVTCP_PF_DEATH_ROW)
+ // loopback (PVTCP_PF_LOOPBACK_INET4)
+ // inet4 (PF_INET)
+ // inet6 (PF_INET6)
+ union {
+ struct in_addr in;
+ struct in6_addr in6;
+ } addr; // inet4 or inet6 address.
+ union {
+ struct in_addr in;
+ struct in6_addr in6;
+ } mask; // inet4 or inet6 netmask.
+} PvtcpIfConf;
+
+
+struct PvtcpState;
+
+typedef struct PvtcpIf {
+ CommOSList sockList; // List of sockets.
+ CommOSList stateLink; // Link in PvtcpState.ifList.
+ struct PvtcpState *state; // Back reference to state.
+ PvtcpIfConf conf; // Interface configuration.
+} PvtcpIf;
+
+
+/*
+ * General pvtcp state associated with a channel.
+ */
+
+typedef struct PvtcpState {
+ unsigned long long id; // Randomly generated state ID.
+ CommOSList ifList; // List of active interfaces.
+ CommChannel channel; // Comm channel back reference.
+ PvtcpIf ifDeathRow; // Always-present netif.
+ PvtcpIf ifUnbound; // Ditto.
+ PvtcpIf ifLoopbackInet4; // Ditto.
+ void *namespace; // Name space, where supported.
+ void *extra; // Used by upper layer to extend state as needed.
+ unsigned int mask; // Mask used to obfuscate socket pointers.
+} PvtcpState;
+
+
+/*
+ * Define pvtcp socket common fields and include the pv or offload header
+ * to get the right PvtcpSock definition.
+ */
+
+#define PVTCP_SOCK_COMMON_FIELDS \
+ CommOSMutex inLock; /* Input lock. */ \
+ CommOSMutex outLock; /* Output lock. */ \
+ CommOSSpinlock stateLock; /* State update lock. */ \
+ CommOSList ifLink; /* Link in PvtcpIf.sockList. */ \
+ CommOSWork work; /* Work item for AIO processing. */ \
+ PvtcpIf *netif; /* Netif reference. */ \
+ PvtcpState *state; /* State reference. */ \
+ unsigned long long stateID; /* State ID. */ \
+ CommChannel channel; /* Comm channel reference. */ \
+ unsigned long long peerSock; /* Peer socket, opaque. */ \
+ volatile int peerSockSet; /* Peer socket valid. */ \
+ CommOSAtomic deltaAckSize; /* Recv size updates required by peer. */ \
+ CommOSAtomic rcvdSize; /* Bytes received since last ack. */ \
+ CommOSAtomic sentSize; /* Bytes sent; also updated by peer. */ \
+ CommOSAtomic queueSize; /* Queue size. */ \
+ CommOSList queue; /* Send queue (off) or recv queue (pv). */ \
+ void *rpcReply; /* RPC reply. */ \
+ int rpcStatus; /* RPC completion status. */ \
+ int err /* Socket error. */
+
+#define PVTCP_PEER_SOCK_NULL ((unsigned long long)0)
+
+
+/*
+ * Helper macros
+ */
+
+#define SOCK_STATE_LOCK(pvsk) CommOS_SpinLock(&(pvsk)->stateLock)
+#define SOCK_STATE_UNLOCK(pvsk) CommOS_SpinUnlock(&(pvsk)->stateLock)
+
+#define SOCK_IN_TRYLOCK(pvsk) CommOS_MutexTrylock(&(pvsk)->inLock)
+#define SOCK_IN_LOCK(pvsk) CommOS_MutexLock(&(pvsk)->inLock)
+#define SOCK_IN_UNLOCK(pvsk) CommOS_MutexUnlock(&(pvsk)->inLock)
+
+#define SOCK_OUT_TRYLOCK(pvsk) CommOS_MutexTrylock(&(pvsk)->outLock)
+#define SOCK_OUT_LOCK(pvsk) CommOS_MutexLock(&(pvsk)->outLock)
+#define SOCK_OUT_LOCK_UNINT(pvsk) \
+ CommOS_MutexLockUninterruptible(&(pvsk)->outLock)
+#define SOCK_OUT_UNLOCK(pvsk) CommOS_MutexUnlock(&(pvsk)->outLock)
+
+#define PVTCP_UNLOCK_DISP_DISCARD_VEC() \
+ CommSvc_DispatchUnlock(channel); \
+ while (vecLen) { \
+ PvtcpBufFree(vec[--vecLen].iov_base); \
+ }
+
+
+#if defined(PVTCP_BUILDING_SERVER)
+#include "pvtcp_off.h"
+#else
+#include "pvtcp_pv.h"
+#endif // defined(PVTCP_BUILDING_SERVER)
+
+
+/*
+ * Data declarations
+ */
+
+extern const PvtcpIfConf *pvtcpIfUnbound;
+extern const PvtcpIfConf *pvtcpIfDeathRow;
+extern const PvtcpIfConf *pvtcpIfLoopbackInet4;
+
+extern CommImpl pvtcpImpl;
+extern CommOperationFunc pvtcpOperations[];
+
+extern CommChannel pvtcpClientChannel;
+
+
+/*
+ * Common state manipulation functions.
+ */
+
+void *PvtcpStateAlloc(CommChannel channel);
+void PvtcpStateFree(void *arg);
+
+int PvtcpStateAddIf(CommChannel channel, const PvtcpIfConf *conf);
+void PvtcpStateRemoveIf(CommChannel channel, const PvtcpIfConf *conf);
+PvtcpIf *PvtcpStateFindIf(PvtcpState *state, const PvtcpIfConf *conf);
+
+int
+PvtcpStateAddSocket(CommChannel channel,
+ const PvtcpIfConf *conf,
+ PvtcpSock *sock);
+int PvtcpStateRemoveSocket(CommChannel channel, PvtcpSock *sock);
+
+
+/*
+ * Common Pvtcp functions.
+ */
+
+int PvtcpCheckArgs(CommTranspInitArgs *transpArgs);
+
+void
+PvtcpCloseNtf(void *ntfData,
+ const CommTranspInitArgs *transpArgs,
+ int inBH);
+
+void *PvtcpBufAlloc(unsigned int size);
+void PvtcpBufFree(void *buf);
+
+void PvtcpReleaseSocket(PvtcpSock *pvsk);
+int PvtcpSockInit(PvtcpSock *pvsk, CommChannel channel);
+
+void PvtcpProcessAIO(CommOSWork *work);
+
+
+/**
+ * @brief Packs an IPV6 address stored in an array of four 32-bit elements,
+ * into two 64-bit variables.
+ * @param addr IPV6 address as an array of 32-bit elements.
+ * @param[out] d64_0 pointer to 64-bit variable.
+ * @param[out] d64_1 pointer to 64-bit variable.
+ */
+
+static inline void
+PvtcpI6AddrPack(const unsigned int addr[4],
+ unsigned long long *d64_0,
+ unsigned long long *d64_1)
+{
+ *d64_0 = *(unsigned long long *)&addr[0];
+ *d64_1 = *(unsigned long long *)&addr[2];
+}
+
+
+/**
+ * @brief Unpacks two 64-bit values into an IPV6 address-storing array of
+ * four 32-bit elements,
+ * @param[out] addr IPV6 address as an array of 32-bit elements.
+ * @param d64_0 64-bit value.
+ * @param d64_1 64-bit value.
+ */
+
+static inline void
+PvtcpI6AddrUnpack(unsigned int addr[4],
+ unsigned long long d64_0,
+ unsigned long long d64_1)
+{
+ *(unsigned long long *)&addr[0] = d64_0;
+ *(unsigned long long *)&addr[2] = d64_1;
+}
+
+
+/**
+ * @brief Verifies whether the argument is a valid socket. If yes, it returns
+ * the actual pointer. Otherwise, it returns from the calling function.
+ * WARNING: This macro must ONLY be used in operation functions, as its
+ * implementation assumes.
+ * @param handle socket handle to verify.
+ * @param container state supposed to contain the socket handle.
+ * @return 32-bit or 64-bit PvtcpSock*, depending on __LP64__ or __LLP64__.
+ */
+
+#if defined(__LP64__) || defined(__LLP64__)
+
+#define PvtcpGetPvskOrReturn(handle, container) \
+ ({ \
+ PvtcpState *__state = (PvtcpState *)(container); \
+ PvtcpSock *__pvsk = \
+ (PvtcpSock *)((handle) ^ (unsigned long long)__state->mask); \
+ \
+ if (__pvsk->stateID != __state->id) { \
+ PVTCP_UNLOCK_DISP_DISCARD_VEC(); \
+ CommSvc_Zombify(__state->channel, 0); \
+ return; \
+ } \
+ (__pvsk); \
+ })
+
+#else // __LP64__ || __LLP64__
+
+#define PvtcpGetPvskOrReturn(handle, container) \
+ ({ \
+ PvtcpState *__state = (PvtcpState *)(container); \
+ PvtcpSock *__pvsk = \
+ (PvtcpSock *)((unsigned int)(handle) ^ __state->mask); \
+ \
+ if (__pvsk->stateID != __state->id) { \
+ PVTCP_UNLOCK_DISP_DISCARD_VEC(); \
+ CommSvc_Zombify(__state->channel, 0); \
+ return; \
+ } \
+ (__pvsk); \
+ })
+
+#endif // __LP64__ || __LLP64__
+
+
+/**
+ * @brief Masks a socket pointer to be passed to the peer module.
+ * @param pvsk socket pointer to mask.
+ * @return 64-bit pvtcp socket handle.
+ */
+
+#if defined(__LP64__) || defined(__LLP64__)
+
+#define PvtcpGetHandle(pvsk) \
+ ((unsigned long long)(pvsk) ^ (unsigned long long)(pvsk)->state->mask)
+
+#else // __LP64__ || __LLP64__
+
+#define PvtcpGetHandle(pvsk) \
+ ((unsigned int)(pvsk) ^ (pvsk)->state->mask)
+
+#endif // __LP64__ || __LLP64__
+
+#endif // _PVTCP_H_
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off.c b/arch/arm/mvp/pvtcpkm/pvtcp_off.c
new file mode 100644
index 0000000..053d9c2
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off.c
@@ -0,0 +1,81 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Server (offload) side code.
+ */
+
+#include "pvtcp.h"
+
+/**
+ * @brief Allocates the net buffer.
+ * @param size buffer size
+ * @return address of buffer or NULL
+ */
+void *
+PvtcpBufAlloc(unsigned int size)
+{
+ PvtcpOffBuf *buf;
+
+ /* coverity[alloc_fn] */
+ /* coverity[var_assign] */
+ buf = CommOS_Kmalloc(size + sizeof *buf - sizeof buf->data);
+ if (buf) {
+ CommOS_ListInit(&buf->link);
+ buf->len = (unsigned short)size;
+ buf->off = 0;
+ return PvtcpOffBufFromInternal(buf);
+ }
+ return NULL;
+}
+
+
+/**
+ * @brief Deallocates given net buffer.
+ * @param buf buffer to deallocate
+ * @sideeffect Frees memory
+ */
+
+void
+PvtcpBufFree(void *buf)
+{
+ CommOS_Kfree(PvtcpOffInternalFromBuf(buf));
+}
+
+
+/**
+ * @brief Initializes the Pvtcp socket offload common fields.
+ * @param pvsk pvtcp socket.
+ * @param channel Comm channel this socket is associated with.
+ * @return 0 if successful, -1 otherwise.
+ */
+
+int
+PvtcpOffSockInit(PvtcpSock *pvsk,
+ CommChannel channel)
+{
+ int rc = PvtcpSockInit(pvsk, channel);
+
+ pvsk->opFlags = 0;
+ pvsk->flags = 0;
+ return rc;
+}
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off.h b/arch/arm/mvp/pvtcpkm/pvtcp_off.h
new file mode 100644
index 0000000..f183968
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off.h
@@ -0,0 +1,219 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Offload common definitions.
+ * This file is meant to only be included via pvtcp.h.
+ */
+
+#ifndef _PVTCP_OFF_H_
+#define _PVTCP_OFF_H_
+
+
+#define PVTCP_OFF_SOCK_COMMON_FIELDS \
+ volatile unsigned int opFlags; /* Saves op codes as bit mask. */ \
+ volatile unsigned int flags /* General purpose flags. */
+
+
+/* General purpose socket flags */
+
+enum PvtcpOffPvskFlags {
+ PVTCP_OFF_PVSKF_IPV6_LOOP = 0, /* Used for IPV6 loopback morphing/reset. */
+ PVTCP_OFF_PVSKF_SHUT_RD, /* Set to initiate socket recv shutdown. */
+ PVTCP_OFF_PVSKF_SHUT_WR, /* Set to initiate socket send shutdown. */
+ PVTCP_OFF_PVSKF_TCP_NODELAY, /* Caches the TCP_NODELAY socket option. */
+ PVTCP_OFF_PVSKF_TCP_CORK, /* Caches the TCP_CORK socket option. */
+ PVTCP_OFF_PVSKF_DISCONNECT, /* Set do indicate connect()/AF_UNSPEC. */
+ PVTCP_OFF_PVSKF_INVALID = 32
+};
+
+
+/*
+ * Include OS-dependent PvtcpSock structure and functions.
+ */
+
+#if defined(__linux__)
+#include "pvtcp_off_linux.h"
+#else
+#error "Unsupported OS."
+#endif
+
+
+/*
+ * Offload packet payload data structure.
+ */
+
+typedef struct PvtcpOffBuf {
+ CommOSList link; // Link in socket queue.
+ unsigned short len;
+ unsigned short off;
+ char data[1];
+} PvtcpOffBuf;
+
+
+/**
+ * @brief Returns net buffer given private data structure pointer and based
+ * on the internal offset pointer
+ * @param arg pointer to PvtcpOffBuf wrapper structure
+ * @return address of buffer or NULL
+ */
+
+static inline void *
+PvtcpOffBufFromInternalOff(PvtcpOffBuf *arg)
+{
+ return arg ?
+ &arg->data[arg->off] :
+ NULL;
+}
+
+
+/**
+ * @brief Returns net buffer given private data structure pointer
+ * @param arg pointer to PvtcpOffBuf wrapper structure
+ * @return address of buffer or NULL
+ */
+
+static inline void *
+PvtcpOffBufFromInternal(PvtcpOffBuf *arg)
+{
+ return arg ?
+ &arg->data[0] :
+ NULL;
+}
+
+
+/**
+ * @brief Returns internal data structure given net buffer pointer
+ * @param arg pointer to PvtcpOffBuf wrapper structure
+ * @return address of internal data structure or NULL
+ */
+
+static inline PvtcpOffBuf *
+PvtcpOffInternalFromBuf(void *arg)
+{
+ return arg ?
+ (PvtcpOffBuf *)((char *)arg - offsetof(PvtcpOffBuf, data)) :
+ NULL;
+}
+
+
+/**
+ * @brief Tests operation flag for AIO processing.
+ * @param pvsk socket to test operation on.
+ * @param op operation to test if set.
+ * @return non-zero if operation set, zero otherwise.
+ * @sideeffect socket processing by AIO threads affected according to operation.
+ */
+
+static inline int
+PvskTestOpFlag(struct PvtcpSock *pvsk,
+ int op)
+{
+ return pvsk->opFlags & (1 << op);
+}
+
+
+/**
+ * @brief Sets operation flag for AIO processing; acquires the state lock.
+ * @param[in,out] pvsk socket to set operation on.
+ * @param op operation to set.
+ * @sideeffect socket processing by AIO threads affected according to operation.
+ */
+
+static inline void
+PvskSetOpFlag(struct PvtcpSock *pvsk,
+ int op)
+{
+ unsigned int ops;
+
+ SOCK_STATE_LOCK(pvsk);
+ ops = pvsk->opFlags | (1 << op);
+ pvsk->opFlags = ops;
+ SOCK_STATE_UNLOCK(pvsk);
+}
+
+
+/**
+ * @brief Resets operation flag for AIO processing; acquires the state lock.
+ * @param[in,out] pvsk socket to reset operation on.
+ * @param op operation to reset.
+ * @sideeffect socket processing by AIO threads affected according to operation.
+ */
+
+static inline void
+PvskResetOpFlag(struct PvtcpSock *pvsk,
+ int op)
+{
+ unsigned int ops;
+
+ SOCK_STATE_LOCK(pvsk);
+ ops = pvsk->opFlags & ~(1 << op);
+ pvsk->opFlags = ops;
+ SOCK_STATE_UNLOCK(pvsk);
+}
+
+
+/**
+ * @brief Tests general purpose socket flags.
+ * @param pvsk socket.
+ * @param flag flag to test.
+ * @return non-zero if flag set, zero otherwise.
+ */
+
+static inline int
+PvskTestFlag(struct PvtcpSock *pvsk,
+ int flag)
+{
+ return (flag < PVTCP_OFF_PVSKF_INVALID) && (pvsk->flags & (1 << flag));
+}
+
+
+/**
+ * @brief Sets general purpose socket flags; acquires the state lock.
+ * @param[in,out] pvsk socket.
+ * @param flag flag to set or clear.
+ * @param onOff whether to set or clear the flag.
+ */
+
+static inline void
+PvskSetFlag(struct PvtcpSock *pvsk,
+ int flag,
+ int onOff)
+{
+ unsigned int flags;
+
+ SOCK_STATE_LOCK(pvsk);
+ if (flag < PVTCP_OFF_PVSKF_INVALID) {
+ if (onOff) {
+ flags = pvsk->flags | (1 << flag);
+ } else {
+ flags = pvsk->flags & ~(1 << flag);
+ }
+ pvsk->flags = flags;
+ }
+ SOCK_STATE_UNLOCK(pvsk);
+}
+
+
+int PvtcpOffSockInit(PvtcpSock *pvsk, CommChannel channel);
+
+#endif // _PVTCP_OFF_H_
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off_io_linux.c b/arch/arm/mvp/pvtcpkm/pvtcp_off_io_linux.c
new file mode 100644
index 0000000..9958c39
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off_io_linux.c
@@ -0,0 +1,831 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Server (offload) side Linux-specific socket I/O functions.
+ */
+
+#include "pvtcp.h"
+
+/*
+ * Data.
+ */
+
+/* Used to check if OutputAIO()-ing is likely in progress. */
+
+CommOSAtomic PvtcpOutputAIOSection;
+
+
+/*
+ * Large datagram bounce buffer (PVTCP_SOCK_BUF_SIZE < size <= 64K).
+ * Only one such buffer is available, shared across cpus via get/put.
+ * A preallocated, smaller buffer is used for most over-size 'allocs'.
+ * A larger, 64K-buffer may need to be __vmalloc()-ed.
+ */
+
+typedef struct LargeDgramBuf {
+ unsigned char buf[PVTCP_SOCK_BUF_SIZE << 1]; /* Fast buffer. */
+ void *spareBuf; /* Dynamically allocated. */
+ CommOSMutex lock;
+} LargeDgramBuf;
+
+static LargeDgramBuf largeDgramBuf;
+
+
+/**
+ * @brief One time initialization of large datagram buffer.
+ */
+
+void
+PvtcpOffLargeDgramBufInit(void)
+{
+ largeDgramBuf.spareBuf = NULL;
+ CommOS_MutexInit(&largeDgramBuf.lock);
+}
+
+
+/**
+ * @brief Reserves/holds the large datagram buffer.
+ * @param size size of buffer.
+ * @sizeeffect may sleep until the buffer is available.
+ * @return address of buffer, or NULL if size too large or allocation failed.
+ */
+
+static inline void *
+LargeDgramBufGet(int size)
+{
+ static const unsigned int maxSize = 64 * 1024;
+
+ /* coverity[alloc_fn] */
+ /* coverity[var_assign] */
+
+ CommOS_MutexLockUninterruptible(&largeDgramBuf.lock);
+
+ if (size <= sizeof largeDgramBuf.buf) {
+ return largeDgramBuf.buf;
+ }
+
+ if (size <= maxSize) {
+ if (!largeDgramBuf.spareBuf) {
+ largeDgramBuf.spareBuf = __vmalloc(maxSize,
+ (GFP_ATOMIC | __GFP_HIGHMEM),
+ PAGE_KERNEL);
+ }
+ if (largeDgramBuf.spareBuf) {
+ return largeDgramBuf.spareBuf;
+ }
+ }
+
+ CommOS_MutexUnlock(&largeDgramBuf.lock);
+ return NULL;
+}
+
+
+/**
+ * @brief Releases hold on the large datagram buffer.
+ * @param buf buffer to put back.
+ */
+
+static inline void
+LargeDgramBufPut(void *buf)
+{
+ static unsigned int spareBufPuts = 0;
+
+ BUG_ON((buf != largeDgramBuf.buf) && (buf != largeDgramBuf.spareBuf));
+
+ if (largeDgramBuf.spareBuf && (++spareBufPuts % 2) == 0) {
+ /* Deallocate the spare buffer every now and then. */
+
+ vfree(largeDgramBuf.spareBuf);
+ largeDgramBuf.spareBuf = NULL;
+ }
+
+ CommOS_MutexUnlock(&largeDgramBuf.lock);
+}
+
+
+/*
+ * I/O offload operations.
+ */
+
+/**
+ * @brief Flow control notification received when more (enough) data was
+ * consumed from a PV socket.
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled
+ */
+
+void
+PvtcpFlowOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+
+ PvtcpHoldSock(pvsk);
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+ CommOS_SubReturnAtomic(&pvsk->rcvdSize, (int)packet->data32);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Outputs bytes to socket.
+ * @param channel communication channel with offloader.
+ * @param upperLayerState state associated with this channel.
+ * @param packet received packet header.
+ * @param vec payload buffer descriptors.
+ * @param vecLen payload buffer descriptor count.
+ * @sideeffect Changes send size/capacity ratio. May schedule AIO processing
+ * for enqueued bytes, if applicable.
+ */
+
+void
+PvtcpIoOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ int rc;
+ unsigned int vecOff;
+ PvtcpOffBuf *internalBuf;
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ unsigned int dataLen = packet->len - sizeof *packet;
+ struct msghdr msg = {
+ .msg_controllen = 0,
+ .msg_control = NULL
+ };
+ int tmpSize;
+ int needSched = 0;
+
+ PvtcpHoldSock(pvsk);
+ rc = 0;
+
+ if (!pvsk->peerSockSet || PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_WR)) {
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+ goto out;
+ }
+
+ tmpSize = (int)COMM_OPF_GET_VAL(packet->flags);
+ if (tmpSize) {
+ /* It was requested that we update deltaAckSize. */
+
+ tmpSize = 1 << tmpSize;
+ CommOS_WriteAtomic(&pvsk->deltaAckSize, tmpSize);
+ }
+
+ if (sk->sk_type == SOCK_STREAM) {
+ unsigned int queueSize = 0;
+
+ if (!SOCK_OUT_TRYLOCK(pvsk)) {
+ if (pvsk->peerSockSet &&
+ (sk->sk_state == TCP_ESTABLISHED) &&
+ (CommOS_ReadAtomic(&pvsk->queueSize) == 0)) {
+ /* Attempt to write directly as many bytes as we can. */
+
+ msg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+ rc = kernel_sendmsg(sock, &msg, vec, vecLen, dataLen);
+
+ if (rc == -EAGAIN) {
+ rc = 0;
+ }
+ if (rc >= 0) {
+ dataLen = rc;
+ for (vecOff = 0; vecOff < vecLen; vecOff++) {
+ if (rc >= vec[vecOff].iov_len) {
+ /* Dispose of all fully consumed buffers. */
+
+ PvtcpBufFree(vec[vecOff].iov_base);
+ rc -= vec[vecOff].iov_len;
+ } else {
+ /* Place partly consumed / unconsumed buffers in queue. */
+
+ internalBuf =
+ PvtcpOffInternalFromBuf(vec[vecOff].iov_base);
+ BUG_ON(internalBuf == NULL);
+ if (rc > 0) {
+ internalBuf->len -= rc;
+ internalBuf->off += rc;
+ rc = 0;
+ }
+ CommOS_ListAddTail(&pvsk->queue, &internalBuf->link);
+ queueSize += internalBuf->len;
+ }
+ }
+ if (queueSize > 0) {
+ CommOS_AddReturnAtomic(&pvsk->queueSize, queueSize);
+ needSched = 1;
+ }
+ } else {
+ /*
+ * We never close offload sockets unless told by the PV side,
+ * or when the comm goes down. Getting out of sync with PV
+ * sockets is a dangerously bad idea.
+ * This is very likely an EPIPE/ECONNRESET.
+ */
+
+ dataLen = 0;
+ for ( vecOff = 0; vecOff < vecLen; vecOff++) {
+ PvtcpBufFree(vec[vecOff].iov_base);
+ }
+ }
+ SOCK_OUT_UNLOCK(pvsk);
+ } else {
+ SOCK_OUT_UNLOCK(pvsk);
+ goto enqueueBytes;
+ }
+ } else {
+ /*
+ * We enqueue the bytes for aio processing. Note that request
+ * level ordering is preserved since we're still under the dispatch
+ * lock. However, accessing 'queue' must be protected via
+ * the state lock to serialize with aio changes.
+ * Note that the struct socket *sock may have been released, but here
+ * we only access sk which is held (albeit potentially orphaned).
+ */
+
+ CommOSList bufList;
+
+enqueueBytes:
+ dataLen = 0;
+ if (pvsk->peerSockSet && (sk->sk_state == TCP_ESTABLISHED)) {
+ queueSize = 0;
+ CommOS_ListInit(&bufList);
+ for (vecOff = 0; vecOff < vecLen; vecOff++) {
+ internalBuf = PvtcpOffInternalFromBuf(vec[vecOff].iov_base);
+ BUG_ON(internalBuf == NULL);
+ CommOS_ListAddTail(&bufList, &internalBuf->link);
+ queueSize += internalBuf->len;
+ }
+
+ if (queueSize > 0) {
+ SOCK_STATE_LOCK(pvsk);
+ CommOS_ListSpliceTail(&pvsk->queue, &bufList);
+ SOCK_STATE_UNLOCK(pvsk);
+ CommOS_AddReturnAtomic(&pvsk->queueSize, queueSize);
+ needSched = 1;
+ }
+ } else {
+ for ( vecOff = 0; vecOff < vecLen; vecOff++) {
+ PvtcpBufFree(vec[vecOff].iov_base);
+ }
+ }
+ }
+ } else { /* SOCK_DGRAM || SOCK_RAW */
+ struct sockaddr *addr;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ int addrLen;
+
+ /*
+ * Non-stream sockets don't use the send queue, packets are sent
+ * directly and they must _not_ be merged.
+ */
+
+ if (sk->sk_family == AF_INET) {
+ sin.sin_family = AF_INET;
+ sin.sin_port = packet->data16;
+ addr = (struct sockaddr *)&sin;
+ addrLen = sizeof sin;
+ sin.sin_addr.s_addr = (unsigned int)packet->data64ex;
+ PvtcpTestAndBindLoopbackInet4(pvsk, &sin.sin_addr.s_addr, 0);
+ } else { /* AF_INET6 */
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = packet->data16;
+ addr = (struct sockaddr *)&sin6;
+ addrLen = sizeof sin6;
+ PvtcpTestAndBindLoopbackInet6(pvsk, &packet->data64ex,
+ &packet->data64ex2, 0);
+ PvtcpI6AddrUnpack(&sin6.sin6_addr.s6_addr32[0],
+ packet->data64ex, packet->data64ex2);
+ }
+ msg.msg_flags = packet->data32 | MSG_DONTWAIT | MSG_NOSIGNAL;
+ msg.msg_name = addr;
+ msg.msg_namelen = addrLen;
+
+ if (pvsk->peerSockSet) {
+ /*
+ * Flow-control already done, based on PVTCP_SOCK_SAFE_RCVSIZE, just
+ * as with stream sockets. Meaning that we block the senders in the
+ * guest (if applicable).
+ *
+ * The send buffer size was set high enough, at socket creation time,
+ * to avoid dropping datagrams during the (non-blocking) write.
+ */
+
+ if (vecLen == 0) {
+ /*
+ * Allow zero-sized datagram sending.
+ */
+
+ struct kvec dummy = { .iov_base = NULL, .iov_len = 0 };
+
+ rc = kernel_sendmsg(sock, &msg, &dummy, 0, 0);
+ if (rc != dummy.iov_len) {
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Dgram [0x%p] sent [%d], expected [%d]\n",
+ __FUNCTION__, sk, rc, dummy.iov_len));
+#endif
+ if (rc == -EAGAIN) { /* As if lost on the wire. */
+ rc = 0;
+ }
+ }
+ }
+
+ for (vecOff = 0; vecOff < vecLen; vecOff++) {
+ rc = kernel_sendmsg(sock, &msg, &vec[vecOff], 1,
+ vec[vecOff].iov_len);
+ PvtcpBufFree(vec[vecOff].iov_base);
+ if (rc != vec[vecOff].iov_len) {
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Dgram [0x%p] sent [%d], expected [%d]\n",
+ __FUNCTION__, sk, rc, vec[vecOff].iov_len));
+#endif
+ if (rc == -EAGAIN) { /* As if lost on the wire. */
+ rc = 0;
+ }
+ }
+ }
+
+ if (COMM_OPF_TEST_ERR(packet->flags)) {
+ /* PV client wants an automatic bind. */
+
+ PvskSetOpFlag(pvsk, PVTCP_OP_BIND);
+ PvtcpSchedSock(pvsk);
+ }
+ } else {
+ for ( vecOff = 0; vecOff < vecLen; vecOff++) {
+ PvtcpBufFree(vec[vecOff].iov_base);
+ }
+ }
+ }
+ CommSvc_DispatchUnlock(channel);
+
+out:
+ if (rc < 0) {
+ pvsk->err = -rc;
+ }
+ tmpSize = CommOS_AddReturnAtomic(&pvsk->sentSize, dataLen);
+ if ((tmpSize >= CommOS_ReadAtomic(&pvsk->deltaAckSize)) ||
+ pvsk->err || needSched) {
+ if (CommOS_AddReturnAtomic(&PvtcpOutputAIOSection, 1) == 1) {
+ /* OutputAIO() (likely) not running. */
+
+ PvtcpSchedSock(pvsk);
+ }
+ CommOS_SubReturnAtomic(&PvtcpOutputAIOSection, 1);
+ }
+
+ PvtcpPutSock(pvsk);
+}
+
+
+/*
+ * AI/O functions called from the main AIO processing function.
+ */
+
+/**
+ * @brief Processes socket flow control acks and error notifications in an
+ * AIO thread. This function is called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket to process.
+ * @param err non-zero if offload was closed, zero otherwise.
+ * @sideeffect May resume PV socket sending or raise errors.
+ */
+
+void
+PvtcpFlowAIO(PvtcpSock *pvsk,
+ int err)
+{
+ CommPacket packet = { .flags = 0 };
+ unsigned long long timeout;
+ int tmpSize;
+
+ COMM_OPF_CLEAR_ERR(packet.flags);
+ packet.data32 = PVTCP_FLOW_OP_INVALID_SIZE;
+ if (pvsk->err || err) {
+ COMM_OPF_SET_ERR(packet.flags);
+ packet.data32ex = !pvsk->err ? 0 : xchg(&pvsk->err, 0);
+ if (!packet.data32ex) {
+ packet.data32ex = -err;
+ }
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sending socket error [%u] on [0x%p -> 0x%0x].\n",
+ __FUNCTION__, packet.data32ex, pvsk,
+ (unsigned)(pvsk->peerSock)));
+#endif
+ } else {
+ SOCK_STATE_LOCK(pvsk);
+ tmpSize = CommOS_ReadAtomic(&pvsk->deltaAckSize);
+ if (CommOS_ReadAtomic(&pvsk->sentSize) >= tmpSize) {
+ if ((SkFromPvsk(pvsk)->sk_type != SOCK_STREAM) &&
+ !sock_writeable(SkFromPvsk(pvsk))) {
+ /* Don't send dgram flow op until WriteSpaceCB tells us to do so. */
+
+ packet.data32 = PVTCP_FLOW_OP_INVALID_SIZE;
+ } else {
+ packet.data32 = CommOS_ReadAtomic(&pvsk->sentSize);
+ CommOS_WriteAtomic(&pvsk->sentSize, 0);
+ if (tmpSize > (1 << (PVTCP_SOCK_SMALL_ACK_ORDER + 1))) {
+ tmpSize >>= 1;
+ CommOS_WriteAtomic(&pvsk->deltaAckSize, tmpSize);
+ }
+ }
+ }
+ SOCK_STATE_UNLOCK(pvsk);
+ packet.data32ex = 0;
+ }
+
+ if (((packet.data32 != PVTCP_FLOW_OP_INVALID_SIZE) ||
+ COMM_OPF_TEST_ERR(packet.flags)) &&
+ pvsk->peerSockSet) {
+ packet.len = sizeof packet;
+ packet.opCode = PVTCP_OP_FLOW;
+ packet.data64 = pvsk->peerSock;
+ timeout = COMM_MAX_TO;
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+ }
+}
+
+
+/**
+ * @brief Processes queued socket output in an AIO thread. This function is
+ * called with the socket 'out' lock taken.
+ * @param[in,out] pvsk socket to process.
+ * @sideeffect Changes send size/capacity ratio.
+ */
+
+void
+PvtcpOutputAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk;
+ struct socket *sock;
+ PvtcpOffBuf *internalBuf;
+ PvtcpOffBuf *tmp;
+ CommOSList queue;
+#define VEC_SIZE 32
+ struct kvec vec[VEC_SIZE];
+ unsigned int vecLen;
+ unsigned int dataLen;
+ struct msghdr msg = {
+ .msg_controllen = 0,
+ .msg_control = NULL,
+ .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL
+ };
+ int queueDelta = 0;
+ int done = 0;
+ int rc;
+
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /* This is an error socket, we don't process it. */
+
+ return;
+ }
+
+ sock = sk->sk_socket;
+
+again:
+ CommOS_AddReturnAtomic(&PvtcpOutputAIOSection, 1);
+ while (!done && CommOS_ReadAtomic(&pvsk->queueSize) > 0) {
+ /* Note: only stream sockets can have a positive send queue size.
+ * Similar to PvtcpIoOp: we must check if sock (struct socket *) is
+ * still valid.
+ */
+
+ /* Take the current queue private. */
+
+ SOCK_STATE_LOCK(pvsk);
+ queue = pvsk->queue;
+ if (CommOS_ListEmpty(&queue)) {
+ SOCK_STATE_UNLOCK(pvsk);
+ return;
+ }
+ queue.next->prev = &queue;
+ queue.prev->next = &queue;
+ CommOS_ListInit(&pvsk->queue);
+ SOCK_STATE_UNLOCK(pvsk);
+
+ vecLen = 0;
+ dataLen = 0;
+
+ if (sk->sk_state == TCP_ESTABLISHED) {
+ CommOS_ListForEach(&queue, internalBuf, link) {
+ if (vecLen == VEC_SIZE) {
+ break;
+ }
+ vec[vecLen].iov_base = PvtcpOffBufFromInternalOff(internalBuf);
+ vec[vecLen].iov_len = internalBuf->len;
+ dataLen += internalBuf->len;
+ vecLen++;
+ }
+
+ rc = kernel_sendmsg(sock, &msg, vec, vecLen, dataLen);
+
+ if (rc == -EAGAIN) {
+ rc = 0;
+ }
+ if (rc >= 0) {
+ /* If we wrote anything, dispose of the buffers in question. */
+
+ queueDelta = rc;
+ if (queueDelta > 0) {
+ CommOS_ListForEachSafe(&queue, internalBuf, tmp, link) {
+ if (rc >= internalBuf->len) {
+ rc -= internalBuf->len;
+ CommOS_ListDel(&internalBuf->link);
+ PvtcpBufFree(PvtcpOffBufFromInternal(internalBuf));
+ } else {
+ internalBuf->len -= rc;
+ internalBuf->off += rc;
+ break;
+ }
+ }
+ }
+ if (!CommOS_ListEmpty(&queue)) {
+ /* Add the remaining bytes to the beginning of the queue. */
+
+ SOCK_STATE_LOCK(pvsk);
+ CommOS_ListSplice(&pvsk->queue, &queue);
+ SOCK_STATE_UNLOCK(pvsk);
+ }
+ if (queueDelta == 0) {
+ /* Bail out if no bytes written, WriteSpaceCB() will resched. */
+
+ done = 1;
+ break;
+ }
+ CommOS_AddReturnAtomic(&pvsk->sentSize, queueDelta);
+ CommOS_SubReturnAtomic(&pvsk->queueSize, queueDelta);
+ } else {
+ /*
+ * Very likely, this is due to the socket being closed, so fine.
+ */
+
+ goto discardOutput;
+ }
+ } else {
+ /* Dispose of all buffers in the queue and mark it empty. */
+
+discardOutput:
+ if (!CommOS_ListEmpty(&queue)) {
+ CommOS_ListForEachSafe(&queue, internalBuf, tmp, link) {
+ CommOS_ListDel(&internalBuf->link);
+ PvtcpBufFree(PvtcpOffBufFromInternal(internalBuf));
+ }
+ }
+ CommOS_WriteAtomic(&pvsk->queueSize, 0);
+ break;
+ }
+ }
+ if (CommOS_SubReturnAtomic(&PvtcpOutputAIOSection, 1) > 0) {
+ if (!done) {
+ goto again;
+ }
+ }
+
+ if (PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_WR)) {
+ kernel_sock_shutdown(sock, SHUT_WR);
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_WR, 0);
+ }
+#undef VEC_SIZE
+}
+
+
+/**
+ * @brief Processes socket input in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket to process.
+ * @param[in,out] perCpuBuf per-cpu socket read buffer.
+ * @return zero if eof was not detected, non-zero otherwise.
+ * @sideeffect Changes receive size/capacity ratio.
+ */
+
+int
+PvtcpInputAIO(PvtcpSock *pvsk,
+ void *perCpuBuf)
+{
+ struct sock *sk;
+ struct socket *sock;
+ int err = 0;
+ CommPacket packet = {
+ .opCode = PVTCP_OP_IO
+ };
+ unsigned long long timeout;
+
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /* IO processing is skipped on socket create-error sockets. */
+
+ return -1;
+ }
+ if (!perCpuBuf) {
+ /* No read buffer. */
+
+ return -1;
+ }
+
+ sock = sk->sk_socket;
+ packet.data64 = pvsk->peerSock;
+ COMM_OPF_CLEAR_ERR(packet.flags);
+
+ if (sk->sk_state == TCP_LISTEN) {
+ /* Process stream listen 'input'. */
+
+ packet.len = sizeof packet;
+ packet.data16 = sk->sk_ack_backlog;
+ timeout = COMM_MAX_TO;
+ if (pvsk->peerSockSet) {
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+ CommOS_Debug(("%s: Listen sock [0x%p] 'ack_backlog' [%hu].\n",
+ __FUNCTION__, sk, packet.data16));
+ }
+ } else {
+ /* Common path for both stream and datagram sockets. */
+
+ int rc;
+ int tmpSize;
+ struct kvec vec[2];
+ void *ioBuf = perCpuBuf;
+ struct kvec *inVec;
+ unsigned int inVecLen;
+ unsigned int iovOffset = 0;
+ unsigned int inputSize = 0;
+ unsigned int coalescingSize = PVTCP_SOCK_RCVSIZE >> 2;
+ struct sockaddr_in sin = { .sin_family = AF_INET };
+ struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6 };
+ struct msghdr msg = {
+ .msg_controllen = 0,
+ .msg_control = NULL,
+ .msg_flags = MSG_DONTWAIT
+ };
+ int tmpFlags = msg.msg_flags;
+ PvtcpDgramPseudoHeader dgramHeader;
+
+ tmpSize = CommOS_ReadAtomic(&pvsk->rcvdSize);
+ while ((tmpSize < PVTCP_SOCK_SAFE_RCVSIZE) && pvsk->peerSockSet) {
+ if (ioBuf != perCpuBuf) {
+ LargeDgramBufPut(ioBuf);
+ ioBuf = perCpuBuf;
+ }
+ vec[0].iov_base = (char *)ioBuf;
+
+ if (sk->sk_type == SOCK_STREAM) {
+ if (PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_RD)) {
+ break;
+ }
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ vec[0].iov_len = PVTCP_SOCK_STREAM_BUF_SIZE;
+ } else { /* SOCK_DGRAM || SOCK_RAW */
+ if (sk->sk_family == AF_INET) {
+ msg.msg_name = &sin;
+ msg.msg_namelen = sizeof sin;
+ } else {
+ msg.msg_name = &sin6;
+ msg.msg_namelen = sizeof sin6;
+ }
+
+ /*
+ * Check if datagram larger than the per cpu buffer; if so,
+ * allocate a large enough buffer. This should happen quite
+ * rarely, as well-behaved applications don't rely on IP
+ * fragmentation to accommodate large sizes.
+ */
+
+ vec[0].iov_len = 1;
+ msg.msg_flags |= (MSG_PEEK | MSG_TRUNC);
+ rc = kernel_recvmsg(sock, &msg, vec, 1, 1, msg.msg_flags);
+ if (rc < 0) {
+ break;
+ }
+ msg.msg_flags = tmpFlags;
+ if (rc > PVTCP_SOCK_DGRAM_BUF_SIZE) {
+ /*
+ * Track large datagram allocations, whether allocation succeeds
+ * or not. No need for atomic overhead, approximating is OK.
+ */
+
+ pvtcpOffDgramAllocations++;
+ ioBuf = LargeDgramBufGet(rc);
+ if (!ioBuf) {
+ /*
+ * We reset it to the per-cpu buffer such that we can still
+ * consume the datagram in the next recvmsg, which will set
+ * MSG_TRUNC so we won't put it on the channel.
+ */
+
+ CommOS_Debug(("%s: Dropping datagram (alloc failure)!\n",
+ __FUNCTION__));
+ ioBuf = perCpuBuf;
+ vec[0].iov_len = PVTCP_SOCK_DGRAM_BUF_SIZE;
+ } else {
+ vec[0].iov_len = rc;
+ }
+ } else {
+ vec[0].iov_len = PVTCP_SOCK_DGRAM_BUF_SIZE;
+ }
+ vec[0].iov_base = (char *)ioBuf;
+ }
+
+ rc = kernel_recvmsg(sock, &msg, vec, 1, vec[0].iov_len, msg.msg_flags);
+ if (rc < 0) {
+ break;
+ }
+
+ if ((rc == 0) && (sk->sk_type == SOCK_STREAM)) {
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_RD, 1);
+ err = -ECONNRESET;
+ break;
+ }
+
+ if (msg.msg_flags & MSG_TRUNC) {
+ continue;
+ }
+
+ inputSize += rc;
+ tmpSize = CommOS_AddReturnAtomic(&pvsk->rcvdSize, rc);
+ if (tmpSize >= PVTCP_SOCK_LARGE_ACK_WM) {
+ COMM_OPF_SET_VAL(packet.flags, PVTCP_SOCK_LARGE_ACK_ORDER);
+ } else {
+ COMM_OPF_SET_VAL(packet.flags, 0);
+ }
+
+ if (sk->sk_type == SOCK_STREAM) {
+ vec[0].iov_base = ioBuf;
+ vec[0].iov_len = rc;
+ inVecLen = 1;
+ packet.len = sizeof packet + rc;
+ } else { /* SOCK_DGRAM || SOCK_RAW */
+ if (sk->sk_family == AF_INET) {
+ dgramHeader.d0 = (unsigned long long)sin.sin_port;
+ PvtcpResetLoopbackInet4(pvsk, &sin.sin_addr.s_addr);
+ dgramHeader.d1 = (unsigned long long)sin.sin_addr.s_addr;
+ } else { /* AF_INET6 */
+ dgramHeader.d0 = (unsigned long long)sin6.sin6_port;
+ PvtcpResetLoopbackInet6(pvsk, &sin6.sin6_addr);
+ PvtcpI6AddrPack(&sin6.sin6_addr.s6_addr32[0],
+ &dgramHeader.d1, &dgramHeader.d2);
+ }
+ vec[0].iov_base = &dgramHeader;
+ vec[0].iov_len = sizeof dgramHeader;
+ vec[1].iov_base = ioBuf;
+ vec[1].iov_len = rc;
+ inVecLen = 2;
+ packet.len = sizeof packet + sizeof dgramHeader + rc;
+ }
+
+ inVec = vec;
+ timeout = COMM_MAX_TO;
+ rc = CommSvc_WriteVec(pvsk->channel, &packet,
+ &inVec, &inVecLen, &timeout, &iovOffset);
+ if (rc != packet.len) {
+ CommOS_Log(("%s: BOOG -- WROTE INCOMPLETE PACKET [%u->%d]!\n",
+ __FUNCTION__, packet.len, rc));
+ break;
+ }
+
+ /*
+ * If the write failed, we could print a warning. But if this
+ * happened, the comm channel went down.
+ */
+ if (inputSize >= coalescingSize) {
+ PvtcpSchedSock(pvsk); /* We must schedule ourselves back in. */
+ break;
+ }
+ }
+ if (ioBuf != perCpuBuf) {
+ LargeDgramBufPut(ioBuf);
+ }
+ }
+ return err;
+}
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.c b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.c
new file mode 100644
index 0000000..047547f
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.c
@@ -0,0 +1,2858 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Server (offload) side Linux-specific functions and callbacks.
+ */
+
+
+#include "pvtcp.h"
+
+#if defined(CONFIG_NET_NS)
+#include <linux/nsproxy.h>
+#include <linux/un.h>
+#endif
+
+#include <net/ipv6.h>
+#include <linux/kobject.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <linux/cred.h>
+
+
+/* The PVSock address (127.238.0.1) in binary form, host byte order. */
+#define PVTCP_PVSOCK_ADDR 0x7fee0001
+#define PVTCP_PVSOCK_NET 0x7fee0000
+#define PVTCP_PVSOCK_MASK 0x000000ff
+
+/* From mvpkm */
+extern uid_t Mvpkm_vmwareUid;
+
+/*
+ * Credentials to back socket file pointer. Used in Android ICS network
+ * data usage accounting to bill guest data to MVP.
+ */
+static struct cred _cred;
+static struct file _file = {
+ .f_cred = &_cred,
+};
+
+/* From pvtcp_off_io_linux.c */
+extern CommOSAtomic PvtcpOutputAIOSection;
+extern void PvtcpOffLargeDgramBufInit(void);
+
+static const unsigned short portRangeBase = 7000;
+static const unsigned int portRangeSize = 31;
+static int hooksRegistered = 0;
+
+static inline int PvtcpTestPortIndexBit(unsigned int addr,
+ unsigned int portIdx);
+/**
+ * @note
+ * Netfilter hooks:
+ *
+ * We decide to drop each packet based on the following criteria:
+ * 1) Destination address is to a pvsock address AND
+ * 3) (NOT(uid == 0 OR uid == vmwareUid)) OR
+ * 4) (type == UDP AND NOT(port-in-pvsock-range)))
+ */
+
+/**
+ * @brief Netfilter hook. Restricts LOCAL_OUT packets.
+ * See note above to filter policy.
+ * @param skb skbuff
+ * @param inet6 is this socket ipv4 or ipv6?
+ * @return NF_ACCEPT if the packet is allowed through, NF_DROP otherwise
+ */
+static inline unsigned int
+PvsockNfHook(struct sk_buff *skb, int inet6)
+{
+ uid_t uid;
+ unsigned int port;
+ struct socket *sock;
+ unsigned int addr = inet6 ?
+ ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]) :
+ ntohl(ip_hdr(skb)->daddr);
+
+ if (likely((addr ^ PVTCP_PVSOCK_NET) & ~PVTCP_PVSOCK_MASK)) {
+ /* Not a pvsock address. */
+ return NF_ACCEPT;
+ }
+
+ sock = skb->sk->sk_socket;
+ if (unlikely(!sock)) {
+ return NF_ACCEPT;
+ }
+
+ /*
+ * Guest (kernel) sockets can send to other guest sockets,
+ * Root can send to whoever it wants, no checks.
+ */
+ uid = (sock->file ? sock->file->f_cred->uid : 0);
+ if (uid == 0 || (sock->type != SOCK_STREAM && sock->type != SOCK_DGRAM)) {
+ return NF_ACCEPT;
+ }
+
+ /*
+ * Only vmware can send to guest.
+ */
+ if (likely(uid == Mvpkm_vmwareUid)) {
+ if (sock->type == SOCK_DGRAM) {
+ /*
+ * Deny sending to UDP port in pvsock range, if receiving socket was
+ * not created by the guest with this pvsock address. Drop all other
+ * UDP packets.
+ */
+ port = ntohs(udp_hdr(skb)->dest) - portRangeBase;
+ if ((port < portRangeSize) &&
+ PvtcpTestPortIndexBit(htonl(addr), port)) {
+ return NF_ACCEPT;
+ }
+ return NF_DROP;
+ }
+ /*
+ * TCP is all-good.
+ */
+ return NF_ACCEPT;
+ }
+
+ return NF_DROP;
+}
+
+
+/**
+ * @brief AF_INET4 Netfilter hook. Restricts LOCAL_OUT packets.
+ * See note above to filter policy.
+ * @param hooknum netfilter hook number
+ * @param skb skbuff
+ * @param in rx net_device
+ * @param out out net_device
+ * @param okfn ignored
+ * @return NF_ACCEPT if the packet is allowed through, NF_DROP otherwise
+ */
+static unsigned int
+Inet4NfHook(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return PvsockNfHook(skb, 0);
+}
+
+/**
+ * @brief AF_INET6 Netfilter hook. Restricts LOCAL_OUT packets.
+ * See note above to filter policy.
+ * @param hooknum netfilter hook number
+ * @param skb skbuff
+ * @param in rx net_device
+ * @param out out net_device
+ * @param okfn ignored
+ * @return NF_ACCEPT if the packet is allowed through, NF_DROP otherwise
+ */
+static unsigned int
+Inet6NfHook(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ if (!ipv6_addr_v4mapped(&ipv6_hdr(skb)->daddr)) {
+ /* Not ipv4-mapped, so not a pvsock address. */
+ return NF_ACCEPT;
+ }
+
+ return PvsockNfHook(skb, 1);
+}
+
+
+static struct nf_hook_ops netfilterHooks[] = {
+ {
+ .hook = Inet4NfHook,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = NF_IP_PRI_SECURITY
+ },
+ {
+ .hook = Inet6NfHook,
+ .owner = THIS_MODULE,
+ .pf = PF_INET6,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = NF_IP6_PRI_SECURITY
+ }
+};
+
+
+#if !defined(CONFIG_SYSFS)
+#error "The pvTCP offload module requires sysfs!"
+#endif
+
+/*
+ * State kobject, attributes and type.
+ */
+
+typedef struct PvtcpStateKObj {
+ struct kobject kobj;
+ CommTranspInitArgs transpArgs;
+ unsigned int pvsockAddr;
+ int useNS;
+ int haveNS;
+} PvtcpStateKObj;
+
+
+typedef struct PvtcpStateKObjAttr {
+ struct attribute attr;
+ ssize_t (*show)(PvtcpStateKObj *stateKObj, char *buf);
+ ssize_t (*store)(PvtcpStateKObj *stateKObj, const char *buf, size_t count);
+} PvtcpStateKObjAttr;
+
+
+/**
+ * @brief Releases state a kobject.
+ * @param kobj (embedded) state kobject.
+ */
+
+static void
+StateKObjRelease(struct kobject *kobj)
+{
+ kfree(container_of(kobj, PvtcpStateKObj, kobj));
+}
+
+
+/**
+ * @brief Sysfs show function for all pvtcp attributes.
+ * @param kobj (embedded) state kobject.
+ * @param attr pvtcp attribute to show.
+ * @param buf output buffer.
+ * @return number of bytes written or negative error code.
+ */
+
+static ssize_t
+StateKObjShow(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ PvtcpStateKObjAttr *stateAttr = container_of(attr, PvtcpStateKObjAttr, attr);
+ PvtcpStateKObj *stateKObj = container_of(kobj, PvtcpStateKObj, kobj);
+
+ if (stateAttr->show) {
+ return stateAttr->show(stateKObj, buf);
+ }
+
+ return -EIO;
+}
+
+
+/**
+ * @brief Sysfs store function for all pvtcp attributes.
+ * @param kobj (embedded) state kobject.
+ * @param attr pvtcp attribute to show.
+ * @param buf input buffer.
+ * @param count input buffer length.
+ * @return number of bytes consumed or negative error code.
+ */
+
+static ssize_t
+StateKObjStore(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ PvtcpStateKObjAttr *stateAttr = container_of(attr, PvtcpStateKObjAttr, attr);
+ PvtcpStateKObj *stateKObj = container_of(kobj, PvtcpStateKObj, kobj);
+
+ if (stateAttr->store) {
+ return stateAttr->store(stateKObj, buf, count);
+ }
+
+ return -EIO;
+}
+
+
+static struct sysfs_ops StateKObjSysfsOps = {
+ .show = StateKObjShow,
+ .store = StateKObjStore
+};
+
+
+/**
+ * @brief Show function for the comm_info pvtcp attribute.
+ * @param stateKObj state kobject.
+ * @param buf output buffer.
+ * @return number of bytes written or negative error code.
+ */
+
+static ssize_t
+StateKObjCommInfoShow(PvtcpStateKObj *stateKObj,
+ char *buf)
+{
+ unsigned int typeHash;
+
+ /*
+ * In the offload module, the transport arguments' type field has been
+ * assigned the matching index in the versions array at probe time.
+ * Recover and print out the type hash.
+ */
+
+ typeHash = CommTransp_GetType(pvtcpVersions[stateKObj->transpArgs.type]);
+
+ return snprintf(buf, PAGE_SIZE, "ID=%u,%u\nCAPACITY=%u\nTYPE=0x%0x\n",
+ stateKObj->transpArgs.id.d32[0],
+ stateKObj->transpArgs.id.d32[1],
+ stateKObj->transpArgs.capacity,
+ typeHash);
+}
+
+
+/**
+ * @brief Show function for the pvsock_addr pvtcp attribute.
+ * @param stateKObj state kobject.
+ * @param buf output buffer.
+ * @return number of bytes written or negative error code.
+ */
+
+static ssize_t
+StateKObjPvsockAddrShow(PvtcpStateKObj *stateKObj,
+ char *buf)
+{
+ union {
+ unsigned int raw;
+ unsigned char bytes[4];
+ } addr;
+
+ addr.raw = stateKObj->pvsockAddr;
+ return snprintf(buf, PAGE_SIZE, "%u.%u.%u.%u\n",
+ (unsigned int)addr.bytes[0], (unsigned int)addr.bytes[1],
+ (unsigned int)addr.bytes[2], (unsigned int)addr.bytes[3]);
+}
+
+
+/**
+ * @brief Show function for the use_ns pvtcp attribute.
+ * @param stateKObj state kobject.
+ * @param buf output buffer.
+ * @return number of bytes written or negative error code.
+ */
+
+static ssize_t
+StateKObjUseNSShow(PvtcpStateKObj *stateKObj,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", stateKObj->useNS);
+}
+
+
+/**
+ * @brief Store function for the use_ns pvtcp attribute.
+ * @param stateKObj state kobject.
+ * @param buf input buffer.
+ * @param count input buffer length.
+ * @return number of bytes consumed or negative error code.
+ */
+
+static ssize_t
+StateKObjUseNSStore(PvtcpStateKObj *stateKObj,
+ const char *buf,
+ size_t count)
+{
+ int rc = -EINVAL;
+
+ /* coverity[secure_coding] */
+ if (stateKObj->haveNS && (sscanf(buf, "%d", &stateKObj->useNS) == 1)) {
+ stateKObj->useNS = !!stateKObj->useNS;
+ rc = count;
+ }
+
+ return rc;
+}
+
+
+static PvtcpStateKObjAttr stateKObjCommInfoAttr =
+ __ATTR(comm_info, 0444, StateKObjCommInfoShow, NULL);
+
+static PvtcpStateKObjAttr stateKObjPvsockAddrAttr =
+ __ATTR(pvsock_addr, 0444, StateKObjPvsockAddrShow, NULL);
+
+static PvtcpStateKObjAttr stateKObjUseNSAttr =
+ __ATTR(use_ns, 0644, StateKObjUseNSShow, StateKObjUseNSStore);
+
+
+static struct attribute *stateKObjDefaultAttrs[] = {
+ &stateKObjCommInfoAttr.attr,
+ &stateKObjPvsockAddrAttr.attr,
+ &stateKObjUseNSAttr.attr,
+ NULL
+};
+
+
+static struct kobj_type stateKType = {
+ .sysfs_ops = &StateKObjSysfsOps,
+ .release = StateKObjRelease,
+ .default_attrs = stateKObjDefaultAttrs
+};
+
+
+/*
+ * Initialization of module entry and exit callbacks.
+ */
+
+static int Init(void *args);
+static void Exit(void);
+
+COMM_OS_MOD_INIT(Init, Exit);
+
+
+/*
+ * AIO socket read buffers, stats and other global state.
+ */
+
+static CommOSMutex globalLock;
+static char perCpuBuf[NR_CPUS][PVTCP_SOCK_BUF_SIZE];
+
+#define PVTCP_OFF_MAX_LB_ADDRS 255
+static unsigned int loopbackAddrs[PVTCP_OFF_MAX_LB_ADDRS] = {
+ 0xffffffff, // Network address always on, all ports allowed.
+ 0x7fffffff // Host address not yet on, all ports allowed.
+ // All the rest zeroed out.
+};
+
+static const unsigned int loopbackReserved = 0x00000001 << 31;
+
+
+#define PvtcpTestLoopbackBit(entry, mask) \
+ ((entry) & (mask))
+
+#define PvtcpSetLoopbackBit(entry, mask) \
+ ((entry) |= (mask))
+
+#define PvtcpResetLoopbackBit(entry, mask) \
+ ((entry) &= ~(mask))
+
+
+static inline int
+PvtcpTestPortIndexBit(unsigned int addr,
+ unsigned int portIdx)
+{
+ return PvtcpTestLoopbackBit(loopbackAddrs[*((unsigned char *)&addr + 3)],
+ BIT(portIdx));
+}
+
+
+static inline void
+PvtcpSetPortIndexBit(unsigned int addr,
+ unsigned int portIdx)
+{
+ PvtcpSetLoopbackBit(loopbackAddrs[*((unsigned char *)&addr + 3)],
+ BIT(portIdx));
+}
+
+
+static inline void
+PvtcpResetPortIndexBit(unsigned int addr,
+ unsigned int portIdx)
+{
+ PvtcpResetLoopbackBit(loopbackAddrs[*((unsigned char *)&addr + 3)],
+ BIT(portIdx));
+}
+
+
+unsigned int pvtcpLoopbackOffAddr;
+
+unsigned long long pvtcpOffDgramAllocations = 0;
+
+/*
+ * Destructor shim addresses and function pointer
+ */
+
+extern void asmDestructorShim(struct sock*);
+
+
+/*
+ * Functions.
+ */
+
+/**
+ * @brief Release a socket, NULLing out the fake file field to avoid confusing
+ * Linux on the release path
+ * @param sock socket to release
+ */
+static void
+SockReleaseWrapper(struct socket *sock)
+{
+ sock->file = NULL;
+ sock_release(sock);
+}
+
+/**
+ * @brief Gets a new loopback address in the 127.238.0.255 network.
+ * Note that the first address, 127.238.0.1, is always the host's.
+ * @return new address or -1U if none is available.
+ */
+
+static unsigned int
+GetLoopbackAddr(void)
+{
+ static unsigned char addrTempl[4] = { 127, 238, 0, 0 };
+ unsigned int rc = -1U;
+ unsigned int idx;
+ struct socket *sock;
+
+ CommOS_MutexLock(&globalLock);
+ for (idx = 1; idx < PVTCP_OFF_MAX_LB_ADDRS; idx++) {
+ if (!PvtcpTestLoopbackBit(loopbackAddrs[idx], loopbackReserved)) {
+ addrTempl[3] = (unsigned char)idx;
+ memcpy(&rc, addrTempl, sizeof rc);
+
+ /* Create a dgram socket to configure/bring-up the lo:N interface. */
+
+ if (!sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock)) {
+ int err;
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr = { .s_addr = rc }
+ };
+ struct ifreq ifr = {
+ .ifr_flags = IFF_UP
+ };
+
+ snprintf(ifr.ifr_name, sizeof ifr.ifr_name, "lo:%u", idx);
+ memcpy(&ifr.ifr_addr, &sin, sizeof ifr.ifr_addr);
+ err = kernel_sock_ioctl(sock, SIOCSIFADDR, (unsigned long)&ifr);
+ sock_release(sock);
+ if (err) {
+ CommOS_Log(("%s: Could not set loopback address (ioctl)!\n",
+ __FUNCTION__));
+ rc = -1U;
+ continue; /* Try next address. */
+ } else {
+ PvtcpSetLoopbackBit(loopbackAddrs[idx], loopbackReserved);
+ CommOS_Debug(("%s: Allocated loopback address [%u.%u.%u.%u].\n",
+ __FUNCTION__,
+ addrTempl[0], addrTempl[1],
+ addrTempl[2], addrTempl[3]));
+ break;
+ }
+ } else {
+ CommOS_Log(("%s: Could not set loopback address (create)!\n",
+ __FUNCTION__));
+ rc = -1U;
+ break;
+ }
+ }
+ }
+ if (idx == PVTCP_OFF_MAX_LB_ADDRS) {
+ CommOS_Log(("%s: loopback address range exceeded!\n", __FUNCTION__));
+ }
+
+ CommOS_MutexUnlock(&globalLock);
+ return rc;
+}
+
+
+/**
+ * @brief Puts back a loopback address in the 127.238.0.255 network.
+ * @param uaddr address to put back.
+ */
+
+static void
+PutLoopbackAddr(unsigned int uaddr)
+{
+ const unsigned char addrTempl[3] = { 127, 238, 0 };
+ unsigned char addr[4];
+ unsigned int idx;
+ struct socket *sock;
+
+ memcpy(addr, &uaddr, sizeof uaddr);
+ if (memcmp(addrTempl, addr, sizeof addrTempl)) {
+ return;
+ }
+
+ idx = addr[3];
+ if ((idx == 0) || (idx >= PVTCP_OFF_MAX_LB_ADDRS)) {
+ return;
+ }
+
+ CommOS_MutexLock(&globalLock);
+ if (!PvtcpTestLoopbackBit(loopbackAddrs[idx], loopbackReserved)) {
+ CommOS_Debug(("%s: loopback entry [%u] already freed.\n",
+ __FUNCTION__, idx));
+ goto out;
+ }
+
+ if (!sock_create_kern(AF_INET, SOCK_DGRAM, 0, &sock)) {
+ struct sockaddr_in sin = {
+ .sin_family = AF_INET,
+ .sin_addr = { .s_addr = uaddr }
+ };
+ struct ifreq ifr = {
+ .ifr_flags = 0
+ };
+
+ snprintf(ifr.ifr_name, sizeof ifr.ifr_name, "lo:%u", idx);
+ memcpy(&ifr.ifr_addr, &sin, sizeof ifr.ifr_addr);
+ kernel_sock_ioctl(sock, SIOCSIFFLAGS, (unsigned long)&ifr);
+ sock_release(sock);
+ loopbackAddrs[idx] = 0; // Zero everything out.
+ CommOS_Debug(("%s: Deallocated loopback address [%u.%u.%u.%u].\n",
+ __FUNCTION__, addr[0], addr[1], addr[2], addr[3]));
+ } else {
+ CommOS_Log(("%s: Could not delete loopback address!\n",
+ __FUNCTION__));
+ }
+
+out:
+ CommOS_MutexUnlock(&globalLock);
+}
+
+
+/**
+ * @brief Retrieves and retains the namespace associated with a channel.
+ * A server must be listening for requests to retrieve the pid of the
+ * process owning the net namespace for the passed context/vm id.
+ * Communication takes place over a datagram socket in the AF_UNIX family,
+ * bound to "/usr/lib/vmware/pvtcp/config/serv_addr".
+ * @param state channel state for which to retrieve the network namespace.
+ * @sideeffect If an associated namespace is found, it is retained and saved
+ * in the state object.
+ */
+
+static void
+GetNetNamespace(PvtcpState *state)
+{
+#if defined(CONFIG_NET_NS) && !defined(PVTCP_NET_NS_DISABLE)
+ CommTranspInitArgs args;
+ pid_t pidn;
+ struct pid *pid;
+ struct task_struct *tsk;
+ struct nsproxy *nsproxy;
+ struct net *ns;
+ struct socket *sock;
+ struct sockaddr_un addr = {
+ .sun_family = AF_UNIX
+ };
+ struct timeval timeout = {
+ .tv_sec = 3000,
+ .tv_usec = 0
+ };
+ const int passcred = 1;
+ char buf[64];
+ struct kvec vec;
+ const char *sockname = "pvtcp-vpn"; /* abstract namespace for AF_UNIX/LOCAL sockets */
+ const size_t socknamelen = strlen(sockname);
+
+ struct msghdr msg = {
+ .msg_name = (struct sockaddr *)&addr,
+ .msg_namelen = 1 + offsetof(struct sockaddr_un, sun_path) + socknamelen
+ };
+
+
+ if (!state) {
+ return;
+ }
+
+ args = CommSvc_GetTranspInitArgs(state->channel);
+ ns = NULL;
+ pidn = 0;
+
+ if (sock_create_kern(AF_UNIX, SOCK_DGRAM, 0, &sock)) {
+ CommOS_Debug(("%s: Can't create config socket!\n", __FUNCTION__));
+ goto out;
+ }
+ if (kernel_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&timeout, sizeof timeout)) {
+ sock_release(sock);
+ CommOS_Debug(("%s: Can't set timeout on config socket!\n", __FUNCTION__));
+ goto out;
+ }
+ if (kernel_setsockopt(sock, SOL_SOCKET, SO_PASSCRED,
+ (char *)&passcred, sizeof passcred)) {
+ sock_release(sock);
+ CommOS_Debug(("%s: Can't set passcred on config socket!\n",
+ __FUNCTION__));
+ goto out;
+ }
+
+ /*
+ * Send the configuration request and receive the reply:
+ * - the request carries the VM/guest ID as used in the transport
+ * arguments used to create the channel.
+ * - the reply is expected to contain the pid of the namespace owner.
+ */
+
+ memset(buf, 0, sizeof buf);
+ snprintf(buf, sizeof buf, "%u\n", args.id.d32[0]);
+ buf[sizeof buf - 1] = '\0';
+ vec.iov_base = buf;
+ vec.iov_len = strlen(buf);
+
+ /* use anonymous name */
+ addr.sun_path[0] = 0;
+ memcpy(addr.sun_path+1, sockname, socknamelen);
+
+ if (kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len) <= 0) {
+ sock_release(sock);
+ CommOS_Debug(("%s: Could not send config request for vm [%u]!\n",
+ __FUNCTION__, args.id.d32[0]));
+ goto out;
+ }
+
+ memset(buf, 0, sizeof buf);
+ vec.iov_base = buf;
+ vec.iov_len = sizeof buf;
+ if (kernel_recvmsg(sock, &msg, &vec, 1, vec.iov_len, 0) <= 0) {
+ CommOS_Debug(("%s: Could not receive config reply for vm [%u]!\n",
+ __FUNCTION__, args.id.d32[0]));
+ } else {
+ buf[sizeof buf - 1] = '\0';
+ /* coverity[secure_coding] */
+ sscanf(buf, "%d", &pidn);
+ }
+ sock_release(sock);
+
+ if (!pidn) {
+ goto out;
+ }
+
+ pid = find_get_pid(pidn);
+ if (pid) {
+ tsk = pid_task(pid, PIDTYPE_PID);
+ if (tsk) {
+ rcu_read_lock();
+ nsproxy = task_nsproxy(tsk);
+ if (nsproxy && nsproxy->net_ns) {
+ ns = maybe_get_net(nsproxy->net_ns);
+ }
+ rcu_read_unlock();
+ }
+ put_pid(pid);
+ }
+
+out:
+ if (!ns) {
+ CommOS_Debug(("%s: Not using a namespace for vm [%u].\n",
+ __FUNCTION__, args.id.d32[0]));
+ ns = &init_net;
+ } else {
+ CommOS_Debug(("%s: Found the net namespace for vm [%u].\n",
+ __FUNCTION__, args.id.d32[0]));
+ }
+#else
+ void *ns = NULL;
+#endif
+
+ state->namespace = ns;
+}
+
+
+/**
+ * @brief Releases the network namespace associated with a channel state.
+ * @param namespace namespace to be released.
+ * @sideeffect If the namespace is not the initial one, it is released.
+ */
+
+static void
+PutNetNamespace(void *namespace)
+{
+#if defined(CONFIG_NET_NS) && !defined(PVTCP_NET_NS_DISABLE)
+ if (namespace && (namespace != &init_net)) {
+ put_net((struct net *)namespace);
+ }
+#endif
+}
+
+
+/**
+ * @brief Offload state constructor called when a channel is created.
+ * The function first calls the default state allocator; it then retrieves
+ * the n/w namespace associated with this client, retains it and stores it
+ * in the state object. Finally, it creates a sysfs node.
+ * @param[in,out] channel channel to initialize.
+ * @return pointer to a new state structure or NULL.
+ * @sideeffect Allocates memory.
+ */
+
+static void *
+StateAlloc(CommChannel channel)
+{
+ extern struct kset *Mvpkm_FindVMNamedKSet(int, const char *);
+ PvtcpState *state = NULL;
+ PvtcpIf *loopbackNetif = NULL;
+ PvtcpStateKObj *stateKObj = NULL;
+ struct kset *kset = NULL;
+ int rc;
+ CommTranspInitArgs transpArgs;
+
+ transpArgs = CommSvc_GetTranspInitArgs(channel);
+
+ /*
+ * The transport ID is assigned in an implementation-dependent way.
+ * (see lib/comm/comm_transp.h for transport type definitions.)
+ * However, the first 32 bits are expected to denote the guest/VM ID,
+ * while the last 32 bits are a resource handle within that VM. On MVP,
+ * transports map to queue pairs, which follow this convention.
+ */
+
+ kset = Mvpkm_FindVMNamedKSet((int)transpArgs.id.d32[0], "devices");
+ if (!kset) {
+ CommOS_Debug(("%s: Could not find sysfs '.../vm/N/devices' kset!\n",
+ __FUNCTION__));
+ goto error;
+ }
+
+ state = PvtcpStateAlloc(channel);
+ if (!state) {
+ CommOS_Debug(("%s: Could not allocate state!\n", __FUNCTION__));
+ goto error;
+ }
+
+ /* coverity[leaked_storage] */
+ stateKObj = kzalloc(sizeof *stateKObj, GFP_KERNEL);
+ if (!stateKObj) {
+ CommOS_Debug(("%s: Could not allocate state kobject!\n", __FUNCTION__));
+ goto error;
+ }
+
+ stateKObj->kobj.kset = kset;
+ /* coverity[leaked_storage] */
+ rc = kobject_init_and_add(&stateKObj->kobj, &stateKType, NULL, "pvtcp");
+ if (rc) {
+ CommOS_Debug(("%s: Could not add state kobject to parent kset [%d]!\n",
+ __FUNCTION__, rc));
+ goto error;
+ }
+
+ loopbackNetif = PvtcpStateFindIf(state, pvtcpIfLoopbackInet4);
+ BUG_ON(loopbackNetif == NULL);
+ loopbackNetif->conf.addr.in.s_addr = GetLoopbackAddr();
+ if (loopbackNetif->conf.addr.in.s_addr == -1U) {
+ CommOS_Log(("%s: Could not allocate loopback address!\n", __FUNCTION__));
+ goto error;
+ }
+
+ GetNetNamespace(state);
+
+ stateKObj->transpArgs = transpArgs;
+ stateKObj->pvsockAddr = loopbackNetif->conf.addr.in.s_addr;
+#if defined(CONFIG_NET_NS)
+ stateKObj->haveNS = (state->namespace != &init_net);
+ stateKObj->useNS = stateKObj->haveNS;
+#endif
+ state->extra = stateKObj;
+
+ _cred.uid = _cred.gid = _cred.suid = _cred.sgid =
+ _cred.euid = _cred.egid = _cred.fsuid = _cred.fsgid = Mvpkm_vmwareUid;
+
+
+out:
+ if (kset) {
+ kset_put(kset);
+ }
+ return state;
+
+error:
+ if (stateKObj) {
+ kobject_del(&stateKObj->kobj);
+ kobject_put(&stateKObj->kobj);
+ }
+ if (loopbackNetif && (loopbackNetif->conf.addr.in.s_addr != -1U)) {
+ PutLoopbackAddr(loopbackNetif->conf.addr.in.s_addr);
+ }
+ if (state) {
+ PvtcpStateFree(state);
+ state = NULL;
+ }
+ goto out;
+}
+
+
+/**
+ * @brief Offload state destructor called when a channel is closed.
+ * The function releases this client's n/w namespace and then calls the
+ * default state deallocator.
+ * @param arg pointer to state structure.
+ * @sideeffect Destroys all netifs and their sockets, deallocates memory.
+ */
+
+static void
+StateFree(void *arg)
+{
+ PvtcpState *state = arg;
+ PvtcpIf *loopbackNetif;
+ void *namespace;
+
+ if (!state) {
+ return;
+ }
+
+ if (state->extra) {
+ PvtcpStateKObj *stateKObj = state->extra;
+
+ kobject_del(&stateKObj->kobj);
+ kobject_put(&stateKObj->kobj);
+ }
+
+ namespace = state->namespace;
+ loopbackNetif = PvtcpStateFindIf(state, pvtcpIfLoopbackInet4);
+ BUG_ON(loopbackNetif == NULL);
+ PutLoopbackAddr(loopbackNetif->conf.addr.in.s_addr);
+ PvtcpStateFree(state);
+ PutNetNamespace(namespace);
+}
+
+
+/**
+ * @brief Releases socket. This function is called when the channel state
+ * owning the socket is closed.
+ * @param[in,out] pvsk PV socket to release.
+ * @sideeffect the socket eventually gets deallocated.
+ */
+
+void
+PvtcpReleaseSocket(PvtcpSock *pvsk)
+{
+ struct socket *sock = SkFromPvsk(pvsk)->sk_socket;
+
+ SOCK_IN_LOCK(pvsk);
+ SOCK_OUT_LOCK(pvsk);
+ pvsk->peerSockSet = 0;
+ SockReleaseWrapper(sock);
+ SOCK_OUT_UNLOCK(pvsk);
+ SOCK_IN_UNLOCK(pvsk);
+ CommOS_Debug(("%s: [0x%p].\n", __FUNCTION__, pvsk));
+}
+
+
+/**
+ * @brief Tests if the passed address is 127.238.0.1 or 127.0.0.1.
+ * @param pvsk socket to test.
+ * @param addr inet4 address to test.
+ * @return > 1: morph and propagate new address to caller, 1: just morph,
+ * 0: don't morph, < 0 (-EADDRNOTAVAIL): bad loopback.
+ */
+
+static inline int
+TestLoopbackInet4(PvtcpSock *pvsk,
+ unsigned int addr)
+{
+ if (!ipv4_is_loopback(addr)) {
+ return 0;
+ }
+
+ if (addr != htonl(PVTCP_PVSOCK_ADDR)) {
+ if (addr != htonl(INADDR_LOOPBACK)) {
+ return -EADDRNOTAVAIL;
+ }
+ if (PvtcpHasSockNamespace(pvsk)) {
+ /* We don't morph normal 127.0.0.1 when NS present. */
+
+ return 0;
+ }
+ return 2;
+ }
+
+ return 1;
+}
+
+
+/**
+ * @brief Tests if the passed address is 127.238.0.1 or 127.0.0.1 and the
+ * socket has a namespace. If yes, the address will be morphed into
+ * the actual loopback address, then a bind() is performed.
+ * Note that the function returns EADDRNOTAVAIL for any other loopbacks.
+ * @param pvsk socket to test.
+ * @param[in,out] addr inet4 address to test.
+ * @param port port to bind, or zero for any port.
+ * @return 1 if bind should be performed by caller, bind return code otherwise.
+ */
+
+int
+PvtcpTestAndBindLoopbackInet4(PvtcpSock *pvsk,
+ unsigned int *addr,
+ unsigned short port)
+{
+ int rc;
+ struct sockaddr_in sin;
+ unsigned int morphedAddr;
+ int propagate = 0;
+
+ rc = TestLoopbackInet4(pvsk, *addr);
+ switch (rc) {
+ case 2:
+ propagate = 1; // Fall through.
+ case 1:
+ break; // Proceed with morphing.
+ case 0:
+ return 1; // Don't morph, let bind() be done by caller.
+ default:
+ return rc;
+ }
+
+ if (pvsk->netif->conf.family == PVTCP_PF_LOOPBACK_INET4) {
+ /* The socket has already been morphed/bound. */
+
+ morphedAddr = pvsk->netif->conf.addr.in.s_addr;
+ rc = 0;
+ goto out;
+ }
+
+ /*
+ * Move the socket to the initial namespace before binding it
+ * such that the loopback address is accessible to the host.
+ */
+
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_INITIAL);
+ PvtcpStateAddSocket(pvsk->channel, pvtcpIfLoopbackInet4, pvsk);
+ morphedAddr = pvsk->netif->conf.addr.in.s_addr;
+ memset(&sin, 0, sizeof sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = port;
+ sin.sin_addr.s_addr = morphedAddr;
+
+ /* Bind to the channel loopback address. */
+
+ rc = kernel_bind(SkFromPvsk(pvsk)->sk_socket,
+ (struct sockaddr *)&sin, sizeof sin);
+ if (rc) {
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_CHANNEL);
+ PvtcpStateAddSocket(pvsk->channel, pvtcpIfUnbound, pvsk);
+ } else {
+ /*
+ * Bind succeeded on pvsock address.
+ * If this is a pvsock UDP reserved port, record it.
+ */
+
+ port = ntohs(port) - portRangeBase;
+ if ((SkFromPvsk(pvsk)->sk_socket->type == SOCK_DGRAM) &&
+ (port < portRangeSize)) {
+ CommOS_MutexLock(&globalLock);
+ PvtcpSetPortIndexBit(pvsk->netif->conf.addr.in.s_addr, port);
+ CommOS_MutexUnlock(&globalLock);
+ }
+
+ /*
+ * pvsock data usage shouldn't be counted as MVP external traffic.
+ */
+ SkFromPvsk(pvsk)->sk_socket->file = NULL;
+ }
+
+out:
+ if (propagate) {
+ *addr = morphedAddr;
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Tests if the passed address is IPV4-mapped 127.238.0.1 or 127.0.0.1,
+ * clean ::1, and whether the socket has a namespace.
+ * If needed, the address will be morphed into the actual loopback address,
+ * then a bind() is performed.
+ * Note that the function returns EADDRNOTAVAIL for any other loopbacks.
+ * @param pvsk socket to test.
+ * @param[in,out] addr0 first 64 bits of inet6 address to test.
+ * @param[in,out] addr1 last 64 bits of inet6 address to test.
+ * @param port port to bind, or zero for any port.
+ * @return 1 if bind should be performed by caller, bind return code otherwise.
+ */
+
+int
+PvtcpTestAndBindLoopbackInet6(PvtcpSock *pvsk,
+ unsigned long long *addr0,
+ unsigned long long *addr1,
+ unsigned short port)
+{
+ int rc;
+ struct sockaddr_in6 sin6;
+ union {
+ unsigned long long halves[2];
+ struct in6_addr in6;
+ } in6Addr = {
+ .halves = { *addr0, *addr1 }
+ };
+ int propagate = 0;
+ const int ipv6Only = 0;
+
+ if (ipv6_addr_loopback(&in6Addr.in6)) {
+ if (PvtcpHasSockNamespace(pvsk)) {
+ return 1;
+ }
+
+ /* Remember that we were passed '::1'. */
+
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_IPV6_LOOP, 1);
+ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK), &in6Addr.in6);
+ }
+
+ if (!ipv6_addr_v4mapped(&in6Addr.in6)) {
+ /* If the address is not ipv4-mapped, stop testing. */
+
+ return 1;
+ }
+
+ rc = TestLoopbackInet4(pvsk, in6Addr.in6.s6_addr32[3]);
+ switch (rc) {
+ case 2:
+ propagate = 1; // Fall through.
+ case 1:
+ break; // Proceed with morphing.
+ case 0:
+ return 1; // Don't morph, let bind() be done by caller.
+ default:
+ return rc;
+ }
+
+ if (pvsk->netif->conf.family == PVTCP_PF_LOOPBACK_INET4) {
+ /* The socket has already been morphed/bound. */
+
+ ipv6_addr_set_v4mapped(pvsk->netif->conf.addr.in.s_addr, &in6Addr.in6);
+ rc = 0;
+ goto out;
+ }
+
+ /*
+ * Move the socket to the initial namespace before binding it
+ * such that the loopback address is accessible to the host.
+ */
+
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_INITIAL);
+ PvtcpStateAddSocket(pvsk->channel, pvtcpIfLoopbackInet4, pvsk);
+ ipv6_addr_set_v4mapped(pvsk->netif->conf.addr.in.s_addr, &in6Addr.in6);
+ memset(&sin6, 0, sizeof sin6);
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = port;
+ sin6.sin6_addr = in6Addr.in6;
+
+ /*
+ * Ensure we can use ipv4 mapped addresses and bind to the channel
+ * loopback address.
+ */
+
+ (void)kernel_setsockopt(SkFromPvsk(pvsk)->sk_socket, IPPROTO_IPV6,
+ IPV6_V6ONLY, (char *)&ipv6Only, sizeof ipv6Only);
+ rc = kernel_bind(SkFromPvsk(pvsk)->sk_socket,
+ (struct sockaddr *)&sin6, sizeof sin6);
+ if (rc) {
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_CHANNEL);
+ PvtcpStateAddSocket(pvsk->channel, pvtcpIfUnbound, pvsk);
+ } else {
+ /*
+ * Bind succeeded on pvsock address.
+ * If this is a pvsock UDP reserved port, record it.
+ */
+
+ port = ntohs(port) - portRangeBase;
+ if ((SkFromPvsk(pvsk)->sk_socket->type == SOCK_DGRAM) &&
+ (port < portRangeSize)) {
+ CommOS_MutexLock(&globalLock);
+ PvtcpSetPortIndexBit(pvsk->netif->conf.addr.in.s_addr, port);
+ CommOS_MutexUnlock(&globalLock);
+ }
+
+ /*
+ * pvsock data usage shouldn't be counted as MVP external traffic.
+ */
+ SkFromPvsk(pvsk)->sk_socket->file = NULL;
+ }
+
+out:
+ if (propagate) {
+ *addr0 = in6Addr.halves[0];
+ *addr1 = in6Addr.halves[1];
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Resets a 127.238.0.N address to 127.0.0.1.
+ * @param pvsk socket whose address needs resetting.
+ * @param[in,out] addr inet4 address to reset.
+ */
+
+void
+PvtcpResetLoopbackInet4(PvtcpSock *pvsk,
+ unsigned int *addr)
+{
+ if (!PvtcpHasSockNamespace(pvsk)) {
+ static const unsigned int pvsockAddr = htonl(PVTCP_PVSOCK_ADDR);
+
+ if (!memcmp(&pvsockAddr, addr, 3) && memcmp(&pvsockAddr, addr, 4)) {
+ /* If it's a pvsock address but _not_ the host's, overwrite it. */
+
+ *addr = htonl(INADDR_LOOPBACK);
+ }
+ }
+}
+
+
+/**
+ * @brief Resets an IPV4-mapped ::ffff:127.238.0.N IPV6 address to loopback.
+ * @param pvsk socket whose address needs resetting.
+ * @param[in,out] in6 inet6 address to reset.
+ */
+
+void
+PvtcpResetLoopbackInet6(PvtcpSock *pvsk,
+ struct in6_addr *in6)
+{
+ if (!PvtcpHasSockNamespace(pvsk) && ipv6_addr_v4mapped(in6)) {
+ if (PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_IPV6_LOOP)) {
+ /* If the original address came in as ::1, we reset as such. */
+
+ static const struct in6_addr in6Loopback = IN6ADDR_LOOPBACK_INIT;
+
+ *in6 = in6Loopback;
+ } else {
+ PvtcpResetLoopbackInet4(pvsk, &in6->s6_addr32[3]);
+ }
+ }
+}
+
+
+/**
+ * @brief Called at module load time. It registers with the Comm runtime.
+ * @param args initialization arguments
+ * @return zero if successful, -1 otherwise
+ * @sideeffect Leaves the module loaded
+ */
+
+static int
+Init(void *args)
+{
+ int rc = -1;
+
+#if !defined(PVTCP_DISABLE_NETFILTER)
+ rc = nf_register_hooks(netfilterHooks, ARRAY_SIZE(netfilterHooks));
+ if (rc) {
+ CommOS_Log(("%s: Could not register netfilter hooks!\n", __FUNCTION__));
+ goto out;
+ } else {
+ CommOS_Debug(("%s: Registered netfilter hooks.\n", __FUNCTION__));
+ }
+ hooksRegistered = 1;
+#else
+ CommOS_Log(("%s: Netfilter hooks disabled.\n", __FUNCTION__));
+#endif
+
+ CommOS_MutexInit(&globalLock);
+ CommOS_WriteAtomic(&PvtcpOutputAIOSection, 0);
+ PvtcpOffLargeDgramBufInit();
+
+ pvtcpImpl.owner = CommOS_ModuleSelf();
+ pvtcpImpl.stateCtor = StateAlloc;
+ pvtcpImpl.stateDtor = StateFree;
+ if (CommSvc_RegisterImpl(&pvtcpImpl) == 0) {
+ rc = 0;
+ pvtcpLoopbackOffAddr = GetLoopbackAddr();
+ if (pvtcpLoopbackOffAddr == -1U) {
+ CommOS_Log(("%s: Could not allocate offload loopback address!\n",
+ __FUNCTION__));
+ rc = -1;
+ CommSvc_UnregisterImpl(&pvtcpImpl);
+ }
+ }
+
+out:
+ if (rc) {
+ if (hooksRegistered) {
+ nf_unregister_hooks(netfilterHooks, ARRAY_SIZE(netfilterHooks));
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * @brief Called at module unload time. It shuts down pvtcp.
+ * @sideeffect Total and utter destruction.
+ */
+
+static void
+Exit(void)
+{
+ PutLoopbackAddr(pvtcpLoopbackOffAddr);
+ CommSvc_UnregisterImpl(&pvtcpImpl);
+#if !defined(PVTCP_DISABLE_NETFILTER)
+ if (hooksRegistered) {
+ nf_unregister_hooks(netfilterHooks, ARRAY_SIZE(netfilterHooks));
+ CommOS_Debug(("%s: Netfilter hooks unregistered.\n", __FUNCTION__));
+ }
+#endif
+ CommOS_Log(("%s: Allocations of large datagrams: %llu.\n",
+ __FUNCTION__, pvtcpOffDgramAllocations));
+}
+
+
+/*
+ * Socket callback interceptors.
+ */
+
+/**
+ * @brief Callback called when socket is destroyed.
+ * @param[in,out] sk socket to cleanup
+ * @return 0 if socket memory is freed, < 0 otherwise (no-op)
+ * @sideeffect Send queue buffers are deallocated
+ */
+
+int
+DestructCB(struct sock *sk)
+{
+ PvtcpOffBuf *internalBuf;
+ PvtcpOffBuf *tmp;
+ PvtcpSock *pvsk = PvskFromSk(sk);
+
+ if (!pvsk ||
+ (SkFromPvsk(pvsk) != sk) ||
+ (pvsk->destruct == asmDestructorShim)) {
+ /* Module put _not_ to be performed by asmDestructorShim. */
+
+ CommOS_Debug(("%s: pvsk / sk inconsistency. Ignored.\n", __FUNCTION__));
+ return -1;
+ }
+
+ CommOS_ListForEachSafe(&pvsk->queue, internalBuf, tmp, link) {
+ CommOS_ListDel(&internalBuf->link);
+ PvtcpBufFree(PvtcpOffBufFromInternal(internalBuf));
+ }
+ if (pvsk->destruct) {
+ pvsk->destruct(sk);
+ }
+
+ if (pvsk->rpcReply) {
+ CommOS_Kfree(pvsk->rpcReply);
+ }
+ CommOS_Kfree(pvsk);
+
+ /*
+ * Module put is performed by asmDestructorShim.
+ */
+
+ return 0;
+}
+
+
+/**
+ * @brief Callback called when socket state changes occur.
+ * @param sk socket specified socket which changed state
+ * @sideeffect A writer task may be scheduled
+ */
+
+static void
+StateChangeCB(struct sock *sk)
+{
+ PvtcpSock *pvsk = PvskFromSk(sk);
+
+ if (!pvsk ||
+ (SkFromPvsk(pvsk) != sk) ||
+ (pvsk->stateChange == StateChangeCB)) {
+ CommOS_Debug(("%s: pvsk / sk inconsistency. Ignored.\n", __FUNCTION__));
+ return;
+ }
+
+ /*
+ * The socket (spin) lock is held when this function is called.
+ */
+
+ CommOS_Debug(("%s: [0x%p] sk_state [%u] sk_err [%d] sk_err_soft [%d].\n",
+ __FUNCTION__, pvsk, sk->sk_state,
+ sk->sk_err, sk->sk_err_soft));
+ if (pvsk->stateChange) {
+ pvsk->stateChange(sk);
+ }
+ if (sk->sk_state == TCP_ESTABLISHED) {
+ PvskSetOpFlag(pvsk, PVTCP_OP_CONNECT);
+ }
+ PvtcpSchedSock(pvsk);
+}
+
+
+/**
+ * @brief Callback called when an error is set on the socket.
+ * @param sk socket the error happened on
+ * @sideeffect A writer task may be scheduled
+ */
+
+static void
+ErrorReportCB(struct sock *sk)
+{
+ PvtcpSock *pvsk = PvskFromSk(sk);
+
+ if (!pvsk ||
+ (SkFromPvsk(pvsk) != sk) ||
+ (pvsk->errorReport == ErrorReportCB)) {
+ CommOS_Debug(("%s: pvsk / sk inconsistency. Ignored\n", __FUNCTION__));
+ return;
+ }
+
+ /*
+ * The socket (spin) lock is held when this function is called.
+ * Interesting sk_err-s:
+ * ECONNRESET - tcp_disconnect(), tcp_reset()
+ * ECONNREFUSED - tcp_reset()
+ * EPIPE - tcp_reset()
+ * ETIMEDOUT - tcp_write_error()
+ * EHOSTUNREACH, etc. - tcp_v4_error()??, icmp errors
+ * etc. - __udp4_lib_err(), icmp errors
+ */
+
+ CommOS_Debug(("%s: [0x%p] sk_err [%d] sk_err_soft [%d].\n",
+ __FUNCTION__, pvsk, sk->sk_err, sk->sk_err_soft));
+ if (pvsk->errorReport) {
+ pvsk->errorReport(sk);
+ }
+ pvsk->err = sk->sk_err;
+ PvtcpSchedSock(pvsk);
+}
+
+
+/**
+ * @brief Callback called when data is available to be read from a socket.
+ * @param sk socket in question
+ * @param bytes number of bytes to read
+ * @sideeffect A writer task is scheduled _iff_ the peer can safely
+ * receive.
+ */
+
+static void
+DataReadyCB(struct sock *sk,
+ int bytes)
+{
+ PvtcpSock *pvsk = PvskFromSk(sk);
+
+ if (!pvsk ||
+ (SkFromPvsk(pvsk) != sk) ||
+ (pvsk->dataReady == DataReadyCB)) {
+ CommOS_Debug(("%s: pvsk / sk inconsistency. Ignored.\n", __FUNCTION__));
+ return;
+ }
+
+ /*
+ * The socket (spin) lock is held when this function is called.
+ */
+
+ if (pvsk->dataReady) {
+ pvsk->dataReady(sk, bytes);
+ }
+ if (sk->sk_state == TCP_LISTEN) {
+ CommOS_Debug(("%s: Listen socket ready to accept [0x%p].\n",
+ __FUNCTION__, pvsk));
+ }
+ PvtcpSchedSock(pvsk);
+}
+
+
+/**
+ * @brief Callback called when writing is possible on a socket.
+ * @param sk socket in question
+ * @sideeffect An AIO thread is scheduled.
+ */
+
+static void
+WriteSpaceCB(struct sock *sk)
+{
+ PvtcpSock *pvsk = PvskFromSk(sk);
+
+ if (!pvsk ||
+ (SkFromPvsk(pvsk) != sk) ||
+ (pvsk->writeSpace == WriteSpaceCB)) {
+ CommOS_Debug(("%s: pvsk / sk inconsistency. Ignored.\n", __FUNCTION__));
+ return;
+ }
+
+ /*
+ * The socket (spin) lock is held when this function is called.
+ */
+
+ if (pvsk->writeSpace) {
+ pvsk->writeSpace(sk);
+ }
+ PvtcpSchedSock(pvsk);
+}
+
+
+/**
+ * @brief Initializes a newly created socket for offload operations.
+ * @param[in,out] sock socket to initialize
+ * @param channel channel to update
+ * @param peerSock peer PV socket of this socket
+ * @param parentPvsk parent of this socket or NULL
+ * @return zero on success, error code otherwise
+ */
+
+static int
+SockAllocInit(struct socket *sock,
+ CommChannel channel,
+ unsigned long long peerSock,
+ PvtcpSock *parentPvsk)
+{
+ struct sock *sk;
+ PvtcpSock *pvsk;
+ int sndBuf = PVTCP_SOCK_RCVSIZE * 4;
+
+ if (!sock || !channel || !peerSock) {
+ return -EINVAL;
+ }
+
+ sk = sock->sk;
+ sk->sk_user_data = NULL;
+
+ pvsk = CommOS_Kmalloc(sizeof *pvsk);
+ if (!pvsk) {
+ return -ENOMEM;
+ }
+
+ if (PvtcpOffSockInit(pvsk, channel)) {
+ CommOS_Kfree(pvsk);
+ return -ENOMEM;
+ }
+
+ /*
+ * PVTCP sockets should be billed against the vmware uid.
+ */
+ sk->sk_socket->file = &_file;
+
+ /* Set peer (pv) socket. */
+ pvsk->peerSock = peerSock;
+ pvsk->peerSockSet = 1;
+
+ /* Set up back pointer. */
+ pvsk->sk = sk;
+
+ /* Keep track of new socket. */
+ if (PvtcpStateAddSocket(channel, pvtcpIfUnbound, pvsk) != 0) {
+ CommOS_Kfree(pvsk);
+ return -ENOMEM;
+ }
+
+ /*
+ * Keep pvtcp around for at least the lifetime of this socket
+ */
+ CommOS_ModuleGet(pvtcpImpl.owner);
+
+ if (!parentPvsk) {
+ pvsk->destruct = sk->sk_destruct;
+ sk->sk_destruct = asmDestructorShim;
+ pvsk->stateChange = sk->sk_state_change;
+ sk->sk_state_change = StateChangeCB;
+ pvsk->errorReport = sk->sk_error_report;
+ sk->sk_error_report = ErrorReportCB;
+ pvsk->dataReady = sk->sk_data_ready;
+ sk->sk_data_ready = DataReadyCB;
+ pvsk->writeSpace = sk->sk_write_space;
+ sk->sk_write_space = WriteSpaceCB;
+ } else {
+ /*
+ * Copy the parent's saved callbacks. The parent pvsk is only passed
+ * when creating/initializing a socket after an 'accept'.
+ */
+
+ pvsk->destruct = parentPvsk->destruct;
+ sk->sk_destruct = asmDestructorShim;
+ pvsk->stateChange = parentPvsk->stateChange;
+ sk->sk_state_change = StateChangeCB;
+ pvsk->errorReport = parentPvsk->errorReport;
+ sk->sk_error_report = ErrorReportCB;
+ pvsk->dataReady = parentPvsk->dataReady;
+ sk->sk_data_ready = DataReadyCB;
+ pvsk->writeSpace = parentPvsk->writeSpace;
+ sk->sk_write_space = WriteSpaceCB;
+
+ if (parentPvsk->netif->conf.family == PVTCP_PF_LOOPBACK_INET4) {
+ /* The parent socket was morphed/bound. */
+
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_INITIAL);
+ PvtcpStateAddSocket(pvsk->channel, pvtcpIfLoopbackInet4, pvsk);
+ }
+ }
+
+ /* Install forward socket reference. */
+ sk->sk_user_data = pvsk;
+
+ /*
+ * Force the send buffer size high enough, such that we don't lose the
+ * just-a-bit-over-the-limit bytes. This is mainly needed for datagrams.
+ * Note that we always apply flow control between host and guest modules,
+ * according to the sizing model; so this is not artificially inflated.
+ */
+
+ kernel_setsockopt(sock, SOL_SOCKET, SO_SNDBUFFORCE,
+ (void *)&sndBuf, sizeof sndBuf);
+
+ return 0;
+}
+
+
+/**
+ * @brief Allocates a pvsk socket for error reporting (create operation).
+ * @param err error code to report to PV side
+ * @param channel channel error socket belongs to
+ * @param peerSock peer PV socket of this socket
+ * @return error socket on success, NULL otherwise
+ */
+
+static PvtcpSock *
+SockAllocErrInit(int err,
+ CommChannel channel,
+ unsigned long long peerSock)
+{
+ PvtcpSock *pvsk;
+
+ if (!channel || !peerSock) {
+ return NULL;
+ }
+
+ pvsk = CommOS_Kmalloc(sizeof *pvsk);
+ if (!pvsk) {
+ return NULL;
+ }
+
+ if (PvtcpOffSockInit(pvsk, channel)) {
+ CommOS_Kfree(pvsk);
+ return NULL;
+ }
+
+ /* Set peer (pv) socket and error. */
+ pvsk->peerSock = peerSock;
+ pvsk->peerSockSet = 1;
+ pvsk->err = err;
+
+ /* Set up back pointer to NULL such that PvtcpPutSock deallocates it. */
+ pvsk->sk = NULL;
+ return pvsk;
+}
+
+
+/*
+ * Offload operations.
+ */
+
+/**
+ * @brief Creates an offload socket and schedules it for reply.
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back.
+ */
+
+void
+PvtcpCreateOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ int rc;
+ struct socket *sock;
+ PvtcpSock *pvsk;
+ PvtcpState *state = (PvtcpState *)upperLayerState;
+ const int enable = 1;
+
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+
+#if defined(PVTCP_IPV6_DISABLE)
+ if (packet->data16 == AF_INET6) {
+ CommOS_Debug(("%s: AF_INET6 support is disabled.\n", __FUNCTION__));
+ rc = -EAFNOSUPPORT;
+ } else
+#endif
+ {
+ rc = sock_create_kern(packet->data16, packet->data32,
+ packet->data32ex, &sock);
+ }
+
+ if (!rc) {
+ rc = SockAllocInit(sock, channel, packet->data64, NULL);
+ if (rc) {
+ SockReleaseWrapper(sock);
+ goto fail;
+ }
+ kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&enable, sizeof enable);
+ pvsk = PvskFromSk(sock->sk);
+ if (state->extra &&
+ ((PvtcpStateKObj *)(state->extra))->useNS) {
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_CHANNEL);
+ } else {
+ PvtcpSwitchSock(pvsk, PVTCP_SOCK_NAMESPACE_INITIAL);
+ }
+ PvtcpStateAddSocket(pvsk->channel, pvtcpIfUnbound, pvsk);
+ PvskSetOpFlag(pvsk, PVTCP_OP_CREATE);
+ } else {
+ CommOS_Debug(("%s: Error creating offload socket: %d\n",
+ __FUNCTION__, rc));
+ /*
+ * Pass -rc so we follow error conventions for other reply ops.
+ * The error code is fixed by the PV side so error codes are properly
+ * reported.
+ */
+ pvsk = SockAllocErrInit(-rc, channel, packet->data64);
+ if (!pvsk) {
+ goto fail;
+ }
+ }
+
+ PvtcpSchedSock(pvsk);
+ return;
+
+fail:
+ CommOS_Log(("%s: BOOG ** FAILED TO CREATE OFFLOAD SOCKET [%d] "
+ "_AND_ ERROR REPORTING SOCKET!\n"
+ " PV SIDE MAY BE LOCKED UP UNTIL CREATE RPC TIMES OUT!",
+ __FUNCTION__, rc));
+}
+
+
+/**
+ * @brief Schedules an offload socket to be removed.
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back and
+ * then release the socket.
+ */
+
+void
+PvtcpReleaseOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+
+ /*
+ * Check if this is a pvsock datagram socket bound on a reserved port.
+ * If so, reset the bit such that filtering drops rogue packets.
+ */
+
+ if ((sk->sk_socket->type == SOCK_DGRAM) &&
+ (pvsk->netif->conf.family == PVTCP_PF_LOOPBACK_INET4)) {
+ unsigned short port = 0;
+
+ if (sk->sk_family == AF_INET) {
+ struct sockaddr_in sin = { .sin_family = AF_INET };
+ int addrLen = sizeof sin;
+
+ if(!kernel_getsockname(sk->sk_socket,
+ (struct sockaddr *)&sin, &addrLen)) {
+ port = sin.sin_port;
+ }
+ } else { /* AF_INET6 */
+ struct sockaddr_in6 sin = { .sin6_family = AF_INET6 };
+ int addrLen = sizeof sin;
+
+ if(!kernel_getsockname(sk->sk_socket,
+ (struct sockaddr *)&sin, &addrLen)) {
+ port = sin.sin6_port;
+ }
+ }
+
+ port = ntohs(port) - portRangeBase;
+ if (port < portRangeSize) {
+ CommOS_MutexLock(&globalLock);
+ PvtcpResetPortIndexBit(pvsk->netif->conf.addr.in.s_addr, port);
+ CommOS_MutexUnlock(&globalLock);
+ }
+ }
+
+ /*
+ * - hold the socket before setting the 'release' flag and until after
+ * the call to PvtcpSchedSock(): if the socket had already been scheduled
+ * ReleaseAIO may run, find the flag set and release this socket while
+ * it's being unlocked here.
+ *
+ * - hold the dispatch lock until done to ensure that subsequent Ops for
+ * this socket see peerSockSet == 0.
+ */
+
+ PvtcpHoldSock(pvsk);
+ SOCK_STATE_LOCK(pvsk);
+ pvsk->peerSockSet = 0;
+ SOCK_STATE_UNLOCK(pvsk);
+ PvskSetOpFlag(pvsk, PVTCP_OP_RELEASE);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+}
+
+
+/**
+ * @brief Binds an offload socket to a given address
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back
+ */
+
+void
+PvtcpBindOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct sockaddr *addr;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ int reuseAddr;
+ int addrLen;
+ int rc;
+
+ PvtcpHoldSock(pvsk);
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+
+ /*
+ * The socket-level option SO_REUSEADDR is set in the common socket code,
+ * meaning that we cannot intercept it in the guest pvtcp implementation.
+ * In order to respect the setting, the guest would pass the current
+ * setting in 'bind' requests.
+ * If the guest requires 'reuse address' setting, the value is incremented
+ * such that we differentiate between: 0) not requested, 1) 'false' and
+ * 2) 'true'.
+ */
+
+ reuseAddr = COMM_OPF_GET_VAL(packet->flags);
+ if ((reuseAddr == 1) || (reuseAddr == 2)) {
+ /* Explicit request, so decrement the value. */
+
+ reuseAddr--;
+ kernel_setsockopt(sk->sk_socket, SOL_SOCKET, SO_REUSEADDR,
+ (void *)&reuseAddr, sizeof reuseAddr);
+ }
+
+ if (sk->sk_family == AF_INET) {
+ memset(&sin, 0, sizeof sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = packet->data16;
+ sin.sin_addr.s_addr = (unsigned int)packet->data64ex;
+ addr = (struct sockaddr *)&sin;
+ addrLen = sizeof sin;
+
+ rc = PvtcpTestAndBindLoopbackInet4(pvsk, &sin.sin_addr.s_addr,
+ sin.sin_port);
+ if (rc <= 0) {
+ /* Bind has already happened. */
+
+ pvsk->err = -rc;
+ goto out;
+ }
+ } else { /* AF_INET6 */
+ memset(&sin6, 0, sizeof sin6);
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = packet->data16;
+ addr = (struct sockaddr *)&sin6;
+ addrLen = sizeof sin6;
+
+ rc = PvtcpTestAndBindLoopbackInet6(pvsk, &packet->data64ex,
+ &packet->data64ex2, sin6.sin6_port);
+ if (rc <= 0) {
+ /* Bind has already happened. */
+
+ pvsk->err = -rc;
+ goto out;
+ }
+ PvtcpI6AddrUnpack(&sin6.sin6_addr.s6_addr32[0],
+ packet->data64ex, packet->data64ex2);
+ }
+
+ /* coverity[check_return] */
+ pvsk->err = -kernel_bind(sk->sk_socket, addr, addrLen);
+
+out:
+ PvskSetOpFlag(pvsk, PVTCP_OP_BIND);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Sets a socket option.
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back
+ */
+void
+PvtcpSetSockOptOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ unsigned int optlen = packet->len - sizeof *packet;
+
+ PvtcpHoldSock(pvsk);
+
+ if ((vecLen != 1) || (vec[0].iov_len != optlen) || (optlen < sizeof(int))) {
+ pvsk->rpcStatus = -EINVAL;
+ goto out;
+ }
+
+ if (packet->data32 == SOL_TCP) {
+ /*
+ * The back-end implementation must always run in 'nodelay' mode.
+ * Consequently, we ignore, but we cache the TCP_NODELAY and TCP_CORK
+ * settings such that getsockopt() can return them as they were 'set'.
+ * Applications use these settings for performance; pvtcp does quite
+ * well if it's not interfered with.
+ */
+
+ int on;
+
+ switch (packet->data32ex) {
+ case TCP_NODELAY:
+ memcpy(&on, vec[0].iov_base, sizeof on);
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_TCP_NODELAY, on);
+ pvsk->rpcStatus = 0;
+ goto out;
+ case TCP_CORK:
+ memcpy(&on, vec[0].iov_base, sizeof on);
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_TCP_CORK, on);
+ pvsk->rpcStatus = 0;
+ goto out;
+ }
+ }
+
+ pvsk->rpcStatus = kernel_setsockopt(sock,
+ packet->data32,
+ packet->data32ex,
+ vec[0].iov_base,
+ optlen);
+
+out:
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+ PvskSetOpFlag(pvsk, PVTCP_OP_SETSOCKOPT);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Retrieves a socket option.
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back
+ */
+void
+PvtcpGetSockOptOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ unsigned int optLen = (unsigned int)(packet->data64ex);
+ char *optBuf;
+ int rc = 0;
+
+ PvtcpHoldSock(pvsk);
+
+ if ((optLen < sizeof(int)) || (optLen > PVTCP_SOCK_SAFE_RCVSIZE)) {
+ pvsk->rpcStatus = -EINVAL;
+ goto out;
+ }
+
+ optBuf = CommOS_Kmalloc(optLen);
+ if (!optBuf) {
+ pvsk->rpcStatus = -EINVAL;
+ goto out;
+ }
+
+ if (packet->data32 == SOL_TCP) {
+ /*
+ * See comment in PvtcpSetSockOptOp() regarding special treatment for
+ * the TCP_NODELAY and TCP_CORK settings.
+ */
+
+ int on;
+
+ switch (packet->data32ex) {
+ case TCP_NODELAY:
+ on = PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_TCP_NODELAY);
+ optLen = sizeof on;
+ memcpy(optBuf, &on, optLen);
+ goto done;
+ case TCP_CORK:
+ on = PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_TCP_CORK);
+ optLen = sizeof on;
+ memcpy(optBuf, &on, optLen);
+ goto done;
+ }
+ }
+
+ rc = kernel_getsockopt(sock, packet->data32,
+ packet->data32ex, optBuf, &optLen);
+
+done:
+ if (!rc) {
+ pvsk->rpcReply = optBuf;
+ CommOS_MemBarrier();
+ pvsk->rpcStatus = (int)optLen;
+ } else {
+ CommOS_Kfree(optBuf);
+ pvsk->rpcStatus = rc;
+ }
+
+out:
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+ PvskSetOpFlag(pvsk, PVTCP_OP_GETSOCKOPT);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Performs ioctl on offload socket.
+ * @param channel communication channel with offloader
+ * @param state state associated with this channel
+ * @param packet packet header received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ */
+
+void
+PvtcpIoctlOp(CommChannel channel,
+ void *state,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, state);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+
+ PvtcpHoldSock(pvsk);
+
+ /* Not implemented yet. */
+
+ (void)sock;
+ pvsk->rpcStatus = -ENOIOCTLCMD;
+
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+ PvskSetOpFlag(pvsk, PVTCP_OP_IOCTL);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Marks a socket for listening to incoming connections
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back
+ */
+
+void
+PvtcpListenOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ int backlog = (int)packet->data32;
+
+ PvtcpHoldSock(pvsk);
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+
+ pvsk->err = -kernel_listen(sk->sk_socket, backlog);
+ PvskSetOpFlag(pvsk, PVTCP_OP_LISTEN);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Accepts a connected socket
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back.
+ */
+
+void
+PvtcpAcceptOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ int rc;
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *newsock = NULL;
+
+ PvtcpHoldSock(pvsk);
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+
+ rc = kernel_accept(sk->sk_socket, &newsock, O_NONBLOCK);
+ if (rc == 0) {
+ rc = SockAllocInit(newsock, channel, packet->data64ex, pvsk);
+ if (rc) {
+ SockReleaseWrapper(newsock);
+ }
+ }
+
+ if (rc == 0) {
+ struct sock *newsk = newsock->sk;
+ PvtcpSock *newpvsk = PvskFromSk(newsk);
+
+ /* We temporarily use the state field to cache parent socket. */
+
+ newpvsk->state = (PvtcpState *)pvsk;
+ PvskSetOpFlag(newpvsk, PVTCP_OP_ACCEPT);
+ PvtcpSchedSock(newpvsk);
+ } else {
+ pvsk->err = -rc;
+ PvskSetOpFlag(pvsk, PVTCP_OP_ACCEPT);
+ PvtcpSchedSock(pvsk);
+ }
+
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Connects an offload socket to given address
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect A writer task is scheduled, which will send reply back
+ */
+
+void
+PvtcpConnectOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct sockaddr *addr;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ int addrLen;
+ int flags = 0;
+ int rc = 0;
+ int disconnect = 0;
+
+ PvtcpHoldSock(pvsk);
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+
+ if (sk->sk_family == AF_INET) {
+ addr = (struct sockaddr *)&sin;
+ addrLen = sizeof sin;
+ memset(&sin, 0, sizeof sin);
+ sin.sin_port = packet->data16;
+ sin.sin_addr.s_addr = (unsigned int)packet->data64ex;
+ if (COMM_OPF_GET_VAL(packet->flags)) {
+ sin.sin_family = AF_UNSPEC;
+ disconnect = 1;
+ goto connect;
+ }
+ sin.sin_family = AF_INET;
+ PvtcpTestAndBindLoopbackInet4(pvsk, &sin.sin_addr.s_addr, 0);
+ } else { /* AF_INET6 */
+ addr = (struct sockaddr *)&sin6;
+ addrLen = sizeof sin6;
+ memset(&sin6, 0, sizeof sin6);
+ sin6.sin6_port = packet->data16;
+ if (COMM_OPF_GET_VAL(packet->flags)) {
+ sin6.sin6_family = AF_UNSPEC;
+ PvtcpI6AddrUnpack(&sin6.sin6_addr.s6_addr32[0],
+ packet->data64ex, packet->data64ex2);
+ disconnect = 1;
+ goto connect;
+ }
+ sin6.sin6_family = AF_INET6;
+ PvtcpTestAndBindLoopbackInet6(pvsk, &packet->data64ex,
+ &packet->data64ex2, 0);
+ PvtcpI6AddrUnpack(&sin6.sin6_addr.s6_addr32[0],
+ packet->data64ex, packet->data64ex2);
+ }
+
+connect:
+ rc = kernel_connect(sk->sk_socket, addr, addrLen, flags | O_NONBLOCK);
+
+ /*
+ * For datagram sockets, ErrorReportCB is not called, so we need to
+ * explicitly set the pvsk error to be returned back to the guest.
+ * This should not be used on SOCK_STREAM sockets. You have been
+ * warned.
+ */
+
+ if (rc && (sk->sk_socket->type == SOCK_DGRAM)) {
+ pvsk->err = -rc;
+ }
+
+ /*
+ * Quite likely, stream actual connect requests will set err to EINPROGRESS.
+ * That's fine, error_report will trigger an AIO/flow-op reply. When the
+ * connection is established, state_change schedules an AIO/connect reply.
+ * Record whether the request was a disconnect.
+ */
+
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_DISCONNECT, disconnect);
+ PvskSetOpFlag(pvsk, PVTCP_OP_CONNECT);
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/**
+ * @brief Initiates socket shutdown on an offload socket
+ * @param channel communication channel with offloader
+ * @param upperLayerState state associated with this channel
+ * @param packet first packet received in reply
+ * @param vec payload buffer descriptors
+ * @param vecLen payload buffer descriptor count
+ * @sideeffect Socket queue will be drained and socket shutdown performed.
+ */
+
+void
+PvtcpShutdownOp(CommChannel channel,
+ void *upperLayerState,
+ CommPacket *packet,
+ struct kvec *vec,
+ unsigned int vecLen)
+{
+ PvtcpSock *pvsk = PvtcpGetPvskOrReturn(packet->data64, upperLayerState);
+ int how = (int)packet->data32;
+
+ PvtcpHoldSock(pvsk);
+ if ((how == SHUT_RD) || (how == SHUT_RDWR)) {
+ kernel_sock_shutdown(SkFromPvsk(pvsk)->sk_socket, SHUT_RD);
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_RD, 1);
+ }
+ if ((how == SHUT_WR) || (how == SHUT_RDWR)) {
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_SHUT_WR, 1);
+ }
+ PVTCP_UNLOCK_DISP_DISCARD_VEC();
+ PvtcpSchedSock(pvsk);
+ PvtcpPutSock(pvsk);
+}
+
+
+/*
+ * AIO functions called from the main AIO processing function.
+ * Most of these functions complete processing initiated by the corresponding
+ * offload operations above.
+ */
+
+/**
+ * @brief Processes socket release in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket to release.
+ * @sideeffect the socket will be released upon return from this function.
+ */
+
+static inline void
+ReleaseAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ CommPacket packet = {
+ .len = sizeof packet,
+ .flags = 0,
+ .opCode = PVTCP_OP_RELEASE,
+ .data64 = pvsk->peerSock,
+ .data64ex = PvtcpGetHandle(pvsk)
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+
+ SOCK_OUT_LOCK(pvsk);
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sent 'Release' [0x%p] -> 0x%0x] reply.\n",
+ __FUNCTION__, pvsk, (unsigned)(pvsk->peerSock)));
+#endif
+ /*
+ * 'sk' goes away in the final ProcessAIO::sock_put()
+ */
+ SockReleaseWrapper(sock);
+ SOCK_OUT_UNLOCK(pvsk);
+
+ PvtcpStateRemoveSocket(pvsk->channel, pvsk);
+}
+
+
+/**
+ * @brief Processes socket create reply in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk newly created socket to send ack for.
+ */
+
+static inline void
+CreateAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk;
+ struct socket *sock;
+ CommPacket packet = {
+ .len = sizeof packet,
+ .flags = 0,
+ .opCode = PVTCP_OP_CREATE,
+ .data64 = pvsk->peerSock,
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+ int rc;
+
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /*
+ * This is a create-error socket. The error reply has been sent out
+ * already, by PvtcpFlowAIO(). This is a paranoid safety measure, as
+ * PVTCP_OP_CREATE OpFlag should not have been set.
+ */
+
+ return;
+ }
+
+ sock = sk->sk_socket;
+ packet.data64ex = PvtcpGetHandle(pvsk);
+
+ rc = CommSvc_Write(pvsk->channel, &packet, &timeout);
+ if (rc != packet.len) {
+ /* We mustn't leak it if PV can't get a hold of it. */
+
+ PvtcpStateRemoveSocket(pvsk->channel, pvsk);
+ SockReleaseWrapper(sock);
+ CommOS_Log(("%s: BOOG -- Couldn't send 'Create' reply [0x%p]!\n",
+ __FUNCTION__, sk));
+ } else {
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sent 'Create' [0x%p] reply [%d].\n",
+ __FUNCTION__, pvsk, rc));
+#endif
+ }
+}
+
+
+/**
+ * @brief Processes socket bind in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket being bound.
+ */
+
+static inline void
+BindAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ CommPacket packet = {
+ .len = sizeof packet,
+ .flags = 0,
+ .opCode = PVTCP_OP_BIND,
+ .data64 = pvsk->peerSock
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+ int rc;
+
+ if (pvsk->peerSockSet) {
+ if (sk->sk_family == AF_INET) {
+ struct sockaddr_in sin = { .sin_family = AF_INET };
+ int addrLen = sizeof sin;
+
+ rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &addrLen);
+ if (rc == 0) {
+ packet.data16 = sin.sin_port;
+ PvtcpResetLoopbackInet4(pvsk, &sin.sin_addr.s_addr);
+ packet.data64ex = (unsigned long long)sin.sin_addr.s_addr;
+ }
+ } else { /* AF_INET6 */
+ struct sockaddr_in6 sin = { .sin6_family = AF_INET6 };
+ int addrLen = sizeof sin;
+
+ rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &addrLen);
+ if (rc == 0) {
+ packet.data16 = sin.sin6_port;
+ PvtcpResetLoopbackInet6(pvsk, &sin.sin6_addr);
+ PvtcpI6AddrPack(&sin.sin6_addr.s6_addr32[0],
+ &packet.data64ex, &packet.data64ex2);
+ }
+ }
+
+ if (rc) {
+ COMM_OPF_SET_ERR(packet.flags);
+ packet.data32ex = (unsigned int)(-rc);
+ packet.opCode = PVTCP_OP_FLOW;
+ }
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sent 'Bind' [0x%p, %d] reply.\n",
+ __FUNCTION__, pvsk, rc));
+#endif
+ }
+}
+
+
+/**
+ * @brief Sends result of setsockopt back to guest.
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket that was modified.
+ */
+
+static inline void
+SetSockOptAIO(PvtcpSock *pvsk)
+{
+ CommPacket packet;
+ unsigned long long timeout;
+
+ packet.len = sizeof packet;
+ packet.flags = 0;
+ packet.opCode = PVTCP_OP_SETSOCKOPT;
+ packet.data64 = pvsk->peerSock;
+ packet.data32 = (unsigned int)(pvsk->rpcStatus);
+ timeout = COMM_MAX_TO;
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+ pvsk->rpcStatus = 0;
+}
+
+
+/**
+ * @brief Sends result of getsockopt back to guest.
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket that was modified.
+ */
+
+static inline void
+GetSockOptAIO(PvtcpSock *pvsk)
+{
+ CommPacket packet = {
+ .opCode = PVTCP_OP_GETSOCKOPT,
+ .flags = 0
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+
+ struct kvec vec[1];
+ struct kvec *inVec = vec;
+ unsigned int vecLen = 1;
+ unsigned int iovOffset = 0;
+
+ if (pvsk->rpcStatus > 0) {
+ packet.len = sizeof packet + pvsk->rpcStatus;
+ vec[0].iov_base = pvsk->rpcReply;
+ vec[0].iov_len = pvsk->rpcStatus;
+ } else {
+ vecLen = 0;
+ }
+
+ packet.data64 = pvsk->peerSock;
+ packet.data32 = pvsk->rpcStatus;
+
+ CommSvc_WriteVec(pvsk->channel, &packet, &inVec, &vecLen,
+ &timeout, &iovOffset);
+
+ if (pvsk->rpcReply) {
+ CommOS_Kfree(pvsk->rpcReply);
+ pvsk->rpcReply = NULL;
+ }
+ pvsk->rpcStatus = 0;
+}
+
+
+/**
+ * @brief Sends result of ioctl back to guest.
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket that was modified.
+ */
+
+static inline void
+IoctlAIO(PvtcpSock *pvsk)
+{
+ CommPacket packet = {
+ .len = sizeof packet,
+ .opCode = PVTCP_OP_IOCTL,
+ .flags = 0
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+
+ packet.data64 = pvsk->peerSock;
+ packet.data32 = pvsk->rpcStatus;
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+ pvsk->rpcStatus = 0;
+}
+
+
+/**
+ * @brief Processes socket listen reply in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket being put in listen mode.
+ */
+
+static inline void
+ListenAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+ CommPacket packet = {
+ .len = sizeof packet,
+ .flags = 0,
+ .opCode = PVTCP_OP_LISTEN,
+ .data64 = pvsk->peerSock
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+
+ if (pvsk->peerSockSet) {
+ if (sk->sk_state != TCP_LISTEN) {
+ COMM_OPF_SET_ERR(packet.flags);
+ packet.data32ex = (unsigned int)pvsk->err;
+ packet.opCode = PVTCP_OP_FLOW;
+ }
+
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sent 'Listen' [0x%p] reply.\n", __FUNCTION__, pvsk));
+#endif
+ }
+}
+
+
+/**
+ * @brief Processes socket accept reply in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk new socket or socket to accept on (see PvtcpAcceptOp).
+ */
+
+static inline void
+AcceptAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ CommPacket packet = {
+ .len = sizeof packet,
+ .flags = 0,
+ .opCode = PVTCP_OP_ACCEPT
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+ const int enable = 1;
+ int rc;
+
+ if (pvsk->peerSockSet) {
+ unsigned long long payloadSocks[2] = { 0, 0 };
+ struct kvec payloadVec[] = {
+ { .iov_base = &payloadSocks, .iov_len = sizeof payloadSocks }
+ };
+ struct kvec *payload = payloadVec;
+ unsigned int payloadLen = 1;
+ unsigned int iovOffset = 0;
+
+ packet.len = sizeof packet + sizeof payloadSocks;
+
+ /*
+ * accept() succeeded, so this is the child socket; its state field
+ * was temporarily changed to hold the parent/accepting socket.
+ * The newly accepted socket and its peer need to be put in a
+ * payload since we use up all available header fields with
+ * addressing information. Finally, the state field is restored.
+ */
+
+ packet.data64 = ((PvtcpSock *)pvsk->state)->peerSock;
+ pvsk->state = CommSvc_GetState(pvsk->channel);
+
+ payloadSocks[0] = pvsk->peerSock;
+ payloadSocks[1] = PvtcpGetHandle(pvsk);
+
+ rc = 0;
+ if (sk->sk_family == AF_INET) {
+ struct sockaddr_in sin = { .sin_family = AF_INET };
+ int addrLen = sizeof sin;
+
+ rc = kernel_getpeername(sock, (struct sockaddr *)&sin, &addrLen);
+ if (rc == 0) {
+ packet.data16 = sin.sin_port;
+ PvtcpResetLoopbackInet4(pvsk, &sin.sin_addr.s_addr);
+ packet.data64ex = (unsigned long long)sin.sin_addr.s_addr;
+ }
+ } else { /* AF_INET6 */
+ struct sockaddr_in6 sin = { .sin6_family = AF_INET6 };
+ int addrLen = sizeof sin;
+
+ rc = kernel_getpeername(sock, (struct sockaddr *)&sin, &addrLen);
+ if (rc == 0) {
+ packet.data16 = sin.sin6_port;
+ PvtcpResetLoopbackInet6(pvsk, &sin.sin6_addr);
+ PvtcpI6AddrPack(&sin.sin6_addr.s6_addr32[0],
+ &packet.data64ex, &packet.data64ex2);
+ }
+ }
+
+ if (rc == 0) {
+ kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
+ (void *)&enable, sizeof enable);
+ kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ (void *)&enable, sizeof enable);
+ kernel_setsockopt(sock, SOL_SOCKET, SO_OOBINLINE,
+ (void *)&enable, sizeof enable);
+ } else {
+ PvtcpStateRemoveSocket(pvsk->channel, pvsk);
+ SockReleaseWrapper(sock);
+ COMM_OPF_SET_ERR(packet.flags);
+ packet.data32ex = (unsigned int)ECONNABORTED;
+ packet.len = sizeof packet;
+ packet.opCode = PVTCP_OP_FLOW;
+ }
+
+ rc = CommSvc_WriteVec(pvsk->channel, &packet,
+ &payload, &payloadLen, &timeout, &iovOffset);
+ if ((rc != packet.len) && !COMM_OPF_TEST_ERR(packet.flags)) {
+ /* Mustn't leak the new socket if PV can't get a hold of it. */
+
+ PvtcpStateRemoveSocket(pvsk->channel, pvsk);
+ SockReleaseWrapper(sock);
+ }
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sent 'Accept' [0x%p] reply.\n", __FUNCTION__, pvsk));
+#endif
+ }
+}
+
+
+/**
+ * @brief Processes socket connect in an AIO thread. This function is
+ * called with the socket 'in' lock taken.
+ * @param[in,out] pvsk socket being connected.
+ */
+
+static inline void
+ConnectAIO(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+ struct socket *sock = sk->sk_socket;
+ CommPacket packet = {
+ .len = sizeof packet,
+ .flags = 0,
+ .opCode = PVTCP_OP_CONNECT,
+ .data64 = pvsk->peerSock
+ };
+ unsigned long long timeout = COMM_MAX_TO;
+ const int enable = 1;
+ int rc;
+
+ if (!pvsk->peerSockSet ||
+ (!PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_DISCONNECT) &&
+ (sk->sk_state != TCP_ESTABLISHED))) {
+ return;
+ }
+
+ if (PvskTestFlag(pvsk, PVTCP_OFF_PVSKF_DISCONNECT)) {
+ COMM_OPF_SET_VAL(packet.flags, 1);
+ PvskSetFlag(pvsk, PVTCP_OFF_PVSKF_DISCONNECT, 0);
+ } else if (sk->sk_state == TCP_ESTABLISHED) {
+ if (sk->sk_family == AF_INET) {
+ struct sockaddr_in sin = { .sin_family = AF_INET };
+ int addrLen = sizeof sin;
+
+ rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &addrLen);
+ if (rc == 0) {
+ packet.data16 = sin.sin_port;
+ PvtcpResetLoopbackInet4(pvsk, &sin.sin_addr.s_addr);
+ packet.data64ex = (unsigned long long)sin.sin_addr.s_addr;
+ }
+ } else { /* AF_INET6 */
+ struct sockaddr_in6 sin = { .sin6_family = AF_INET6 };
+ int addrLen = sizeof sin;
+
+ rc = kernel_getsockname(sock, (struct sockaddr *)&sin, &addrLen);
+ if (rc == 0) {
+ packet.data16 = sin.sin6_port;
+ PvtcpResetLoopbackInet6(pvsk, &sin.sin6_addr);
+ PvtcpI6AddrPack(&sin.sin6_addr.s6_addr32[0],
+ &packet.data64ex, &packet.data64ex2);
+ }
+ }
+
+ if (rc == 0) {
+ kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
+ (void *)&enable, sizeof enable);
+ kernel_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ (void *)&enable, sizeof enable);
+ kernel_setsockopt(sock, SOL_SOCKET, SO_OOBINLINE,
+ (void *)&enable, sizeof enable);
+ } else {
+ COMM_OPF_SET_ERR(packet.flags);
+ packet.data32ex = ECONNABORTED;
+ packet.opCode = PVTCP_OP_FLOW;
+ }
+ }
+
+ CommSvc_Write(pvsk->channel, &packet, &timeout);
+#if defined(PVTCP_FULL_DEBUG)
+ CommOS_Debug(("%s: Sent 'Connect' [0x%p] reply.\n", __FUNCTION__, pvsk));
+#endif
+}
+
+
+/**
+ * @brief Server side main asynchronous processing function. It writes to
+ * socket queued output buffers, it reads from socket and outputs to PV; it
+ * also completes operation processing and sends applicable replies to PV.
+ * Finally, processes error reporting and delta size acks.
+ * @param arg socket work item.
+ */
+
+void
+PvtcpProcessAIO(CommOSWork *arg)
+{
+ PvtcpSock *pvsk = container_of(arg, PvtcpSock, work);
+ struct sock *sk = SkFromPvsk(pvsk);
+
+ if (!SOCK_OUT_TRYLOCK(pvsk)) {
+ /*
+ * Queued output processing. If trylock failed, we don't retry.
+ * There are only two reasons for not being able to take the lock:
+ * - IoOp() has it -- when done, it reschedules us if we're not running.
+ * - OutputAIO() is already running on another core.
+ */
+
+ if (sk && sk->sk_socket) {
+ PvtcpOutputAIO(pvsk);
+ }
+ SOCK_OUT_UNLOCK(pvsk);
+ }
+
+ /* All other processing needs the socket IN lock. */
+
+ if (!SOCK_IN_TRYLOCK(pvsk)) {
+
+ if (sk && sk->sk_socket) {
+ int err;
+
+ /* Input processing. */
+
+ /*
+ * Workqueue handlers are pinned to a CPU core and therefore not
+ * migratable. No need to disable preemption.
+ */
+ err = PvtcpInputAIO(pvsk, perCpuBuf[smp_processor_id()]);
+
+ /* Error and ack notifications. */
+
+ PvtcpFlowAIO(pvsk, err);
+
+ if (!pvsk->opFlags) {
+ /* No other operations need to be completed. */
+
+ goto doneInUnlock;
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_RELEASE)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_RELEASE);
+ ReleaseAIO(pvsk);
+
+ /* All possible in-flight operations must be dropped. */
+ goto doneInUnlock;
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_CREATE)) {
+ /* No state locking required. */
+
+ PvskResetOpFlag(pvsk, PVTCP_OP_CREATE);
+ CreateAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_BIND)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_BIND);
+ BindAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_SETSOCKOPT)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_SETSOCKOPT);
+ SetSockOptAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_GETSOCKOPT)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_GETSOCKOPT);
+ GetSockOptAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_IOCTL)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_IOCTL);
+ IoctlAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_LISTEN)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_LISTEN);
+ ListenAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_ACCEPT)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_ACCEPT);
+ AcceptAIO(pvsk);
+ }
+
+ if (PvskTestOpFlag(pvsk, PVTCP_OP_CONNECT)) {
+ PvskResetOpFlag(pvsk, PVTCP_OP_CONNECT);
+ ConnectAIO(pvsk);
+ }
+
+doneInUnlock:
+ SOCK_IN_UNLOCK(pvsk);
+ } else {
+ /*
+ * Special case for error sockets which don't have a sk.
+ * Note that this socket was created by SockAllocErrInit() and so
+ * no 'real' socket sits atop it and is not present on any state
+ * netif list. The socket has a refcnt of one and it will get
+ * deallocated by the PvtcpPutSock() call below, so we don't need
+ * to unlock it.
+ */
+
+ PvtcpFlowAIO(pvsk, -ENETDOWN);
+ }
+ } else {
+ if ((pvsk->peerSockSet || PvskTestOpFlag(pvsk, PVTCP_OP_RELEASE)) &&
+ sk && sk->sk_socket) {
+ PvtcpSchedSock(pvsk);
+ }
+ }
+
+ PvtcpPutSock(pvsk);
+}
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h
new file mode 100644
index 0000000..34992da
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux.h
@@ -0,0 +1,226 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief Linux Offload definitions.
+ * This file is only meant to be included via pvtcp_off.h.
+ */
+
+#ifndef _PVTCP_OFF_LINUX_H_
+#define _PVTCP_OFF_LINUX_H_
+
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/tcp.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/skbuff.h>
+#include <linux/random.h>
+#include <linux/fs.h>
+#include <linux/cred.h>
+
+
+typedef struct PvtcpSock {
+ struct sock *sk;
+ PVTCP_SOCK_COMMON_FIELDS;
+ PVTCP_OFF_SOCK_COMMON_FIELDS;
+ void (*destruct)(struct sock *sk);
+ void (*stateChange)(struct sock *sk);
+ void (*dataReady)(struct sock *sk, int bytes);
+ void (*writeSpace)(struct sock *sk);
+ void (*errorReport)(struct sock *sk);
+} PvtcpSock;
+
+
+typedef enum PvtcpSockNamespace {
+ PVTCP_SOCK_NAMESPACE_INITIAL,
+ PVTCP_SOCK_NAMESPACE_CHANNEL
+} PvtcpSockNamespace;
+
+
+/* Number of large datagram allocations. */
+extern unsigned long long pvtcpOffDgramAllocations;
+
+/* Inet4 loopback addresses. */
+extern unsigned int pvtcpLoopbackOffAddr;
+
+/* Get the 'struct sock' from a PvtcpSock. */
+#define SkFromPvsk(pvsk) ((pvsk)->sk)
+
+/* Get the PvtcpSock from a 'struct sock'. */
+#define PvskFromSk(sk) ((PvtcpSock *)(sk)->sk_user_data)
+
+int
+PvtcpTestAndBindLoopbackInet4(PvtcpSock *pvsk,
+ unsigned int *addr,
+ unsigned short port);
+int
+PvtcpTestAndBindLoopbackInet6(PvtcpSock *pvsk,
+ unsigned long long *addr0,
+ unsigned long long *addr1,
+ unsigned short port);
+
+void PvtcpResetLoopbackInet4(PvtcpSock *pvsk, unsigned int *addr);
+void PvtcpResetLoopbackInet6(PvtcpSock *pvsk, struct in6_addr *in6);
+
+void PvtcpFlowAIO(PvtcpSock *pvsk, int eof);
+void PvtcpOutputAIO(PvtcpSock *pvsk);
+int PvtcpInputAIO(PvtcpSock *pvsk, void *perCpuBuf);
+
+
+/**
+ * @brief Switches a socket to the channel, or the initial name space.
+ * @param pvsk socket to switch.
+ * @param ns which namespace to switch to.
+ */
+
+static inline void
+PvtcpSwitchSock(PvtcpSock *pvsk,
+ PvtcpSockNamespace ns)
+{
+#if defined(CONFIG_NET_NS) && !defined(PVTCP_NET_NS_DISABLE)
+ struct sock *sk;
+ struct net *prevNet;
+
+ if (!pvsk) {
+ return;
+ }
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /* If this is a phony, create fail reporting pvsk, just return. */
+
+ return;
+ }
+
+ prevNet = sock_net(sk);
+ switch (ns) {
+ case PVTCP_SOCK_NAMESPACE_INITIAL:
+ sock_net_set(sk, get_net(&init_net));
+ break;
+ case PVTCP_SOCK_NAMESPACE_CHANNEL:
+ sock_net_set(sk, get_net(pvsk->state->namespace));
+ break;
+ }
+ put_net(prevNet);
+#endif
+}
+
+
+/**
+ * @brief Tests whether a socket has an explicit namespace.
+ * @param pvsk socket to test.
+ * @return 1 if the socket has a namespace, 0 otherwise.
+ */
+
+static inline int
+PvtcpHasSockNamespace(PvtcpSock *pvsk)
+{
+#if defined(CONFIG_NET_NS) && !defined(PVTCP_NET_NS_DISABLE)
+ struct sock *sk;
+ int rc = 0;
+
+ if (!pvsk) {
+ return rc;
+ }
+ sk = SkFromPvsk(pvsk);
+ if (!sk) {
+ /* If this is a phony, create fail reporting pvsk, just return 0. */
+
+ return rc;
+ }
+
+ rc = (sock_net(sk) != &init_net);
+ return rc;
+#else
+ return 0;
+#endif
+}
+
+
+/**
+ * @brief Retains the pvsock's underlying socket.
+ * @param pvsk socket to retain.
+ */
+
+static inline void
+PvtcpHoldSock(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+
+ if (likely(sk)) {
+ sock_hold(sk);
+ }
+}
+
+
+/**
+ * @brief Releases a hold on the pvsock's underlying socket. If the underlying
+ * socket is NULL, this is an error socket and we deallocate it.
+ * @param pvsk socket to release hold on.
+ */
+
+static inline void
+PvtcpPutSock(PvtcpSock *pvsk)
+{
+ struct sock *sk = SkFromPvsk(pvsk);
+
+ if (likely(sk)) {
+ sock_put(sk);
+ } else {
+ /*
+ * This is an error socket, which does _not_ have an underlying socket.
+ * We simply need to free it.
+ */
+
+ CommOS_Kfree(pvsk);
+ }
+}
+
+
+/**
+ * @brief Schedules an offload socket for AIO.
+ * @param pvsk socket to schedule.
+ * @sideeffect the socket will be processed by AIO threads.
+ */
+
+static inline void
+PvtcpSchedSock(PvtcpSock *pvsk)
+{
+ /*
+ * We must hold the socket before we enqueue it for AIO, such that it may
+ * not be released while in the workqueue. If CommSvc_ScheduleAIOWork()
+ * returned non-zero, it means the socket had already been enqueued. In
+ * that case, we release the hold. Otherwise, the hold is released by the
+ * AIO function (PvtcpProcessAIO()).
+ * Note that error pv sockets may only originate from synchronized RPCs,
+ * or to be more precise, from PvtcpCreateOp(), and not from IO processing;
+ * this means that they cannot be attempted to be enqueued more than once.
+ */
+
+ PvtcpHoldSock(pvsk);
+ if (CommSvc_ScheduleAIOWork(&pvsk->work)) {
+ PvtcpPutSock(pvsk);
+ }
+}
+
+#endif // _PVTCP_OFF_LINUX_H_
diff --git a/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S
new file mode 100644
index 0000000..824286b
--- /dev/null
+++ b/arch/arm/mvp/pvtcpkm/pvtcp_off_linux_shim.S
@@ -0,0 +1,70 @@
+/*
+ * Linux 2.6.32 and later Kernel module for VMware MVP PVTCP Server
+ *
+ * Copyright (C) 2010-2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#line 5
+
+/**
+ * @file
+ *
+ * @brief PVTCP socket destructor shim.
+ *
+ * The module reference accounting code for socket destruction in the core
+ * Linux kernel does not know about PVTCP sockets, so it does not properly
+ * increment/decrement the reference count on pvtcpkm when calling through a
+ * function pointer into our destructor. If a module unload is requested on
+ * pvtcpkm while a socket is being destroyed, it is possible for the destructor
+ * to be preempted after decrementing the module reference count but before
+ * returning to the core kernel. If the module code is unmapped before the
+ * function return, it is possible that we will attempt to execute unmapped
+ * code, resulting in a host crash.
+ *
+ * This shim proxies socket destruction requests through to the PVTCP socket
+ * destructor, then jumps directly to module_put to drop the reference count.
+ * module_put will return directly to the caller, eliminating the race.
+ */
+
+.text
+.p2align 4
+
+.global asmDestructorShim
+
+/**
+ * @brief Socket destructor callback. Calls into pvtcpkm to destroy a socket
+ * and then decrements the refcount.
+ * @param r0 pointer to struct sock
+ */
+
+asmDestructorShim:
+ push {lr}
+ ldr r1, targetAddr @ Destroy socket
+ blx r1
+ pop {lr}
+ cmp r0, #0
+ bxne lr @ We shouldn't module_put, just return.
+ ldr r0, owner
+ ldr r1, modulePutAddr @ Jump to module_put. module_put
+ bx r1 @ returns directly to caller
+
+owner:
+ .word __this_module
+
+targetAddr:
+ .word DestructCB
+
+modulePutAddr:
+ .word module_put
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index c074e66..4e0a371 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -116,7 +116,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
return oprofile_perf_init(ops);
}
-void __exit oprofile_arch_exit(void)
+void oprofile_arch_exit(void)
{
oprofile_perf_exit();
}
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 4a10c0f..3c46ff3 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -230,19 +230,18 @@ static void s3c24xx_pm_restart(char mode, const char *cmd)
void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
{
- unsigned long idcode = 0x0;
-
/* initialise the io descriptors we need for initialisation */
iotable_init(mach_desc, size);
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
if (cpu_architecture() >= CPU_ARCH_ARMv5) {
- idcode = s3c24xx_read_idcode_v5();
+ samsung_cpu_id = s3c24xx_read_idcode_v5();
} else {
- idcode = s3c24xx_read_idcode_v4();
+ samsung_cpu_id = s3c24xx_read_idcode_v4();
}
+ s3c24xx_init_cpu();
arm_pm_restart = s3c24xx_pm_restart;
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 7366799..a76bf2d 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -150,9 +150,8 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
struct s3c2410fb_mach_info *npd;
- npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL);
+ npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_lcd);
if (npd) {
- s3c_device_lcd.dev.platform_data = npd;
npd->displays = kmemdup(pd->displays,
sizeof(struct s3c2410fb_display) * npd->num_displays,
GFP_KERNEL);
@@ -188,12 +187,10 @@ struct platform_device s3c_device_ts = {
};
EXPORT_SYMBOL(s3c_device_ts);
-static struct s3c2410_ts_mach_info s3c2410ts_info;
-
void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
{
- memcpy(&s3c2410ts_info, hard_s3c2410ts_info, sizeof(struct s3c2410_ts_mach_info));
- s3c_device_ts.dev.platform_data = &s3c2410ts_info;
+ s3c_set_platdata(hard_s3c2410ts_info,
+ sizeof(struct s3c2410_ts_mach_info), &s3c_device_ts);
}
/* USB Device (Gadget)*/
@@ -223,15 +220,7 @@ EXPORT_SYMBOL(s3c_device_usbgadget);
void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
{
- struct s3c2410_udc_mach_info *npd;
-
- npd = kmalloc(sizeof(*npd), GFP_KERNEL);
- if (npd) {
- memcpy(npd, pd, sizeof(*npd));
- s3c_device_usbgadget.dev.platform_data = npd;
- } else {
- printk(KERN_ERR "no memory for udc platform data\n");
- }
+ s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usbgadget);
}
/* USB High Speed 2.0 Device (Gadget) */
@@ -263,15 +252,7 @@ struct platform_device s3c_device_usb_hsudc = {
void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
{
- struct s3c24xx_hsudc_platdata *npd;
-
- npd = kmalloc(sizeof(*npd), GFP_KERNEL);
- if (npd) {
- memcpy(npd, pd, sizeof(*npd));
- s3c_device_usb_hsudc.dev.platform_data = npd;
- } else {
- printk(KERN_ERR "no memory for udc platform data\n");
- }
+ s3c_set_platdata(pd, sizeof(*pd), &s3c_device_usb_hsudc);
}
/* IIS */
@@ -383,13 +364,8 @@ EXPORT_SYMBOL(s3c_device_sdi);
void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
{
- struct s3c24xx_mci_pdata *npd;
-
- npd = kmemdup(pdata, sizeof(struct s3c24xx_mci_pdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory to copy pdata", __func__);
-
- s3c_device_sdi.dev.platform_data = npd;
+ s3c_set_platdata(pdata, sizeof(struct s3c24xx_mci_pdata),
+ &s3c_device_sdi);
}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index e98f5c5..3398d3b 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -7,10 +7,10 @@
config PLAT_S5P
bool
- depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
default y
- select ARM_VIC if !ARCH_EXYNOS4
- select ARM_GIC if ARCH_EXYNOS4
+ select ARM_VIC if !ARCH_EXYNOS
+ select ARM_GIC if ARCH_EXYNOS
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
select S3C_GPIO_TRACK
@@ -39,58 +39,239 @@ config S5P_GPIO_INT
config S5P_HRT
bool
+ select SAMSUNG_DEV_PWM
help
Use the High Resolution timer support
-comment "System MMU"
-
config S5P_SYSTEM_MMU
- bool "S5P SYSTEM MMU"
+ bool "System MMU for Exynos families"
depends on ARCH_EXYNOS4
+ select IOMMU_EXYNOS4_API
+ select IOVMM
help
Say Y here if you want to enable System MMU
+config S5P_SYSTEM_MMU_REFCOUNT
+ bool "Counting System MMU activations"
+ depends on S5P_SYSTEM_MMU
+ help
+ Say Y here if you want to enable counting System MMU enabling and
+ disabling.
+
+config S5P_SYSTEM_MMU_DEBUG
+ bool "Enables verbose debugging message about System MMU"
+ depends on S5P_SYSTEM_MMU
+ help
+ Say Y here if you need detailed message while System MMU driver works
+
+config S5P_SYSTEM_MMU_WA5250ERR
+ bool "Ensure 64KB-aligned mapping for DMA I/O buffers"
+ depends on S5P_SYSTEM_MMU && CPU_EXYNOS5250
+ default y
+ help
+ Select this to avoid unexpected fault occurred by System MMU v3.0.
+ This is just a makeshift option for those problems.
+
+ If unsure, n here.
+
+config IOVMM
+ bool
+ select GENERIC_ALLOCATOR
+
+config IOMMU_EXYNOS4_API
+ bool
+
+config S3C_DEV_FIMC
+ bool
+ depends on VIDEO_FIMC
+ default y
+ help
+ Compile in platform device definitions for FIMC
+
config S5P_DEV_FIMC0
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 0
config S5P_DEV_FIMC1
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 1
config S5P_DEV_FIMC2
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 2
config S5P_DEV_FIMC3
bool
+ depends on VIDEO_SAMSUNG_S5P_FIMC
+ default y
help
Compile in platform device definitions for FIMC controller 3
+config S5P_DEV_I2C_HDMIPHY
+ bool
+ help
+ Compile in platform device definitions for I2C HDMIPHY controller
+
+config S5P_DEV_TV
+ bool
+ help
+ Compile in platform device definition for TV interface
+
+config S5P_DEV_MFC
+ bool
+ help
+ Compile in platform device definitions for MFC
+
+config S5P_DEV_FIMD0
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 0
+
+config S5P_DEV_FIMD1
+ bool
+ help
+ Compile in platform device definitions for FIMD controller 1
+
+config S5P_DEV_DP
+ bool
+ help
+ Compile in platform device definitions for DP controller
+
+config S5P_DEV_TVOUT
+ bool
+ depends on VIDEO_TVOUT
+ default y
+ help
+ Compile in platform device definitions for TVOUT
+
+config S5P_DEV_FIMG2D
+ bool
+ help
+ Compile in platform device definitions for FIMG2D controller
+
+config S5P_DEV_ROTATOR
+ bool
+ help
+ Compile in platform device definitions for ROTATOR
+
config S5P_DEV_ONENAND
bool
help
Compile in platform device definition for OneNAND controller
+config S5P_DEV_CSIS
+ bool
+ depends on VIDEO_FIMC_MIPI
+ default y
+ help
+ Compile in platform device definitions for MIPI-CSIS
+
config S5P_DEV_CSIS0
bool
+ depends on (VIDEO_S5P_MIPI_CSIS || VIDEO_EXYNOS_MIPI_CSIS)
+ default y
help
Compile in platform device definitions for MIPI-CSIS channel 0
config S5P_DEV_CSIS1
bool
+ depends on (VIDEO_S5P_MIPI_CSIS || VIDEO_EXYNOS_MIPI_CSIS)
+ default y
help
Compile in platform device definitions for MIPI-CSIS channel 1
+config S5P_DEV_JPEG
+ bool
+ depends on VIDEO_JPEG || VIDEO_JPEG_V2X
+ default y
+ help
+ Compile in platform device definitions for JPEG
+
config S5P_DEV_USB_EHCI
bool
help
Compile in platform device definition for USB EHCI
+config S5P_DEV_FIMD_S5P
+ bool
+ help
+ Compile in platform device definitions for FIMD controller
+
+config S5P_DEV_USBGADGET
+ bool
+ help
+ compile in platform device definitions for USB-GADGET
+
+config S5P_DEV_USB_SWITCH
+ bool
+ help
+ compile in platform device definitions for USB-SWITCH
+
config S5P_SETUP_MIPIPHY
bool
+ depends on (VIDEO_S5P_MIPI_CSIS || S5P_MIPI_DSI2 || VIDEO_EXYNOS_MIPI_CSIS)
+ default y
help
Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+
+config S5P_MEM_CMA
+ bool "Fixed memory through CMA"
+ select CMA
+ help
+ Use CMA(Contiguous memory allocator) to reserve machine specific memory.
+
+config S5P_DEV_THERMAL
+ bool
+ help
+ Compile in platform device definitions for THERMAL management unit.
+
+config S5P_DEV_ACE
+ bool
+ help
+ Compile in common setup code for Crypto Engine devices.
+
+config S5P_DEV_MIPI_DSI
+ bool
+ depends on FB_S5P_MIPI_DSIM
+ default y
+ help
+ Compile in platform device definitions for MIPI_DSI
+
+config S5P_DEV_DSIM02
+ bool
+ help
+ Compile in platform device definitions for MIPI-DSIM channel 0
+
+config S5P_DEV_DSIM12
+ bool
+ help
+ Compile in platform device definitions for MIPI-DSIM channel 1
+
+config S5P_BTS
+ bool "S5P BTS driver"
+ default n
+ help
+ Use Bus Traffic Shaper Driver
+
+config S5P_DEV_MIPI_DSIM
+ bool
+ depends on FB_MIPI_DSIM
+ default y
+ help
+ Compile in platform device definitions for MIPI_DSIM
+ to support mainlile style fimd
+
+config S3C_DEV_TSI
+ boolean "DEV TSI"
+ default n
+ ---help---
+ Compile in platform device definitions for S3C_DEV_TSI controller
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..282efc6 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -17,21 +17,51 @@ obj-y += dev-uart.o
obj-y += cpu.o
obj-y += clock.o
obj-y += irq.o
+obj-y += reset.o
+obj-y += reserve_mem.o
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
-obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
+obj-$(CONFIG_S5P_SYSTEM_MMU) += s5p-sysmmu.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += irq-pm.o
obj-$(CONFIG_S5P_HRT) += s5p-time.o
+obj-$(CONFIG_S5P_BTS) += bts.o
# devices
+obj-$(CONFIG_S3C_DEV_FIMC) += dev-fimc-s5p.o
obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o
+obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
+obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o
+obj-$(CONFIG_S5P_DEV_FIMD1) += dev-fimd1.o
+obj-$(CONFIG_S5P_DEV_I2C_HDMIPHY) += dev-i2c-hdmiphy.o
+obj-$(CONFIG_S5P_DEV_DP) += dev-dp.o
+obj-$(CONFIG_S5P_DEV_FIMD_S5P) += dev-fimd-s5p.o
+obj-$(CONFIG_S5P_DEV_TVOUT) += dev-tvout.o
+obj-$(CONFIG_S5P_DEV_TV) += dev-tv.o
+obj-$(CONFIG_S5P_DEV_FIMG2D) += dev-fimg2d.o
+obj-$(CONFIG_S5P_DEV_ROTATOR) += dev-rotator.o
obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
+obj-$(CONFIG_S5P_DEV_CSIS) += dev-csis-s5p.o
+obj-$(CONFIG_S5P_DEV_JPEG) += dev-jpeg.o
obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
+obj-$(CONFIG_S5P_DEV_USB_SWITCH) += dev-usb-switch.o
+obj-$(CONFIG_S5P_DEV_USBGADGET) += dev-usbgadget.o
+obj-$(CONFIG_S5P_DEV_MIPI_DSI) += dev-dsim.o
+obj-$(CONFIG_S5P_DEV_DSIM02) += dev-dsim02.o
+obj-$(CONFIG_S5P_DEV_DSIM12) += dev-dsim12.o
+obj-$(CONFIG_S5P_DEV_MIPI_DSIM) += dev-mipidsim.o
obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
+obj-$(CONFIG_EXYNOS4_SETUP_THERMAL) += dev-tmu.o
+obj-$(CONFIG_S5P_DEV_ACE) += dev-ace.o
+ifeq ($(CONFIG_ARCH_EXYNOS4), y)
+obj-$(CONFIG_IOMMU_EXYNOS4_API) += s5p_iommu.o
+obj-$(CONFIG_IOVMM) += s5p_iovmm.o
+endif
+obj-$(CONFIG_S5P_DEV_I2C_HDMIPHY) += dev-i2c-hdmiphy.o
+obj-$(CONFIG_S3C_DEV_TSI) += dev-tsi.o
diff --git a/arch/arm/plat-s5p/bts.c b/arch/arm/plat-s5p/bts.c
new file mode 100644
index 0000000..c0dba21
--- /dev/null
+++ b/arch/arm/plat-s5p/bts.c
@@ -0,0 +1,393 @@
+/* linux/arch/arm/plat-s5p/bts.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+#include <linux/pm_runtime.h>
+#include <plat/pd.h>
+#endif
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/bts.h>
+#include <mach/map.h>
+
+/* BTS register */
+#define BTS_CONTROL 0x0
+#define BTS_SHAPING_ON_OFF_REG0 0x4
+#define BTS_MASTER_PRIORITY 0x8
+#define BTS_SHAPING_ON_OFF_REG2 0xc
+#define BTS_SHAPING_ON_OFF_REG1 0x44
+#define BTS_DEBLOCKING_SOURCE_SELECTION 0x50
+
+/* FBM register */
+#define FBM_MODESEL0 0x0
+#define FBM_THRESHOLDSEL0 0x40
+
+/* BTS priority values */
+#define BTS_PRIOR_HARDTIME 15
+#define BTS_PRIOR_BESTEFFORT 8
+
+/* Fields of BTS_CONTROL register */
+#define BTS_ON_OFF (1<<0)
+#define BLOCKING_ON_OFF (1<<2)
+#define FLEXIBLE_ON_OFF (1<<7)
+
+/* Fields of FLEXIBLE_BLOCKING_CONTROL register */
+#define SEL_GRP0 (1<<0)
+#define SEL_LEFT0 (1<<4)
+#define SEL_RIGHT0 (1<<5)
+#define SEL_GRP1 (1<<8)
+#define SEL_LEFT1 (1<<12)
+#define SEL_RIGHT1 (1<<13)
+#define SEL_GRP2 (1<<16)
+#define SEL_LEFT2 (1<<20)
+#define SEL_RIGHT2 (1<<21)
+
+/* Fields of FBM MODESEL0 register */
+#define RD_COUNTER 0
+#define WT_COUNTER 1
+#define RDWT_COUNTER 2
+
+/* Values of FBM THRESHOLDSEL0 register */
+#define FBM_THR_HARDTIME 0x3
+#define FBM_THR_BE 0x4
+
+/* Shaping Value for Low priority */
+#define LOW_SHAPING_VAL0 0x100010
+#define LOW_SHAPING_VAL1 0x3ff
+#define LOW_SHAPING_VAL2_BE 0x200
+#define LOW_SHAPING_VAL2_HARDTIME 0x3
+#define MASTER_PRIOR_BE_NUMBER (1<<16)
+#define MASTER_PRIOR_HARDTIME_NUMBER (3<<16)
+
+static LIST_HEAD(fbm_list);
+static LIST_HEAD(bts_list);
+
+struct exynos_bts_local_data {
+ enum exynos_bts_id id;
+ void __iomem *base;
+ enum bts_priority def_priority;
+};
+
+struct exynos_bts_data {
+ struct list_head node;
+ struct device *dev;
+ struct exynos_bts_local_data *bts_local_data;
+ struct clk *clk;
+ enum exynos_pd_block pd_block;
+ u32 listnum;
+};
+
+struct exynos_fbm_data {
+ struct exynos_fbm_resource fbm;
+ struct list_head node;
+};
+
+static void bts_set_control(void __iomem *base, enum bts_priority prior)
+{
+ u32 val = BTS_ON_OFF;
+
+ if (prior == BTS_BE)
+ val |= BLOCKING_ON_OFF|FLEXIBLE_ON_OFF;
+
+ writel(val, base + BTS_CONTROL);
+}
+
+static void bts_set_master_priority(void __iomem *base,
+ enum bts_priority prior)
+{
+ u32 val = 0;
+ int priority = BTS_PRIOR_BESTEFFORT;
+
+ if (prior == BTS_BE) {
+ val = MASTER_PRIOR_BE_NUMBER;
+ } else if (prior == BTS_HARDTIME) {
+ val = MASTER_PRIOR_HARDTIME_NUMBER;
+ priority = BTS_PRIOR_HARDTIME;
+ }
+
+ val |= (priority<<8) | (priority<<4) | (priority);
+ writel(val, base + BTS_MASTER_PRIORITY);
+}
+
+static void bts_set_besteffort_shaping(void __iomem *base,
+ enum bts_priority prior)
+{
+ if (prior == BTS_BE) {
+ writel(LOW_SHAPING_VAL0, base + BTS_SHAPING_ON_OFF_REG0);
+ writel(LOW_SHAPING_VAL1, base + BTS_SHAPING_ON_OFF_REG1);
+ writel(LOW_SHAPING_VAL2_BE, base + BTS_SHAPING_ON_OFF_REG2);
+ } else if (prior == BTS_HARDTIME) {
+ writel(LOW_SHAPING_VAL2_HARDTIME,
+ base + BTS_SHAPING_ON_OFF_REG2);
+ }
+}
+
+static void bts_set_deblocking(void __iomem *base,
+ enum bts_fbm_group deblocking)
+{
+ u32 val = 0;
+
+ if (deblocking & BTS_FBM_G0_L)
+ val |= SEL_GRP0 | SEL_LEFT0;
+ if (deblocking & BTS_FBM_G0_R)
+ val |= SEL_GRP0 | SEL_RIGHT0;
+ if (deblocking & BTS_FBM_G1_L)
+ val |= SEL_GRP1 | SEL_LEFT1;
+ if (deblocking & BTS_FBM_G1_R)
+ val |= SEL_GRP1 | SEL_RIGHT1;
+ if (deblocking & BTS_FBM_G2_L)
+ val |= SEL_GRP2 | SEL_LEFT2;
+ if (deblocking & BTS_FBM_G2_R)
+ val |= SEL_GRP2 | SEL_RIGHT2;
+
+ writel(val, base + BTS_DEBLOCKING_SOURCE_SELECTION);
+}
+
+static enum bts_fbm_group find_fbm_group(enum bts_priority prior)
+{
+ struct exynos_fbm_data *fbm_data;
+ enum bts_fbm_group fbm_group = 0;
+
+ list_for_each_entry(fbm_data, &fbm_list, node) {
+ if (prior == BTS_BE) {
+ if (fbm_data->fbm.priority == BTS_HARDTIME)
+ fbm_group |= fbm_data->fbm.fbm_group;
+ } else if (prior == BTS_HARDTIME) {
+ if ((fbm_data->fbm.priority == BTS_BE) ||
+ (fbm_data->fbm.priority == BTS_HARDTIME))
+ fbm_group |= fbm_data->fbm.fbm_group;
+ }
+ }
+
+ return fbm_group;
+}
+
+static void fbm_init_config(void __iomem *base, enum bts_priority prior)
+{
+ if (prior == BTS_BE) {
+ writel(RD_COUNTER, base + FBM_MODESEL0);
+ writel(FBM_THR_BE, base + FBM_THRESHOLDSEL0);
+ } else if (prior == BTS_HARDTIME) {
+ writel(RDWT_COUNTER, base + FBM_MODESEL0);
+ writel(FBM_THR_HARDTIME, base + FBM_THRESHOLDSEL0);
+ }
+}
+
+static void bts_init_config(void __iomem *base, enum bts_priority prior)
+{
+ if (prior == BTS_BE) {
+ bts_set_besteffort_shaping(base, prior);
+ bts_set_deblocking(base, find_fbm_group(prior));
+ bts_set_master_priority(base, prior);
+ bts_set_control(base, prior);
+ } else if (prior == BTS_HARDTIME) {
+ bts_set_besteffort_shaping(base, prior);
+ bts_set_master_priority(base, prior);
+ bts_set_control(base, prior);
+ }
+}
+
+static void __exynos_bts_enable(struct exynos_bts_data *bts_data)
+{
+ struct exynos_bts_local_data *bts_local_data;
+ int i;
+
+ if (bts_data->clk)
+ clk_enable(bts_data->clk);
+
+ bts_local_data = bts_data->bts_local_data;
+ for (i = 0; i < bts_data->listnum; i++) {
+ bts_init_config(bts_local_data->base,
+ bts_local_data->def_priority);
+ bts_local_data++;
+ }
+
+ if (bts_data->clk)
+ clk_disable(bts_data->clk);
+}
+
+void exynos_bts_set_priority(enum bts_priority prior)
+{
+ struct exynos_bts_data *bts_data;
+ struct exynos_bts_local_data *bts_local_data;
+ int i;
+
+ list_for_each_entry(bts_data, &bts_list, node) {
+ bts_local_data = bts_data->bts_local_data;
+ for (i = 0; i < bts_data->listnum; i++) {
+ bts_local_data = bts_data->bts_local_data;
+ if ((bts_local_data->id == BTS_CPU) |
+ (bts_local_data->id == BTS_G3D_ACP) |
+ (bts_local_data->id == BTS_ROTATOR))
+ bts_set_deblocking(bts_local_data->base,
+ find_fbm_group(prior));
+ bts_local_data++;
+ }
+ }
+}
+
+void exynos_bts_enable(enum exynos_pd_block pd_block)
+{
+ struct exynos_bts_data *bts_data;
+ struct exynos_fbm_data *fbm_data;
+
+ if (pd_block == PD_TOP) {
+ list_for_each_entry(fbm_data, &fbm_list, node)
+ fbm_init_config((void __iomem *)fbm_data->fbm.base,
+ fbm_data->fbm.priority);
+ }
+
+ list_for_each_entry(bts_data, &bts_list, node) {
+ if (bts_data->pd_block == pd_block)
+ __exynos_bts_enable(bts_data);
+ }
+}
+
+static int bts_probe(struct platform_device *pdev)
+{
+ struct exynos_bts_pdata *bts_pdata;
+ struct exynos_fbm_resource *fbm_res;
+ struct exynos_bts_data *bts_data;
+ struct exynos_bts_local_data *bts_local_data, *bts_local_data_h;
+ struct exynos_fbm_data *fbm_data;
+ struct resource *res = NULL;
+ void __iomem *base;
+ struct clk *clk = NULL;
+ int i, ret = 0;
+
+ bts_pdata = pdev->dev.platform_data;
+ fbm_res = bts_pdata->fbm->res;
+
+ if (!bts_pdata) {
+ dev_err(&pdev->dev, "platform data is missed!\n");
+ return -ENODEV;
+ }
+
+ if (list_empty(&fbm_list)) {
+ for (i = 0; i < bts_pdata->fbm->res_num; i++) {
+ base = ioremap(fbm_res->base, FBM_THRESHOLDSEL0);
+ if (!base)
+ return -ENODEV;
+ fbm_init_config(base, fbm_res->priority);
+ fbm_data = kzalloc(sizeof(struct exynos_fbm_data),
+ GFP_KERNEL);
+ fbm_data->fbm.base = (u32)base;
+ fbm_data->fbm.fbm_group = fbm_res->fbm_group;
+ fbm_data->fbm.priority = fbm_res->priority;
+ list_add_tail(&fbm_data->node, &fbm_list);
+ fbm_res++;
+ }
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "can't get resource!\n");
+ return -ENODEV;
+ }
+
+ if (bts_pdata->clk_name) {
+ clk = clk_get(pdev->dev.parent, bts_pdata->clk_name);
+ if (IS_ERR(clk))
+ return -EINVAL;
+ clk_enable(clk);
+ }
+
+ bts_data = kzalloc(sizeof(struct exynos_bts_data), GFP_KERNEL);
+ bts_data->listnum = bts_pdata->res_num;
+ bts_local_data_h = bts_local_data =
+ kzalloc(sizeof(struct exynos_bts_local_data)*bts_data->listnum,
+ GFP_KERNEL);
+
+ for (i = 0; i < bts_data->listnum; i++) {
+ bts_local_data->id = bts_pdata->id;
+ bts_local_data->base = ioremap(res->start, resource_size(res));
+ bts_local_data->def_priority = bts_pdata->def_priority;
+ if (!bts_local_data->base) {
+ ret = -ENXIO;
+ goto probe_err;
+ }
+ bts_init_config(bts_local_data->base,
+ bts_local_data->def_priority);
+ bts_local_data++;
+ res++;
+ }
+
+ bts_data->bts_local_data = bts_local_data_h;
+ bts_data->pd_block = bts_pdata->pd_block;
+ bts_data->clk = clk;
+ bts_data->dev = &pdev->dev;
+ list_add_tail(&bts_data->node, &bts_list);
+ pdev->dev.platform_data = bts_data;
+
+probe_err:
+
+ if (bts_pdata->clk_name)
+ clk_disable(clk);
+
+ return ret;
+}
+
+static int bts_remove(struct platform_device *pdev)
+{
+ struct exynos_fbm_data *fbm_data;
+ struct exynos_bts_data *bts_data = pdev->dev.platform_data;
+ struct exynos_bts_local_data *bts_local_data;
+ int i;
+
+ bts_local_data = bts_data->bts_local_data;
+ for (i = 0; i < bts_data->listnum; i++) {
+ bts_local_data++;
+ iounmap(bts_local_data->base);
+ }
+ kfree(bts_data->bts_local_data);
+ list_del(&bts_data->node);
+ kfree(bts_data);
+
+ if (list_empty(&bts_list))
+ list_for_each_entry(fbm_data, &fbm_list, node) {
+ iounmap((void __iomem *)fbm_data->fbm.base);
+ kfree(fbm_data);
+ list_del(&fbm_data->node);
+ }
+
+ if (bts_data->clk)
+ clk_put(bts_data->clk);
+
+ return 0;
+}
+
+static struct platform_driver bts_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "exynos-bts"
+ },
+ .probe = bts_probe,
+ .remove = bts_remove,
+};
+
+static int __init bts_init(void)
+{
+ return platform_driver_register(&bts_driver);
+}
+arch_initcall(bts_init);
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
index 8d081d9..7b4ec47 100644
--- a/arch/arm/plat-s5p/clock.c
+++ b/arch/arm/plat-s5p/clock.c
@@ -40,6 +40,11 @@ struct clk clk_xusbxti = {
.id = -1,
};
+struct clk clk_xxti = {
+ .name = "xxti",
+ .id = -1,
+};
+
struct clk s5p_clk_27m = {
.name = "clk_27m",
.id = -1,
@@ -73,6 +78,7 @@ struct clk clk_fout_mpll = {
struct clk clk_fout_epll = {
.name = "fout_epll",
.id = -1,
+ .parent = &clk_ext_xtal_mux,
.ctrlbit = (1 << 31),
};
@@ -168,6 +174,41 @@ unsigned long s5p_epll_get_rate(struct clk *clk)
return clk->rate;
}
+int s5p_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+unsigned long s5p_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(pclk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+struct clk_ops s5p_sclk_spdif_ops = {
+ .set_rate = s5p_spdif_set_rate,
+ .get_rate = s5p_spdif_get_rate,
+};
+
static struct clk *s5p_clks[] __initdata = {
&clk_ext_xtal_mux,
&clk_48m,
@@ -179,6 +220,7 @@ static struct clk *s5p_clks[] __initdata = {
&clk_fout_vpll,
&clk_vpll,
&clk_xusbxti,
+ &clk_xxti,
};
void __init s5p_register_clocks(unsigned long xtal_freq)
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index bbc2aa7..15c3a39 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -25,6 +25,7 @@
#include <plat/s5pc100.h>
#include <plat/s5pv210.h>
#include <plat/exynos4.h>
+#include <plat/exynos5.h>
/* table of supported CPUs */
@@ -33,48 +34,85 @@ static const char name_s5p6450[] = "S5P6450";
static const char name_s5pc100[] = "S5PC100";
static const char name_s5pv210[] = "S5PV210/S5PC110";
static const char name_exynos4210[] = "EXYNOS4210";
+static const char name_exynos4212[] = "EXYNOS4212";
+static const char name_exynos4412[] = "EXYNOS4412";
+static const char name_exynos5210[] = "EXYNOS5210";
+static const char name_exynos5250[] = "EXYNOS5250";
static struct cpu_table cpu_ids[] __initdata = {
{
- .idcode = 0x56440100,
- .idmask = 0xfffff000,
+ .idcode = S5P6440_CPU_ID,
+ .idmask = S5P64XX_CPU_MASK,
.map_io = s5p6440_map_io,
.init_clocks = s5p6440_init_clocks,
.init_uarts = s5p6440_init_uarts,
.init = s5p64x0_init,
.name = name_s5p6440,
}, {
- .idcode = 0x36450000,
- .idmask = 0xfffff000,
+ .idcode = S5P6450_CPU_ID,
+ .idmask = S5P64XX_CPU_MASK,
.map_io = s5p6450_map_io,
.init_clocks = s5p6450_init_clocks,
.init_uarts = s5p6450_init_uarts,
.init = s5p64x0_init,
.name = name_s5p6450,
}, {
- .idcode = 0x43100000,
- .idmask = 0xfffff000,
+ .idcode = S5PC100_CPU_ID,
+ .idmask = S5PC100_CPU_MASK,
.map_io = s5pc100_map_io,
.init_clocks = s5pc100_init_clocks,
.init_uarts = s5pc100_init_uarts,
.init = s5pc100_init,
.name = name_s5pc100,
}, {
- .idcode = 0x43110000,
- .idmask = 0xfffff000,
+ .idcode = S5PV210_CPU_ID,
+ .idmask = S5PV210_CPU_MASK,
.map_io = s5pv210_map_io,
.init_clocks = s5pv210_init_clocks,
.init_uarts = s5pv210_init_uarts,
.init = s5pv210_init,
.name = name_s5pv210,
}, {
- .idcode = 0x43210000,
- .idmask = 0xfffe0000,
+ .idcode = EXYNOS4210_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
.map_io = exynos4_map_io,
.init_clocks = exynos4_init_clocks,
.init_uarts = exynos4_init_uarts,
.init = exynos4_init,
.name = name_exynos4210,
+ }, {
+ .idcode = EXYNOS4212_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos4_map_io,
+ .init_clocks = exynos4_init_clocks,
+ .init_uarts = exynos4_init_uarts,
+ .init = exynos4_init,
+ .name = name_exynos4212,
+ }, {
+ .idcode = EXYNOS4412_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos4_map_io,
+ .init_clocks = exynos4_init_clocks,
+ .init_uarts = exynos4_init_uarts,
+ .init = exynos4_init,
+ .name = name_exynos4412,
+
+ }, {
+ .idcode = EXYNOS5210_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos5_map_io,
+ .init_clocks = exynos5_init_clocks,
+ .init_uarts = exynos5_init_uarts,
+ .init = exynos5_init,
+ .name = name_exynos5210,
+ }, {
+ .idcode = EXYNOS5250_CPU_ID,
+ .idmask = EXYNOS_CPU_MASK,
+ .map_io = exynos5_map_io,
+ .init_clocks = exynos5_init_clocks,
+ .init_uarts = exynos5_init_uarts,
+ .init = exynos5_init,
+ .name = name_exynos5250,
},
};
@@ -106,21 +144,27 @@ static struct map_desc s5p_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S5P_PA_SROMC),
.length = SZ_4K,
.type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_HSPHY,
+ .pfn = __phys_to_pfn(S5P_PA_HSPHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
},
};
/* read cpu identification code */
+unsigned long cpu_idcode;
void __init s5p_init_io(struct map_desc *mach_desc,
int size, void __iomem *cpuid_addr)
{
- unsigned long idcode;
-
/* initialize the io descriptors we need for initialization */
iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
if (mach_desc)
iotable_init(mach_desc, size);
- idcode = __raw_readl(cpuid_addr);
- s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+ /* detect cpu id and rev. */
+ s5p_init_cpu(cpuid_addr);
+
+ s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
}
diff --git a/arch/arm/plat-s5p/dev-ace.c b/arch/arm/plat-s5p/dev-ace.c
new file mode 100644
index 0000000..7a9dcd7
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-ace.c
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/plat-s5p/dev-ace.c
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * Base S5P Crypto Engine resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+static struct resource s5p_ace_resource[] = {
+ [0] = {
+ .start = S5P_PA_ACE,
+ .end = S5P_PA_ACE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+#if defined(CONFIG_ARCH_S5PV210)
+ [1] = {
+ .start = IRQ_SSS_INT,
+ .end = IRQ_SSS_HASH,
+ .flags = IORESOURCE_IRQ,
+ },
+#elif defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
+ [1] = {
+ .start = IRQ_INTFEEDCTRL_SSS,
+ .end = IRQ_INTFEEDCTRL_SSS,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+struct platform_device s5p_device_ace = {
+ .name = "s5p-ace",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_ace_resource),
+ .resource = s5p_ace_resource,
+};
+EXPORT_SYMBOL(s5p_device_ace);
diff --git a/arch/arm/plat-s5p/dev-csis-s5p.c b/arch/arm/plat-s5p/dev-csis-s5p.c
new file mode 100644
index 0000000..f3a12a7
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis-s5p.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series device definition for MIPI-CSIS
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/csis.h>
+
+static struct resource s3c_csis0_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_CSIS0,
+ .end = S5P_PA_MIPI_CSIS0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPICSI0,
+ .end = IRQ_MIPICSI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_csis0 = {
+ .name = "s3c-csis",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_csis0_resource),
+ .resource = s3c_csis0_resource,
+};
+
+static struct s3c_platform_csis default_csis0_data __initdata = {
+ .srclk_name = "mout_mpll",
+ .clk_name = "sclk_csis",
+ .clk_rate = 166000000,
+};
+
+void __init s3c_csis0_set_platdata(struct s3c_platform_csis *pd)
+{
+ struct s3c_platform_csis *npd;
+
+ if (!pd)
+ pd = &default_csis0_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL);
+ if (!npd) {
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ return;
+ }
+
+ if (soc_is_exynos4212() || soc_is_exynos4412())
+ npd->srclk_name = "mout_mpll_user";
+ npd->cfg_gpio = s3c_csis0_cfg_gpio;
+ npd->cfg_phy_global = s3c_csis0_cfg_phy_global;
+ npd->clk_on = s3c_csis_clk_on;
+ npd->clk_off = s3c_csis_clk_off;
+ s3c_device_csis0.dev.platform_data = npd;
+}
+static struct resource s3c_csis1_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_CSIS1,
+ .end = S5P_PA_MIPI_CSIS1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPICSI1,
+ .end = IRQ_MIPICSI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_csis1 = {
+ .name = "s3c-csis",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_csis1_resource),
+ .resource = s3c_csis1_resource,
+};
+
+static struct s3c_platform_csis default_csis1_data __initdata = {
+ .srclk_name = "mout_mpll",
+ .clk_name = "sclk_csis",
+ .clk_rate = 166000000,
+};
+
+void __init s3c_csis1_set_platdata(struct s3c_platform_csis *pd)
+{
+ struct s3c_platform_csis *npd;
+
+ if (!pd)
+ pd = &default_csis1_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL);
+ if (!npd) {
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ return;
+ }
+
+ if (soc_is_exynos4212() || soc_is_exynos4412())
+ npd->srclk_name = "mout_mpll_user";
+ npd->cfg_gpio = s3c_csis1_cfg_gpio;
+ npd->cfg_phy_global = s3c_csis1_cfg_phy_global;
+ npd->clk_on = s3c_csis_clk_on;
+ npd->clk_off = s3c_csis_clk_off;
+ s3c_device_csis1.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
index e3aabef..a071c7b 100644
--- a/arch/arm/plat-s5p/dev-csis0.c
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -12,16 +12,17 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <mach/map.h>
+#include <plat/mipi_csis.h>
static struct resource s5p_mipi_csis0_resource[] = {
[0] = {
.start = S5P_PA_MIPI_CSIS0,
- .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
+ .end = S5P_PA_MIPI_CSIS0 + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_MIPI_CSIS0,
- .end = IRQ_MIPI_CSIS0,
+ .start = IRQ_MIPICSI0,
+ .end = IRQ_MIPICSI0,
.flags = IORESOURCE_IRQ,
}
};
@@ -32,3 +33,11 @@ struct platform_device s5p_device_mipi_csis0 = {
.num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
.resource = s5p_mipi_csis0_resource,
};
+
+struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data __initdata = {
+ .clk_rate = 166000000,
+ .lanes = 2,
+ .alignment = 32,
+ .hs_settle = 12,
+ .phy_enable = s5p_csis_phy_enable,
+};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
index 08b91b5..5cf9efa 100644
--- a/arch/arm/plat-s5p/dev-csis1.c
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -12,16 +12,17 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <mach/map.h>
+#include <plat/mipi_csis.h>
static struct resource s5p_mipi_csis1_resource[] = {
[0] = {
.start = S5P_PA_MIPI_CSIS1,
- .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
+ .end = S5P_PA_MIPI_CSIS1 + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = IRQ_MIPI_CSIS1,
- .end = IRQ_MIPI_CSIS1,
+ .start = IRQ_MIPICSI1,
+ .end = IRQ_MIPICSI1,
.flags = IORESOURCE_IRQ,
},
};
@@ -32,3 +33,11 @@ struct platform_device s5p_device_mipi_csis1 = {
.num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
.resource = s5p_mipi_csis1_resource,
};
+
+struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data __initdata = {
+ .clk_rate = 166000000,
+ .lanes = 2,
+ .alignment = 32,
+ .hs_settle = 12,
+ .phy_enable = s5p_csis_phy_enable,
+};
diff --git a/arch/arm/plat-s5p/dev-dp.c b/arch/arm/plat-s5p/dev-dp.c
new file mode 100644
index 0000000..1132e78
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-dp.c
@@ -0,0 +1,52 @@
+/* linux/arch/arm/plat-s5p/dev-dp.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Base S5P DP resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <video/s5p-dp.h>
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/dp.h>
+
+static struct resource s5p_dp_resource[] = {
+ [0] = {
+ .start = S5P_PA_DP,
+ .end = S5P_PA_DP + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DP,
+ .end = IRQ_DP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 s5p_dp_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_dp = {
+ .name = "s5p-dp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_dp_resource),
+ .resource = s5p_dp_resource,
+ .dev = {
+ .dma_mask = &s5p_dp_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p_dp_set_platdata(struct s5p_dp_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct s5p_dp_platdata),
+ &s5p_device_dp);
+}
diff --git a/arch/arm/plat-s5p/dev-dsim.c b/arch/arm/plat-s5p/dev-dsim.c
new file mode 100644
index 0000000..0467c63
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-dsim.c
@@ -0,0 +1,110 @@
+/* linux/arch/arm/plat-s5p/dev-dsim.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * DSIM controller configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <asm/irq.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <mach/map.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#include <linux/regulator/machine.h>
+
+static struct dsim_config dsim_info = {
+ .auto_flush = false, /* main frame fifo auto flush at VSYNC pulse */
+
+ .eot_disable = false, /* only DSIM_1_02 or DSIM_1_03 */
+
+ .auto_vertical_cnt = false,
+ .hse = false,
+ .hfp = true,
+ .hbp = false,
+ .hsa = false,
+
+ .e_no_data_lane = DSIM_DATA_LANE_4,
+ .e_byte_clk = DSIM_PLL_OUT_DIV8,
+
+#ifdef CONFIG_MACH_JENGA
+ .p = 3,
+ .m = 75,
+ .s = 0,
+#endif
+
+ .pll_stable_time = 500, /* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
+
+#ifdef CONFIG_MACH_JENGA
+ .esc_clk = 10 * 1000000, /* escape clk : 10MHz */
+#else
+ .esc_clk = 20 * 1000000, /* escape clk : 10MHz */
+#endif
+
+ .stop_holding_cnt = 0, /* stop state holding counter after bta change count 0 ~ 0xfff */
+ .bta_timeout = 0xff, /* bta timeout 0 ~ 0xff */
+ .rx_timeout = 0xffff, /* lp rx timeout 0 ~ 0xffff */
+
+ .e_lane_swap = DSIM_NO_CHANGE,
+};
+
+/* define ddi platform data based on MIPI-DSI. */
+static struct mipi_ddi_platform_data mipi_ddi_pd = {
+ .backlight_on = NULL,
+};
+
+static struct dsim_lcd_config dsim_lcd_info = {
+ .e_interface = DSIM_VIDEO,
+
+ .parameter[DSI_VIRTUAL_CH_ID] = (unsigned int) DSIM_VIRTUAL_CH_0,
+ .parameter[DSI_FORMAT] = (unsigned int) DSIM_24BPP_888,
+ .parameter[DSI_VIDEO_MODE_SEL] = (unsigned int) DSIM_BURST_SYNC_EVENT,
+ .mipi_ddi_pd = (void *) &mipi_ddi_pd,
+};
+
+static struct resource s5p_dsim_resource[] = {
+ [0] = {
+ .start = S5P_PA_DSIM0,
+ .end = S5P_PA_DSIM0 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPIDSI0,
+ .end = IRQ_MIPIDSI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s5p_platform_dsim dsim_platform_data = {
+ .clk_name = "dsim0",
+ .dsim_info = &dsim_info,
+ .dsim_lcd_info = &dsim_lcd_info,
+ .mipi_power = NULL,
+ .enable_clk = s5p_dsim_enable_clk,
+ .part_reset = s5p_dsim_part_reset,
+ .init_d_phy = s5p_dsim_init_d_phy,
+ .exit_d_phy = s5p_dsim_exit_d_phy,
+
+ /* default platform revision is 0(evt0). */
+ .platform_rev = 0,
+ .cfg_gpio = exynos4_dsim_gpio_setup_24bpp,
+};
+
+struct platform_device s5p_device_dsim = {
+ .name = "s5p-dsim",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_dsim_resource),
+ .resource = s5p_dsim_resource,
+ .dev = {
+ .platform_data = (void *) &dsim_platform_data,
+ },
+};
diff --git a/arch/arm/plat-s5p/dev-dsim02.c b/arch/arm/plat-s5p/dev-dsim02.c
new file mode 100644
index 0000000..2216446
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-dsim02.c
@@ -0,0 +1,47 @@
+/* linux/arch/arm/plat-s5pc11x/dev-dsim0.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * device definitions for Samsung SoC MIPI-DSIM.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fb.h>
+
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+
+#include <plat/mipi_dsim2.h>
+
+static struct resource s5p_mipi_dsim_resource[] = {
+ [0] = {
+ .start = EXYNOS4_PA_DSIM0,
+ .end = EXYNOS4_PA_DSIM0 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPIDSI0,
+ .end = IRQ_MIPIDSI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_mipi_dsim0 = {
+ .name = "s5p-mipi-dsim",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_mipi_dsim_resource),
+ .resource = s5p_mipi_dsim_resource,
+};
diff --git a/arch/arm/plat-s5p/dev-dsim12.c b/arch/arm/plat-s5p/dev-dsim12.c
new file mode 100644
index 0000000..35409c9
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-dsim12.c
@@ -0,0 +1,52 @@
+/* linux/arch/arm/plat-s5pc11x/dev-dsim1.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * device definitions for Samsung SoC MIPI-DSIM.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fb.h>
+
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+
+#include <plat/mipi_dsim2.h>
+
+static struct resource s5p_mipi_dsim_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_DSIM1,
+ .end = S5P_PA_MIPI_DSIM1 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPIDSI,
+ .end = IRQ_MIPIDSI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s5p_platform_mipi_dsim dsim_platform_data = {
+ .phy_enable = s5p_dsim_phy_enable,
+ .dsim_config = &dsim_config,
+};
+
+struct platform_device s5p_device_mipi_dsim1 = {
+ .name = "s5p-mipi-dsim",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p_mipi_dsim_resource),
+ .resource = s5p_mipi_dsim_resource,
+};
diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c
index 94080ff..5c5f5a5 100644
--- a/arch/arm/plat-s5p/dev-ehci.c
+++ b/arch/arm/plat-s5p/dev-ehci.c
@@ -12,9 +12,13 @@
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
+#include <mach/gpio.h>
#include <plat/devs.h>
#include <plat/ehci.h>
#include <plat/usb-phy.h>
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+#include <mach/sec_modem.h>
+#endif
/* USB EHCI Host Controller registration */
static struct resource s5p_ehci_resource[] = {
@@ -54,4 +58,58 @@ void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
npd->phy_init = s5p_usb_phy_init;
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
+ if (!npd->phy_suspend)
+ npd->phy_suspend = s5p_usb_phy_suspend;
+ if (!npd->phy_resume)
+ npd->phy_resume = s5p_usb_phy_resume;
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB)
+ if (!npd->noti_host_states)
+ npd->noti_host_states = set_host_states;
+ if (!npd->get_cp_active_state)
+ npd->get_cp_active_state = get_cp_active_state;
+#endif
+}
+
+/* USB Host Controlle OHCI registrations */
+static struct resource s5p_ohci_resource[] = {
+ [0] = {
+ .start = S5P_PA_OHCI,
+ .end = S5P_PA_OHCI + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB_HOST,
+ .end = IRQ_USB_HOST,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s5p_device_ohci_dmamask = 0xffffffffUL;
+
+struct platform_device s5p_device_ohci = {
+ .name = "s5p-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_ohci_resource),
+ .resource = s5p_ohci_resource,
+ .dev = {
+ .dma_mask = &s5p_device_ohci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+void __init s5p_ohci_set_platdata(struct s5p_ohci_platdata *pd)
+{
+ struct s5p_ohci_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s5p_ohci_platdata),
+ &s5p_device_ohci);
+
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+ if (!npd->phy_suspend)
+ npd->phy_suspend = s5p_usb_phy_suspend;
+ if (!npd->phy_resume)
+ npd->phy_resume = s5p_usb_phy_resume;
}
diff --git a/arch/arm/plat-s5p/dev-fimc-s5p.c b/arch/arm/plat-s5p/dev-fimc-s5p.c
new file mode 100644
index 0000000..53a256d
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc-s5p.c
@@ -0,0 +1,225 @@
+/* linux/arch/arm/plat-s5p/dev-fimc-s5p.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Device definition for FIMC device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fimc.h>
+
+static struct resource s3c_fimc0_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC0,
+ .end = S5P_PA_FIMC0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC0,
+ .end = IRQ_FIMC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc0 = {
+ .name = "s3c-fimc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_fimc0_resource),
+ .resource = s3c_fimc0_resource,
+};
+
+static struct s3c_platform_fimc default_fimc0_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x51,
+};
+
+void __init s3c_fimc0_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc0_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc0_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x51;
+ npd->use_cam = true;
+ s3c_device_fimc0.dev.platform_data = npd;
+ }
+}
+
+static struct resource s3c_fimc1_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC1,
+ .end = S5P_PA_FIMC1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC1,
+ .end = IRQ_FIMC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc1 = {
+ .name = "s3c-fimc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_fimc1_resource),
+ .resource = s3c_fimc1_resource,
+};
+
+static struct s3c_platform_fimc default_fimc1_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x51,
+};
+
+void __init s3c_fimc1_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc1_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc1_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x51;
+ npd->use_cam = false;
+ s3c_device_fimc1.dev.platform_data = npd;
+ }
+}
+
+static struct resource s3c_fimc2_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC2,
+ .end = S5P_PA_FIMC2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC2,
+ .end = IRQ_FIMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc2 = {
+ .name = "s3c-fimc",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c_fimc2_resource),
+ .resource = s3c_fimc2_resource,
+};
+
+static struct s3c_platform_fimc default_fimc2_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x51,
+};
+
+void __init s3c_fimc2_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc2_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc2_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x51;
+ npd->use_cam = false;
+ s3c_device_fimc2.dev.platform_data = npd;
+ }
+}
+
+static struct resource s3c_fimc3_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMC3,
+ .end = S5P_PA_FIMC3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMC3,
+ .end = IRQ_FIMC3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fimc3 = {
+ .name = "s3c-fimc",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s3c_fimc3_resource),
+ .resource = s3c_fimc3_resource,
+};
+
+static struct s3c_platform_fimc default_fimc3_data __initdata = {
+ .default_cam = CAMERA_PAR_A,
+ .hw_ver = 0x51,
+};
+
+void __init s3c_fimc3_set_platdata(struct s3c_platform_fimc *pd)
+{
+ struct s3c_platform_fimc *npd;
+
+ if (!pd)
+ pd = &default_fimc3_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fimc), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_fimc3_cfg_gpio;
+
+ if (!npd->clk_on)
+ npd->clk_on = s3c_fimc_clk_on;
+
+ if (!npd->clk_off)
+ npd->clk_off = s3c_fimc_clk_off;
+
+ npd->hw_ver = 0x51;
+ npd->use_cam = false;
+ s3c_device_fimc3.dev.platform_data = npd;
+ }
+}
+
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c
index 608770f..4045b9a 100644
--- a/arch/arm/plat-s5p/dev-fimc0.c
+++ b/arch/arm/plat-s5p/dev-fimc0.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc0_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc0 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc0_default_data __initdata;
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c
index 76e3a97..c33fbce 100644
--- a/arch/arm/plat-s5p/dev-fimc1.c
+++ b/arch/arm/plat-s5p/dev-fimc1.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc1_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc1 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc1_default_data __initdata;
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c
index 24d2981..ed98127 100644
--- a/arch/arm/plat-s5p/dev-fimc2.c
+++ b/arch/arm/plat-s5p/dev-fimc2.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc2_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc2 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc2_default_data __initdata;
diff --git a/arch/arm/plat-s5p/dev-fimc3.c b/arch/arm/plat-s5p/dev-fimc3.c
index ef31bec..8fb3f01 100644
--- a/arch/arm/plat-s5p/dev-fimc3.c
+++ b/arch/arm/plat-s5p/dev-fimc3.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <mach/map.h>
+#include <media/s5p_fimc.h>
static struct resource s5p_fimc3_resource[] = {
[0] = {
@@ -41,3 +42,5 @@ struct platform_device s5p_device_fimc3 = {
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
+
+struct s5p_platform_fimc s3c_fimc3_default_data __initdata;
diff --git a/arch/arm/plat-s5p/dev-fimd-s5p.c b/arch/arm/plat-s5p/dev-fimd-s5p.c
new file mode 100644
index 0000000..80d0bfd
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd-s5p.c
@@ -0,0 +1,104 @@
+/* linux/arch/arm/plat-s5p/dev-fimd-s5p.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base S5P platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <mach/map.h>
+#include <plat/fb-s5p.h>
+
+#ifdef CONFIG_FB_S5P
+static struct resource s3cfb_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMD0,
+ .end = S5P_PA_FIMD0 + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMD0_VSYNC,
+ .end = IRQ_FIMD0_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_FIMD0_FIFO,
+ .end = IRQ_FIMD0_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fb_dma_mask = 0xffffffffUL;
+
+struct platform_device s3c_device_fb = {
+ .name = "s3cfb",
+#if defined(CONFIG_ARCH_EXYNOS4)
+ .id = 0,
+#else
+ .id = -1,
+#endif
+ .num_resources = ARRAY_SIZE(s3cfb_resource),
+ .resource = s3cfb_resource,
+ .dev = {
+ .dma_mask = &fb_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+static struct s3c_platform_fb default_fb_data __initdata = {
+#if defined(CONFIG_ARCH_EXYNOS4)
+ .hw_ver = 0x70,
+#else
+ .hw_ver = 0x62,
+#endif
+ .nr_wins = 5,
+#if defined(CONFIG_FB_S5P_DEFAULT_WINDOW)
+ .default_win = CONFIG_FB_S5P_DEFAULT_WINDOW,
+#else
+ .default_win = 0,
+#endif
+ .swap = FB_SWAP_WORD | FB_SWAP_HWORD,
+};
+
+void __init s3cfb_set_platdata(struct s3c_platform_fb *pd)
+{
+ struct s3c_platform_fb *npd;
+ int i;
+
+ if (!pd)
+ pd = &default_fb_data;
+
+ npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ for (i = 0; i < npd->nr_wins; i++)
+ npd->nr_buffers[i] = 1;
+
+#if defined(CONFIG_FB_S5P_NR_BUFFERS)
+ npd->nr_buffers[npd->default_win] = CONFIG_FB_S5P_NR_BUFFERS;
+#else
+ npd->nr_buffers[npd->default_win] = 1;
+#endif
+
+ s3cfb_get_clk_name(npd->clk_name);
+ npd->cfg_gpio = s3cfb_cfg_gpio;
+ npd->backlight_on = s3cfb_backlight_on;
+ npd->backlight_off = s3cfb_backlight_off;
+ npd->lcd_on = s3cfb_lcd_on;
+ npd->lcd_off = s3cfb_lcd_off;
+ npd->clk_on = s3cfb_clk_on;
+ npd->clk_off = s3cfb_clk_off;
+
+ s3c_device_fb.dev.platform_data = npd;
+ }
+}
+#endif
+
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 0000000..9e7176c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s5p/dev-fimd0.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd0_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMD0,
+ .end = S5P_PA_FIMD0 + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMD0_VSYNC,
+ .end = IRQ_FIMD0_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_FIMD0_FIFO,
+ .end = IRQ_FIMD0_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_FIMD0_SYSTEM,
+ .end = IRQ_FIMD0_SYSTEM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fimd0_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd0 = {
+ .name = "s5p-fb",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_fimd0_resource),
+ .resource = s5p_fimd0_resource,
+ .dev = {
+ .dma_mask = &fimd0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s5p_device_fimd0);
+}
diff --git a/arch/arm/plat-s5p/dev-fimd1.c b/arch/arm/plat-s5p/dev-fimd1.c
new file mode 100644
index 0000000..e00b635
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd1.c
@@ -0,0 +1,71 @@
+/* linux/arch/arm/plat-s5p/dev-fimd1.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/gfp.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s5p_fimd1_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMD1,
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+ .end = S5P_PA_FIMD1 + SZ_256K - 1,
+#else
+ .end = S5P_PA_FIMD1 + SZ_32K - 1,
+#endif
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FIMD1_VSYNC,
+ .end = IRQ_FIMD1_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_FIMD1_FIFO,
+ .end = IRQ_FIMD1_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_FIMD1_SYSTEM,
+ .end = IRQ_FIMD1_SYSTEM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fimd1_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimd1 = {
+ .name = "s5p-fb",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p_fimd1_resource),
+ .resource = s5p_fimd1_resource,
+ .dev = {
+ .dma_mask = &fimd1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p_fimd1_set_platdata(struct s3c_fb_platdata *pd)
+{
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s5p_device_fimd1);
+}
diff --git a/arch/arm/plat-s5p/dev-fimg2d.c b/arch/arm/plat-s5p/dev-fimg2d.c
new file mode 100644
index 0000000..35896ff
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimg2d.c
@@ -0,0 +1,75 @@
+/* linux/arch/arm/plat-s5p/dev-fimg2d.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P FIMG2D resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <plat/fimg2d.h>
+#include <plat/cpu.h>
+#include <mach/map.h>
+
+#define S5P_PA_FIMG2D_OFFSET 0x02000000
+#define S5P_PA_FIMG2D_3X (S5P_PA_FIMG2D+S5P_PA_FIMG2D_OFFSET)
+
+static struct resource s5p_fimg2d_resource[] = {
+ [0] = {
+ .start = S5P_PA_FIMG2D,
+ .end = S5P_PA_FIMG2D + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_2D,
+ .end = IRQ_2D,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s5p_device_fimg2d_dmamask = 0xffffffffUL;
+
+struct platform_device s5p_device_fimg2d = {
+ .name = "s5p-fimg2d",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_fimg2d_resource),
+ .resource = s5p_fimg2d_resource,
+ .dev = {
+ .dma_mask = &s5p_device_fimg2d_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ },
+};
+EXPORT_SYMBOL(s5p_device_fimg2d);
+
+static struct fimg2d_platdata default_fimg2d_data __initdata = {
+ .parent_clkname = "mout_g2d0",
+ .clkname = "sclk_fimg2d",
+ .gate_clkname = "fimg2d",
+ .clkrate = 250 * 1000000,
+};
+
+void __init s5p_fimg2d_set_platdata(struct fimg2d_platdata *pd)
+{
+ struct fimg2d_platdata *npd;
+
+ if (soc_is_exynos4210()) {
+ s5p_fimg2d_resource[0].start = S5P_PA_FIMG2D_3X;
+ s5p_fimg2d_resource[0].end = S5P_PA_FIMG2D_3X + SZ_4K - 1;
+ }
+
+ if (!pd)
+ pd = &default_fimg2d_data;
+
+ npd = kmemdup(pd, sizeof(*pd), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "no memory for fimg2d platform data\n");
+ else
+ s5p_device_fimg2d.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-s5p/dev-i2c-hdmiphy.c b/arch/arm/plat-s5p/dev-i2c-hdmiphy.c
new file mode 100644
index 0000000..9dd0ff3
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-i2c-hdmiphy.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c for hdmiphy device
+ *
+ * Based on plat-samsung/dev-i2c7.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/iic-hdmiphy.h>
+
+#include <plat/regs-iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+
+static struct resource s5p_i2c_resource[] = {
+ [0] = {
+ .start = S5P_PA_IIC_HDMIPHY,
+ .end = S5P_PA_IIC_HDMIPHY + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC_HDMIPHY,
+ .end = IRQ_IIC_HDMIPHY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_i2c_hdmiphy = {
+ .name = "s3c2440-hdmiphy-i2c",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_i2c_resource),
+ .resource = s5p_i2c_resource,
+};
+EXPORT_SYMBOL(s5p_device_i2c_hdmiphy);
+
+void __init s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = S5P_IIC_HDMIPHY_BUS_NUM;
+ }
+
+ s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s5p_device_i2c_hdmiphy);
+}
+EXPORT_SYMBOL(s5p_i2c_hdmiphy_set_platdata);
diff --git a/arch/arm/plat-s5p/dev-jpeg.c b/arch/arm/plat-s5p/dev-jpeg.c
new file mode 100644
index 0000000..b14eca5
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-jpeg.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series device definition for JPEG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+
+static struct resource s5p_jpeg_resource[] = {
+ [0] = {
+ .start = S5P_PA_JPEG,
+ .end = S5P_PA_JPEG + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_JPEG,
+ .end = IRQ_JPEG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_jpeg = {
+ .name = "s5p-jpeg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_jpeg_resource),
+ .resource = s5p_jpeg_resource,
+};
+EXPORT_SYMBOL(s5p_device_jpeg);
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c
new file mode 100644
index 0000000..e6b9483
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-mfc.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/plat-s5p/dev-mfc.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Base S5P MFC resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <mach/map.h>
+
+static struct resource s5p_mfc_resource[] = {
+ [0] = {
+ .start = S5P_PA_MFC,
+ .end = S5P_PA_MFC + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MFC,
+ .end = IRQ_MFC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_mfc = {
+ .name = "s3c-mfc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_mfc_resource),
+ .resource = s5p_mfc_resource,
+};
+
diff --git a/arch/arm/plat-s5p/dev-mipidsim.c b/arch/arm/plat-s5p/dev-mipidsim.c
new file mode 100644
index 0000000..c8c38b5
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-mipidsim.c
@@ -0,0 +1,53 @@
+/* linux/arch/arm/plat-s5p/dev-mipidsim.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fb.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/regs-clock.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+
+#include <plat/dsim.h>
+#include <plat/mipi_dsi.h>
+
+static struct resource s5p_dsim_resource[] = {
+ [0] = {
+ .start = S5P_PA_DSIM0,
+ .end = S5P_PA_DSIM0 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPIDSI0,
+ .end = IRQ_MIPIDSI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_mipi_dsim = {
+ .name = "s5p-mipi-dsim",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_dsim_resource),
+ .resource = s5p_dsim_resource,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+void __init s5p_dsim_set_platdata(struct s5p_platform_mipi_dsim *pd) {
+ s3c_set_platdata(pd, sizeof(struct s5p_platform_mipi_dsim), &s5p_device_mipi_dsim);
+}
diff --git a/arch/arm/plat-s5p/dev-pmu.c b/arch/arm/plat-s5p/dev-pmu.c
index a08576d..2880f47 100644
--- a/arch/arm/plat-s5p/dev-pmu.c
+++ b/arch/arm/plat-s5p/dev-pmu.c
@@ -15,22 +15,49 @@
#include <asm/pmu.h>
#include <mach/irqs.h>
-static struct resource s5p_pmu_resource = {
- .start = IRQ_PMU,
- .end = IRQ_PMU,
- .flags = IORESOURCE_IRQ,
+static struct resource s5p_pmu_resource[] = {
+ {
+ .start = IRQ_PMU,
+ .end = IRQ_PMU,
+ .flags = IORESOURCE_IRQ,
+ },
+#if CONFIG_NR_CPUS > 1
+ {
+ .start = IRQ_PMU_CPU1,
+ .end = IRQ_PMU_CPU1,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+#if CONFIG_NR_CPUS > 2
+ {
+ .start = IRQ_PMU_CPU2,
+ .end = IRQ_PMU_CPU2,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_PMU_CPU3,
+ .end = IRQ_PMU_CPU3,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
};
struct platform_device s5p_device_pmu = {
.name = "arm-pmu",
.id = ARM_PMU_DEVICE_CPU,
- .num_resources = 1,
- .resource = &s5p_pmu_resource,
+ .num_resources = ARRAY_SIZE(s5p_pmu_resource),
+ .resource = s5p_pmu_resource,
};
static int __init s5p_pmu_init(void)
{
- platform_device_register(&s5p_device_pmu);
+ int ret;
+
+ ret = platform_device_register(&s5p_device_pmu);
+ if (ret) {
+ pr_warning("s5p_pmu_init: pmu device not registered.\n");
+ return ret;
+ }
+
return 0;
}
arch_initcall(s5p_pmu_init);
diff --git a/arch/arm/plat-s5p/dev-rotator.c b/arch/arm/plat-s5p/dev-rotator.c
new file mode 100644
index 0000000..5ff8e70
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-rotator.c
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-s5p/dev-rotator.c
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Base S5P Rotator resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <mach/map.h>
+
+static struct resource exynos_rot_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_ROTATOR,
+ .end = EXYNOS_PA_ROTATOR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ROTATOR,
+ .end = IRQ_ROTATOR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 exynos_rot_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_rotator = {
+ .name = "exynos-rot",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_rot_resource),
+ .resource = exynos_rot_resource,
+ .dev = {
+ .dma_mask = &exynos_rot_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-s5p/dev-tmu.c b/arch/arm/plat-s5p/dev-tmu.c
new file mode 100644
index 0000000..ea330cd
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-tmu.c
@@ -0,0 +1,118 @@
+/* linux/arch/arm/plat-s5p/dev-tmu.c
+ *
+ * Copyright 2009 by SAMSUNG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <asm/irq.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/s5p-tmu.h>
+
+static struct resource s5p_tmu_resource[] = {
+ [0] = {
+ .start = S5P_PA_TMU,
+ .end = S5P_PA_TMU + 0xFFFF - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TMU,
+ .end = IRQ_TMU,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_tmu = {
+ .name = "s5p-tmu",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_tmu_resource),
+ .resource = s5p_tmu_resource,
+};
+
+/*
+ * The below temperature value is derived from testing smdk4x12 board
+ * in chamber
+ * 78 degree : threshold temp
+ * 87 degree : throttling temperature
+ * 103 degree : Waring temperature
+ * 110 degree : Tripping temperature
+ * 85 degree : Memory throttling
+ * 120 degree : To protect chip,forcely kernel panic
+*/
+static struct s5p_platform_tmu default_tmu_data __initdata = {
+ .ts = {
+ .stop_1st_throttle = 78,
+ .start_1st_throttle = 80,
+ .stop_2nd_throttle = 87,
+ .start_2nd_throttle = 103,
+ .start_tripping = 110,
+ .start_emergency = 120,
+ .stop_mem_throttle = 80,
+ .start_mem_throttle = 85,
+ },
+ .cpufreq = {
+ .limit_1st_throttle = 800000,
+ .limit_2nd_throttle = 200000,
+ },
+ .mp = {
+ .rclk = 24000000,
+ .period_bank_refresh = 3900,
+ },
+ .cfg = {
+ .mode = 1,
+ .slope = 80,
+ .sampling_rate = 1000,
+ .monitoring_rate = 10000,
+ },
+};
+
+int s5p_tmu_get_irqno(int num)
+{
+ return platform_get_irq(&s5p_device_tmu, num);
+}
+
+struct s5p_tmu *s5p_tmu_get_platdata(void)
+{
+ return platform_get_drvdata(&s5p_device_tmu);
+}
+
+void __init s5p_tmu_set_platdata(struct s5p_platform_tmu *pd)
+{
+ struct s5p_platform_tmu *npd;
+
+ npd = kmalloc(sizeof(struct s5p_platform_tmu), GFP_KERNEL);
+ if (!npd) {
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ } else {
+ if (!pd->ts.stop_1st_throttle)
+ memcpy(&npd->ts, &default_tmu_data.ts,
+ sizeof(struct temperature_params));
+ else
+ memcpy(&npd->ts, &pd->ts,
+ sizeof(struct temperature_params));
+
+ if (!(pd->cpufreq.limit_1st_throttle))
+ memcpy(&npd->cpufreq, &default_tmu_data.cpufreq,
+ sizeof(struct cpufreq_params));
+ else
+ memcpy(&npd->cpufreq, &pd->cpufreq,
+ sizeof(struct cpufreq_params));
+
+ if (pd->temp_compensate.arm_volt)
+ memcpy(&npd->temp_compensate, &pd->temp_compensate,
+ sizeof(struct temp_compensate_params));
+
+ s5p_device_tmu.dev.platform_data = npd;
+ }
+}
diff --git a/arch/arm/plat-s5p/dev-tsi.c b/arch/arm/plat-s5p/dev-tsi.c
new file mode 100644
index 0000000..9ac42cc
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-tsi.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series device definition for TSI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+/*TSI Interface*/
+static u64 tsi_dma_mask = 0xffffffffUL;
+
+static struct resource s3c_tsi_resource[] = {
+ [0] = {
+ .start = S5P_PA_TSI,
+ .end = S5P_PA_TSI + S5P_SZ_TSI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TSI,
+ .end = IRQ_TSI,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s3c_device_tsi = {
+ .name = "s3c-tsi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_tsi_resource),
+ .resource = s3c_tsi_resource,
+ .dev = {
+ .dma_mask = &tsi_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+
+
+};
+EXPORT_SYMBOL(s3c_device_tsi);
diff --git a/arch/arm/plat-s5p/dev-tv.c b/arch/arm/plat-s5p/dev-tv.c
new file mode 100644
index 0000000..2bb955c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-tv.c
@@ -0,0 +1,185 @@
+/* linux/arch/arm/plat-s5p/dev-tv.c
+ *
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
+ *
+ * S5P series device definition for TV device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/hdmi.h>
+#include <plat/tvout.h>
+
+/* HDMI interface */
+static struct resource s5p_hdmi_resources[] = {
+ [0] = {
+ .start = S5P_PA_HDMI,
+ .end = S5P_PA_HDMI + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TVOUT_HPD,
+ .end = IRQ_TVOUT_HPD,
+ .flags = IORESOURCE_IRQ,
+ .name = "external_irq"
+ },
+ [2] = {
+ .start = IRQ_HDMI,
+ .end = IRQ_HDMI,
+ .flags = IORESOURCE_IRQ,
+ .name = "internal_irq"
+ },
+};
+
+struct platform_device s5p_device_hdmi = {
+ .name = "s5p-hdmi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_hdmi_resources),
+ .resource = s5p_hdmi_resources,
+};
+EXPORT_SYMBOL(s5p_device_hdmi);
+
+void __init s5p_hdmi_set_platdata(struct s5p_hdmi_platdata *pd)
+{
+ struct s5p_hdmi_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s5p_hdmi_platdata),
+ &s5p_device_hdmi);
+ if (!npd)
+ return;
+
+ if (soc_is_s5pv210() || soc_is_exynos4210())
+ npd->is_v13 = true;
+
+ if (!npd->cfg_hpd)
+ npd->cfg_hpd = s5p_hdmi_cfg_hpd;
+ if (!npd->get_hpd)
+ npd->get_hpd = s5p_hdmi_get_hpd;
+}
+
+/* MIXER */
+#if defined(CONFIG_ARCH_EXYNOS4)
+static struct resource s5p_mixer_resources[] = {
+ [0] = {
+ .start = S5P_PA_MIXER,
+ .end = S5P_PA_MIXER + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "mxr"
+ },
+ [1] = {
+ .start = S5P_PA_VP,
+ .end = S5P_PA_VP + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "vp"
+ },
+ [2] = {
+ .start = IRQ_MIXER,
+ .end = IRQ_MIXER,
+ .flags = IORESOURCE_IRQ,
+ .name = "irq"
+ }
+};
+#else
+static struct resource s5p_mixer_resources[] = {
+ [0] = {
+ .start = S5P_PA_MIXER,
+ .end = S5P_PA_MIXER + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "mxr"
+ },
+ [2] = {
+ .start = IRQ_MIXER,
+ .end = IRQ_MIXER,
+ .flags = IORESOURCE_IRQ,
+ .name = "irq"
+ }
+};
+#endif
+
+struct platform_device s5p_device_mixer = {
+ .name = "s5p-mixer",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_mixer_resources),
+ .resource = s5p_mixer_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &s5p_device_mixer.dev.coherent_dma_mask,
+ }
+};
+EXPORT_SYMBOL(s5p_device_mixer);
+
+#if defined(CONFIG_ARCH_EXYNOS4)
+/* HDMI interface */
+static struct resource s5p_sdo_resources[] = {
+ [0] = {
+ .start = S5P_PA_SDO,
+ .end = S5P_PA_SDO + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SDO,
+ .end = IRQ_SDO,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_sdo = {
+ .name = "s5p-sdo",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_sdo_resources),
+ .resource = s5p_sdo_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &s5p_device_sdo.dev.coherent_dma_mask,
+ }
+};
+EXPORT_SYMBOL(s5p_device_sdo);
+#endif
+
+/* CEC */
+static struct resource s5p_cec_resources[] = {
+ [0] = {
+ .start = S5P_PA_HDMI_CEC,
+ .end = S5P_PA_HDMI_CEC + S5P_SZ_HDMI_CEC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CEC,
+ .end = IRQ_CEC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_cec = {
+ .name = "s5p-tvout-cec",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_cec_resources),
+ .resource = s5p_cec_resources,
+};
+EXPORT_SYMBOL(s5p_device_cec);
+
+
+void __init s5p_hdmi_cec_set_platdata(struct s5p_platform_cec *pd)
+{
+ struct s5p_platform_cec *npd;
+
+ npd = kmemdup(pd, sizeof(struct s5p_platform_cec), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s5p_cec_cfg_gpio;
+
+ s5p_device_cec.dev.platform_data = npd;
+ }
+}
diff --git a/arch/arm/plat-s5p/dev-tvout.c b/arch/arm/plat-s5p/dev-tvout.c
new file mode 100644
index 0000000..dd057dd
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-tvout.c
@@ -0,0 +1,151 @@
+/* linux/arch/arm/plat-s5p/dev-tvout.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P TVOUT resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <mach/map.h>
+#include <plat/tvout.h>
+
+/* TVOUT interface */
+static struct resource s5p_tvout_resources[] = {
+ [0] = {
+ .start = S5P_PA_TVENC,
+ .end = S5P_PA_TVENC + S5P_SZ_TVENC - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "s5p-sdo"
+ },
+ [1] = {
+ .start = S5P_PA_VP,
+ .end = S5P_PA_VP + S5P_SZ_VP - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "s5p-vp"
+ },
+ [2] = {
+ .start = S5P_PA_MIXER,
+ .end = S5P_PA_MIXER + S5P_SZ_MIXER - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "s5p-mixer"
+ },
+ [3] = {
+ .start = S5P_PA_HDMI,
+ .end = S5P_PA_HDMI + S5P_SZ_HDMI - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "s5p-hdmi"
+ },
+ [4] = {
+ .start = S5P_I2C_HDMI_PHY,
+ .end = S5P_I2C_HDMI_PHY + S5P_I2C_HDMI_SZ_PHY - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "s5p-i2c-hdmi-phy"
+ },
+ [5] = {
+ .start = IRQ_MIXER,
+ .end = IRQ_MIXER,
+ .flags = IORESOURCE_IRQ,
+ .name = "s5p-mixer"
+ },
+ [6] = {
+ .start = IRQ_HDMI,
+ .end = IRQ_HDMI,
+ .flags = IORESOURCE_IRQ,
+ .name = "s5p-hdmi"
+ },
+ [7] = {
+ .start = IRQ_TVENC,
+ .end = IRQ_TVENC,
+ .flags = IORESOURCE_IRQ,
+ .name = "s5p-sdo"
+ },
+};
+
+struct platform_device s5p_device_tvout = {
+ .name = "s5p-tvout",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_tvout_resources),
+ .resource = s5p_tvout_resources,
+};
+EXPORT_SYMBOL(s5p_device_tvout);
+
+/* HPD */
+static struct resource s5p_hpd_resources[] = {
+ [0] = {
+ .start = IRQ_TVOUT_HPD,
+ .end = IRQ_TVOUT_HPD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+struct platform_device s5p_device_hpd = {
+ .name = "s5p-tvout-hpd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_hpd_resources),
+ .resource = s5p_hpd_resources,
+};
+EXPORT_SYMBOL(s5p_device_hpd);
+
+void __init s5p_hdmi_hpd_set_platdata(struct s5p_platform_hpd *pd)
+{
+ struct s5p_platform_hpd *npd;
+
+ npd = kmemdup(pd, sizeof(struct s5p_platform_hpd), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->int_src_ext_hpd)
+ npd->int_src_ext_hpd = s5p_int_src_ext_hpd;
+ if (!npd->int_src_hdmi_hpd)
+ npd->int_src_hdmi_hpd = s5p_int_src_hdmi_hpd;
+ if (!npd->read_gpio)
+ npd->read_gpio = s5p_hpd_read_gpio;
+
+ s5p_device_hpd.dev.platform_data = npd;
+ }
+}
+
+/* CEC */
+static struct resource s5p_cec_resources[] = {
+ [0] = {
+ .start = S5P_PA_HDMI_CEC,
+ .end = S5P_PA_HDMI_CEC + S5P_SZ_HDMI_CEC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CEC,
+ .end = IRQ_CEC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_cec = {
+ .name = "s5p-tvout-cec",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_cec_resources),
+ .resource = s5p_cec_resources,
+};
+EXPORT_SYMBOL(s5p_device_cec);
+
+
+void __init s5p_hdmi_cec_set_platdata(struct s5p_platform_cec *pd)
+{
+ struct s5p_platform_cec *npd;
+
+ npd = kmemdup(pd, sizeof(struct s5p_platform_cec), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s5p_cec_cfg_gpio;
+
+ s5p_device_cec.dev.platform_data = npd;
+ }
+}
diff --git a/arch/arm/plat-s5p/dev-usb-switch.c b/arch/arm/plat-s5p/dev-usb-switch.c
new file mode 100644
index 0000000..889362c
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-usb-switch.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/gpio.h>
+#include <plat/devs.h>
+#include <plat/usb-switch.h>
+
+/* USB Switch */
+static struct resource s5p_usbswitch_res[4];
+
+struct platform_device s5p_device_usbswitch = {
+ .name = "exynos-usb-switch",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_usbswitch_res),
+ .resource = s5p_usbswitch_res,
+};
+
+void __init s5p_usbswitch_set_platdata(struct s5p_usbswitch_platdata *pd)
+{
+ struct s5p_usbswitch_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s5p_usbswitch_platdata),
+ &s5p_device_usbswitch);
+
+ s5p_usbswitch_res[0].start = gpio_to_irq(npd->gpio_host_detect);
+ s5p_usbswitch_res[0].end = gpio_to_irq(npd->gpio_host_detect);
+ s5p_usbswitch_res[0].flags = IORESOURCE_IRQ;
+
+ s5p_usbswitch_res[1].start = gpio_to_irq(npd->gpio_device_detect);
+ s5p_usbswitch_res[1].end = gpio_to_irq(npd->gpio_device_detect);
+ s5p_usbswitch_res[1].flags = IORESOURCE_IRQ;
+
+ s5p_usbswitch_res[2].start = gpio_to_irq(npd->gpio_drd_host_detect);
+ s5p_usbswitch_res[2].end = gpio_to_irq(npd->gpio_drd_host_detect);
+ s5p_usbswitch_res[2].flags = IORESOURCE_IRQ;
+
+ s5p_usbswitch_res[3].start = gpio_to_irq(npd->gpio_drd_device_detect);
+ s5p_usbswitch_res[3].end = gpio_to_irq(npd->gpio_drd_device_detect);
+ s5p_usbswitch_res[3].flags = IORESOURCE_IRQ;
+#ifdef CONFIG_USB_EHCI_S5P
+ npd->ehci_dev = &s5p_device_ehci.dev;
+#endif
+#ifdef CONFIG_USB_OHCI_S5P
+ npd->ohci_dev = &s5p_device_ohci.dev;
+#endif
+#ifdef CONFIG_USB_XHCI_EXYNOS
+ npd->xhci_dev = &exynos_device_xhci.dev;
+#endif
+#ifdef CONFIG_USB_S3C_OTGD
+ npd->s3c_udc_dev = &s3c_device_usbgadget.dev;
+#endif
+#ifdef CONFIG_USB_EXYNOS_SS_UDC
+ npd->exynos_udc_dev = &exynos_device_ss_udc.dev;
+#endif
+}
diff --git a/arch/arm/plat-s5p/dev-usbgadget.c b/arch/arm/plat-s5p/dev-usbgadget.c
new file mode 100644
index 0000000..3890ce3
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-usbgadget.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S3C series device definition for USB-GADGET
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+#include <linux/usb/android_composite.h>
+#endif
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/usbgadget.h>
+#include <plat/usb-phy.h>
+
+/* USB Device (Gadget)*/
+static struct resource s3c_usbgadget_resource[] = {
+ [0] = {
+ .start = S5P_PA_HSOTG,
+ .end = S5P_PA_HSOTG + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB_HSOTG,
+ .end = IRQ_USB_HSOTG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s5p_device_usb_gadget_dmamask = 0xffffffffUL;
+struct platform_device s3c_device_usbgadget = {
+ .name = "s3c-usbgadget",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
+ .resource = s3c_usbgadget_resource,
+ .dev = {
+ .dma_mask = &s5p_device_usb_gadget_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p_usbgadget_set_platdata(struct s5p_usbgadget_platdata *pd)
+{
+ struct s5p_usbgadget_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s5p_usbgadget_platdata),
+ &s3c_device_usbgadget);
+
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+}
+
+#if defined(CONFIG_USB_ANDROID) || defined(CONFIG_USB_G_ANDROID)
+/* default samsung vendor ID */
+#define SAMSUNG_VENDOR_ID 0x04e8
+/* dynamic composite using devguru driver */
+#define SAMSUNG_MTP_PRODUCT_ID 0x6860 /* mtp(0)+...*/
+#define SAMSUNG_UMS_PRODUCT_ID 0x685e /* ums(0)+...*/
+#define SAMSUNG_RNDIS_PRODUCT_ID 0x6864 /* RNDIS +...*/
+#define SAMSUNG_NCM_PRODUCT_ID 0x685D /* NCM + ...*/
+/* only mode using devguru driver */
+#define SAMSUNG_UMS_ONLY_PRODUCT_ID 0x685B /* UMS Only */
+#define SAMSUNG_MTP_ONLY_PRODUCT_ID 0x685C /* MTP Only */
+#define SAMSUNG_RNDIS_ONLY_PRODUCT_ID 0x6863 /* RNDIS only */
+#define SAMSUNG_ADB_ONLY_PRODUCT_ID SAMSUNG_MTP_ONLY_PRODUCT_ID
+
+#ifdef CONFIG_USB_ANDROID_MTP
+#define SAMSUNG_PRODUCT_ID SAMSUNG_MTP_PRODUCT_ID
+#else
+#define SAMSUNG_PRODUCT_ID SAMSUNG_UMS_PRODUCT_ID
+#endif
+
+#define MAX_USB_SERIAL_NUM 17
+
+#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
+static char *usb_functions_ums[] = {
+ "usb_mass_storage",
+};
+#endif
+
+#ifdef CONFIG_USB_ANDROID_RNDIS
+static char *usb_functions_rndis[] = {
+ "rndis",
+};
+#endif
+
+#ifdef CONFIG_USB_ANDROID_MTP
+static char *usb_functions_mtp[] = {
+ "mtp",
+};
+#endif
+
+#ifdef CONFIG_USB_ANDROID_ADB
+static char *usb_functions_adb[] = {
+ "adb",
+};
+#endif
+
+#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB)
+static char *usb_functions_ums_adb[] = {
+ "usb_mass_storage",
+ "adb",
+};
+#endif
+
+#if defined(CONFIG_USB_ANDROID_MTP) && defined(CONFIG_USB_ANDROID_ADB)
+static char *usb_functions_mtp_adb[] = {
+ "mtp",
+ "adb",
+};
+#endif
+
+#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB) && defined(CONFIG_USB_ANDROID_ACM)
+static char *usb_functions_ums_adb_acm[] = {
+ "usb_mass_storage",
+ "adb",
+ "acm",
+};
+#endif
+
+static char *usb_functions_all[] = {
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ "rndis",
+#endif
+#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
+ "usb_mass_storage",
+#endif
+#ifdef CONFIG_USB_ANDROID_MTP
+ "mtp",
+#endif
+#ifdef CONFIG_USB_ANDROID_ADB
+ "adb",
+#endif
+#ifdef CONFIG_USB_ANDROID_ACM
+ "acm",
+#endif
+};
+
+static struct android_usb_product usb_products[] = {
+#ifdef CONFIG_USB_ANDROID_MASS_STORAGE
+ {
+ .product_id = SAMSUNG_UMS_ONLY_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_ums),
+ .functions = usb_functions_ums,
+ },
+#endif
+#ifdef CONFIG_USB_ANDROID_RNDIS
+ {
+ .product_id = SAMSUNG_RNDIS_ONLY_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_rndis),
+ .functions = usb_functions_rndis,
+ },
+#endif
+#ifdef CONFIG_USB_ANDROID_MTP
+ {
+ .product_id = SAMSUNG_MTP_ONLY_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_mtp),
+ .functions = usb_functions_mtp,
+ },
+#endif
+#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB)
+ {
+ .product_id = SAMSUNG_UMS_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_ums_adb),
+ .functions = usb_functions_ums_adb,
+ },
+#endif
+#if defined(CONFIG_USB_ANDROID_MTP) && defined(CONFIG_USB_ANDROID_ADB)
+ {
+ .product_id = SAMSUNG_MTP_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_mtp_adb),
+ .functions = usb_functions_mtp_adb,
+ },
+#endif
+#ifdef CONFIG_USB_ANDROID_ADB
+ {
+ .product_id = SAMSUNG_ADB_ONLY_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_adb),
+ .functions = usb_functions_adb,
+ },
+#endif
+#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB) && defined(CONFIG_USB_ANDROID_ACM)
+ {
+ .product_id = SAMSUNG_UMS_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_ums_adb_acm),
+ .functions = usb_functions_ums_adb_acm,
+ },
+#endif
+};
+
+static char device_serial[MAX_USB_SERIAL_NUM] = "0123456789ABCDEF";
+
+/* standard android USB platform data */
+static struct android_usb_platform_data android_usb_pdata = {
+ .vendor_id = SAMSUNG_VENDOR_ID,
+ .product_id = SAMSUNG_PRODUCT_ID,
+ .manufacturer_name = "SAMSUNG",
+ .product_name = "S5P OTG-USB",
+ .serial_number = device_serial,
+ .num_products = ARRAY_SIZE(usb_products),
+ .products = usb_products,
+ .num_functions = ARRAY_SIZE(usb_functions_all),
+ .functions = usb_functions_all,
+};
+
+struct platform_device s3c_device_android_usb = {
+ .name = "android_usb",
+ .id = -1,
+ .dev = {
+ .platform_data = &android_usb_pdata,
+ },
+};
+
+static struct usb_mass_storage_platform_data ums_pdata = {
+ .vendor = "SAMSUNG",
+ .product = "S5P UMS",
+ .release = 1,
+ .nluns = 1,
+};
+struct platform_device s3c_device_usb_mass_storage = {
+ .name = "usb_mass_storage",
+ .id = -1,
+ .dev = {
+ .platform_data = &ums_pdata,
+ },
+};
+
+#ifdef CONFIG_USB_ANDROID_RNDIS
+static struct usb_ether_platform_data rndis_pdata = {
+/* ethaddr is filled by board_serialno_setup */
+ .vendorID = SAMSUNG_VENDOR_ID,
+ .vendorDescr = "SAMSUNG",
+};
+struct platform_device s3c_device_rndis = {
+ .name = "rndis",
+ .id = -1,
+ .dev = {
+ .platform_data = &rndis_pdata,
+ },
+};
+#endif
+#endif /* CONFIG_USB_ANDROID */
+
diff --git a/arch/arm/plat-s5p/include/plat/ace-core.h b/arch/arm/plat-s5p/include/plat/ace-core.h
new file mode 100644
index 0000000..7eb60b7
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/ace-core.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/plat-s5p/include/plat/ace-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung Advanced Crypto Engine core function
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ACE_CORE_H
+#define __ASM_PLAT_ACE_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s5p_ace_setname(char *name)
+{
+ s5p_device_ace.name = name;
+}
+
+#endif /* __ASM_PLAT_ACE_CORE_H */
diff --git a/arch/arm/plat-s5p/include/plat/bts.h b/arch/arm/plat-s5p/include/plat/bts.h
new file mode 100644
index 0000000..a7cbc18
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/bts.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __EXYNOS_BTS_H_
+#define __EXYNOS_BTS_H_
+
+#include <plat/pd.h>
+
+enum exynos_bts_id {
+ BTS_CPU,
+ BTS_DISP,
+ BTS_DISP10,
+ BTS_DISP11,
+ BTS_TV,
+ BTS_TV0,
+ BTS_TV1,
+ BTS_C2C,
+ BTS_JPEG,
+ BTS_MDMA1,
+ BTS_ROTATOR,
+ BTS_GSCL,
+ BTS_GSCL0,
+ BTS_GSCL1,
+ BTS_GSCL2,
+ BTS_GSCL3,
+ BTS_MFC,
+ BTS_MFC0,
+ BTS_MFC1,
+ BTS_G3D_ACP,
+ BTS_ISP0,
+ BTS_ISP1,
+ BTS_FIMC_ISP,
+ BTS_FIMC_FD,
+ BTS_FIMC_ODC,
+ BTS_FIMC_DIS0,
+ BTS_FIMC_DIS1,
+ BTS_3DNR,
+ BTS_SCALER_C,
+ BTS_SCALER_P
+};
+
+enum bts_priority {
+ BTS_LOW,
+ BTS_BE,
+ BTS_HARDTIME,
+};
+
+enum bts_fbm_group {
+ BTS_FBM_G0_L = (1<<1),
+ BTS_FBM_G0_R = (1<<2),
+ BTS_FBM_G1_L = (1<<3),
+ BTS_FBM_G1_R = (1<<4),
+ BTS_FBM_G2_L = (1<<5),
+ BTS_FBM_G2_R = (1<<6),
+};
+
+struct exynos_fbm_resource {
+ enum bts_fbm_group fbm_group;
+ enum bts_priority priority;
+ u32 base;
+};
+
+struct exynos_fbm_pdata {
+ struct exynos_fbm_resource *res;
+ int res_num;
+};
+
+struct exynos_bts_pdata {
+ enum exynos_bts_id id;
+ enum bts_priority def_priority;
+ enum exynos_pd_block pd_block;
+ char *clk_name;
+ struct exynos_fbm_pdata *fbm;
+ int res_num;
+};
+
+/* BTS functions */
+void exynos_bts_enable(enum exynos_pd_block pd_block);
+void exynos_bts_set_priority(enum bts_priority prior);
+#ifdef CONFIG_S5P_BTS
+#define bts_enable(a) exynos_bts_enable(a);
+#else
+#define bts_enable(a) do {} while (0)
+#endif
+#endif /* __EXYNOS_BTS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/csis.h b/arch/arm/plat-s5p/include/plat/csis.h
new file mode 100644
index 0000000..1cb1fae
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/csis.h
@@ -0,0 +1,45 @@
+/* linux/arch/arm/plat-s5p/include/plat/csis.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform header file for MIPI-CSI2 driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_CSIS_H
+#define __ASM_PLAT_CSIS_H __FILE__
+
+#define to_csis_plat(d) (to_platform_device(d)->dev.platform_data)
+
+struct platform_device;
+struct clk;
+
+struct s3c_platform_csis {
+ char *srclk_name;
+ char *clk_name;
+ unsigned long clk_rate;
+
+ void (*cfg_gpio)(void);
+ void (*cfg_phy_global)(int on);
+ int (*clk_on)(struct platform_device *pdev, struct clk **clk);
+ int (*clk_off)(struct platform_device *pdev, struct clk **clk);
+};
+#ifdef CONFIG_ARCH_EXYNOS4
+extern void s3c_csis0_set_platdata(struct s3c_platform_csis *csis);
+extern void s3c_csis1_set_platdata(struct s3c_platform_csis *csis);
+extern void s3c_csis0_cfg_gpio(void);
+extern void s3c_csis1_cfg_gpio(void);
+extern void s3c_csis0_cfg_phy_global(int on);
+extern void s3c_csis1_cfg_phy_global(int on);
+#else
+extern void s3c_csis_set_platdata(struct s3c_platform_csis *csis);
+extern void s3c_csis_cfg_gpio(void);
+extern void s3c_csis_cfg_phy_global(int on);
+#endif
+extern int s3c_csis_clk_on(struct platform_device *pdev, struct clk **clk);
+extern int s3c_csis_clk_off(struct platform_device *pdev, struct clk **clk);
+#endif /* __ASM_PLAT_CSIS_H */
diff --git a/arch/arm/plat-s5p/include/plat/dp.h b/arch/arm/plat-s5p/include/plat/dp.h
new file mode 100644
index 0000000..0c4c97b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/dp.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * Samsung S5P series DP device support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef PLAT_S5P_DP_H_
+#define PLAT_S5P_DP_H_ __FILE__
+
+#include <video/s5p-dp.h>
+
+extern void s5p_dp_set_platdata(struct s5p_dp_platdata *pd);
+extern void s5p_dp_phy_init(void);
+extern void s5p_dp_phy_exit(void);
+
+#endif /* PLAT_S5P_DP_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/dsim.h b/arch/arm/plat-s5p/include/plat/dsim.h
new file mode 100644
index 0000000..bbfb52b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/dsim.h
@@ -0,0 +1,330 @@
+/* linux/arm/arch/plat-s5p/include/plat/dsim.h
+ *
+ * Platform data header for Samsung SoC MIPI-DSIM.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _DSIM_H
+#define _DSIM_H
+
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/notifier.h>
+
+#include <linux/regulator/consumer.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#define to_dsim_plat(d) (to_platform_device(d)->dev.platform_data)
+
+enum mipi_dsim_interface_type {
+ DSIM_COMMAND,
+ DSIM_VIDEO
+};
+
+enum mipi_dsim_virtual_ch_no {
+ DSIM_VIRTUAL_CH_0,
+ DSIM_VIRTUAL_CH_1,
+ DSIM_VIRTUAL_CH_2,
+ DSIM_VIRTUAL_CH_3
+};
+
+enum mipi_dsim_burst_mode_type {
+ DSIM_NON_BURST_SYNC_EVENT,
+ DSIM_NON_BURST_SYNC_PULSE = 2,
+ DSIM_BURST = 1,
+ DSIM_NON_VIDEO_MODE = 4
+};
+
+enum mipi_dsim_no_of_data_lane {
+ DSIM_DATA_LANE_1,
+ DSIM_DATA_LANE_2,
+ DSIM_DATA_LANE_3,
+ DSIM_DATA_LANE_4
+};
+
+enum mipi_dsim_byte_clk_src {
+ DSIM_PLL_OUT_DIV8,
+ DSIM_EXT_CLK_DIV8,
+ DSIM_EXT_CLK_BYPASS
+};
+
+enum mipi_dsim_pixel_format {
+ DSIM_CMD_3BPP,
+ DSIM_CMD_8BPP,
+ DSIM_CMD_12BPP,
+ DSIM_CMD_16BPP,
+ DSIM_VID_16BPP_565,
+ DSIM_VID_18BPP_666PACKED,
+ DSIM_18BPP_666LOOSELYPACKED,
+ DSIM_24BPP_888
+};
+
+/**
+ * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
+ *
+ * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
+ * @eot_disable: enable or disable EoT packet in HS mode.
+ * @auto_vertical_cnt: specifies auto vertical count mode.
+ * in Video mode, the vertical line transition uses line counter
+ * configured by VSA, VBP, and Vertical resolution.
+ * If this bit is set to '1', the line counter does not use VSA and VBP
+ * registers.(in command mode, this variable is ignored)
+ * @hse: set horizontal sync event mode.
+ * In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
+ * start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
+ * this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
+ * (in mommand mode, this variable is ignored)
+ * @hfp: specifies HFP disable mode.
+ * if this variable is set, DSI master ignores HFP area in VIDEO mode.
+ * (in command mode, this variable is ignored)
+ * @hbp: specifies HBP disable mode.
+ * if this variable is set, DSI master ignores HBP area in VIDEO mode.
+ * (in command mode, this variable is ignored)
+ * @hsa: specifies HSA disable mode.
+ * if this variable is set, DSI master ignores HSA area in VIDEO mode.
+ * (in command mode, this variable is ignored)
+ * @e_interface: specifies interface to be used.(CPU or RGB interface)
+ * @e_virtual_ch: specifies virtual channel number that main or
+ * sub diaplsy uses.
+ * @e_pixel_format: specifies pixel stream format for main or sub display.
+ * @e_burst_mode: selects Burst mode in Video mode.
+ * in Non-burst mode, RGB data area is filled with RGB data and NULL
+ * packets, according to input bandwidth of RGB interface.
+ * In Burst mode, RGB data area is filled with RGB data only.
+ * @e_no_data_lane: specifies data lane count to be used by Master.
+ * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
+ * DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
+ * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
+ * clock(System clock cycle base)
+ * if the timer value goes to 0x00000000, the clock stable bit of
+status
+ * and interrupt register is set.
+ * @esc_clk: specifies escape clock frequency for getting the escape clock
+ * prescaler value.
+ * @stop_holding_cnt: specifies the interval value between transmitting
+ * read packet(or write "set_tear_on" command) and BTA request.
+ * after transmitting read packet or write "set_tear_on" command,
+ * BTA requests to D-PHY automatically. this counter value specifies
+ * the interval between them.
+ * @bta_timeout: specifies the timer for BTA.
+ * this register specifies time out from BTA request to change
+ * the direction with respect to Tx escape clock.
+ * @rx_timeout: specifies the timer for LP Rx mode timeout.
+ * this register specifies time out on how long RxValid deasserts,
+ * after RxLpdt asserts with respect to Tx escape clock.
+ * - RxValid specifies Rx data valid indicator.
+ * - RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
+ * - RxValid and RxLpdt specifies signal from D-PHY.
+ * @lcd_panel_info: pointer for lcd panel specific structure.
+ * this structure specifies width, height, timing and polarity and so
+on.
+ * @mipi_ddi_pd: pointer to lcd panel platform data.
+ */
+struct mipi_dsim_config {
+ unsigned char auto_flush;
+ unsigned char eot_disable;
+
+ unsigned char auto_vertical_cnt;
+ unsigned char hse;
+ unsigned char hfp;
+ unsigned char hbp;
+ unsigned char hsa;
+
+ enum mipi_dsim_interface_type e_interface;
+ enum mipi_dsim_virtual_ch_no e_virtual_ch;
+ enum mipi_dsim_pixel_format e_pixel_format;
+ enum mipi_dsim_burst_mode_type e_burst_mode;
+ enum mipi_dsim_no_of_data_lane e_no_data_lane;
+ enum mipi_dsim_byte_clk_src e_byte_clk;
+
+ unsigned char p;
+ unsigned short m;
+ unsigned char s;
+
+ unsigned int pll_stable_time;
+ unsigned long esc_clk;
+
+ unsigned short stop_holding_cnt;
+ unsigned char bta_timeout;
+ unsigned short rx_timeout;
+
+ void *lcd_panel_info;
+ void *dsim_ddi_pd;
+};
+
+/* for RGB Interface */
+struct mipi_dsi_lcd_timing {
+ int left_margin;
+ int right_margin;
+ int upper_margin;
+ int lower_margin;
+ int hsync_len;
+ int vsync_len;
+};
+
+/* for CPU Interface */
+struct mipi_dsi_cpu_timing {
+ unsigned int cs_setup;
+ unsigned int wr_setup;
+ unsigned int wr_act;
+ unsigned int wr_hold;
+};
+
+struct mipi_dsi_lcd_size {
+ unsigned int width;
+ unsigned int height;
+};
+
+struct mipi_dsim_lcd_config {
+ enum mipi_dsim_interface_type e_interface;
+ unsigned int parameter[3];
+
+ /* lcd panel info */
+ struct mipi_dsi_lcd_timing rgb_timing;
+ struct mipi_dsi_cpu_timing cpu_timing;
+ struct mipi_dsi_lcd_size lcd_size;
+ /* platform data for lcd panel based on MIPI-DSI. */
+ void *mipi_ddi_pd;
+};
+
+/**
+ * struct mipi_dsim_device - global interface for mipi-dsi driver.
+ *
+ * @dev: driver model representation of the device.
+ * @clock: pointer to MIPI-DSI clock of clock framework.
+ * @irq: interrupt number to MIPI-DSI controller.
+ * @reg_base: base address to memory mapped SRF of MIPI-DSI controller.
+ * (virtual address)
+ * @pd: pointer to MIPI-DSI driver platform data.
+ * @dsim_info: infomation for configuring mipi-dsi controller.
+ * @master_ops: callbacks to mipi-dsi operations.
+ * @lcd_info: pointer to mipi_lcd_info structure.
+ * @state: specifies status of MIPI-DSI controller.
+ * the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
+ * @data_lane: specifiec enabled data lane number.
+ * this variable would be set by driver according to e_no_data_lane
+ * automatically.
+ * @e_clk_src: select byte clock source.
+ * this variable would be set by driver according to e_byte_clock
+ * automatically.
+ * @hs_clk: HS clock rate.
+ * this variable would be set by driver automatically.
+ * @byte_clk: Byte clock rate.
+ * this variable would be set by driver automatically.
+ * @escape_clk: ESCAPE clock rate.
+ * this variable would be set by driver automatically.
+ * @freq_band: indicates Bitclk frequency band for D-PHY global timing.
+ * Serial Clock(=ByteClk X 8) FreqBand[3:0]
+ * ~ 99.99 MHz 0000
+ * 100 ~ 119.99 MHz 0001
+ * 120 ~ 159.99 MHz 0010
+ * 160 ~ 199.99 MHz 0011
+ * 200 ~ 239.99 MHz 0100
+ * 140 ~ 319.99 MHz 0101
+ * 320 ~ 389.99 MHz 0110
+ * 390 ~ 449.99 MHz 0111
+ * 450 ~ 509.99 MHz 1000
+ * 510 ~ 559.99 MHz 1001
+ * 560 ~ 639.99 MHz 1010
+ * 640 ~ 689.99 MHz 1011
+ * 690 ~ 769.99 MHz 1100
+ * 770 ~ 869.99 MHz 1101
+ * 870 ~ 949.99 MHz 1110
+ * 950 ~ 1000 MHz 1111
+ * this variable would be calculated by driver automatically.
+ */
+struct mipi_dsim_device {
+ struct device *dev;
+ struct resource *res;
+ struct clk *clock;
+ unsigned int irq;
+ void __iomem *reg_base;
+
+ struct s5p_platform_mipi_dsim *pd;
+ struct mipi_dsim_config *dsim_config;
+
+ unsigned int state;
+ unsigned int data_lane;
+ enum mipi_dsim_byte_clk_src e_clk_src;
+ unsigned long hs_clk;
+ unsigned long byte_clk;
+ unsigned long escape_clk;
+ unsigned char freq_band;
+ unsigned char id;
+ struct notifier_block fb_notif;
+
+ struct mipi_dsim_lcd_driver *dsim_lcd_drv;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+};
+
+/**
+ * struct s5p_platform_mipi_dsim - interface to platform data
+ * for mipi-dsi driver.
+ *
+ * @mipi_dsim_config: pointer of structure for configuring mipi-dsi controller.
+ * @dsim_lcd_info: pointer to structure for configuring
+ * mipi-dsi based lcd panel.
+ * @mipi_power: callback pointer for enabling or disabling mipi power.
+ * @part_reset: callback pointer for reseting mipi phy.
+ * @init_d_phy: callback pointer for enabing d_phy of dsi master.
+ * @get_fb_frame_done: callback pointer for getting frame done status of
+the
+ * display controller(FIMD).
+ * @trigger: callback pointer for triggering display controller(FIMD)
+ * in case of CPU mode.
+ * @delay_for_stabilization: specifies stable time.
+ * this delay needs when writing data on SFR
+ * after mipi mode became LP mode.
+ */
+struct s5p_platform_mipi_dsim {
+ const char clk_name[16];
+
+ struct mipi_dsim_config *dsim_config;
+ struct mipi_dsim_lcd_config *dsim_lcd_config;
+
+ unsigned int delay_for_stabilization;
+
+ int (*mipi_power) (struct mipi_dsim_device *dsim, unsigned int
+ enable);
+ int (*part_reset) (struct mipi_dsim_device *dsim);
+ int (*init_d_phy) (struct mipi_dsim_device *dsim, unsigned int enable);
+ int (*get_fb_frame_done) (struct fb_info *info);
+ void (*trigger) (struct fb_info *info);
+};
+
+/**
+ * driver structure for mipi-dsi based lcd panel.
+ *
+ * this structure should be registered by lcd panel driver.
+ * mipi-dsi driver seeks lcd panel registered through name field
+ * and calls these callback functions in appropriate time.
+ */
+
+struct mipi_dsim_lcd_driver {
+ int (*probe)(struct mipi_dsim_device *dsim);
+ int (*suspend)(struct mipi_dsim_device *dsim);
+ int (*displayon)(struct mipi_dsim_device *dsim);
+ int (*resume)(struct mipi_dsim_device *dsim);
+};
+
+/**
+ * register mipi_dsim_lcd_driver object defined by lcd panel driver
+ * to mipi-dsi driver.
+ */
+extern int s5p_dsim_part_reset(struct mipi_dsim_device *dsim);
+extern int s5p_dsim_init_d_phy(struct mipi_dsim_device *dsim,
+ unsigned int enable);
+extern void s5p_dsim_set_platdata(struct s5p_platform_mipi_dsim * pd);
+#endif /* _DSIM_H */
diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-s5p/include/plat/ehci.h
index 6ae6810..0cdc0b5 100644
--- a/arch/arm/plat-s5p/include/plat/ehci.h
+++ b/arch/arm/plat-s5p/include/plat/ehci.h
@@ -14,8 +14,28 @@
struct s5p_ehci_platdata {
int (*phy_init)(struct platform_device *pdev, int type);
int (*phy_exit)(struct platform_device *pdev, int type);
+ int (*phy_suspend)(struct platform_device *pdev, int type);
+ int (*phy_resume)(struct platform_device *pdev, int type);
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) ||\
+ defined(CONFIG_CDMA_MODEM_MDM6600)
+/* for SAMSUNG Modem*/
+ void (*noti_host_states)(struct platform_device *pdev, int type);
+ int (*get_cp_active_state)(void);
+#endif
+};
+
+struct s5p_ohci_platdata {
+ int (*phy_init)(struct platform_device *pdev, int type);
+ int (*phy_exit)(struct platform_device *pdev, int type);
+ int (*phy_suspend)(struct platform_device *pdev, int type);
+ int (*phy_resume)(struct platform_device *pdev, int type);
};
extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
+extern void s5p_ohci_set_platdata(struct s5p_ohci_platdata *pd);
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) ||\
+ defined(CONFIG_CDMA_MODEM_MDM6600)
+int s5p_ehci_port_control(struct platform_device *pdev, int port, int enable);
+#endif
#endif /* __PLAT_S5P_EHCI_H */
diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-s5p/include/plat/exynos4.h
index 907caab..474a7c0 100644
--- a/arch/arm/plat-s5p/include/plat/exynos4.h
+++ b/arch/arm/plat-s5p/include/plat/exynos4.h
@@ -12,11 +12,13 @@
/* Common init code for EXYNOS4 related SoCs */
-extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+struct s3c2410_uartcfg;
+
+extern void exynos_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void exynos4_register_clocks(void);
extern void exynos4_setup_clocks(void);
-#ifdef CONFIG_CPU_EXYNOS4210
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_CPU_EXYNOS4212)
extern int exynos4_init(void);
extern void exynos4_init_irq(void);
@@ -24,7 +26,7 @@ extern void exynos4_map_io(void);
extern void exynos4_init_clocks(int xtal);
extern struct sys_timer exynos4_timer;
-#define exynos4_init_uarts exynos4_common_init_uarts
+#define exynos4_init_uarts exynos_common_init_uarts
#else
#define exynos4_init_clocks NULL
@@ -32,3 +34,15 @@ extern struct sys_timer exynos4_timer;
#define exynos4_map_io NULL
#define exynos4_init NULL
#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+extern void exynos4210_register_clocks(void);
+#else
+#define exynos4210_register_clocks() do { } while(0)
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4212)
+extern void exynos4212_register_clocks(void);
+#else
+#define exynos4212_register_clocks() do { } while(0)
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/exynos5.h b/arch/arm/plat-s5p/include/plat/exynos5.h
new file mode 100644
index 0000000..bcc22ef
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/exynos5.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-s5p/include/plat/exynos5.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for exynos5 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for EXYNOS5 related SoCs */
+
+struct s3c2410_uartcfg;
+
+extern void exynos_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void exynos5_register_clocks(void);
+extern void exynos5_setup_clocks(void);
+
+#if defined(CONFIG_CPU_EXYNOS5210) || defined(CONFIG_CPU_EXYNOS5250)
+
+extern int exynos5_init(void);
+extern void exynos5_init_irq(void);
+extern void exynos5_map_io(void);
+extern void exynos5_init_clocks(int xtal);
+extern struct sys_timer exynos4_timer;
+
+#define exynos5_init_uarts exynos_common_init_uarts
+
+#else
+#define exynos5_init_clocks NULL
+#define exynos5_init_uarts NULL
+#define exynos5_map_io NULL
+#define exynos5_init NULL
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/fb-s5p.h b/arch/arm/plat-s5p/include/plat/fb-s5p.h
new file mode 100644
index 0000000..017a8b0
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/fb-s5p.h
@@ -0,0 +1,97 @@
+/* linux/arch/arm/plat-s5p/include/plat/fb-s5p.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Core file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_FB_S5P_H
+#define __ASM_PLAT_FB_S5P_H __FILE__
+
+#define FB_SWAP_WORD (1 << 24)
+#define FB_SWAP_HWORD (1 << 16)
+#define FB_SWAP_BYTE (1 << 8)
+#define FB_SWAP_BIT (1 << 0)
+
+struct platform_device;
+struct clk;
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+/* enumerates display mode. */
+enum {
+ SINGLE_LCD_MODE = 1,
+ DUAL_LCD_MODE = 2,
+};
+
+/* enumerates interface mode. */
+enum {
+ FIMD_RGB_INTERFACE = 1,
+ FIMD_CPU_INTERFACE = 2,
+};
+#endif
+
+struct s3c_platform_fb {
+ int hw_ver;
+ char clk_name[16];
+ int nr_wins;
+ int nr_buffers[5];
+ int default_win;
+ int swap;
+ void *lcd;
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+ unsigned int sub_lcd_enabled;
+ unsigned int machine_is_cypress;
+ unsigned int machine_is_p1p2;
+ unsigned int mdnie_is_enabled;
+ unsigned int mipi_is_enabled;
+ unsigned int interface_mode;
+
+ void *single_lcd;
+ void *dual_lcd;
+
+ void (*set_display_path)(unsigned int mode);
+ int (*reset_lcd)(void);
+
+ /* variables and interface for mDNIe */
+ char mdnie_clk_name[20];
+ void *mdnie_clk;
+ unsigned int mdnie_phy_base;
+ unsigned int ielcd_phy_base;
+ void __iomem *mdnie_mmio_base;
+ void __iomem *ielcd_mmio_base;
+ unsigned char mdnie_mode;
+
+ void (*set_mdnie_clock)(void *mdnie_clk, unsigned char enable);
+ void (*init_mdnie)(unsigned int mdnie_base,
+ unsigned int hsize, unsigned int vsize);
+ void (*mdnie_set_mode)(unsigned int mdnie_base, unsigned char mode);
+
+ void (*start_ielcd_logic)(unsigned int ielcd_base);
+ void (*init_ielcd)(unsigned int ielcd_base, void *l, void *c);
+#endif
+ void (*cfg_gpio)(struct platform_device *dev);
+ int (*backlight_on)(struct platform_device *dev);
+ int (*backlight_off)(struct platform_device *dev);
+ int (*lcd_on)(struct platform_device *dev);
+ int (*lcd_off)(struct platform_device *dev);
+ int (*clk_on)(struct platform_device *pdev, struct clk **s3cfb_clk);
+ int (*clk_off)(struct platform_device *pdev, struct clk **clk);
+};
+
+extern void s3cfb_set_platdata(struct s3c_platform_fb *fimd);
+
+/* defined by architecture to configure gpio */
+extern void s3cfb_cfg_gpio(struct platform_device *pdev);
+extern int s3cfb_backlight_on(struct platform_device *pdev);
+extern int s3cfb_backlight_off(struct platform_device *pdev);
+extern int s3cfb_lcd_on(struct platform_device *pdev);
+extern int s3cfb_lcd_off(struct platform_device *pdev);
+extern int s3cfb_clk_on(struct platform_device *pdev, struct clk **s3cfb_clk);
+extern int s3cfb_clk_off(struct platform_device *pdev, struct clk **clk);
+extern void s3cfb_get_clk_name(char *clk_name);
+#endif /* __ASM_PLAT_FB_S5P_H */
diff --git a/arch/arm/plat-s5p/include/plat/fimc.h b/arch/arm/plat-s5p/include/plat/fimc.h
new file mode 100644
index 0000000..037b70f
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/fimc.h
@@ -0,0 +1,153 @@
+/* linux/arch/arm/plat-s5p/include/plat/fimc.h
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform header file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __ASM_PLAT_FIMC_H
+#define __ASM_PLAT_FIMC_H __FILE__
+
+#include <linux/videodev2.h>
+
+#define FIMC_SRC_MAX_W 4224
+#define FIMC_SRC_MAX_H 4224
+#define FLITE_MAX_NUM 2
+
+struct platform_device;
+
+/* For exnternal camera device */
+enum fimc_cam_type {
+ CAM_TYPE_ITU = 0,
+ CAM_TYPE_MIPI = 1,
+};
+
+enum fimc_cam_format {
+ ITU_601_YCBCR422_8BIT = (1 << 31),
+ ITU_656_YCBCR422_8BIT = (0 << 31),
+ ITU_601_YCBCR422_16BIT = (1 << 29),
+ MIPI_CSI_YCBCR422_8BIT = 0x1e,
+ MIPI_CSI_RAW8 = 0x2a,
+ MIPI_CSI_RAW10 = 0x2b,
+ MIPI_CSI_RAW12 = 0x2c,
+ MIPI_USER_DEF_PACKET_1 = 0x30, /* User defined Byte-based packet 1 */
+};
+
+enum fimc_cam_order422 {
+ CAM_ORDER422_8BIT_YCBYCR = (0 << 14),
+ CAM_ORDER422_8BIT_YCRYCB = (1 << 14),
+ CAM_ORDER422_8BIT_CBYCRY = (2 << 14),
+ CAM_ORDER422_8BIT_CRYCBY = (3 << 14),
+ CAM_ORDER422_16BIT_Y4CBCRCBCR = (0 << 14),
+ CAM_ORDER422_16BIT_Y4CRCBCRCB = (1 << 14),
+};
+
+enum fimc_cam_index {
+ CAMERA_PAR_A = 0,
+ CAMERA_PAR_B = 1,
+ CAMERA_CSI_C = 2,
+ CAMERA_CSI_D = 3,
+ CAMERA_WB = 4,
+ CAMERA_WB_B = 5,
+ CAMERA_PATTERN = 6,
+};
+
+enum flite_index {
+ FLITE_IDX_A = 0,
+ FLITE_IDX_B = 1,
+};
+
+/* struct s3c_platform_camera: abstraction for input camera */
+struct s3c_platform_camera {
+ /*
+ * ITU cam A,B: 0,1
+ * CSI-2 cam C: 2
+ */
+ enum fimc_cam_index id;
+
+ enum fimc_cam_type type; /* ITU or MIPI */
+ enum fimc_cam_format fmt; /* input format */
+ enum fimc_cam_order422 order422; /* YCBCR422 order for ITU */
+ u32 pixelformat; /* default fourcc */
+
+ int i2c_busnum;
+ int (*get_i2c_busnum)(void);
+ struct i2c_board_info *info;
+ struct v4l2_subdev *sd;
+
+ const char srclk_name[16]; /* source of mclk name */
+ const char clk_name[16]; /* mclk name */
+ const char* (*get_clk_name)(void); /* mclk name */
+ u32 clk_rate; /* mclk ratio */
+ struct clk *clk; /* mclk */
+ int line_length; /* max length */
+ int width; /* default resol */
+ int height; /* default resol */
+ struct v4l2_rect window; /* real cut region from source */
+
+ int mipi_lanes; /* MIPI data lanes */
+ int mipi_settle; /* MIPI settle */
+ int mipi_align; /* MIPI data align: 24/32 */
+
+ /* Polarity: 1 if inverted polarity used */
+ int inv_pclk;
+ int inv_vsync;
+ int inv_href;
+ int inv_hsync;
+
+ int initialized;
+ /* The cam needs reset before start streaming */
+ int reset_camera;
+
+ /* Board specific power pin control */
+ int (*cam_power)(int onoff);
+ enum flite_index flite_id;
+ bool use_isp;
+ int sensor_index;
+};
+
+/* For camera interface driver */
+struct s3c_platform_fimc {
+ enum fimc_cam_index default_cam; /* index of default cam */
+#ifdef CONFIG_ARCH_EXYNOS4
+ struct s3c_platform_camera *camera[7]; /* FIXME */
+#else
+ struct s3c_platform_camera *camera[5]; /* FIXME */
+#endif
+ int hw_ver;
+ bool use_cam;
+
+ void (*cfg_gpio)(struct platform_device *pdev);
+ int (*clk_on)(struct platform_device *pdev, struct clk **clk);
+ int (*clk_off)(struct platform_device *pdev, struct clk **clk);
+};
+
+extern void s3c_fimc0_set_platdata(struct s3c_platform_fimc *fimc);
+extern void s3c_fimc1_set_platdata(struct s3c_platform_fimc *fimc);
+extern void s3c_fimc2_set_platdata(struct s3c_platform_fimc *fimc);
+#ifdef CONFIG_ARCH_EXYNOS4
+extern void s3c_fimc3_set_platdata(struct s3c_platform_fimc *fimc);
+#endif
+
+/* defined by architecture to configure gpio */
+extern void s3c_fimc0_cfg_gpio(struct platform_device *pdev);
+extern void s3c_fimc1_cfg_gpio(struct platform_device *pdev);
+extern void s3c_fimc2_cfg_gpio(struct platform_device *pdev);
+#ifdef CONFIG_ARCH_EXYNOS4
+extern void s3c_fimc3_cfg_gpio(struct platform_device *pdev);
+#endif
+/* platform specific clock functions */
+extern int s3c_fimc_clk_on(struct platform_device *pdev, struct clk **clk);
+extern int s3c_fimc_clk_off(struct platform_device *pdev, struct clk **clk);
+
+#ifdef CONFIG_DRM_EXYNOS_FIMD_WB
+#include <linux/notifier.h>
+extern int fimc_register_client(struct notifier_block *nb);
+extern int fimc_unregister_client(struct notifier_block *nb);
+#endif
+
+#endif /*__ASM_PLAT_FIMC_H */
diff --git a/arch/arm/plat-s5p/include/plat/fimg2d.h b/arch/arm/plat-s5p/include/plat/fimg2d.h
new file mode 100644
index 0000000..2a2e622
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/fimg2d.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/plat-s5p/include/plat/fimg2d.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform Data Structure for Samsung Graphics 2D Hardware
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_FIMG2D_H
+#define __ASM_ARCH_FIMG2D_H __FILE__
+
+struct fimg2d_platdata {
+ int hw_ver;
+ const char *parent_clkname;
+ const char *clkname;
+ const char *gate_clkname;
+ unsigned long clkrate;
+};
+
+extern void __init s5p_fimg2d_set_platdata(struct fimg2d_platdata *pd);
+
+#endif /* __ASM_ARCH_FIMG2D_H */
diff --git a/arch/arm/plat-s5p/include/plat/hdmi.h b/arch/arm/plat-s5p/include/plat/hdmi.h
new file mode 100644
index 0000000..3dcd034
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/hdmi.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundationr
+ */
+
+#ifndef __PLAT_SAMSUNG_HDMI_H
+#define __PLAT_SAMSUNG_HDMI_H
+
+/**
+ * Platform device data for Samsung hdmi
+ *
+ * @is_v13: use hdmi version 1.3
+ * @cfg_hpd: configure the hpd pin, if enable, set to hpd special function 3,
+ * else set to external interrupt.
+ * @get_hpd: get level value of hpd pin
+ */
+struct s5p_hdmi_platdata {
+ bool is_v13;
+ void (*cfg_hpd)(bool enable);
+ int (*get_hpd)(void);
+};
+
+extern void s5p_hdmi_set_platdata(struct s5p_hdmi_platdata *pd);
+#ifdef CONFIG_EXYNOS4_SETUP_HDMI
+extern void s5p_hdmi_cfg_hpd(bool enable);
+extern int s5p_hdmi_get_hpd(void);
+#else
+static inline void s5p_hdmi_cfg_hpd(bool enable) { }
+static inline int s5p_hdmi_get_hpd(void) { return 0; }
+#endif
+
+#endif /* __PLAT_SAMSUNG_HDMI_H */
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
index ba9121c..8f3f616 100644
--- a/arch/arm/plat-s5p/include/plat/irqs.h
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -101,7 +101,11 @@
S5P_GPIOINT_GROUP_COUNT chips, each with total number of
S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
to any gpio chip with the s5p_register_gpio_interrupt() function */
+#ifdef CONFIG_MACH_MIDAS
+#define S5P_GPIOINT_GROUP_COUNT 5
+#else
#define S5P_GPIOINT_GROUP_COUNT 4
+#endif
#define S5P_GPIOINT_GROUP_SIZE 8
#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
diff --git a/arch/arm/plat-s5p/include/plat/jpeg.h b/arch/arm/plat-s5p/include/plat/jpeg.h
new file mode 100644
index 0000000..29784fb
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/jpeg.h
@@ -0,0 +1,17 @@
+/* linux/arch/arm/plat-s5p/include/plat/jpeg.h
+ *
+ * Copyright 201i Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef __ASM_PLAT_JPEG_H
+#define __ASM_PLAT_JPEG_H __FILE__
+
+int __init exynos4_jpeg_setup_clock(struct device *dev,
+ unsigned long clk_rate);
+int __init exynos5_jpeg_setup_clock(struct device *dev,
+ unsigned long clk_rate);
+#endif /*__ASM_PLAT_JPEG_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
index d973d39..3e576956 100644
--- a/arch/arm/plat-s5p/include/plat/map-s5p.h
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -20,8 +20,10 @@
#define S5P_VA_GPIO1 S5P_VA_GPIO
#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
+#define S5P_VA_GPIO4 S3C_ADDR(0x022C0000)
#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
+#define S5P_VA_SYSRAM_NS S3C_ADDR(0x02410000)
#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
@@ -35,12 +37,34 @@
#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
-#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
-#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
+
+#define S5P_VA_GIC_CPU S3C_ADDR(0x02810000)
+#define S5P_VA_GIC_DIST S3C_ADDR(0x02820000)
#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
+#define S5P_VA_AUDSS S3C_ADDR(0x02910000)
+
+#define S5P_VA_PPMU_DMC0 S3C_ADDR(0x02930000)
+#define S5P_VA_PPMU_DMC1 S3C_ADDR(0x02932000)
+#define S5P_VA_PPMU_CPU S3C_ADDR(0x02934000)
+
+#define S5P_VA_GDL S3C_ADDR(0x02940000)
+#define S5P_VA_GDR S3C_ADDR(0x02941000)
+
+#define S5P_VA_PPMU_DDR_C S3C_ADDR(0x02936000)
+#define S5P_VA_PPMU_DDR_R1 S3C_ADDR(0x02938000)
+#define S5P_VA_PPMU_DDR_L S3C_ADDR(0x0293a000)
+#define S5P_VA_PPMU_RIGHT0_BUS S3C_ADDR(0x0293c000)
+
+#define S5P_VA_SS_PHY S3C_ADDR(0x02A00000)
+#define S5P_VA_FIMCLITE0 S3C_ADDR(0x02A10000)
+#define S5P_VA_FIMCLITE1 S3C_ADDR(0x02A20000)
+#define S5P_VA_MIPICSI0 S3C_ADDR(0x02A30000)
+#define S5P_VA_MIPICSI1 S3C_ADDR(0x02A40000)
+#define S5P_VA_FIMCLITE2 S3C_ADDR(0x02A90000)
+
#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
#define VA_VIC0 VA_VIC(0)
#define VA_VIC1 VA_VIC(1)
diff --git a/arch/arm/plat-s5p/include/plat/media.h b/arch/arm/plat-s5p/include/plat/media.h
new file mode 100644
index 0000000..61e28bc
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/media.h
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-s5p/include/plat/media.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung Media device descriptions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S5P_MEDIA_H
+#define _S5P_MEDIA_H
+
+#include <linux/types.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_CMA
+#include <linux/cma.h>
+void s5p_cma_region_reserve(struct cma_region *regions_normal,
+ struct cma_region *regions_secure,
+ size_t align_secure, const char *map);
+#else
+
+struct s5p_media_device {
+ u32 id;
+ const char *name;
+ u32 bank;
+ size_t memsize;
+ dma_addr_t paddr;
+};
+
+extern struct meminfo meminfo;
+extern dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank);
+extern size_t s5p_get_media_memsize_bank(int dev_id, int bank);
+extern dma_addr_t s5p_get_media_membase_bank(int bank);
+extern void s5p_reserve_mem(size_t boundary);
+#endif /* CONFIG_CMA */
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/mipi_csis.h b/arch/arm/plat-s5p/include/plat/mipi_csis.h
index 9bd254c..561a8c6 100644
--- a/arch/arm/plat-s5p/include/plat/mipi_csis.h
+++ b/arch/arm/plat-s5p/include/plat/mipi_csis.h
@@ -39,5 +39,7 @@ struct s5p_platform_mipi_csis {
* false to disable D-PHY
*/
int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
+extern struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data;
+extern struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data;
#endif /* PLAT_S5P_MIPI_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/mipi_dsi.h b/arch/arm/plat-s5p/include/plat/mipi_dsi.h
new file mode 100644
index 0000000..9fcde67
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/mipi_dsi.h
@@ -0,0 +1,51 @@
+/* linux/arm/arch/mach-s5pc110/include/plat/mipi_dsi.h
+ *
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ * InKi Dae <inki.dae <at> samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _MIPI_DSI_H
+#define _MIPI_DSI_H
+
+#if defined(CONFIG_LCD_MIPI_S6E8AB0)
+extern struct mipi_dsim_lcd_driver s6e8ab0_mipi_lcd_driver;
+#elif defined (CONFIG_LCD_MIPI_S6E63M0)
+extern struct mipi_dsim_lcd_driver s6e63m0_mipi_lcd_driver;
+#elif defined (CONFIG_LCD_MIPI_TC358764)
+extern struct mipi_dsim_lcd_driver tc358764_mipi_lcd_driver;
+#endif
+
+extern int s5p_mipi_dsi_wr_data(struct mipi_dsim_device *dsim,
+ unsigned int data_id, unsigned int data0, unsigned int data1);
+
+enum mipi_ddi_interface {
+ RGB_IF = 0x4000,
+ I80_IF = 0x8000,
+ YUV_601 = 0x10000,
+ YUV_656 = 0x20000,
+ MIPI_VIDEO = 0x1000,
+ MIPI_COMMAND = 0x2000,
+};
+
+enum mipi_ddi_panel_select {
+ DDI_MAIN_LCD = 0,
+ DDI_SUB_LCD = 1,
+};
+
+enum mipi_ddi_model {
+ S6DR117 = 0,
+};
+
+enum mipi_ddi_parameter {
+ /* DSIM video interface parameter */
+ DSI_VIRTUAL_CH_ID = 0,
+ DSI_FORMAT = 1,
+ DSI_VIDEO_MODE_SEL = 2,
+};
+
+#endif /* _MIPI_DSI_H */
diff --git a/arch/arm/plat-s5p/include/plat/mipi_dsim2.h b/arch/arm/plat-s5p/include/plat/mipi_dsim2.h
new file mode 100644
index 0000000..3aaff61
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/mipi_dsim2.h
@@ -0,0 +1,392 @@
+/* linux/arm/arch/plat-s5p/include/plat/mipi_dsim2.h
+ *
+ * Platform data header for Samsung SoC MIPI-DSIM.
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _MIPI_DSIM2_H
+#define _MIPI_DSIM2_H
+
+#include <linux/device.h>
+#include <linux/fb.h>
+
+#define PANEL_NAME_SIZE (32)
+
+/*
+ * enumurate display interface type.
+ *
+ * DSIM_COMMAND means cpu interface and rgb interface for DSIM_VIDEO.
+ *
+ * P.S. MIPI DSI Master has two display controller intefaces, RGB Interface
+ * for main display and CPU Interface(same as I80 Interface) for main
+ * and sub display.
+ */
+enum mipi_dsim_interface_type {
+ DSIM_COMMAND,
+ DSIM_VIDEO
+};
+
+enum mipi_dsim_virtual_ch_no {
+ DSIM_VIRTUAL_CH_0,
+ DSIM_VIRTUAL_CH_1,
+ DSIM_VIRTUAL_CH_2,
+ DSIM_VIRTUAL_CH_3
+};
+
+enum mipi_dsim_burst_mode_type {
+ DSIM_NON_BURST_SYNC_EVENT,
+ DSIM_BURST_SYNC_EVENT,
+ DSIM_NON_BURST_SYNC_PULSE,
+ DSIM_BURST,
+ DSIM_NON_VIDEO_MODE
+};
+
+enum mipi_dsim_no_of_data_lane {
+ DSIM_DATA_LANE_1,
+ DSIM_DATA_LANE_2,
+ DSIM_DATA_LANE_3,
+ DSIM_DATA_LANE_4
+};
+
+enum mipi_dsim_byte_clk_src {
+ DSIM_PLL_OUT_DIV8,
+ DSIM_EXT_CLK_DIV8,
+ DSIM_EXT_CLK_BYPASS
+};
+
+enum mipi_dsim_pixel_format {
+ DSIM_CMD_3BPP,
+ DSIM_CMD_8BPP,
+ DSIM_CMD_12BPP,
+ DSIM_CMD_16BPP,
+ DSIM_VID_16BPP_565,
+ DSIM_VID_18BPP_666PACKED,
+ DSIM_18BPP_666LOOSELYPACKED,
+ DSIM_24BPP_888
+};
+
+/**
+ * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
+ *
+ * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
+ * @eot_disable: enable or disable EoT packet in HS mode.
+ * @auto_vertical_cnt: specifies auto vertical count mode.
+ * in Video mode, the vertical line transition uses line counter
+ * configured by VSA, VBP, and Vertical resolution.
+ * If this bit is set to '1', the line counter does not use VSA and VBP
+ * registers.(in command mode, this variable is ignored)
+ * @hse: set horizontal sync event mode.
+ * In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
+ * start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
+ * this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
+ * (in mommand mode, this variable is ignored)
+ * @hfp: specifies HFP disable mode.
+ * if this variable is set, DSI master ignores HFP area in VIDEO mode.
+ * (in command mode, this variable is ignored)
+ * @hbp: specifies HBP disable mode.
+ * if this variable is set, DSI master ignores HBP area in VIDEO mode.
+ * (in command mode, this variable is ignored)
+ * @hsa: specifies HSA disable mode.
+ * if this variable is set, DSI master ignores HSA area in VIDEO mode.
+ * (in command mode, this variable is ignored)
+ * @cma_allow: specifies the number of horizontal lines, where command packet
+ * transmission is allowed after Stable VFP period.
+ * @e_interface: specifies interface to be used.(CPU or RGB interface)
+ * @e_virtual_ch: specifies virtual channel number that main or
+ * sub diaplsy uses.
+ * @e_pixel_format: specifies pixel stream format for main or sub display.
+ * @e_burst_mode: selects Burst mode in Video mode.
+ * in Non-burst mode, RGB data area is filled with RGB data and NULL
+ * packets, according to input bandwidth of RGB interface.
+ * In Burst mode, RGB data area is filled with RGB data only.
+ * @e_no_data_lane: specifies data lane count to be used by Master.
+ * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
+ * DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
+ * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
+ * clock(System clock cycle base)
+ * if the timer value goes to 0x00000000, the clock stable bit of status
+ * and interrupt register is set.
+ * @esc_clk: specifies escape clock frequency for getting the escape clock
+ * prescaler value.
+ * @stop_holding_cnt: specifies the interval value between transmitting
+ * read packet(or write "set_tear_on" command) and BTA request.
+ * after transmitting read packet or write "set_tear_on" command,
+ * BTA requests to D-PHY automatically. this counter value specifies
+ * the interval between them.
+ * @bta_timeout: specifies the timer for BTA.
+ * this register specifies time out from BTA request to change
+ * the direction with respect to Tx escape clock.
+ * @rx_timeout: specifies the timer for LP Rx mode timeout.
+ * this register specifies time out on how long RxValid deasserts,
+ * after RxLpdt asserts with respect to Tx escape clock.
+ * - RxValid specifies Rx data valid indicator.
+ * - RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
+ * - RxValid and RxLpdt specifies signal from D-PHY.
+ */
+struct mipi_dsim_config {
+ unsigned char auto_flush;
+ unsigned char eot_disable;
+
+ unsigned char auto_vertical_cnt;
+ unsigned char hse;
+ unsigned char hfp;
+ unsigned char hbp;
+ unsigned char hsa;
+ unsigned char cmd_allow;
+
+ enum mipi_dsim_interface_type e_interface;
+ enum mipi_dsim_virtual_ch_no e_virtual_ch;
+ enum mipi_dsim_pixel_format e_pixel_format;
+ enum mipi_dsim_burst_mode_type e_burst_mode;
+ enum mipi_dsim_no_of_data_lane e_no_data_lane;
+ enum mipi_dsim_byte_clk_src e_byte_clk;
+
+ /*
+ * ===========================================
+ * | P | M | S | MHz |
+ * -------------------------------------------
+ * | 3 | 100 | 3 | 100 |
+ * | 3 | 100 | 2 | 200 |
+ * | 3 | 63 | 1 | 252 |
+ * | 4 | 100 | 1 | 300 |
+ * | 4 | 110 | 1 | 330 |
+ * | 12 | 350 | 1 | 350 |
+ * | 3 | 100 | 1 | 400 |
+ * | 4 | 150 | 1 | 450 |
+ * | 6 | 118 | 1 | 472 |
+ * | 3 | 120 | 1 | 480 |
+ * | 12 | 250 | 0 | 500 |
+ * | 4 | 100 | 0 | 600 |
+ * | 3 | 81 | 0 | 648 |
+ * | 3 | 88 | 0 | 704 |
+ * | 3 | 90 | 0 | 720 |
+ * | 3 | 100 | 0 | 800 |
+ * | 12 | 425 | 0 | 850 |
+ * | 4 | 150 | 0 | 900 |
+ * | 12 | 475 | 0 | 950 |
+ * | 6 | 250 | 0 | 1000 |
+ * -------------------------------------------
+ */
+
+ /*
+ * pms could be calculated as the following.
+ * M * 24 / P * 2 ^ S = MHz
+ */
+ unsigned char p;
+ unsigned short m;
+ unsigned char s;
+
+ unsigned int pll_stable_time;
+ unsigned long esc_clk;
+
+ unsigned short stop_holding_cnt;
+ unsigned char bta_timeout;
+ unsigned short rx_timeout;
+};
+
+/**
+ * struct mipi_dsim_device - global interface for mipi-dsi driver.
+ *
+ * @dev: driver model representation of the device.
+ * @id: unique device id.
+ * @clock: pointer to MIPI-DSI clock of clock framework.
+ * @irq: interrupt number to MIPI-DSI controller.
+ * @reg_base: base address to memory mapped SRF of MIPI-DSI controller.
+ * (virtual address)
+ * @lock: the mutex protecting this data structure.
+ * @dsim_info: infomation for configuring mipi-dsi controller.
+ * @master_ops: callbacks to mipi-dsi operations.
+ * @dsim_lcd_dev: pointer to activated ddi device.
+ * (it would be registered by mipi-dsi driver.)
+ * @dsim_lcd_drv: pointer to activated_ddi driver.
+ * (it would be registered by mipi-dsi driver.)
+ * @lcd_info: pointer to mipi_lcd_info structure.
+ * @early_blank_used_t: indicate whether mipi blank function is called
+ * or not by early fb blank envent and dpms operation of drm needs
+ * this flag.
+ * @state: specifies status of MIPI-DSI controller.
+ * the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
+ * @data_lane: specifiec enabled data lane number.
+ * this variable would be set by driver according to e_no_data_lane
+ * automatically.
+ * @e_clk_src: select byte clock source.
+ * @pd: pointer to MIPI-DSI driver platform data.
+ * @reg_vdd10: 1.0V regulator for mipi.
+ * @reg_vdd18: 1.8V regulator for mipi.
+ * @suspended: indicate mipi-dsi driver is suspended or not.
+ * @enabled: power enable flag.
+ */
+struct mipi_dsim_device {
+ struct device *dev;
+ int id;
+ struct resource *res;
+ struct clk *clock;
+ unsigned int irq;
+ void __iomem *reg_base;
+ struct mutex lock;
+
+ struct mipi_dsim_config *dsim_config;
+ struct mipi_dsim_master_ops *master_ops;
+ struct mipi_dsim_lcd_device *dsim_lcd_dev;
+ struct mipi_dsim_lcd_driver *dsim_lcd_drv;
+
+ atomic_t early_blank_used_t;
+ unsigned int state;
+ unsigned int data_lane;
+ enum mipi_dsim_byte_clk_src e_clk_src;
+
+ struct s5p_platform_mipi_dsim *pd;
+
+ struct regulator *reg_vdd10;
+ struct regulator *reg_vdd18;
+ bool suspended;
+ bool enabled;
+};
+
+/**
+ * struct s5p_platform_mipi_dsim - interface to platform data
+ * for mipi-dsi driver.
+ *
+ * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver.
+ * lcd panel driver searched would be actived.
+ * @dsim_config: pointer of structure for configuring mipi-dsi controller.
+ * @lcd_panel_info: pointer for lcd panel specific structure.
+ * this structure specifies width, height, timing and polarity and so on.
+ * @mipi_power: callback pointer for enabling or disabling mipi power.
+ * @enabled: flag to check mipi is turned on mipi already from bootloader.
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct s5p_platform_mipi_dsim {
+ char lcd_panel_name[PANEL_NAME_SIZE];
+
+ struct mipi_dsim_config *dsim_config;
+ void *lcd_panel_info;
+
+ bool enabled;
+ int (*phy_enable)(struct platform_device *pdev, bool on);
+};
+/**
+ * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations.
+ *
+ * @cmd_write: transfer command to lcd panel at LP mode.
+ * @cmd_read: read command from rx register.
+ * @get_dsim_frame_done: get the status that all screen data have been
+ * transferred to mipi-dsi.
+ * @clear_dsim_frame_done: clear frame done status.
+ * @get_fb_frame_done: get frame done status of display controller.
+ * @trigger: trigger display controller.
+ * - this one would be used only in case of CPU mode.
+ * @set_early_blank_mode: set framebuffer blank mode.
+ * - this callback should be called prior to fb_blank() by a client driver
+ * only if needing.
+ * @set_blank_mode: set framebuffer blank mode.
+ * - this callback should be called after fb_blank() by a client driver
+ * only if needing.
+ */
+
+struct mipi_dsim_master_ops {
+ int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id,
+ unsigned int data0, unsigned int data1);
+ int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id,
+ unsigned int data0, unsigned int req_size, u8 *rx_buf);
+ int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim);
+ int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim);
+
+ int (*get_fb_frame_done)(struct fb_info *info);
+ void (*trigger)(struct fb_info *info);
+ int (*set_early_blank_mode)(struct mipi_dsim_device *dsim, int power);
+ int (*set_blank_mode)(struct mipi_dsim_device *dsim, int power);
+ void (*set_pms)(struct mipi_dsim_device *dsim, unsigned int p,
+ unsigned int m, unsigned int s, unsigned int freq_band);
+};
+
+/**
+ * device structure for mipi-dsi based lcd panel.
+ *
+ * @name: name of the device to use with this device, or an
+ * alias for that name.
+ * @dev: driver model representation of the device.
+ * @id: id of device to be registered.
+ * @bus_id: bus id for identifing connected bus
+ * and this bus id should be same as id of mipi_dsim_device.
+ * @irq: irq number for signaling when framebuffer transfer of
+ * lcd panel module is completed.
+ * this irq would be used only for MIPI-DSI based CPU mode lcd panel.
+ * @master: pointer to mipi-dsi master device object.
+ * @platform_data: lcd panel specific platform data.
+ */
+struct mipi_dsim_lcd_device {
+ char *name;
+ struct device dev;
+ int id;
+ int bus_id;
+ int irq;
+
+ struct mipi_dsim_device *master;
+ void *platform_data;
+};
+
+/**
+ * driver structure for mipi-dsi based lcd panel.
+ *
+ * this structure should be registered by lcd panel driver.
+ * mipi-dsi driver seeks lcd panel registered through name field
+ * and calls these callback functions in appropriate time.
+ *
+ * @name: name of the driver to use with this device, or an
+ * alias for that name.
+ * @id: id of driver to be registered.
+ * this id would be used for finding device object registered.
+ */
+struct mipi_dsim_lcd_driver {
+ char *name;
+ int id;
+
+ int (*check_mtp)(struct mipi_dsim_lcd_device *dsim_dev);
+ void (*power_on)(struct mipi_dsim_lcd_device *dsim_dev,
+ unsigned int enable);
+ void (*set_sequence)(struct mipi_dsim_lcd_device *dsim_dev);
+ int (*probe)(struct mipi_dsim_lcd_device *dsim_dev);
+ void (*remove)(struct mipi_dsim_lcd_device *dsim_dev);
+ void (*shutdown)(struct mipi_dsim_lcd_device *dsim_dev);
+ int (*suspend)(struct mipi_dsim_lcd_device *dsim_dev);
+ int (*resume)(struct mipi_dsim_lcd_device *dsim_dev);
+};
+
+/**
+ * register mipi_dsim_lcd_driver object defined by lcd panel driver
+ * to mipi-dsi driver.
+ */
+int s5p_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
+ *lcd_drv);
+
+/**
+ * register mipi_dsim_lcd_device to mipi-dsi master.
+ */
+int s5p_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
+ *lcd_dev);
+
+/**
+ * s5p_dsim_phy_enable - global MIPI-DSI receiver D-PHY control
+ * @pdev: MIPI-DSIM platform device
+ * @on: true to enable D-PHY and deassert its reset
+ * false to disable D-PHY
+ */
+int s5p_dsim_phy_enable(struct platform_device *pdev, bool on);
+
+/* register a callback for mipi-dsi driver to drm based fimd driver. */
+extern int fimd_register_client(int (*client_notifier)(unsigned int val,
+ void *data), void *data);
+
+/* unregister the callback above from drm based fimd driver. */
+extern void fimd_unregister_client(int (*client_notifier)(unsigned int val,
+ void *data));
+
+#endif /* _MIPI_DSIM2_H */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index bf28fad..4b50b32 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -12,6 +12,59 @@
* published by the Free Software Foundation.
*/
+#define PLL35XX_MDIV_MASK (0x3FF)
+#define PLL35XX_PDIV_MASK (0x3F)
+#define PLL35XX_SDIV_MASK (0x7)
+#define PLL35XX_MDIV_SHIFT (16)
+#define PLL35XX_PDIV_SHIFT (8)
+#define PLL35XX_SDIV_SHIFT (0)
+
+#include <asm/div64.h>
+
+static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
+{
+ u32 mdiv, pdiv, sdiv;
+ u64 fvco = baseclk;
+
+ mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+#define PLL36XX_KDIV_MASK (0xFFFF)
+#define PLL36XX_MDIV_MASK (0x1FF)
+#define PLL36XX_PDIV_MASK (0x3F)
+#define PLL36XX_SDIV_MASK (0x7)
+#define PLL36XX_MDIV_SHIFT (16)
+#define PLL36XX_PDIV_SHIFT (8)
+#define PLL36XX_SDIV_SHIFT (0)
+
+static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
+ u32 pll_con0, u32 pll_con1)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+ pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+ sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+ kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+ tmp = baseclk;
+
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+
+ return result;
+}
+
#define PLL45XX_MDIV_MASK (0x3FF)
#define PLL45XX_PDIV_MASK (0x3F)
#define PLL45XX_SDIV_MASK (0x7)
@@ -19,8 +72,6 @@
#define PLL45XX_PDIV_SHIFT (8)
#define PLL45XX_SDIV_SHIFT (0)
-#include <asm/div64.h>
-
enum pll45xx_type_t {
pll_4500,
pll_4502,
@@ -72,7 +123,6 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
- kdiv = pll_con1 & PLL46XX_KDIV_MASK;
if (pll_type == pll_4650c)
kdiv = pll_con1 & PLL4650C_KDIV_MASK;
diff --git a/arch/arm/plat-s5p/include/plat/regs-csis.h b/arch/arm/plat-s5p/include/plat/regs-csis.h
new file mode 100644
index 0000000..da80917
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-csis.h
@@ -0,0 +1,124 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-csis.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for MIPI-CSI2 Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_CSIS_H
+#define __ASM_PLAT_REGS_CSIS_H __FILE__
+
+/*
+ * Registers
+*/
+#define S3C_CSIS_CONTROL (0x00)
+#define S3C_CSIS_DPHYCTRL (0x04)
+#define S3C_CSIS_CONFIG (0x08)
+#define S3C_CSIS_DPHYSTS (0x0c)
+#define S3C_CSIS_INTMSK (0x10)
+#define S3C_CSIS_INTSRC (0x14)
+#define S3C_CSIS_RESOL (0x2c)
+#define S3C_CSIS_PKTDATA_ODD (0x2000)
+#define S3C_CSIS_PKTDATA_EVEN (0x3000)
+
+
+
+/*
+ * Bit Definitions
+*/
+/* Control Register */
+#define S3C_CSIS_CONTROL_DPDN_DEFAULT (0 << 31)
+#define S3C_CSIS_CONTROL_DPDN_SWAP (1 << 31)
+#define S3C_CSIS_CONTROL_ALIGN_32BIT (1 << 20)
+#define S3C_CSIS_CONTROL_ALIGN_24BIT (0 << 20)
+#define S3C_CSIS_CONTROL_ALIGN_MASK (1 << 20)
+#define S3C_CSIS_CONTROL_UPDATE_SHADOW (1 << 16)
+#define S3C_CSIS_CONTROL_WCLK_PCLK (0 << 8)
+#define S3C_CSIS_CONTROL_WCLK_EXTCLK (1 << 8)
+#define S3C_CSIS_CONTROL_WCLK_MASK (1 << 8)
+#define S3C_CSIS_CONTROL_RESET (1 << 4)
+#define S3C_CSIS_CONTROL_DISABLE (0 << 0)
+#define S3C_CSIS_CONTROL_ENABLE (1 << 0)
+
+/* D-PHY Control Register */
+#define S3C_CSIS_DPHYCTRL_HS_SETTLE_MASK (0x1f << 27)
+#define S3C_CSIS_DPHYCTRL_HS_SETTLE_SHIFT (27)
+#define S3C_CSIS_DPHYCTRL_ENABLE (0x1f << 0)
+
+/* Configuration Register */
+#define S3C_CSIS_CONFIG_FORMAT_SHIFT (2)
+#define S3C_CSIS_CONFIG_FORMAT_MASK (0x3f << 2)
+#define S3C_CSIS_CONFIG_NR_LANE_1 (0 << 0)
+#define S3C_CSIS_CONFIG_NR_LANE_2 (1 << 0)
+#define S3C_CSIS_CONFIG_NR_LANE_3 (1 << 1)
+#define S3C_CSIS_CONFIG_NR_LANE_4 (0x3 << 0)
+#define S3C_CSIS_CONFIG_NR_LANE_MASK (1 << 0)
+
+/* D-PHY Status Register */
+#define S3C_CSIS_DPHYSTS_STOPSTATE_LANE1 (1 << 5)
+#define S3C_CSIS_DPHYSTS_STOPSTATE_LANE0 (1 << 4)
+#define S3C_CSIS_DPHYSTS_STOPSTATE_CLOCK (1 << 0)
+
+/* Interrupt Mask Register */
+#define S3C_CSIS_INTMSK_EVEN_BEFORE_DISABLE (0 << 31)
+#define S3C_CSIS_INTMSK_EVEN_BEFORE_ENABLE (1 << 31)
+#define S3C_CSIS_INTMSK_EVEN_AFTER_DISABLE (0 << 30)
+#define S3C_CSIS_INTMSK_EVEN_AFTER_ENABLE (1 << 30)
+#define S3C_CSIS_INTMSK_ODD_BEFORE_DISABLE (0 << 29)
+#define S3C_CSIS_INTMSK_ODD_BEFORE_ENABLE (1 << 29)
+#define S3C_CSIS_INTMSK_ODD_AFTER_DISABLE (0 << 28)
+#define S3C_CSIS_INTMSK_ODD_AFTER_ENABLE (1 << 28)
+#define S3C_CSIS_INTMSK_ERR_SOT_HS_DISABLE (0 << 12)
+#define S3C_CSIS_INTMSK_ERR_SOT_HS_ENABLE (1 << 12)
+
+#define S3C_CSIS_INTMSK_ERR_LOST_FS_DISABLE (0 << 5)
+#define S3C_CSIS_INTMSK_ERR_LOST_FS_ENABLE (1 << 5)
+
+#define S3C_CSIS_INTMSK_ERR_LOST_FE_DISABLE (0 << 4)
+#define S3C_CSIS_INTMSK_ERR_LOST_FE_ENABLE (1 << 4)
+#define S3C_CSIS_INTMSK_ERR_OVER_DISABLE (0 << 3)
+#define S3C_CSIS_INTMSK_ERR_OVER_ENABLE (1 << 3)
+
+#define S3C_CSIS_INTMSK_ERR_ECC_DISABLE (0 << 2)
+#define S3C_CSIS_INTMSK_ERR_ECC_ENABLE (1 << 2)
+#define S3C_CSIS_INTMSK_ERR_CRC_DISABLE (0 << 1)
+#define S3C_CSIS_INTMSK_ERR_CRC_ENABLE (1 << 1)
+#define S3C_CSIS_INTMSK_ERR_ID_DISABLE (0 << 0)
+#define S3C_CSIS_INTMSK_ERR_ID_ENABLE (1 << 0)
+
+/* Interrupt Source Register */
+#define S3C_CSIS_INTSRC_EVEN_BEFORE (1 << 31)
+#define S3C_CSIS_INTSRC_EVEN_AFTER (1 << 30)
+#define S3C_CSIS_INTSRC_ODD_BEFORE (1 << 29)
+#define S3C_CSIS_INTSRC_ODD_AFTER (1 << 28)
+
+#define S3C_CSIS_INTSRC_ERR_SOT_HS (0xF << 12)
+#define S3C_CSIS_INTSRC_ERR_LOST_FS (1 << 5)
+#define S3C_CSIS_INTSRC_ERR_LOST_FE (1 << 4)
+#define S3C_CSIS_INTSRC_ERR_OVER (1 << 3)
+#define S3C_CSIS_INTSRC_ERR_ECC (1 << 2)
+#define S3C_CSIS_INTSRC_ERR_CRC (1 << 1)
+#define S3C_CSIS_INTSRC_ERR_ID (1 << 0)
+#define S3C_CSIS_INTSRC_ERR (S3C_CSIS_INTSRC_ERR_SOT_HS | \
+ S3C_CSIS_INTSRC_ERR_LOST_FS | \
+ S3C_CSIS_INTSRC_ERR_LOST_FE | \
+ S3C_CSIS_INTSRC_ERR_OVER | \
+ S3C_CSIS_INTSRC_ERR_ECC | \
+ S3C_CSIS_INTSRC_ERR_CRC | \
+ S3C_CSIS_INTSRC_ERR_ID)
+
+#define S3C_CSIS_INTSRC_NON_IMAGE_DATA (S3C_CSIS_INTSRC_EVEN_BEFORE | \
+ S3C_CSIS_INTSRC_EVEN_AFTER | \
+ S3C_CSIS_INTSRC_ODD_BEFORE | \
+ S3C_CSIS_INTSRC_ODD_AFTER)
+
+/* Resolution Register */
+#define S3C_CSIS_RESOL_HOR_SHIFT (16)
+#define S3C_CSIS_RESOL_VER_SHIFT (0)
+
+#endif /* __ASM_PLAT_REGS_CSIS_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-dsim.h b/arch/arm/plat-s5p/include/plat/regs-dsim.h
new file mode 100644
index 0000000..f4d1eed
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-dsim.h
@@ -0,0 +1,237 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-dsim.h
+ *
+ * Register definition file for Samsung MIPI-DSIM driver
+ *
+ * InKi Dae <inki.dae@samsung.com>, Copyright (c) 2009 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_DSIM_H
+#define _REGS_DSIM_H
+
+#define S5P_DSIM_STATUS (0x0) /* Status register */
+#define S5P_DSIM_SWRST (0x4) /* Software reset register */
+#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */
+#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */
+#define S5P_DSIM_CONFIG (0x10) /* Configuration register */
+#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */
+#define S5P_DSIM_MDRESOL (0x18) /* Main display image resolution register */
+#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */
+#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */
+#define S5P_DSIM_MSYNC (0x24) /* Main display sync area register */
+#define S5P_DSIM_SDRESOL (0x28) /* Sub display image resolution register */
+#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source register */
+#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register */
+#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO register */
+#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */
+#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */
+#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */
+#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register */
+#define S5P_DSIM_MEMACCHR (0x48) /* FIFO memory AC characteristic register */
+#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */
+#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */
+#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register */
+#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic register 1 */
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST (1 << 16)
+#define DSIM_SWRST (1 << 0)
+
+/* S5P_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT (0)
+#define DSIM_BTA_TOUT_SHIFT (16)
+#define DSIM_LPDR_TOUT(x) (((x) & 0xffff) << DSIM_LPDR_TOUT_SHIFT)
+#define DSIM_BTA_TOUT(x) (((x) & 0xff) << DSIM_BTA_TOUT_SHIFT)
+
+/* S5P_DSIM_CLKCTRL */
+#define DSIM_ESC_PRESCALER_SHIFT (0)
+#define DSIM_LANE_ESC_CLKEN_SHIFT (19)
+#define DSIM_BYTE_CLKEN_SHIFT (24)
+#define DSIM_BYTE_CLK_SRC_SHIFT (25)
+#define DSIM_PLL_BYPASS_SHIFT (27)
+#define DSIM_ESC_CLKEN_SHIFT (28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT (31)
+#define DSIM_ESC_PRESCALER(x) (((x) & 0xffff) << DSIM_ESC_PRESCALER_SHIFT)
+#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << DSIM_LANE_ESC_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_BYTE_CLKSRC(x) (((x) & 0x3) << DSIM_BYTE_CLK_SRC_SHIFT)
+#define DSIM_PLL_BYPASS_PLL (0 << DSIM_PLL_BYPASS_SHIFT)
+#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT)
+#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT)
+#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT)
+
+/* S5P_DSIM_CONFIG */
+#define DSIM_LANE_EN_SHIFT (0)
+#define DSIM_NUM_OF_DATALANE_SHIFT (5)
+#define DSIM_SUB_PIX_FORMAT_SHIFT (8)
+#define DSIM_MAIN_PIX_FORMAT_SHIFT (12)
+#define DSIM_SUB_VC_SHIFT (16)
+#define DSIM_MAIN_VC_SHIFT (18)
+#define DSIM_HSA_MODE_SHIFT (20)
+#define DSIM_HBP_MODE_SHIFT (21)
+#define DSIM_HFP_MODE_SHIFT (22)
+#define DSIM_HSE_MODE_SHIFT (23)
+#define DSIM_AUTO_MODE_SHIFT (24)
+#define DSIM_VIDEO_MODE_SHIFT (25)
+#define DSIM_BURST_MODE_SHIFT (26)
+#define DSIM_SYNC_INFORM_SHIFT (27)
+#define DSIM_EOT_R03_SHIFT (28)
+#define DSIM_LANE_ENx(x) ((1) << x)
+#define DSIM_NUM_OF_DATA_LANE(x) ((x) << 5) /* in case of Gemunus, it should be 0x1. */
+#define DSIM_SUB_PIX_FORMAT_3BPP (0 << 8) /* command mode only */
+#define DSIM_SUB_PIX_FORMAT_8BPP (1 << 8) /* command mode only */
+#define DSIM_SUB_PIX_FORMAT_12BPP (2 << 8) /* command mode only */
+#define DSIM_SUB_PIX_FORMAT_16BPP (3 << 8) /* command mode only */
+#define DSIM_SUB_PIX_FORMAT_16BPP_RGB (4 << 8) /* video mode only */
+#define DSIM_SUB_PIX_FORMAT_18BPP_PRGB (5 << 8) /* video mode only */
+#define DSIM_SUB_PIX_FORMAT_18BPP_LRGB (6 << 8) /* common */
+#define DSIM_SUB_PIX_FORMAT_24BPP_RGB (7 << 8) /* common */
+#define DSIM_MAIN_PIX_FORMAT_3BPP (0 << 12) /* command mode only */
+#define DSIM_MAIN_PIX_FORMAT_8BPP (1 << 12) /* command mode only */
+#define DSIM_MAIN_PIX_FORMAT_12BPP (2 << 12) /* command mode only */
+#define DSIM_MAIN_PIX_FORMAT_16BPP (3 << 12) /* command mode only */
+#define DSIM_MAIN_PIX_FORMAT_16BPP_RGB (4 << 12) /* video mode only */
+#define DSIM_MAIN_PIX_FORMAT_18BPP_PRGB (5 << 12) /* video mode only */
+#define DSIM_MAIN_PIX_FORMAT_18BPP_LRGB (6 << 12) /* common */
+#define DSIM_MAIN_PIX_FORMAT_24BPP_RGB (7 << 12) /* common */
+#define DSIM_SUB_VC(x) (((x) & 0x3) << 16) /* Virtual channel number for sub display */
+#define DSIM_MAIN_VC(x) (((x) & 0x3) << 18) /* Virtual channel number for main display */
+#define DSIM_HSA_MODE_ENABLE (1 << 20)
+#define DSIM_HSA_MODE_DISABLE (0 << 20)
+#define DSIM_HBP_MODE_ENABLE (1 << 21)
+#define DSIM_HBP_MODE_DISABLE (0 << 21)
+#define DSIM_HFP_MODE_ENABLE (1 << 22)
+#define DSIM_HFP_MODE_DISABLE (0 << 22)
+#define DSIM_HSE_MODE_ENABLE (1 << 23)
+#define DSIM_HSE_MODE_DISABLE (0 << 23)
+#define DSIM_AUTO_MODE (1 << 24)
+#define DSIM_CONFIGURATION_MODE (0 << 24)
+#define DSIM_VIDEO_MODE (1 << 25)
+#define DSIM_COMMAND_MODE (0 << 25)
+#define DSIM_BURST_MODE (1 << 26)
+#define DSIM_NON_BURST_MODE (0 << 26)
+#define DSIM_SYNC_INFORM_PULSE (1 << 27)
+#define DSIM_SYNC_INFORM_EVENT (0 << 27)
+#define DSIM_EOT_R03_ENABLE (0 << 28) /* enable EoT packet generation for V1.01r11 */
+#define DSIM_EOT_R03_DISABLE (1 << 28) /* disable EoT packet generation for V1.01r03 */
+
+/* S5P_DSIM_ESCMODE */
+#define DSIM_STOP_STATE_CNT_SHIFT (21)
+#define DSIM_STOP_STATE_CNT(x) (((x) & 0x3ff) << DSIM_STOP_STATE_CNT_SHIFT)
+#define DSIM_FORCE_STOP_STATE_SHIFT (20)
+#define DSIM_FORCE_BTA_SHIFT (16)
+#define DSIM_CMD_LPDT_HS_MODE (0 << 7)
+#define DSIM_CMD_LPDT_LP_MODE (1 << 7)
+#define DSIM_TX_LPDT_HS_MODE (0 << 6)
+#define DSIM_TX_LPDT_LP_MODE (1 << 6)
+#define DSIM_TX_TRIGGER_RST_SHIFT (4)
+#define DSIM_TX_UIPS_DAT_SHIFT (3)
+#define DSIM_TX_UIPS_EXIT_SHIFT (2)
+#define DSIM_TX_UIPS_CLK_SHIFT (1)
+#define DSIM_TX_UIPS_CLK_EXIT_SHIFT (0)
+
+/* S5P_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY (1 << 31)
+#define DSIM_MAIN_NOT_READY (0 << 31)
+#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0)
+
+/* S5P_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT (28)
+#define DSIM_STABLE_VFP_SHIFT (16)
+#define DSIM_MAIN_VBP_SHIFT (0)
+#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT)
+#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT)
+#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT)
+#define DSIM_CMD_ALLOW(x) (((x) & 0xf) << DSIM_CMD_ALLOW_SHIFT)
+#define DSIM_STABLE_VFP(x) (((x) & 0x7ff) << DSIM_STABLE_VFP_SHIFT)
+#define DSIM_MAIN_VBP(x) (((x) & 0x7ff) << DSIM_MAIN_VBP_SHIFT)
+
+/* S5P_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT (16)
+#define DSIM_MAIN_HBP_SHIFT (0)
+#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT)
+#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT)
+#define DSIM_MAIN_HFP(x) (((x) & 0xffff) << DSIM_MAIN_HFP_SHIFT)
+#define DSIM_MAIN_HBP(x) (((x) & 0xffff) << DSIM_MAIN_HBP_SHIFT)
+
+/* S5P_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT (22)
+#define DSIM_MAIN_HSA_SHIFT (0)
+#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT)
+#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT)
+#define DSIM_MAIN_VSA(x) (((x) & 0x3ff) << DSIM_MAIN_VSA_SHIFT)
+#define DSIM_MAIN_HSA(x) (((x) & 0xffff) << DSIM_MAIN_HSA_SHIFT)
+
+/* S5P_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT (31)
+#define DSIM_SUB_VRESOL_SHIFT (16)
+#define DSIM_SUB_HRESOL_SHIFT (0)
+#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT)
+#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT)
+#define DSIM_SUB_STANDY (1 << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_NOT_READY (0 << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_VRESOL(x) (((x) & 0x7ff) << DSIM_SUB_VRESOL_SHIFT)
+#define DSIM_SUB_HRESOL(x) (((x) & 0x7ff) << DSIM_SUB_HRESOL_SHIFT)
+
+/* S5P_DSIM_PKTHDR */
+#define DSIM_PACKET_HEADER_DI(x) (((x) & 0xff) << 0)
+#define DSIM_PACKET_HEADER_DAT0(x) (((x) & 0xff) << 8) /* Word count lower byte for long packet */
+#define DSIM_PACKET_HEADER_DAT1(x) (((x) & 0xff) << 16) /* Word count upper byte for long packet */
+
+/* S5P_DSIM_FIFOCTRL */
+#define DSIM_RX_FIFO (1 << 4)
+#define DSIM_TX_SFR_FIFO (1 << 3)
+#define DSIM_I80_FIFO (1 << 2)
+#define DSIM_SUB_DISP_FIFO (1 << 1)
+#define DSIM_MAIN_DISP_FIFO (1 << 0)
+
+/* S5P_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
+#define DSIM_AFC_ENABLE (1 << 14)
+#define DSIM_AFC_DISABLE (0 << 14)
+
+/* S5P_DSIM_PLLCTRL */
+#define DSIM_PMS_SHIFT (1)
+#define DSIM_PLL_EN_SHIFT (23)
+#define DSIM_FREQ_BAND_SHIFT (24)
+#define DSIM_PMS(x) (((x) & 0x7ffff) << DSIM_PMS_SHIFT)
+#define DSIM_FREQ_BAND(x) (((x) & 0xf) << DSIM_FREQ_BAND_SHIFT)
+
+typedef enum {
+ PllStable = 1 << 31,
+ SwRstRelease = 1 << 30,
+ SFRFifoEmpty = 1 << 29,
+ BusTrunOVer = 1 << 25,
+ FrameDone = 1 << 24,
+ LpdrTout = 1 << 21,
+ TaTout = 1 << 20,
+ RxDatDone = 1 << 18,
+ RxTE = 1 << 17,
+ ErrRxEcc = 1 << 15,
+ ErrRxCRC = 1 << 14,
+ ErrEsc3 = 1 << 13,
+ ErrEsc2 = 1 << 12,
+ ErrEsc1 = 1 << 11,
+ ErrEsc0 = 1 << 10,
+ ErrSync3 = 1 << 9,
+ ErrSync2 = 1 << 8,
+ ErrSync1 = 1 << 7,
+ ErrSync0 = 1 << 6,
+ ErrControl3 = 1 << 5,
+ ErrControl2 = 1 << 4,
+ ErrControl1 = 1 << 3,
+ ErrControl0 = 1 << 2,
+ ErrContentLP0 = 1 << 1,
+ ErrContentLP1 = 1 << 0,
+
+ AllDsimIntr = 0xffffffff,
+ ErrDsimIntr = 0xffff,
+} DSIM_INTSRC;
+
+#endif /* _REGS_DSIM_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-dsim2.h b/arch/arm/plat-s5p/include/plat/regs-dsim2.h
new file mode 100644
index 0000000..95a49e1
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-dsim2.h
@@ -0,0 +1,155 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-dsim.h
+ *
+ * Register definition file for Samsung MIPI-DSIM driver
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_DSIM_H
+#define _REGS_DSIM_H
+
+#define S5P_DSIM_STATUS (0x0) /* Status register */
+#define S5P_DSIM_SWRST (0x4) /* Software reset register */
+#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */
+#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */
+#define S5P_DSIM_CONFIG (0x10) /* Configuration register */
+#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */
+
+/* Main display image resolution register */
+#define S5P_DSIM_MDRESOL (0x18)
+#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */
+#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */
+#define S5P_DSIM_MSYNC (0x24) /* Main display sync area register */
+
+/* Sub display image resolution register */
+#define S5P_DSIM_SDRESOL (0x28)
+#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source register */
+#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register */
+#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO register */
+#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */
+#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */
+#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */
+#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register */
+
+/* FIFO memory AC characteristic register */
+#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */
+#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */
+#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register */
+#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic register1 */
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK (1 << 8)
+#define DSIM_TX_READY_HS_CLK (1 << 10)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST (1 << 16)
+#define DSIM_SWRST (1 << 0)
+
+/* S5P_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT (0)
+#define DSIM_BTA_TOUT_SHIFT (16)
+
+/* S5P_DSIM_CLKCTRL */
+#define DSIM_LANE_ESC_CLKEN_SHIFT (19)
+#define DSIM_BYTE_CLKEN_SHIFT (24)
+#define DSIM_BYTE_CLK_SRC_SHIFT (25)
+#define DSIM_PLL_BYPASS_SHIFT (27)
+#define DSIM_ESC_CLKEN_SHIFT (28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT (31)
+#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << \
+ DSIM_LANE_ESC_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT)
+#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT)
+#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT)
+
+/* S5P_DSIM_CONFIG */
+#define DSIM_NUM_OF_DATALANE_SHIFT (5)
+#define DSIM_HSA_MODE_SHIFT (20)
+#define DSIM_HBP_MODE_SHIFT (21)
+#define DSIM_HFP_MODE_SHIFT (22)
+#define DSIM_HSE_MODE_SHIFT (23)
+#define DSIM_AUTO_MODE_SHIFT (24)
+#define DSIM_LANE_ENx(x) (((x) & 0x1f) << 0)
+
+#define DSIM_NUM_OF_DATA_LANE(x) ((x) << DSIM_NUM_OF_DATALANE_SHIFT)
+
+/* S5P_DSIM_ESCMODE */
+#define DSIM_TX_LPDT_SHIFT (6)
+#define DSIM_CMD_LPDT_SHIFT (7)
+#define DSIM_TX_LPDT_LP (1 << DSIM_TX_LPDT_SHIFT)
+#define DSIM_CMD_LPDT_LP (1 << DSIM_CMD_LPDT_SHIFT)
+#define DSIM_STOP_STATE_CNT_SHIFT (21)
+#define DSIM_FORCE_STOP_STATE_SHIFT (20)
+
+/* S5P_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY (1 << 31)
+#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0)
+
+/* S5P_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT (28)
+#define DSIM_STABLE_VFP_SHIFT (16)
+#define DSIM_MAIN_VBP_SHIFT (0)
+#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT)
+#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT)
+#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT)
+
+/* S5P_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT (16)
+#define DSIM_MAIN_HBP_SHIFT (0)
+#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT)
+#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT)
+
+/* S5P_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT (22)
+#define DSIM_MAIN_HSA_SHIFT (0)
+#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT)
+#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT)
+
+/* S5P_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT (31)
+#define DSIM_SUB_VRESOL_SHIFT (16)
+#define DSIM_SUB_HRESOL_SHIFT (0)
+#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT)
+#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT)
+
+/* S5P_DSIM_INTSRC */
+#define INTSRC_PLL_STABLE (1 << 31)
+#define INTSRC_SW_RST_RELEASE (1 << 30)
+#define INTSRC_SFR_FIFO_EMPTY (1 << 29)
+#define INTSRC_FRAME_DONE (1 << 24)
+#define INTSRC_RX_DATA_DONE (1 << 18)
+
+/* S5P_DSIM_INTMSK */
+#define INTMSK_FIFO_EMPTY (1 << 29)
+#define INTMSK_BTA (1 << 25)
+#define INTMSK_FRAME_DONE (1 << 24)
+#define INTMSK_RX_TIMEOUT (1 << 21)
+#define INTMSK_BTA_TIMEOUT (1 << 20)
+#define INTMSK_RX_DONE (1 << 18)
+#define INTMSK_RX_TE (1 << 17)
+#define INTMSK_RX_ACK (1 << 16)
+#define INTMSK_RX_ECC_ERR (1 << 15)
+#define INTMSK_RX_CRC_ERR (1 << 14)
+
+/* S5P_DSIM_FIFOCTRL */
+#define SFR_HEADER_EMPTY (1 << 22)
+
+/* S5P_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
+
+/* S5P_DSIM_PLLCTRL */
+#define DSIM_PLL_EN_SHIFT (23)
+#define DSIM_FREQ_BAND_SHIFT (24)
+
+#endif /* _REGS_DSIM_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h b/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h
new file mode 100644
index 0000000..b616f2c
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h
@@ -0,0 +1,415 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-fb-s5p.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung Display Controller (FIMD) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_FB_S5P_H
+#define __ASM_PLAT_REGS_FB_S5P_H __FILE__
+
+#define S3C_WINCON(x) (0x0020 + (x * 0x04))
+#define S3C_VIDOSD_A(x) (0x0040 + (x * 0x10))
+#define S3C_VIDOSD_B(x) (0x0044 + (x * 0x10))
+#define S3C_VIDOSD_C(x) (0x0048 + (x * 0x10))
+#define S3C_VIDOSD_D(x) (0x004C + (x * 0x10))
+#define S3C_VIDADDR_START0(x) (0x00A0 + (x * 0x08))
+#define S3C_VIDADDR_START1(x) (0x00A4 + (x * 0x08))
+#define S3C_VIDADDR_END0(x) (0x00D0 + (x * 0x08))
+#define S3C_VIDADDR_END1(x) (0x00D4 + (x * 0x08))
+#define S3C_VIDADDR_SIZE(x) (0x0100 + (x * 0x04))
+#define S3C_KEYCON(x) (0x0140 + ((x - 1) * 0x08))
+#define S3C_KEYVAL(x) (0x0144 + ((x - 1) * 0x08))
+#define S3C_WINMAP(x) (0x0180 + (x * 0x04))
+
+/*
+ * Register Map
+*/
+#define S3C_VIDCON0 (0x0000) /* Video control 0 */
+#define S3C_VIDCON1 (0x0004) /* Video control 1 */
+#define S3C_VIDCON2 (0x0008) /* Video control 2 */
+#define S3C_PRTCON (0x000C) /* Protect control */
+
+#define S3C_VIDTCON0 (0x0010) /* Video time control 0 */
+#define S3C_VIDTCON1 (0x0014) /* Video time control 1 */
+#define S3C_VIDTCON2 (0x0018) /* Video time control 2 */
+
+#define S3C_WINCON0 (0x0020) /* Window control 0 */
+#define S3C_WINCON1 (0x0024) /* Window control 1 */
+#define S3C_WINCON2 (0x0028) /* Window control 2 */
+#define S3C_WINCON3 (0x002C) /* Window control 3 */
+#define S3C_WINCON4 (0x0030) /* Window control 4 */
+
+#define S3C_WINSHMAP (0x0034) /* Window Shadow control */
+
+#define S3C_VIDOSD0A (0x0040) /* Video Window 0 position control */
+#define S3C_VIDOSD0B (0x0044) /* Video Window 0 position control1 */
+#define S3C_VIDOSD0C (0x0048) /* Video Window 0 position control */
+
+#define S3C_VIDOSD1A (0x0050) /* Video Window 1 position control */
+#define S3C_VIDOSD1B (0x0054) /* Video Window 1 position control */
+#define S3C_VIDOSD1C (0x0058) /* Video Window 1 position control */
+#define S3C_VIDOSD1D (0x005C) /* Video Window 1 position control */
+
+#define S3C_VIDOSD2A (0x0060) /* Video Window 2 position control */
+#define S3C_VIDOSD2B (0x0064) /* Video Window 2 position control */
+#define S3C_VIDOSD2C (0x0068) /* Video Window 2 position control */
+#define S3C_VIDOSD2D (0x006C) /* Video Window 2 position control */
+
+#define S3C_VIDOSD3A (0x0070) /* Video Window 3 position control */
+#define S3C_VIDOSD3B (0x0074) /* Video Window 3 position control */
+#define S3C_VIDOSD3C (0x0078) /* Video Window 3 position control */
+
+#define S3C_VIDOSD4A (0x0080) /* Video Window 4 position control */
+#define S3C_VIDOSD4B (0x0084) /* Video Window 4 position control */
+#define S3C_VIDOSD4C (0x0088) /* Video Window 4 position control */
+
+#define S3C_VIDW00ADD0B0 (0x00A0) /* Window 0 buffer start address, buffer 0 */
+#define S3C_VIDW00ADD0B1 (0x00A4) /* Window 0 buffer start address, buffer 1 */
+#define S3C_VIDW01ADD0B0 (0x00A8) /* Window 1 buffer start address, buffer 0 */
+#define S3C_VIDW01ADD0B1 (0x00AC) /* Window 1 buffer start address, buffer 1 */
+#define S3C_VIDW02ADD0 (0x00B0) /* Window 2 buffer start address, buffer 0 */
+#define S3C_VIDW03ADD0 (0x00B8) /* Window 3 buffer start address, buffer 0 */
+#define S3C_VIDW04ADD0 (0x00C0) /* Window 4 buffer start address, buffer 0 */
+#define S3C_VIDW00ADD1B0 (0x00D0) /* Window 0 buffer end address, buffer 0 */
+#define S3C_VIDW00ADD1B1 (0x00D4) /* Window 0 buffer end address, buffer 1 */
+#define S3C_VIDW01ADD1B0 (0x00D8) /* Window 1 buffer end address, buffer 0 */
+#define S3C_VIDW01ADD1B1 (0x00DC) /* Window 1 buffer end address, buffer 1 */
+#define S3C_VIDW02ADD1 (0x00E0) /* Window 2 buffer end address */
+#define S3C_VIDW03ADD1 (0x00E8) /* Window 3 buffer end address */
+#define S3C_VIDW04ADD1 (0x00F0) /* Window 4 buffer end address */
+#define S3C_VIDW00ADD2 (0x0100) /* Window 0 buffer size */
+#define S3C_VIDW01ADD2 (0x0104) /* Window 1 buffer size */
+#define S3C_VIDW02ADD2 (0x0108) /* Window 2 buffer size */
+#define S3C_VIDW03ADD2 (0x010C) /* Window 3 buffer size */
+#define S3C_VIDW04ADD2 (0x0110) /* Window 4 buffer size */
+
+#define S3C_VP1TCON0 (0x0118) /* VP1 interface timing control 0 */
+#define S3C_VP1TCON1 (0x011C) /* VP1 interface timing control 1 */
+
+#define S3C_VIDINTCON0 (0x0130) /* Indicate the Video interrupt control */
+#define S3C_VIDINTCON1 (0x0134) /* Video Interrupt Pending */
+
+#define S3C_W1KEYCON0 (0x0140) /* Color key control */
+#define S3C_W1KEYCON1 (0x0144) /* Color key value (transparent value) */
+#define S3C_W2KEYCON0 (0x0148) /* Color key control */
+#define S3C_W2KEYCON1 (0x014C) /* Color key value (transparent value) */
+#define S3C_W3KEYCON0 (0x0150) /* Color key control */
+#define S3C_W3KEYCON1 (0x0154) /* Color key value (transparent value) */
+#define S3C_W4KEYCON0 (0x0158) /* Color key control */
+#define S3C_W4KEYCON1 (0x015C) /* Color key value (transparent value) */
+
+#define S3C_W1KEYALPHA (0x0160) /* Color key alpha value */
+#define S3C_W2KEYALPHA (0x0164) /* Color key alpha value */
+#define S3C_W3KEYALPHA (0x0168) /* Color key alpha value */
+#define S3C_W4KEYALPHA (0x016C) /* Color key alpha value */
+
+#define S3C_DITHMODE (0x0170) /* Dithering mode */
+
+#define S3C_WIN0MAP (0x0180) /* Window color control */
+#define S3C_WIN1MAP (0x0184) /* Window color control */
+#define S3C_WIN2MAP (0x0188) /* Window color control */
+#define S3C_WIN3MAP (0x018C) /* Window color control */
+#define S3C_WIN4MAP (0x0190) /* Window color control */
+
+#define S3C_WPALCON_H (0x019C) /* Window Palette control */
+#define S3C_WPALCON_L (0x01A0) /* Window Palette control */
+#define S3C_TRIGCON (0x01A4) /* I80 / RGB Trigger Control Regiter */
+#define S3C_I80IFCONA0 (0x01B0) /* I80 Interface control 0 for Main LDI */
+#define S3C_I80IFCONA1 (0x01B4) /* I80 Interface control 0 for Sub LDI */
+#define S3C_I80IFCONB0 (0x01B8) /* I80 Interface control 1 for Main LDI */
+#define S3C_I80IFCONB1 (0x01BC) /* I80 Interface control 1 for Sub LDI */
+#define S3C_LDI_CMDCON0 (0x01D0) /* I80 Interface LDI Command Control 0 */
+#define S3C_LDI_CMDCON1 (0x01D4) /* I80 Interface LDI Command Control 1 */
+#define S3C_SIFCCON0 (0x01E0) /* LCD i80 System Interface Command Control 0 */
+#define S3C_SIFCCON1 (0x01E4) /* LCD i80 System Interface Command Control 1 */
+#define S3C_SIFCCON2 (0x01E8) /* LCD i80 System Interface Command Control 2 */
+
+#define S3C_VIDW0ALPHA0 (0x0200) /* Window 0 alpha value 0 */
+#define S3C_VIDW0ALPHA1 (0x0204) /* Window 0 alpha value 1 */
+#define S3C_VIDW1ALPHA0 (0x0208) /* Window 1 alpha value 0 */
+#define S3C_VIDW1ALPHA1 (0x020C) /* Window 1 alpha value 1 */
+#define S3C_VIDW2ALPHA0 (0x0210) /* Window 2 alpha value 0 */
+#define S3C_VIDW2ALPHA1 (0x0214) /* Window 2 alpha value 1 */
+#define S3C_VIDW3ALPHA0 (0x0218) /* Window 3 alpha value 0 */
+#define S3C_VIDW3ALPHA1 (0x021C) /* Window 3 alpha value 1 */
+#define S3C_VIDW4ALPHA0 (0x0220) /* Window 4 alpha value 0 */
+#define S3C_VIDW4ALPHA1 (0x0224) /* Window 4 alpha value 1 */
+
+#define S3C_BLENDEQ1 (0x0244) /* Window 1 blending equation control */
+#define S3C_BLENDEQ2 (0x0248) /* Window 2 blending equation control */
+#define S3C_BLENDEQ3 (0x024C) /* Window 3 blending equation control */
+#define S3C_BLENDEQ4 (0x0250) /* Window 4 blending equation control */
+#define S3C_BLENDCON (0x0260) /* Blending control */
+#define S3C_SHD_WIN_BASE (0x4000) /* Shadow Window control reg Base */
+/*
+ * Bit Definitions
+*/
+
+/* VIDCON0 */
+#define S3C_VIDCON0_DSI_DISABLE (0 << 30)
+#define S3C_VIDCON0_DSI_ENABLE (1 << 30)
+#define S3C_VIDCON0_SCAN_PROGRESSIVE (0 << 29)
+#define S3C_VIDCON0_SCAN_INTERLACE (1 << 29)
+#define S3C_VIDCON0_SCAN_MASK (1 << 29)
+#define S3C_VIDCON0_VIDOUT_RGB (0 << 26)
+#define S3C_VIDCON0_VIDOUT_ITU (1 << 26)
+#define S3C_VIDCON0_VIDOUT_I80LDI0 (2 << 26)
+#define S3C_VIDCON0_VIDOUT_I80LDI1 (3 << 26)
+#define S3C_VIDCON0_VIDOUT_WB_RGB (4 << 26)
+#define S3C_VIDCON0_VIDOUT_WB_I80LDI0 (6 << 26)
+#define S3C_VIDCON0_VIDOUT_WB_I80LDI1 (7 << 26)
+#define S3C_VIDCON0_VIDOUT_MASK (7 << 26)
+#define S3C_VIDCON0_PNRMODE_RGB_P (0 << 17)
+#define S3C_VIDCON0_PNRMODE_BGR_P (1 << 17)
+#define S3C_VIDCON0_PNRMODE_RGB_S (2 << 17)
+#define S3C_VIDCON0_PNRMODE_BGR_S (3 << 17)
+#define S3C_VIDCON0_PNRMODE_MASK (3 << 17)
+#define S3C_VIDCON0_PNRMODE_SHIFT (17)
+#define S3C_VIDCON0_CLKVALUP_ALWAYS (0 << 16)
+#define S3C_VIDCON0_CLKVALUP_START_FRAME (1 << 16)
+#define S3C_VIDCON0_CLKVALUP_MASK (1 << 16)
+#define S3C_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6)
+#define S3C_VIDCON0_VCLKEN_NORMAL (0 << 5)
+#define S3C_VIDCON0_VCLKEN_FREERUN (1 << 5)
+#define S3C_VIDCON0_VCLKEN_MASK (1 << 5)
+#define S3C_VIDCON0_CLKDIR_DIRECTED (0 << 4)
+#define S3C_VIDCON0_CLKDIR_DIVIDED (1 << 4)
+#define S3C_VIDCON0_CLKDIR_MASK (1 << 4)
+#define S3C_VIDCON0_CLKSEL_HCLK (0 << 2)
+#define S3C_VIDCON0_CLKSEL_SCLK (1 << 2)
+#define S3C_VIDCON0_CLKSEL_MASK (1 << 2)
+#define S3C_VIDCON0_ENVID_ENABLE (1 << 1)
+#define S3C_VIDCON0_ENVID_DISABLE (0 << 1)
+#define S3C_VIDCON0_ENVID_F_ENABLE (1 << 0)
+#define S3C_VIDCON0_ENVID_F_DISABLE (0 << 0)
+
+/* VIDCON1 */
+#define S3C_VIDCON1_FIXVCLK_VCLK_HOLD (0 << 9)
+#define S3C_VIDCON1_FIXVCLK_VCLK_RUN (1 << 9)
+#define S3C_VIDCON1_FIXVCLK_VCLK_RUN_VDEN_DIS (3 << 9)
+#define S3C_VIDCON1_FIXVCLK_MASK (3 << 9)
+#define S3C_VIDCON1_IVCLK_FALLING_EDGE (0 << 7)
+#define S3C_VIDCON1_IVCLK_RISING_EDGE (1 << 7)
+#define S3C_VIDCON1_IHSYNC_NORMAL (0 << 6)
+#define S3C_VIDCON1_IHSYNC_INVERT (1 << 6)
+#define S3C_VIDCON1_IVSYNC_NORMAL (0 << 5)
+#define S3C_VIDCON1_IVSYNC_INVERT (1 << 5)
+#define S3C_VIDCON1_IVDEN_NORMAL (0 << 4)
+#define S3C_VIDCON1_IVDEN_INVERT (1 << 4)
+#define S3C_VIDCON1_VSTATUS_VSYNC (0 << 13)
+#define S3C_VIDCON1_VSTATUS_BACK (1 << 13)
+#define S3C_VIDCON1_VSTATUS_ACTIVE (2 << 13)
+#define S3C_VIDCON1_VSTATUS_FRONT (3 << 13)
+#define S3C_VIDCON1_VSTATUS_MASK (3 << 13)
+
+
+/* VIDCON2 */
+#define S3C_VIDCON2_EN601_DISABLE (0 << 23)
+#define S3C_VIDCON2_EN601_ENABLE (1 << 23)
+#define S3C_VIDCON2_EN601_MASK (1 << 23)
+#define S3C_VIDCON2_WB_DISABLE (0 << 15)
+#define S3C_VIDCON2_WB_ENABLE (1 << 15)
+#define S3C_VIDCON2_WB_MASK (1 << 15)
+#define S3C_VIDCON2_TVFORMATSEL_HW (0 << 14)
+#define S3C_VIDCON2_TVFORMATSEL_SW (1 << 14)
+#define S3C_VIDCON2_TVFORMATSEL_MASK (1 << 14)
+#define S3C_VIDCON2_TVFORMATSEL_YUV422 (1 << 12)
+#define S3C_VIDCON2_TVFORMATSEL_YUV444 (2 << 12)
+#define S3C_VIDCON2_TVFORMATSEL_YUV_MASK (3 << 12)
+#define S3C_VIDCON2_ORGYUV_YCBCR (0 << 8)
+#define S3C_VIDCON2_ORGYUV_CBCRY (1 << 8)
+#define S3C_VIDCON2_ORGYUV_MASK (1 << 8)
+#define S3C_VIDCON2_YUVORD_CBCR (0 << 7)
+#define S3C_VIDCON2_YUVORD_CRCB (1 << 7)
+#define S3C_VIDCON2_YUVORD_MASK (1 << 7)
+
+/* PRTCON */
+#define S3C_PRTCON_UPDATABLE (0 << 11)
+#define S3C_PRTCON_PROTECT (1 << 11)
+
+/* VIDTCON0 */
+#define S3C_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24)
+#define S3C_VIDTCON0_VBPD(x) (((x) & 0xff) << 16)
+#define S3C_VIDTCON0_VFPD(x) (((x) & 0xff) << 8)
+#define S3C_VIDTCON0_VSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON1 */
+#define S3C_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24)
+#define S3C_VIDTCON1_HBPD(x) (((x) & 0xff) << 16)
+#define S3C_VIDTCON1_HFPD(x) (((x) & 0xff) << 8)
+#define S3C_VIDTCON1_HSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON2 */
+#define S3C_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11)
+#define S3C_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0)
+
+/* Window 0~4 Control - WINCONx */
+#define S3C_WINCON_DATAPATH_DMA (0 << 22)
+#define S3C_WINCON_DATAPATH_LOCAL (1 << 22)
+#define S3C_WINCON_DATAPATH_MASK (1 << 22)
+#define S3C_WINCON_BUFSEL_0 (0 << 20)
+#define S3C_WINCON_BUFSEL_1 (1 << 20)
+#define S3C_WINCON_BUFSEL_MASK (1 << 20)
+#define S3C_WINCON_BUFSEL_SHIFT (20)
+#define S3C_WINCON_BUFAUTO_DISABLE (0 << 19)
+#define S3C_WINCON_BUFAUTO_ENABLE (1 << 19)
+#define S3C_WINCON_BUFAUTO_MASK (1 << 19)
+#define S3C_WINCON_BITSWP_DISABLE (0 << 18)
+#define S3C_WINCON_BITSWP_ENABLE (1 << 18)
+#define S3C_WINCON_BITSWP_SHIFT (18)
+#define S3C_WINCON_BYTESWP_DISABLE (0 << 17)
+#define S3C_WINCON_BYTESWP_ENABLE (1 << 17)
+#define S3C_WINCON_BYTESWP_SHIFT (17)
+#define S3C_WINCON_HAWSWP_DISABLE (0 << 16)
+#define S3C_WINCON_HAWSWP_ENABLE (1 << 16)
+#define S3C_WINCON_HAWSWP_SHIFT (16)
+#define S3C_WINCON_WSWP_DISABLE (0 << 15)
+#define S3C_WINCON_WSWP_ENABLE (1 << 15)
+#define S3C_WINCON_WSWP_SHIFT (15)
+#define S3C_WINCON_INRGB_RGB (0 << 13)
+#define S3C_WINCON_INRGB_YUV (1 << 13)
+#define S3C_WINCON_INRGB_MASK (1 << 13)
+#define S3C_WINCON_BURSTLEN_16WORD (0 << 9)
+#define S3C_WINCON_BURSTLEN_8WORD (1 << 9)
+#define S3C_WINCON_BURSTLEN_4WORD (2 << 9)
+#define S3C_WINCON_BURSTLEN_MASK (3 << 9)
+#define S3C_WINCON_ALPHA_MULTI_DISABLE (0 << 7)
+#define S3C_WINCON_ALPHA_MULTI_ENABLE (1 << 7)
+#define S3C_WINCON_BLD_PLANE (0 << 6)
+#define S3C_WINCON_BLD_PIXEL (1 << 6)
+#define S3C_WINCON_BLD_MASK (1 << 6)
+#define S3C_WINCON_BPPMODE_1BPP (0 << 2)
+#define S3C_WINCON_BPPMODE_2BPP (1 << 2)
+#define S3C_WINCON_BPPMODE_4BPP (2 << 2)
+#define S3C_WINCON_BPPMODE_8BPP_PAL (3 << 2)
+#define S3C_WINCON_BPPMODE_8BPP (4 << 2)
+#define S3C_WINCON_BPPMODE_16BPP_565 (5 << 2)
+#define S3C_WINCON_BPPMODE_16BPP_A555 (6 << 2)
+#define S3C_WINCON_BPPMODE_18BPP_666 (8 << 2)
+#define S3C_WINCON_BPPMODE_18BPP_A665 (9 << 2)
+#define S3C_WINCON_BPPMODE_24BPP_888 (0xb << 2)
+#define S3C_WINCON_BPPMODE_24BPP_A887 (0xc << 2)
+#define S3C_WINCON_BPPMODE_32BPP (0xd << 2)
+#define S3C_WINCON_BPPMODE_16BPP_A444 (0xe << 2)
+#define S3C_WINCON_BPPMODE_15BPP_555 (0xf << 2)
+#define S3C_WINCON_BPPMODE_MASK (0xf << 2)
+#define S3C_WINCON_BPPMODE_SHIFT (2)
+#define S3C_WINCON_ALPHA0_SEL (0 << 1)
+#define S3C_WINCON_ALPHA1_SEL (1 << 1)
+#define S3C_WINCON_ALPHA_SEL_MASK (1 << 1)
+#define S3C_WINCON_ENWIN_DISABLE (0 << 0)
+#define S3C_WINCON_ENWIN_ENABLE (1 << 0)
+
+/* WINCON1 special */
+#define S3C_WINCON1_VP_DISABLE (0 << 24)
+#define S3C_WINCON1_VP_ENABLE (1 << 24)
+#define S3C_WINCON1_LOCALSEL_FIMC1 (0 << 23)
+#define S3C_WINCON1_LOCALSEL_VP (1 << 23)
+#define S3C_WINCON1_LOCALSEL_MASK (1 << 23)
+
+/* WINSHMAP */
+#define S3C_WINSHMAP_PROTECT(x) (((x) & 0x1f) << 10)
+#define S3C_WINSHMAP_CH_ENABLE(x) (1 << (x))
+#define S3C_WINSHMAP_CH_DISABLE(x) (1 << (x))
+#define S3C_WINSHMAP_LOCAL_ENABLE(x) (0x20 << (x))
+#define S3C_WINSHMAP_LOCAL_DISABLE(x) (0x20 << (x))
+
+
+/* VIDOSDxA, VIDOSDxB */
+#define S3C_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11)
+#define S3C_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0)
+#define S3C_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11)
+#define S3C_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0)
+
+/* VIDOSD0C, VIDOSDxD */
+#define S3C_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0)
+
+/* VIDOSDxC (1~4) */
+#define S3C_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20)
+#define S3C_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16)
+#define S3C_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12)
+#define S3C_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8)
+#define S3C_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4)
+#define S3C_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0)
+#define S3C_VIDOSD_ALPHA0_SHIFT (12)
+#define S3C_VIDOSD_ALPHA1_SHIFT (0)
+
+/* Start Address */
+#define S3C_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24)
+#define S3C_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0)
+
+/* End Address */
+#define S3C_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0)
+
+/* Buffer Size */
+#define S3C_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13)
+#define S3C_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0)
+
+/* WIN Color Map */
+#define S3C_WINMAP_COLOR(x) ((x) & 0xffffff)
+
+/* VIDINTCON0 */
+#define S3C_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19)
+#define S3C_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19)
+#define S3C_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18)
+#define S3C_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18)
+#define S3C_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17)
+#define S3C_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17)
+#define S3C_VIDINTCON0_FRAMESEL0_BACK (0 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_FRONT (3 << 15)
+#define S3C_VIDINTCON0_FRAMESEL0_MASK (3 << 15)
+#define S3C_VIDINTCON0_FRAMESEL1_NONE (0 << 13)
+#define S3C_VIDINTCON0_FRAMESEL1_BACK (1 << 13)
+#define S3C_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13)
+#define S3C_VIDINTCON0_FRAMESEL1_FRONT (3 << 13)
+#define S3C_VIDINTCON0_INTFRMEN_DISABLE (0 << 12)
+#define S3C_VIDINTCON0_INTFRMEN_ENABLE (1 << 12)
+#define S3C_VIDINTCON0_FIFOSEL_WIN4 (1 << 11)
+#define S3C_VIDINTCON0_FIFOSEL_WIN3 (1 << 10)
+#define S3C_VIDINTCON0_FIFOSEL_WIN2 (1 << 9)
+#define S3C_VIDINTCON0_FIFOSEL_WIN1 (1 << 6)
+#define S3C_VIDINTCON0_FIFOSEL_WIN0 (1 << 5)
+#define S3C_VIDINTCON0_FIFOSEL_ALL (0x73 << 5)
+#define S3C_VIDINTCON0_FIFOSEL_MASK (0x73 << 5)
+#define S3C_VIDINTCON0_FIFOLEVEL_25 (0 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_50 (1 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_75 (2 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_FULL (4 << 2)
+#define S3C_VIDINTCON0_FIFOLEVEL_MASK (7 << 2)
+#define S3C_VIDINTCON0_INTFIFO_DISABLE (0 << 1)
+#define S3C_VIDINTCON0_INTFIFO_ENABLE (1 << 1)
+#define S3C_VIDINTCON0_INT_DISABLE (0 << 0)
+#define S3C_VIDINTCON0_INT_ENABLE (1 << 0)
+#define S3C_VIDINTCON0_INT_MASK (1 << 0)
+
+/* VIDINTCON1 */
+#define S3C_VIDINTCON1_INTVPPEND (1 << 5)
+#define S3C_VIDINTCON1_INTI80PEND (1 << 2)
+#define S3C_VIDINTCON1_INTFRMPEND (1 << 1)
+#define S3C_VIDINTCON1_INTFIFOPEND (1 << 0)
+
+/* WINMAP */
+#define S3C_WINMAP_ENABLE (1 << 24)
+
+/* WxKEYCON0 (1~4) */
+#define S3C_KEYCON0_KEYBLEN_DISABLE (0 << 26)
+#define S3C_KEYCON0_KEYBLEN_ENABLE (1 << 26)
+#define S3C_KEYCON0_KEY_DISABLE (0 << 25)
+#define S3C_KEYCON0_KEY_ENABLE (1 << 25)
+#define S3C_KEYCON0_DIRCON_MATCH_FG (0 << 24)
+#define S3C_KEYCON0_DIRCON_MATCH_BG (1 << 24)
+#define S3C_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0)
+
+/* WxKEYCON1 (1~4) */
+#define S3C_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0)
+
+#endif /* __ASM_PLAT_REGS_FB_S5P_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-fimc.h b/arch/arm/plat-s5p/include/plat/regs-fimc.h
new file mode 100644
index 0000000..883d37d
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-fimc.h
@@ -0,0 +1,510 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-fimc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung Camera Interface (FIMC) driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_FIMC_H
+#define __ASM_PLAT_REGS_FIMC_H __FILE__
+
+/*
+ * Register part
+*/
+#define S3C_CISRCFMT (0x00) /* Input source format */
+#define S3C_CIWDOFST (0x04) /* Window offset */
+#define S3C_CIGCTRL (0x08) /* Global control */
+#define S3C_CIWDOFST2 (0x14) /* Window offset 2 */
+#define S3C_CIOYSA1 (0x18) /* Y 1st frame start address for output DMA */
+#define S3C_CIOYSA2 (0x1c) /* Y 2nd frame start address for output DMA */
+#define S3C_CIOYSA3 (0x20) /* Y 3rd frame start address for output DMA */
+#define S3C_CIOYSA4 (0x24) /* Y 4th frame start address for output DMA */
+#define S3C_CIOCBSA1 (0x28) /* Cb 1st frame start address for output DMA */
+#define S3C_CIOCBSA2 (0x2c) /* Cb 2nd frame start address for output DMA */
+#define S3C_CIOCBSA3 (0x30) /* Cb 3rd frame start address for output DMA */
+#define S3C_CIOCBSA4 (0x34) /* Cb 4th frame start address for output DMA */
+#define S3C_CIOCRSA1 (0x38) /* Cr 1st frame start address for output DMA */
+#define S3C_CIOCRSA2 (0x3c) /* Cr 2nd frame start address for output DMA */
+#define S3C_CIOCRSA3 (0x40) /* Cr 3rd frame start address for output DMA */
+#define S3C_CIOCRSA4 (0x44) /* Cr 4th frame start address for output DMA */
+#define S3C_CITRGFMT (0x48) /* Target image format */
+#define S3C_CIOCTRL (0x4c) /* Output DMA control */
+#define S3C_CISCPRERATIO (0x50) /* Pre-scaler control 1 */
+#define S3C_CISCPREDST (0x54) /* Pre-scaler control 2 */
+#define S3C_CISCCTRL (0x58) /* Main scaler control */
+#define S3C_CITAREA (0x5c) /* Target area */
+#define S3C_CISTATUS (0x64) /* Status */
+#define S3C_CISTATUS2 (0x68) /* Status2 */
+#define S3C_CIIMGCPT (0xc0) /* Image capture enable command */
+#define S3C_CICPTSEQ (0xc4) /* Capture sequence */
+#define S3C_CIIMGEFF (0xd0) /* Image effects */
+#define S3C_CIIYSA0 (0xd4) /* Y frame start address for input DMA */
+#define S3C_CIICBSA0 (0xd8) /* Cb frame start address for input DMA */
+#define S3C_CIICRSA0 (0xdc) /* Cr frame start address for input DMA */
+#define S3C_CIILINESKIP_Y (0xec) /* Input DMA Y Line Skip */
+#define S3C_CIILINESKIP_CB (0xf0) /* Input DMA Cb Line Skip */
+#define S3C_CIILINESKIP_CR (0xf4) /* Input DMA Cr Line Skip */
+#define S3C_CIREAL_ISIZE (0xf8) /* Real input DMA image size */
+#define S3C_MSCTRL (0xfc) /* Input DMA control */
+#define S3C_CIOYOFF (0x168) /* Output DMA Y offset */
+#define S3C_CIOCBOFF (0x16c) /* Output DMA CB offset */
+#define S3C_CIOCROFF (0x170) /* Output DMA CR offset */
+#define S3C_CIIYOFF (0x174) /* Input DMA Y offset */
+#define S3C_CIICBOFF (0x178) /* Input DMA CB offset */
+#define S3C_CIICROFF (0x17c) /* Input DMA CR offset */
+#define S3C_ORGISIZE (0x180) /* Input DMA original image size */
+#define S3C_ORGOSIZE (0x184) /* Output DMA original image size */
+#define S3C_CIEXTEN (0x188) /* Real output DMA image size */
+#define S3C_CIDMAPARAM (0x18c) /* DMA parameter */
+#define S3C_CSIIMGFMT (0x194) /* MIPI CSI image format */
+#define S3C_MISC_FIMC (0x198) /* FIMC Clock Source Select */
+
+/* Add for FIMC v5.1 */
+#define S3C_CIFCNTSEQ (0x1fc) /* Output Frame Buffer Sequence */
+#define S3C_CIOYSA5 (0x200) /* Y 5th frame start address for output DMA */
+#define S3C_CIOYSA6 (0x204) /* Y 6th frame start address for output DMA */
+#define S3C_CIOYSA7 (0x208) /* Y 7th frame start address for output DMA */
+#define S3C_CIOYSA8 (0x20c) /* Y 8th frame start address for output DMA */
+#define S3C_CIOYSA9 (0x210) /* Y 9th frame start address for output DMA */
+#define S3C_CIOYSA10 (0x214) /* Y 10th frame start address for output DMA */
+#define S3C_CIOYSA11 (0x218) /* Y 11th frame start address for output DMA */
+#define S3C_CIOYSA12 (0x21c) /* Y 12th frame start address for output DMA */
+#define S3C_CIOYSA13 (0x220) /* Y 13th frame start address for output DMA */
+#define S3C_CIOYSA14 (0x224) /* Y 14th frame start address for output DMA */
+#define S3C_CIOYSA15 (0x228) /* Y 15th frame start address for output DMA */
+#define S3C_CIOYSA16 (0x22c) /* Y 16th frame start address for output DMA */
+#define S3C_CIOYSA17 (0x230) /* Y 17th frame start address for output DMA */
+#define S3C_CIOYSA18 (0x234) /* Y 18th frame start address for output DMA */
+#define S3C_CIOYSA19 (0x238) /* Y 19th frame start address for output DMA */
+#define S3C_CIOYSA20 (0x23c) /* Y 20th frame start address for output DMA */
+#define S3C_CIOYSA21 (0x240) /* Y 21th frame start address for output DMA */
+#define S3C_CIOYSA22 (0x244) /* Y 22th frame start address for output DMA */
+#define S3C_CIOYSA23 (0x248) /* Y 23th frame start address for output DMA */
+#define S3C_CIOYSA24 (0x24c) /* Y 24th frame start address for output DMA */
+#define S3C_CIOYSA25 (0x250) /* Y 25th frame start address for output DMA */
+#define S3C_CIOYSA26 (0x254) /* Y 26th frame start address for output DMA */
+#define S3C_CIOYSA27 (0x258) /* Y 27th frame start address for output DMA */
+#define S3C_CIOYSA28 (0x25c) /* Y 28th frame start address for output DMA */
+#define S3C_CIOYSA29 (0x260) /* Y 29th frame start address for output DMA */
+#define S3C_CIOYSA30 (0x264) /* Y 30th frame start address for output DMA */
+#define S3C_CIOYSA31 (0x268) /* Y 31th frame start address for output DMA */
+#define S3C_CIOYSA32 (0x26c) /* Y 32th frame start address for output DMA */
+
+#define S3C_CIOCBSA5 (0x270) /* CB 5th frame start address for output DMA */
+#define S3C_CIOCBSA6 (0x274) /* CB 6th frame start address for output DMA */
+#define S3C_CIOCBSA7 (0x278) /* CB 7th frame start address for output DMA */
+#define S3C_CIOCBSA8 (0x27c) /* CB 8th frame start address for output DMA */
+#define S3C_CIOCBSA9 (0x280) /* CB 9th frame start address for output DMA */
+#define S3C_CIOCBSA10 (0x284) /* CB 10th frame start address for output DMA */
+#define S3C_CIOCBSA11 (0x288) /* CB 11th frame start address for output DMA */
+#define S3C_CIOCBSA12 (0x28c) /* CB 12th frame start address for output DMA */
+#define S3C_CIOCBSA13 (0x290) /* CB 13th frame start address for output DMA */
+#define S3C_CIOCBSA14 (0x294) /* CB 14th frame start address for output DMA */
+#define S3C_CIOCBSA15 (0x298) /* CB 15th frame start address for output DMA */
+#define S3C_CIOCBSA16 (0x29c) /* CB 16th frame start address for output DMA */
+#define S3C_CIOCBSA17 (0x2a0) /* CB 17th frame start address for output DMA */
+#define S3C_CIOCBSA18 (0x2a4) /* CB 18th frame start address for output DMA */
+#define S3C_CIOCBSA19 (0x2a8) /* CB 19th frame start address for output DMA */
+#define S3C_CIOCBSA20 (0x2ac) /* CB 20th frame start address for output DMA */
+#define S3C_CIOCBSA21 (0x2b0) /* CB 21th frame start address for output DMA */
+#define S3C_CIOCBSA22 (0x2b4) /* CB 22th frame start address for output DMA */
+#define S3C_CIOCBSA23 (0x2b8) /* CB 23th frame start address for output DMA */
+#define S3C_CIOCBSA24 (0x2bc) /* CB 24th frame start address for output DMA */
+#define S3C_CIOCBSA25 (0x2c0) /* CB 25th frame start address for output DMA */
+#define S3C_CIOCBSA26 (0x2c4) /* CB 26th frame start address for output DMA */
+#define S3C_CIOCBSA27 (0x2c8) /* CB 27th frame start address for output DMA */
+#define S3C_CIOCBSA28 (0x2cc) /* CB 28th frame start address for output DMA */
+#define S3C_CIOCBSA29 (0x2d0) /* CB 29th frame start address for output DMA */
+#define S3C_CIOCBSA30 (0x2d4) /* CB 30th frame start address for output DMA */
+#define S3C_CIOCBSA31 (0x2d8) /* CB 31th frame start address for output DMA */
+#define S3C_CIOCBSA32 (0x2dc) /* CB 32th frame start address for output DMA */
+
+#define S3C_CIOCRSA5 (0x2e0) /* CR 5th frame start address for output DMA */
+#define S3C_CIOCRSA6 (0x2e4) /* CR 6th frame start address for output DMA */
+#define S3C_CIOCRSA7 (0x2e8) /* CR 7th frame start address for output DMA */
+#define S3C_CIOCRSA8 (0x2ec) /* CR 8th frame start address for output DMA */
+#define S3C_CIOCRSA9 (0x2f0) /* CR 9th frame start address for output DMA */
+#define S3C_CIOCRSA10 (0x2f4) /* CR 10th frame start address for output DMA */
+#define S3C_CIOCRSA11 (0x2f8) /* CR 11th frame start address for output DMA */
+#define S3C_CIOCRSA12 (0x2fc) /* CR 12th frame start address for output DMA */
+#define S3C_CIOCRSA13 (0x300) /* CR 13th frame start address for output DMA */
+#define S3C_CIOCRSA14 (0x304) /* CR 14th frame start address for output DMA */
+#define S3C_CIOCRSA15 (0x308) /* CR 15th frame start address for output DMA */
+#define S3C_CIOCRSA16 (0x30c) /* CR 16th frame start address for output DMA */
+#define S3C_CIOCRSA17 (0x310) /* CR 17th frame start address for output DMA */
+#define S3C_CIOCRSA18 (0x314) /* CR 18th frame start address for output DMA */
+#define S3C_CIOCRSA19 (0x318) /* CR 19th frame start address for output DMA */
+#define S3C_CIOCRSA20 (0x31c) /* CR 20th frame start address for output DMA */
+#define S3C_CIOCRSA21 (0x320) /* CR 21th frame start address for output DMA */
+#define S3C_CIOCRSA22 (0x324) /* CR 22th frame start address for output DMA */
+#define S3C_CIOCRSA23 (0x328) /* CR 23th frame start address for output DMA */
+#define S3C_CIOCRSA24 (0x32c) /* CR 24th frame start address for output DMA */
+#define S3C_CIOCRSA25 (0x330) /* CR 25th frame start address for output DMA */
+#define S3C_CIOCRSA26 (0x334) /* CR 26th frame start address for output DMA */
+#define S3C_CIOCRSA27 (0x338) /* CR 27th frame start address for output DMA */
+#define S3C_CIOCRSA28 (0x33c) /* CR 28th frame start address for output DMA */
+#define S3C_CIOCRSA29 (0x340) /* CR 29th frame start address for output DMA */
+#define S3C_CIOCRSA30 (0x344) /* CR 30th frame start address for output DMA */
+#define S3C_CIOCRSA31 (0x348) /* CR 31th frame start address for output DMA */
+#define S3C_CIOCRSA32 (0x34c) /* CR 32th frame start address for output DMA */
+/*
+ * Macro part
+*/
+/* frame start address 1 ~ 4, 5 ~ 32 */
+#define DEF_PP 4 /* Number of Default PingPong Memory */
+#define S3C_CIOYSA(__x) \
+ (((__x) < DEF_PP) ? \
+ (S3C_CIOYSA1 + (__x) * 4) : (S3C_CIOYSA5 + ((__x) - DEF_PP) * 4))
+#define S3C_CIOCBSA(__x) \
+ (((__x) < DEF_PP) ? \
+ (S3C_CIOCBSA1 + (__x) * 4) : (S3C_CIOCBSA5 + ((__x) - DEF_PP) * 4))
+#define S3C_CIOCRSA(__x) \
+ (((__x) < DEF_PP) ? \
+ (S3C_CIOCRSA1 + (__x) * 4) : (S3C_CIOCRSA5 + ((__x) - DEF_PP) * 4))
+
+#define S3C_CISRCFMT_SOURCEHSIZE(x) ((x) << 16)
+#define S3C_CISRCFMT_SOURCEVSIZE(x) ((x) << 0)
+
+#define S3C_CIWDOFST_WINHOROFST(x) ((x) << 16)
+#define S3C_CIWDOFST_WINVEROFST(x) ((x) << 0)
+
+#define S3C_CIWDOFST2_WINHOROFST2(x) ((x) << 16)
+#define S3C_CIWDOFST2_WINVEROFST2(x) ((x) << 0)
+
+#define S3C_CITRGFMT_TARGETHSIZE(x) (((x) & 0x1fff) << 16)
+#define S3C_CITRGFMT_TARGETVSIZE(x) (((x) & 0x1fff) << 0)
+
+#define S3C_CISCPRERATIO_SHFACTOR(x) ((x) << 28)
+#define S3C_CISCPRERATIO_PREHORRATIO(x) ((x) << 16)
+#define S3C_CISCPRERATIO_PREVERRATIO(x) ((x) << 0)
+
+#define S3C_CISCPREDST_PREDSTWIDTH(x) ((x) << 16)
+#define S3C_CISCPREDST_PREDSTHEIGHT(x) ((x) << 0)
+
+#define S3C_CISCCTRL_MAINHORRATIO(x) ((x) << 16)
+#define S3C_CISCCTRL_MAINVERRATIO(x) ((x) << 0)
+
+#define S3C_CITAREA_TARGET_AREA(x) ((x) << 0)
+
+#define S3C_CISTATUS_GET_FRAME_COUNT(x) (((x) >> 26) & 0x3)
+#define S3C_CISTATUS_GET_FRAME_END(x) (((x) >> 17) & 0x1)
+#define S3C_CISTATUS_GET_LAST_CAPTURE_END(x) (((x) >> 16) & 0x1)
+#define S3C_CISTATUS_GET_LCD_STATUS(x) (((x) >> 9) & 0x1)
+#define S3C_CISTATUS_GET_ENVID_STATUS(x) (((x) >> 8) & 0x1)
+
+#define S3C_CISTATUS2_GET_FRAMECOUNT_BEFORE(x) (((x) >> 7) & 0x3f)
+#define S3C_CISTATUS2_GET_FRAMECOUNT_PRESENT(x) ((x) & 0x3f)
+
+#define S3C_CIIMGEFF_FIN(x) ((x & 0x7) << 26)
+#define S3C_CIIMGEFF_PAT_CB(x) ((x) << 13)
+#define S3C_CIIMGEFF_PAT_CR(x) ((x) << 0)
+
+#define S3C_CIILINESKIP(x) (((x) & 0xf) << 24)
+
+#define S3C_CIREAL_ISIZE_HEIGHT(x) ((x) << 16)
+#define S3C_CIREAL_ISIZE_WIDTH(x) ((x) << 0)
+
+#define S3C_MSCTRL_SUCCESSIVE_COUNT(x) ((x) << 24)
+#define S3C_MSCTRL_GET_INDMA_STATUS(x) ((x) & 0x1)
+
+#define S3C_CIOYOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIOYOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIOCBOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIOCBOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIOCROFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIOCROFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIIYOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIIYOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIICBOFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIICBOFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIICROFF_VERTICAL(x) ((x) << 16)
+#define S3C_CIICROFF_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_ORGISIZE_VERTICAL(x) ((x) << 16)
+#define S3C_ORGISIZE_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_ORGOSIZE_VERTICAL(x) ((x) << 16)
+#define S3C_ORGOSIZE_HORIZONTAL(x) ((x) << 0)
+
+#define S3C_CIEXTEN_TARGETH_EXT(x) ((((x) & 0x2000) >> 13) << 26)
+#define S3C_CIEXTEN_TARGETV_EXT(x) ((((x) & 0x2000) >> 13) << 24)
+#define S3C_CIEXTEN_MAINHORRATIO_EXT(x) (((x) & 0x3F) << 10)
+#define S3C_CIEXTEN_MAINVERRATIO_EXT(x) ((x) & 0x3F)
+
+/*
+ * Bit definition part
+*/
+/* Source format register */
+#define S3C_CISRCFMT_ITU601_8BIT (1 << 31)
+#define S3C_CISRCFMT_ITU656_8BIT (0 << 31)
+#define S3C_CISRCFMT_ITU601_16BIT (1 << 29)
+#define S3C_CISRCFMT_ORDER422_YCBYCR (0 << 14)
+#define S3C_CISRCFMT_ORDER422_YCRYCB (1 << 14)
+#define S3C_CISRCFMT_ORDER422_CBYCRY (2 << 14)
+#define S3C_CISRCFMT_ORDER422_CRYCBY (3 << 14)
+#define S3C_CISRCFMT_ORDER422_Y4CBCRCBCR (0 << 14) /* ITU601 16bit only */
+#define S3C_CISRCFMT_ORDER422_Y4CRCBCRCB (1 << 14) /* ITU601 16bit only */
+
+/* Window offset register */
+#define S3C_CIWDOFST_WINOFSEN (1 << 31)
+#define S3C_CIWDOFST_CLROVFIY (1 << 30)
+#define S3C_CIWDOFST_CLROVRLB (1 << 29)
+#define S3C_CIWDOFST_WINHOROFST_MASK (0x7ff << 16)
+#define S3C_CIWDOFST_CLROVFICB (1 << 15)
+#define S3C_CIWDOFST_CLROVFICR (1 << 14)
+#define S3C_CIWDOFST_WINVEROFST_MASK (0xfff << 0)
+
+/* Global control register */
+#define S3C_CIGCTRL_SWRST (1 << 31)
+#define S3C_CIGCTRL_CAMRST_A (1 << 30)
+#define S3C_CIGCTRL_SELCAM_ITU_B (0 << 29)
+#define S3C_CIGCTRL_SELCAM_ITU_A (1 << 29)
+#define S3C_CIGCTRL_SELCAM_ITU_MASK (1 << 29)
+#define S3C_CIGCTRL_TESTPATTERN_NORMAL (0 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_COLOR_BAR (1 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_HOR_INC (2 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_VER_INC (3 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_MASK (3 << 27)
+#define S3C_CIGCTRL_TESTPATTERN_SHIFT (27)
+#define S3C_CIGCTRL_INVPOLPCLK (1 << 26)
+#define S3C_CIGCTRL_INVPOLVSYNC (1 << 25)
+#define S3C_CIGCTRL_INVPOLHREF (1 << 24)
+#define S3C_CIGCTRL_IRQ_OVFEN (1 << 22)
+#define S3C_CIGCTRL_HREF_MASK (1 << 21)
+#define S3C_CIGCTRL_IRQ_EDGE (0 << 20)
+#define S3C_CIGCTRL_IRQ_LEVEL (1 << 20)
+#define S3C_CIGCTRL_IRQ_CLR (1 << 19)
+#define S3C_CIGCTRL_IRQ_END_DISABLE (1 << 18)
+#define S3C_CIGCTRL_IRQ_DISABLE (0 << 16)
+#define S3C_CIGCTRL_IRQ_ENABLE (1 << 16)
+#define S3C_CIGCTRL_SHADOW_DISABLE (1 << 12)
+#define S3C_CIGCTRL_CAM_JPEG (1 << 8)
+#define S3C_CIGCTRL_SELCAM_MIPI_B (0 << 7)
+#define S3C_CIGCTRL_SELCAM_MIPI_A (1 << 7)
+#define S3C_CIGCTRL_SELCAM_MIPI_MASK (1 << 7)
+#define S3C_CIGCTRL_SELWB_CAMIF_CAMERA (0 << 6)
+#define S3C_CIGCTRL_SELWB_CAMIF_WRITEBACK (1 << 6)
+#define S3C_CIGCTRL_SELWRITEBACK_MASK (1 << 10)
+#define S3C_CIGCTRL_SELWRITEBACK_A (1 << 10)
+#define S3C_CIGCTRL_SELWRITEBACK_B (0 << 10)
+#define S3C_CIGCTRL_SELWB_CAMIF_MASK (1 << 6)
+#define S3C_CIGCTRL_CSC_ITU601 (0 << 5)
+#define S3C_CIGCTRL_CSC_ITU709 (1 << 5)
+#define S3C_CIGCTRL_CSC_MASK (1 << 5)
+#define S3C_CIGCTRL_INVPOLHSYNC (1 << 4)
+#define S3C_CIGCTRL_SELCAM_FIMC_ITU (0 << 3)
+#define S3C_CIGCTRL_SELCAM_FIMC_MIPI (1 << 3)
+#define S3C_CIGCTRL_SELCAM_FIMC_MASK (1 << 3)
+#define S3C_CIGCTRL_PROGRESSIVE (0 << 0)
+#define S3C_CIGCTRL_INTERLACE (1 << 0)
+
+/* Window offset2 register */
+#define S3C_CIWDOFST_WINHOROFST2_MASK (0xfff << 16)
+#define S3C_CIWDOFST_WINVEROFST2_MASK (0xfff << 16)
+
+/* Target format register */
+#define S3C_CITRGFMT_INROT90_CLOCKWISE (1 << 31)
+#define S3C_CITRGFMT_OUTFORMAT_YCBCR420 (0 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_YCBCR422 (1 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE (2 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_RGB (3 << 29)
+#define S3C_CITRGFMT_OUTFORMAT_MASK (3 << 29)
+#define S3C_CITRGFMT_FLIP_SHIFT (14)
+#define S3C_CITRGFMT_FLIP_NORMAL (0 << 14)
+#define S3C_CITRGFMT_FLIP_X_MIRROR (1 << 14)
+#define S3C_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
+#define S3C_CITRGFMT_FLIP_180 (3 << 14)
+#define S3C_CITRGFMT_FLIP_MASK (3 << 14)
+#define S3C_CITRGFMT_OUTROT90_CLOCKWISE (1 << 13)
+#define S3C_CITRGFMT_TARGETV_MASK (0x1fff << 0)
+#define S3C_CITRGFMT_TARGETH_MASK (0x1fff << 16)
+
+/* Output DMA control register */
+#define S3C_CIOCTRL_WEAVE_OUT (1 << 31)
+#define S3C_CIOCTRL_WEAVE_MASK (1 << 31)
+#define S3C_CIOCTRL_LASTENDEN (1 << 30)
+#define S3C_CIOCTRL_ORDER2P_LSB_CBCR (0 << 24)
+#define S3C_CIOCTRL_ORDER2P_LSB_CRCB (1 << 24)
+#define S3C_CIOCTRL_ORDER2P_MSB_CRCB (2 << 24)
+#define S3C_CIOCTRL_ORDER2P_MSB_CBCR (3 << 24)
+#define S3C_CIOCTRL_ORDER2P_SHIFT (24)
+#define S3C_CIOCTRL_ORDER2P_MASK (3 << 24)
+#define S3C_CIOCTRL_YCBCR_3PLANE (0 << 3)
+#define S3C_CIOCTRL_YCBCR_2PLANE (1 << 3)
+#define S3C_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
+#define S3C_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
+#define S3C_CIOCTRL_ORDER422_YCBYCR (0 << 0)
+#define S3C_CIOCTRL_ORDER422_YCRYCB (1 << 0)
+#define S3C_CIOCTRL_ORDER422_CBYCRY (2 << 0)
+#define S3C_CIOCTRL_ORDER422_CRYCBY (3 << 0)
+#define S3C_CIOCTRL_ORDER422_MASK (3 << 0)
+
+/* Main scaler control register */
+#define S3C_CISCCTRL_SCALERBYPASS (1 << 31)
+#define S3C_CISCCTRL_SCALEUP_H (1 << 30)
+#define S3C_CISCCTRL_SCALEUP_V (1 << 29)
+#define S3C_CISCCTRL_CSCR2Y_NARROW (0 << 28)
+#define S3C_CISCCTRL_CSCR2Y_WIDE (1 << 28)
+#define S3C_CISCCTRL_CSCY2R_NARROW (0 << 27)
+#define S3C_CISCCTRL_CSCY2R_WIDE (1 << 27)
+#define S3C_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
+#define S3C_CISCCTRL_PROGRESSIVE (0 << 25)
+#define S3C_CISCCTRL_INTERLACE (1 << 25)
+#define S3C_CISCCTRL_SCAN_MASK (1 << 25)
+#define S3C_CISCCTRL_SCALERSTART (1 << 15)
+#define S3C_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
+#define S3C_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
+#define S3C_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
+#define S3C_CISCCTRL_INRGB_FMT_RGB_MASK (3 << 13)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
+#define S3C_CISCCTRL_OUTRGB_FMT_RGB_MASK (3 << 11)
+#define S3C_CISCCTRL_EXTRGB_NORMAL (0 << 10)
+#define S3C_CISCCTRL_EXTRGB_EXTENSION (1 << 10)
+#define S3C_CISCCTRL_ONE2ONE (1 << 9)
+#define S3C_CISCCTRL_MAIN_V_RATIO_MASK (0x1ff << 0)
+#define S3C_CISCCTRL_MAIN_H_RATIO_MASK (0x1ff << 16)
+
+/* Status register */
+#define S3C_CISTATUS_OVFIY (1 << 31)
+#define S3C_CISTATUS_OVFICB (1 << 30)
+#define S3C_CISTATUS_OVFICR (1 << 29)
+#define S3C_CISTATUS_VSYNC (1 << 28)
+#define S3C_CISTATUS_SCALERSTART (1 << 26)
+#define S3C_CISTATUS_WINOFSTEN (1 << 25)
+#define S3C_CISTATUS_IMGCPTEN (1 << 22)
+#define S3C_CISTATUS_IMGCPTENSC (1 << 21)
+#define S3C_CISTATUS_VSYNC_A (1 << 20)
+#define S3C_CISTATUS_VSYNC_B (1 << 19)
+#define S3C_CISTATUS_OVRLB (1 << 18)
+#define S3C_CISTATUS_FRAMEEND (1 << 17)
+#define S3C_CISTATUS_LASTCAPTUREEND (1 << 16)
+#define S3C_CISTATUS_VVALID_A (1 << 15)
+#define S3C_CISTATUS_VVALID_B (1 << 14)
+
+/* Image capture enable register */
+#define S3C_CIIMGCPT_IMGCPTEN (1 << 31)
+#define S3C_CIIMGCPT_IMGCPTEN_SC (1 << 30)
+#define S3C_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
+#define S3C_CIIMGCPT_CPT_FRMOD_EN (0 << 18)
+#define S3C_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
+
+/* Image effects register */
+#define S3C_CIIMGEFF_IE_DISABLE (0 << 30)
+#define S3C_CIIMGEFF_IE_ENABLE (1 << 30)
+#define S3C_CIIMGEFF_IE_SC_BEFORE (0 << 29)
+#define S3C_CIIMGEFF_IE_SC_AFTER (1 << 29)
+#define S3C_CIIMGEFF_FIN_BYPASS (0 << 26)
+#define S3C_CIIMGEFF_FIN_ARBITRARY (1 << 26)
+#define S3C_CIIMGEFF_FIN_NEGATIVE (2 << 26)
+#define S3C_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
+#define S3C_CIIMGEFF_FIN_EMBOSSING (4 << 26)
+#define S3C_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
+#define S3C_CIIMGEFF_FIN_MASK (7 << 26)
+#define S3C_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0))
+
+/* Real input DMA size register */
+#define S3C_CIREAL_ISIZE_AUTOLOAD_ENABLE (1 << 31)
+#define S3C_CIREAL_ISIZE_ADDR_CH_DISABLE (1 << 30)
+#define S3C_CIREAL_ISIZE_HEIGHT_MASK (0x3FFF << 16)
+#define S3C_CIREAL_ISIZE_WIDTH_MASK (0x3FFF << 0)
+
+/* Input DMA control register */
+#define S3C_MSCTRL_FIELD_MASK (1 << 31)
+#define S3C_MSCTRL_FIELD_WEAVE (1 << 31)
+#define S3C_MSCTRL_FIELD_NORMAL (0 << 31)
+#define S3C_MSCTRL_BURST_CNT (24)
+#define S3C_MSCTRL_BURST_CNT_MASK (0xf << 24)
+#define S3C_MSCTRL_ORDER2P_LSB_CBCR (0 << 16)
+#define S3C_MSCTRL_ORDER2P_LSB_CRCB (1 << 16)
+#define S3C_MSCTRL_ORDER2P_MSB_CRCB (2 << 16)
+#define S3C_MSCTRL_ORDER2P_MSB_CBCR (3 << 16)
+#define S3C_MSCTRL_ORDER2P_SHIFT (16)
+#define S3C_MSCTRL_ORDER2P_SHIFT_MASK (0x3 << 16)
+#define S3C_MSCTRL_C_INT_IN_3PLANE (0 << 15)
+#define S3C_MSCTRL_C_INT_IN_2PLANE (1 << 15)
+#define S3C_MSCTRL_FLIP_SHIFT (13)
+#define S3C_MSCTRL_FLIP_NORMAL (0 << 13)
+#define S3C_MSCTRL_FLIP_X_MIRROR (1 << 13)
+#define S3C_MSCTRL_FLIP_Y_MIRROR (2 << 13)
+#define S3C_MSCTRL_FLIP_180 (3 << 13)
+#define S3C_MSCTRL_FLIP_MASK (3 << 13)
+#define S3C_MSCTRL_ORDER422_CRYCBY (0 << 4)
+#define S3C_MSCTRL_ORDER422_YCRYCB (1 << 4)
+#define S3C_MSCTRL_ORDER422_CBYCRY (2 << 4)
+#define S3C_MSCTRL_ORDER422_YCBYCR (3 << 4)
+#define S3C_MSCTRL_INPUT_EXTCAM (0 << 3)
+#define S3C_MSCTRL_INPUT_MEMORY (1 << 3)
+#define S3C_MSCTRL_INPUT_MASK (1 << 3)
+#define S3C_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
+#define S3C_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
+#define S3C_MSCTRL_INFORMAT_YCBCR422_1PLANE (2 << 1)
+#define S3C_MSCTRL_INFORMAT_RGB (3 << 1)
+#define S3C_MSCTRL_ENVID (1 << 0)
+
+/* DMA parameter register */
+#define S3C_CIDMAPARAM_R_MODE_LINEAR (0 << 29)
+#define S3C_CIDMAPARAM_R_MODE_CONFTILE (1 << 29)
+#define S3C_CIDMAPARAM_R_MODE_16X16 (2 << 29)
+#define S3C_CIDMAPARAM_R_MODE_64X32 (3 << 29)
+#define S3C_CIDMAPARAM_R_MODE_MASK (3 << 29)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_64 (0 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_128 (1 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_256 (2 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_512 (3 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_1024 (4 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_2048 (5 << 24)
+#define S3C_CIDMAPARAM_R_TILE_HSIZE_4096 (6 << 24)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_1 (0 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_2 (1 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_4 (2 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_8 (3 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_16 (4 << 20)
+#define S3C_CIDMAPARAM_R_TILE_VSIZE_32 (5 << 20)
+#define S3C_CIDMAPARAM_W_MODE_LINEAR (0 << 13)
+#define S3C_CIDMAPARAM_W_MODE_CONFTILE (1 << 13)
+#define S3C_CIDMAPARAM_W_MODE_16X16 (2 << 13)
+#define S3C_CIDMAPARAM_W_MODE_64X32 (3 << 13)
+#define S3C_CIDMAPARAM_W_MODE_MASK (3 << 13)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_64 (0 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_128 (1 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_256 (2 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_512 (3 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_1024 (4 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_2048 (5 << 8)
+#define S3C_CIDMAPARAM_W_TILE_HSIZE_4096 (6 << 8)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_1 (0 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_2 (1 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_4 (2 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_8 (3 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_16 (4 << 4)
+#define S3C_CIDMAPARAM_W_TILE_VSIZE_32 (5 << 4)
+
+/* Gathering Extension register */
+#define S3C_CIEXTEN_TARGETH_EXT_MASK (1 << 26)
+#define S3C_CIEXTEN_TARGETV_EXT_MASK (1 << 24)
+#define S3C_CIEXTEN_MAINHORRATIO_EXT_MASK (0x3F << 10)
+#define S3C_CIEXTEN_MAINVERRATIO_EXT_MASK (0x3F)
+#define S3C_CIEXTEN_YUV444_OUT (1 << 22)
+
+/* FIMC Clock Source Select register */
+#define S3C_CLKSRC_HCLK (0 << 1)
+#define S3C_CLKSRC_HCLK_MASK (1 << 1)
+#define S3C_CLKSRC_SCLK (1 << 1)
+
+/* SYSREG for FIMC writeback */
+#define SYSREG_CAMERA_BLK (S3C_VA_SYS + 0x0218)
+#define SYSREG_ISP_BLK (S3C_VA_SYS + 0x020c)
+
+#endif /* __ASM_PLAT_REGS_FIMC_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-ipc.h b/arch/arm/plat-s5p/include/plat/regs-ipc.h
new file mode 100644
index 0000000..ea439c8
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-ipc.h
@@ -0,0 +1,143 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-ipc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for IPC driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_IPC_H
+#define __ASM_PLAT_REGS_IPC_H __FILE__
+
+#define IPC_2D_ENABLE 0x10000
+#define IPC_HOR_SCALING_ENABLE 0x8000
+
+/*
+ * Registers
+*/
+#define S3C_IPC_ENABLE (0x00)
+#define S3C_IPC_SRESET (0x04)
+#define S3C_IPC_SHADOW_UPDATE (0x08)
+#define S3C_IPC_FIELD_ID (0x0c)
+#define S3C_IPC_MODE (0x10)
+#define S3C_IPC_PEL_RATE_CTRL (0x1C)
+#define S3C_IPC_ENDIAN_MODE (0x3C)
+#define S3C_IPC_SRC_WIDTH (0x4C)
+#define S3C_IPC_SRC_HEIGHT (0x50)
+#define S3C_IPC_DST_WIDTH (0x5C)
+#define S3C_IPC_DST_HEIGHT (0x60)
+#define S3C_IPC_H_RATIO (0x64)
+#define S3C_IPC_V_RATIO (0x68)
+
+#define S3C_IPC_POLY8_Y0_LL (0x6C)
+#define S3C_IPC_POLY8_Y0_LH (0x70)
+#define S3C_IPC_POLY8_Y0_HL (0x74)
+#define S3C_IPC_POLY8_Y0_HH (0x78)
+#define S3C_IPC_POLY8_Y1_LL (0x7C)
+#define S3C_IPC_POLY8_Y1_LH (0x80)
+#define S3C_IPC_POLY8_Y1_HL (0x84)
+#define S3C_IPC_POLY8_Y1_HH (0x88)
+#define S3C_IPC_POLY8_Y2_LL (0x8C)
+#define S3C_IPC_POLY8_Y2_LH (0x90)
+#define S3C_IPC_POLY8_Y2_HL (0x94)
+#define S3C_IPC_POLY8_Y2_HH (0x98)
+#define S3C_IPC_POLY8_Y3_LL (0x9C)
+#define S3C_IPC_POLY8_Y3_LH (0xA0)
+#define S3C_IPC_POLY8_Y3_HL (0xA4)
+#define S3C_IPC_POLY8_Y3_HH (0xA8)
+#define S3C_IPC_POLY4_Y0_LL (0xEC)
+#define S3C_IPC_POLY4_Y0_LH (0xF0)
+#define S3C_IPC_POLY4_Y0_HL (0xF4)
+#define S3C_IPC_POLY4_Y0_HH (0xF8)
+#define S3C_IPC_POLY4_Y1_LL (0xFC)
+#define S3C_IPC_POLY4_Y1_LH (0x100)
+#define S3C_IPC_POLY4_Y1_HL (0x104)
+#define S3C_IPC_POLY4_Y1_HH (0x108)
+#define S3C_IPC_POLY4_Y2_LL (0x10C)
+#define S3C_IPC_POLY4_Y2_LH (0x110)
+#define S3C_IPC_POLY4_Y2_HL (0x114)
+#define S3C_IPC_POLY4_Y2_HH (0x118)
+#define S3C_IPC_POLY4_Y3_LL (0x11C)
+#define S3C_IPC_POLY4_Y3_LH (0x120)
+#define S3C_IPC_POLY4_Y3_HL (0x124)
+#define S3C_IPC_POLY4_Y3_HH (0x128)
+#define S3C_IPC_POLY4_C0_LL (0x12C)
+#define S3C_IPC_POLY4_C0_LH (0x130)
+#define S3C_IPC_POLY4_C0_HL (0x134)
+#define S3C_IPC_POLY4_C0_HH (0x138)
+#define S3C_IPC_POLY4_C1_LL (0x13C)
+#define S3C_IPC_POLY4_C1_LH (0x140)
+#define S3C_IPC_POLY4_C1_HL (0x144)
+#define S3C_IPC_POLY4_C1_HH (0x148)
+#define S3C_IPC_BYPASS (0x200)
+#define S3C_IPC_PP_SATURATION (0x20C)
+#define S3C_IPC_PP_SHARPNESS (0x210)
+#define S3C_IPC_PP_LINE_EQ0 (0x218)
+#define S3C_IPC_PP_LINE_EQ1 (0x21C)
+#define S3C_IPC_PP_LINE_EQ2 (0x220)
+#define S3C_IPC_PP_LINE_EQ3 (0x224)
+#define S3C_IPC_PP_LINE_EQ4 (0x228)
+#define S3C_IPC_PP_LINE_EQ5 (0x22C)
+#define S3C_IPC_PP_LINE_EQ6 (0x230)
+#define S3C_IPC_PP_LINE_EQ7 (0x234)
+#define S3C_IPC_PP_BRIGHT_OFFSET (0x238)
+#define S3C_IPC_VERSION_INFO (0x3FC)
+
+/*
+ * Bit Definitions
+*/
+/* ENABLE/DISABLE CONTROL */
+#define S3C_IPC_ON (1 << 0)
+#define S3C_IPC_OFF (0 << 0)
+
+/* SOFTWARE RESET */
+#define S3C_IPC_SRESET_ENABLE (1 << 0)
+#define S3C_IPC_SRESET_MASK (1 << 0)
+
+/* SHADOW UPDATE ENABLE CONTROL */
+#define S3C_IPC_SHADOW_UPDATE_ENABLE (1 << 0)
+#define S3C_IPC_SHADOW_UPDATE_DISABLE (0 << 0)
+
+/* OPERATION MODE CONTROL */
+#define S3C_IPC_2D_ENABLE (1 << 0)
+#define S3C_IPC_2D_DISABLE (0 << 0)
+#define S3C_IPC_2D_MASK (1 << 1)
+
+/* VERTICAL SCALER PIXEL RATE CONTROL */
+#define S3C_IPC_PEL_RATE_SET (0 << 0)
+
+/* HORIZONTAL ZOOM RATIO */
+#define S3C_IPC_H_RATIO_MASK (0x7fff << 0)
+#define S3C_IPC_V_RATIO_MASK (0x7fff << 0)
+
+/* POST PROCESSING IMAGE BYPASS MODE CONTROL */
+#define S3C_IPC_PP_BYPASS_ENABLE (0 << 0)
+#define S3C_IPC_PP_BYPASS_DISABLE (1 << 0)
+#define S3C_IPC_PP_BYPASS_MASK (1 << 0)
+
+/* BRIGHTNESS AND CONTRAST CONTROL */
+#define S3C_IPC_PP_LINE_CONTRAST_MASK (0xff << 0)
+#define S3C_IPC_PP_LINE_BRIGTHNESS_MASK (0xffff << 8)
+
+/*
+ * Macro part
+*/
+#define S3C_IPC_FIELD_ID_SELECTION(x) ((x) << 6)
+#define S3C_IPC_FIELD_ID_AUTO_TOGGLING(x) ((x) << 2)
+#define S3C_IPC_2D_CTRL(x) ((x) << 1)
+#define S3C_IPC_SRC_WIDTH_SET(x) ((x) & 0x7ff << 0)
+#define S3C_IPC_SRC_HEIGHT_SET(x) ((x) & 0x3ff << 0)
+#define S3C_IPC_DST_WIDTH_SET(x) ((x) & 0x7ff << 0)
+#define S3C_IPC_DST_HEIGHT_SET(x) ((x) & 0x3ff << 0)
+#define S3C_IPC_PP_SATURATION_SET(x) ((x) & 0xff << 0)
+#define S3C_IPC_PP_TH_HNOISE_SET(x) ((x) & 0xff << 8)
+#define S3C_IPC_PP_SHARPNESS_SET(x) ((x) & 0x3 << 8)
+#define S3C_IPC_PP_BRIGHT_OFFSET_SET(x) ((x) & 0x1ff << 8)
+#define S3C_IPC_PP_LINE_CONTRAST(x) (((x) & S3C_IPC_PP_LINE_CONTRAST_MASK) << 0)
+#define S3C_IPC_PP_LINE_BRIGHT(x) (((x) & S3C_IPC_PP_LINE_BRIGTHNESS_MASK) << 8)
+
+#endif /* __ASM_PLAT_REGS_IPC_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs-mipidsim.h b/arch/arm/plat-s5p/include/plat/regs-mipidsim.h
new file mode 100644
index 0000000..43b69cf
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-mipidsim.h
@@ -0,0 +1,149 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-mipidsim.h
+ *
+ * Register definition file for Samsung MIPI-DSIM driver
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _REGS_MIPIDSIM_H
+#define _REGS_MIPIDSIM_H
+
+#define S5P_DSIM_STATUS (0x0) /* Status register */
+#define S5P_DSIM_SWRST (0x4) /* Software reset register */
+#define S5P_DSIM_CLKCTRL (0x8) /* Clock control register */
+#define S5P_DSIM_TIMEOUT (0xc) /* Time out register */
+#define S5P_DSIM_CONFIG (0x10) /* Configuration register */
+#define S5P_DSIM_ESCMODE (0x14) /* Escape mode register */
+
+/* Main display image resolution register */
+#define S5P_DSIM_MDRESOL (0x18)
+#define S5P_DSIM_MVPORCH (0x1c) /* Main display Vporch register */
+#define S5P_DSIM_MHPORCH (0x20) /* Main display Hporch register */
+#define S5P_DSIM_MSYNC (0x24) /* Main display sync area register
+*/
+
+/* Sub display image resolution register */
+#define S5P_DSIM_SDRESOL (0x28)
+#define S5P_DSIM_INTSRC (0x2c) /* Interrupt source
+register */
+#define S5P_DSIM_INTMSK (0x30) /* Interrupt mask register
+*/
+#define S5P_DSIM_PKTHDR (0x34) /* Packet Header FIFO
+register */
+#define S5P_DSIM_PAYLOAD (0x38) /* Payload FIFO register */
+#define S5P_DSIM_RXFIFO (0x3c) /* Read FIFO register */
+#define S5P_DSIM_FIFOTHLD (0x40) /* FIFO threshold level register */
+#define S5P_DSIM_FIFOCTRL (0x44) /* FIFO status and control register
+*/
+
+/* FIFO memory AC characteristic register */
+#define S5P_DSIM_PLLCTRL (0x4c) /* PLL control register */
+#define S5P_DSIM_PLLTMR (0x50) /* PLL timer register */
+#define S5P_DSIM_PHYACCHR (0x54) /* D-PHY AC characteristic register
+*/
+#define S5P_DSIM_PHYACCHR1 (0x58) /* D-PHY AC characteristic
+register1 */
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK (1 << 8)
+#define DSIM_TX_READY_HS_CLK (1 << 10)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST (1 << 16)
+#define DSIM_SWRST (1 << 0)
+
+/* S5P_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT (0)
+#define DSIM_BTA_TOUT_SHIFT (16)
+
+/* S5P_DSIM_CLKCTRL */
+#define DSIM_LANE_ESC_CLKEN_SHIFT (19)
+#define DSIM_BYTE_CLKEN_SHIFT (24)
+#define DSIM_BYTE_CLK_SRC_SHIFT (25)
+#define DSIM_PLL_BYPASS_SHIFT (27)
+#define DSIM_ESC_CLKEN_SHIFT (28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT (31)
+#define DSIM_LANE_ESC_CLKEN(x) (((x) & 0x1f) << \
+ DSIM_LANE_ESC_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_ENABLE (1 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_DISABLE (0 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_PLL_BYPASS_EXTERNAL (1 << DSIM_PLL_BYPASS_SHIFT)
+#define DSIM_ESC_CLKEN_ENABLE (1 << DSIM_ESC_CLKEN_SHIFT)
+#define DSIM_ESC_CLKEN_DISABLE (0 << DSIM_ESC_CLKEN_SHIFT)
+
+/* S5P_DSIM_CONFIG */
+#define DSIM_NUM_OF_DATALANE_SHIFT (5)
+#define DSIM_HSA_MODE_SHIFT (20)
+#define DSIM_HBP_MODE_SHIFT (21)
+#define DSIM_HFP_MODE_SHIFT (22)
+#define DSIM_HSE_MODE_SHIFT (23)
+#define DSIM_AUTO_MODE_SHIFT (24)
+#define DSIM_LANE_ENx(x) (((x) & 0x1f) << 0)
+
+#define DSIM_NUM_OF_DATA_LANE(x) ((x) << DSIM_NUM_OF_DATALANE_SHIFT)
+
+/* S5P_DSIM_ESCMODE */
+#define DSIM_TX_LPDT_SHIFT (6)
+#define DSIM_CMD_LPDT_SHIFT (7)
+#define DSIM_TX_LPDT_LP (1 << DSIM_TX_LPDT_SHIFT)
+#define DSIM_CMD_LPDT_LP (1 << DSIM_CMD_LPDT_SHIFT)
+#define DSIM_STOP_STATE_CNT_SHIFT (21)
+#define DSIM_FORCE_STOP_STATE_SHIFT (20)
+
+/* S5P_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY (1 << 31)
+#define DSIM_MAIN_VRESOL(x) (((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x) (((x) & 0X7ff) << 0)
+
+/* S5P_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT (28)
+#define DSIM_STABLE_VFP_SHIFT (16)
+#define DSIM_MAIN_VBP_SHIFT (0)
+#define DSIM_CMD_ALLOW_MASK (0xf << DSIM_CMD_ALLOW_SHIFT)
+#define DSIM_STABLE_VFP_MASK (0x7ff << DSIM_STABLE_VFP_SHIFT)
+#define DSIM_MAIN_VBP_MASK (0x7ff << DSIM_MAIN_VBP_SHIFT)
+
+/* S5P_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT (16)
+#define DSIM_MAIN_HBP_SHIFT (0)
+#define DSIM_MAIN_HFP_MASK ((0xffff) << DSIM_MAIN_HFP_SHIFT)
+#define DSIM_MAIN_HBP_MASK ((0xffff) << DSIM_MAIN_HBP_SHIFT)
+
+/* S5P_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT (22)
+#define DSIM_MAIN_HSA_SHIFT (0)
+#define DSIM_MAIN_VSA_MASK ((0x3ff) << DSIM_MAIN_VSA_SHIFT)
+#define DSIM_MAIN_HSA_MASK ((0xffff) << DSIM_MAIN_HSA_SHIFT)
+
+/* S5P_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT (31)
+#define DSIM_SUB_VRESOL_SHIFT (16)
+#define DSIM_SUB_HRESOL_SHIFT (0)
+#define DSIM_SUB_STANDY_MASK ((0x1) << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_VRESOL_MASK ((0x7ff) << DSIM_SUB_VRESOL_SHIFT)
+#define DSIM_SUB_HRESOL_MASK ((0x7ff) << DSIM_SUB_HRESOL_SHIFT)
+
+/* S5P_DSIM_INTSRC */
+#define INTSRC_FRAME_DONE (1 << 24)
+#define INTSRC_PLL_STABLE (1 << 31)
+#define INTSRC_SFR_FIFO_EMPTY (1 << 29)
+
+/* S5P_DSIM_INTMSK */
+#define INTMSK_FRAME_DONE (1 << 24)
+
+/* S5P_DSIM_FIFOCTRL */
+#define SFR_HEADER_EMPTY (1 << 22)
+
+/* S5P_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)
+
+/* S5P_DSIM_PLLCTRL */
+#define DSIM_PLL_EN_SHIFT (23)
+#define DSIM_FREQ_BAND_SHIFT (24)
+
+#endif /* _REGS_MIPIDSIM_H */
diff --git a/arch/arm/plat-s5p/include/plat/regs_jpeg.h b/arch/arm/plat-s5p/include/plat/regs_jpeg.h
new file mode 100644
index 0000000..cd9bb2f
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs_jpeg.h
@@ -0,0 +1,144 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-jpeg.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung JPEG Encoder/Decoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_S5P_JPEG_H
+#define __ASM_ARM_REGS_S5P_JPEG_H
+
+/* JPEG Registers part */
+
+/* JPEG Codec Control Registers */
+#define S5P_JPEG_MOD_REG 0x00
+#define S5P_JPEG_OPR_REG 0x04
+#define S5P_JPEG_QTBL_REG 0x08
+#define S5P_JPEG_HTBL_REG 0x0c
+#define S5P_JPEG_DRI_U_REG 0x10
+#define S5P_JPEG_DRI_L_REG 0x14
+#define S5P_JPEG_Y_U_REG 0x18
+#define S5P_JPEG_Y_L_REG 0x1c
+#define S5P_JPEG_X_U_REG 0x20
+#define S5P_JPEG_X_L_REG 0x24
+#define S5P_JPEG_CNT_U_REG 0x28
+#define S5P_JPEG_CNT_M_REG 0x2c
+#define S5P_JPEG_CNT_L_REG 0x30
+#define S5P_JPEG_INTSE_REG 0x34
+#define S5P_JPEG_INTST_REG 0x38
+
+#define S5P_JPEG_COM_REG 0x4c
+
+/* raw image data address */
+#define S5P_JPEG_IMGADR_REG 0x50
+
+#define S5P_JPEG_JPGADR_REG 0x58
+#define S5P_JPEG_COEF1_REG 0x5c
+#define S5P_JPEG_COEF2_REG 0x60
+#define S5P_JPEG_COEF3_REG 0x64
+
+#define S5P_JPEG_CMOD_REG 0x68
+#define S5P_JPEG_CLKCON_REG 0x6c
+
+#define S5P_JPEG_JSTART_REG 0x70
+#define S5P_JPEG_JRSTART_REG 0x74
+#define S5P_JPEG_SW_RESET_REG 0x78
+
+#define S5P_JPEG_TIMER_SE_REG 0x7c
+#define S5P_JPEG_TIMER_ST_REG 0x80
+#define S5P_JPEG_COMSTAT_REG 0x84
+#define S5P_JPEG_OUTFORM_REG 0x88
+#define S5P_JPEG_VERSION_REG 0x8c
+
+#define S5P_JPEG_ENC_STREAM_INTSE_REG 0x98
+#define S5P_JPEG_ENC_STREAM_INTST_REG 0x9c
+
+#define S5P_JPEG_QTBL0_REG 0x400
+#define S5P_JPEG_QTBL1_REG 0x500
+#define S5P_JPEG_QTBL2_REG 0x600
+#define S5P_JPEG_QTBL3_REG 0x700
+
+#define S5P_JPEG_HDCTBL0_REG 0x800
+#define S5P_JPEG_HDCTBLG0_REG 0x840
+#define S5P_JPEG_HACTBL0_REG 0x880
+#define S5P_JPEG_HACTBLG0_REG 0x8c0
+#define S5P_JPEG_HDCTBL1_REG 0xc00
+#define S5P_JPEG_HDCTBLG1_REG 0xc40
+#define S5P_JPEG_HACTBL1_REG 0xc80
+#define S5P_JPEG_HACTBLG1_REG 0xcc0
+
+/***************************************************************/
+/* Bit definition part */
+/***************************************************************/
+
+/* JPEG Mode Register bit */
+#define S5P_JPEG_MOD_REG_PROC_ENC (0<<3)
+#define S5P_JPEG_MOD_REG_PROC_DEC (1<<3)
+
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_444 (0<<0)
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_422 (1<<0)
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_420 (2<<0)
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_GRAY (3<<0)
+
+/* JPEG Operation Status Register bit */
+#define S5P_JPEG_OPR_REG_OPERATE (1<<0)
+#define S5P_JPEG_OPR_REG_NO_OPERATE (0<<0)
+
+/* Quantization Table And Huffman Table Number Register bit */
+#define S5P_JPEG_QHTBL_REG_QT_NUM4 (1<<6)
+#define S5P_JPEG_QHTBL_REG_QT_NUM3 (1<<4)
+#define S5P_JPEG_QHTBL_REG_QT_NUM2 (1<<2)
+#define S5P_JPEG_QHTBL_REG_QT_NUM1 (1<<0)
+
+#define S5P_JPEG_QHTBL_REG_HT_NUM4_AC (1<<7)
+#define S5P_JPEG_QHTBL_REG_HT_NUM4_DC (1<<6)
+#define S5P_JPEG_QHTBL_REG_HT_NUM3_AC (1<<5)
+#define S5P_JPEG_QHTBL_REG_HT_NUM3_DC (1<<4)
+#define S5P_JPEG_QHTBL_REG_HT_NUM2_AC (1<<3)
+#define S5P_JPEG_QHTBL_REG_HT_NUM2_DC (1<<2)
+#define S5P_JPEG_QHTBL_REG_HT_NUM1_AC (1<<1)
+#define S5P_JPEG_QHTBL_REG_HT_NUM1_DC (1<<0)
+
+/* JPEG Color Mode Register bit */
+#define S5P_JPEG_CMOD_REG_MOD_SEL_RGB (2<<5)
+#define S5P_JPEG_CMOD_REG_MOD_SEL_YCBCR422 (1<<5)
+#define S5P_JPEG_CMOD_REG_MOD_MODE_Y16 (1<<1)
+#define S5P_JPEG_CMOD_REG_MOD_MODE_0 (0<<1)
+
+/* JPEG Clock Control Register bit */
+#define S5P_JPEG_CLKCON_REG_CLK_DOWN_READY_ENABLE (0<<1)
+#define S5P_JPEG_CLKCON_REG_CLK_DOWN_READY_DISABLE (1<<1)
+#define S5P_JPEG_CLKCON_REG_POWER_ON_ACTIVATE (1<<0)
+#define S5P_JPEG_CLKCON_REG_POWER_ON_DISABLE (0<<0)
+
+/* JPEG Start Register bit */
+#define S5P_JPEG_JSTART_REG_ENABLE (1<<0)
+
+/* JPEG Rdstart Register bit */
+#define S5P_JPEG_JRSTART_REG_ENABLE (1<<0)
+
+/* JPEG SW Reset Register bit */
+#define S5P_JPEG_SW_RESET_REG_ENABLE (1<<0)
+
+/* JPEG Interrupt Setting Register bit */
+#define S5P_JPEG_INTSE_REG_RSTM_INT_EN (1<<7)
+#define S5P_JPEG_INTSE_REG_DATA_NUM_INT_EN (1<<6)
+#define S5P_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN (1<<5)
+
+/* JPEG Decompression Output Format Register bit */
+#define S5P_JPEG_OUTFORM_REG_YCBCY422 (0<<0)
+#define S5P_JPEG_OUTFORM_REG_YCBCY420 (1<<0)
+
+/* JPEG Decompression Input Stream Size Register bit */
+#define S5P_JPEG_DEC_STREAM_SIZE_REG_PROHIBIT (0x1FFFFFFF<<0)
+
+/* JPEG Command Register bit */
+#define S5P_JPEG_COM_INT_RELEASE (1<<2)
+
+#endif /* __ASM_ARM_REGS_S3C_JPEG_H */
+
diff --git a/arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h b/arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h
new file mode 100644
index 0000000..33ad38a
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs_jpeg_v2_x.h
@@ -0,0 +1,217 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-jpeg_v2_x.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung JPEG v.2 Encoder/Decoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_S5P_JPEG_H
+#define __ASM_ARM_REGS_S5P_JPEG_H
+
+/* JPEG Registers part */
+
+/* JPEG Codec Control Registers */
+#define S5P_JPEG_CNTL_REG 0x00
+#define S5P_JPEG_INT_EN_REG 0x04
+#define S5P_JPEG_INT_TIMER_COUNT_REG 0x08
+#define S5P_JPEG_INT_STATUS_REG 0x0c
+#define S5P_JPEG_OUT_MEM_BASE_REG 0x10
+#define S5P_JPEG_IMG_SIZE_REG 0x14
+#define S5P_JPEG_IMG_BA_PLANE_1_REG 0x18
+#define S5P_JPEG_IMG_SO_PLANE_1_REG 0x1c
+#define S5P_JPEG_IMG_PO_PLANE_1_REG 0x20
+#define S5P_JPEG_IMG_BA_PLANE_2_REG 0x24
+#define S5P_JPEG_IMG_SO_PLANE_2_REG 0x28
+#define S5P_JPEG_IMG_PO_PLANE_2_REG 0x2c
+#define S5P_JPEG_IMG_BA_PLANE_3_REG 0x30
+#define S5P_JPEG_IMG_SO_PLANE_3_REG 0x34
+#define S5P_JPEG_IMG_PO_PLANE_3_REG 0x38
+
+#define S5P_JPEG_TBL_SEL_REG 0x3c
+
+#define S5P_JPEG_IMG_FMT_REG 0x40
+
+#define S5P_JPEG_BITSTREAM_SIZE_REG 0x44
+#define S5P_JPEG_PADDING_REG 0x48
+#define S5P_JPEG_HUFF_CNT_REG 0x4c
+#define S5P_JPEG_FIFO_STATUS_REG 0x50
+#define S5P_JPEG_DECODE_XY_SIZE_REG 0x54
+#define S5P_JPEG_DECODE_IMG_FMT_REG 0x58
+
+#define S5P_JPEG_QUAN_TBL_ENTRY_REG 0x100
+#define S5P_JPEG_HUFF_TBL_ENTRY_REG 0x200
+
+
+/****************************************************************/
+/* Bit definition part */
+/****************************************************************/
+
+/* JPEG CNTL Register bit */
+#define S5P_JPEG_ENC_DEC_MODE_MASK (0xfffffffc << 0)
+#define S5P_JPEG_DEC_MODE (1 << 0)
+#define S5P_JPEG_ENC_MODE (1 << 1)
+#define S5P_JPEG_AUTO_RST_MARKER (1 << 2)
+#define S5P_JPEG_RST_INTERVAL_SHIFT 3
+#define S5P_JPEG_RST_INTERVAL(x) (((x) & 0xffff) << S5P_JPEG_RST_INTERVAL_SHIFT)
+#define S5P_JPEG_HUF_TBL_EN (1 << 19)
+#define S5P_JPEG_HOR_SCALING_SHIFT 20
+#define S5P_JPEG_HOR_SCALING_MASK (3 << S5P_JPEG_HOR_SCALING_SHIFT)
+#define S5P_JPEG_HOR_SCALING(x) (((x) & 0x3) << S5P_JPEG_HOR_SCALING_SHIFT)
+#define S5P_JPEG_VER_SCALING_SHIFT 22
+#define S5P_JPEG_VER_SCALING_MASK (3 << S5P_JPEG_VER_SCALING_SHIFT)
+#define S5P_JPEG_VER_SCALING(x) (((x) & 0x3) << S5P_JPEG_VER_SCALING_SHIFT)
+#define S5P_JPEG_PADDING (1 << 27)
+#define S5P_JPEG_SYS_INT_EN (1 << 28)
+#define S5P_JPEG_SOFT_RESET_HI (1 << 29)
+
+/* JPEG INT Register bit */
+#if defined (CONFIG_JPEG_V2_2)
+#define S5P_JPEG_INT_EN_MASK (0x1ff << 0)
+#define S5P_JPEG_INT_EN_ALL (0x1ff << 0)
+#define S5P_JPEG_TIMER_INT_EN (1 << 5)
+#define S5P_JPEG_DEC_UPSAMPLING_ERR_EN (1 << 6)
+#define S5P_JPEG_ENC_WRONG_CONFIG_ERR_EN (1 << 7)
+#define S5P_JPEG_WRONG_IP_CONFIG_ERR_EN (1 << 8)
+#elif defined (CONFIG_JPEG_V2_1)
+#define S5P_JPEG_INT_EN_MASK (0x1f << 0)
+#define S5P_JPEG_INT_EN_ALL (0x1f << 0)
+#endif
+
+#define S5P_JPEG_PROT_ERR_INT_EN (1 << 0)
+#define S5P_JPEG_IMG_COMPLETION_INT_EN (1 << 1)
+#define S5P_JPEG_DEC_INVALID_FORMAT_EN (1 << 2)
+#define S5P_JPEG_MULTI_SCAN_ERROR_EN (1 << 3)
+#define S5P_JPEG_FRAME_ERR_EN (1 << 4)
+
+#define S5P_JPEG_MOD_REG_PROC_ENC (0 << 3)
+#define S5P_JPEG_MOD_REG_PROC_DEC (1 << 3)
+
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_444 (0 << 0)
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_422 (1 << 0)
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_420 (2 << 0)
+#define S5P_JPEG_MOD_REG_SUBSAMPLE_GRAY (3 << 0)
+
+
+/* JPEG IMAGE SIZE Register bit */
+#define S5P_JPEG_X_SIZE_SHIFT 0
+#define S5P_JPEG_X_SIZE_MASK (0xffff << S5P_JPEG_X_SIZE_SHIFT)
+#define S5P_JPEG_X_SIZE(x) (((x) & 0xffff) << S5P_JPEG_X_SIZE_SHIFT)
+#define S5P_JPEG_Y_SIZE_SHIFT 16
+#define S5P_JPEG_Y_SIZE_MASK (0xffff << S5P_JPEG_Y_SIZE_SHIFT)
+#define S5P_JPEG_Y_SIZE(x) (((x) & 0xffff) << S5P_JPEG_Y_SIZE_SHIFT)
+
+/* JPEG IMAGE FORMAT Register bit */
+#define S5P_JPEG_ENC_IN_FMT_MASK 0xffff0000
+#define S5P_JPEG_ENC_GRAY_IMG (0 << 0)
+#define S5P_JPEG_ENC_RGB_IMG (1 << 0)
+#define S5P_JPEG_ENC_YUV_444_IMG (2 << 0)
+#define S5P_JPEG_ENC_YUV_422_IMG (3 << 0)
+#define S5P_JPEG_ENC_YUV_440_IMG (4 << 0)
+
+#define S5P_JPEG_DEC_GRAY_IMG (0 << 0)
+#define S5P_JPEG_DEC_RGB_IMG (1 << 0)
+#define S5P_JPEG_DEC_YUV_444_IMG (2 << 0)
+#define S5P_JPEG_DEC_YUV_422_IMG (3 << 0)
+#define S5P_JPEG_DEC_YUV_420_IMG (4 << 0)
+
+#define S5P_JPEG_GRAY_IMG_IP_SHIFT 3
+#define S5P_JPEG_GRAY_IMG_IP_MASK (7 << S5P_JPEG_GRAY_IMG_IP_SHIFT)
+#define S5P_JPEG_GRAY_IMG_IP (4 << S5P_JPEG_GRAY_IMG_IP_SHIFT)
+
+#define S5P_JPEG_RGB_IP_SHIFT 6
+#define S5P_JPEG_RGB_IP_MASK (7 << S5P_JPEG_RGB_IP_SHIFT)
+#define S5P_JPEG_RGB_IP_RGB_16BIT_IMG (4 << S5P_JPEG_RGB_IP_SHIFT)
+#define S5P_JPEG_RGB_IP_RGB_32BIT_IMG (5 << S5P_JPEG_RGB_IP_SHIFT)
+
+#define S5P_JPEG_YUV_444_IP_SHIFT 9
+#define S5P_JPEG_YUV_444_IP_MASK (7 << S5P_JPEG_YUV_444_IP_SHIFT)
+#define S5P_JPEG_YUV_444_IP_YUV_444_2P_IMG (4 << S5P_JPEG_YUV_444_IP_SHIFT)
+#define S5P_JPEG_YUV_444_IP_YUV_444_3P_IMG (5 << S5P_JPEG_YUV_444_IP_SHIFT)
+
+#define S5P_JPEG_YUV_422_IP_SHIFT 12
+#define S5P_JPEG_YUV_422_IP_MASK (7 << S5P_JPEG_YUV_422_IP_SHIFT)
+#define S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG (4 << S5P_JPEG_YUV_422_IP_SHIFT)
+#define S5P_JPEG_YUV_422_IP_YUV_422_2P_IMG (5 << S5P_JPEG_YUV_422_IP_SHIFT)
+#define S5P_JPEG_YUV_422_IP_YUV_422_3P_IMG (6 << S5P_JPEG_YUV_422_IP_SHIFT)
+
+#define S5P_JPEG_YUV_420_IP_SHIFT 15
+#define S5P_JPEG_YUV_420_IP_MASK (7 << S5P_JPEG_YUV_420_IP_SHIFT)
+#define S5P_JPEG_YUV_420_IP_YUV_420_2P_IMG (4 << S5P_JPEG_YUV_420_IP_SHIFT)
+#define S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG (5 << S5P_JPEG_YUV_420_IP_SHIFT)
+
+#define S5P_JPEG_ENC_FMT_SHIFT 24
+#define S5P_JPEG_ENC_FMT_MASK (3 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_GRAY (0 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUV_444 (1 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUV_422 (2 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUV_420 (3 << S5P_JPEG_ENC_FMT_SHIFT)
+
+#define S5P_JPEG_SWAP_CHROMA_CrCb (1 << 26)
+#define S5P_JPEG_SWAP_CHROMA_CbCr (0 << 26)
+
+#if defined (CONFIG_JPEG_V2_2)
+#define S5P_JPEG_SWAP_RGB_SHIFT 29
+#define S5P_JPEG_SWAP_RGB_MASK (1 << S5P_JPEG_SWAP_RGB_SHIFT)
+#define S5P_JPEG_ENC_FMT_BGR (1 << S5P_JPEG_SWAP_RGB_SHIFT)
+#define S5P_JPEG_ENC_FMT_RGB (0 << S5P_JPEG_SWAP_RGB_SHIFT)
+
+#define S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT 27
+#define S5P_JPEG_RE_ORDER_YUV_422_1P_MASK (3 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUYV (0 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT)
+#define S5P_JPEG_ENC_FMT_YVYU (1 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT)
+#define S5P_JPEG_ENC_FMT_UYVY (2 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT)
+#define S5P_JPEG_ENC_FMT_VYUY (3 << S5P_JPEG_RE_ORDER_YUV_422_1P_SHIFT)
+#endif
+/* JPEG HUFF count Register bit */
+#define S5P_JPEG_HUFF_COUNT_MASK 0xffff
+
+/* JPEG Decoded_img_x_y_size Register bit */
+#define S5P_JPEG_DECODED_SIZE_MASK 0x0000ffff
+
+/* JPEG Decoded image format Register bit */
+#define S5P_JPEG_DECODED_IMG_FMT_MASK 0x3
+
+/* JPEG TBL SEL Register bit */
+#define S5P_JPEG_Q_TBL_COMP1_SHIFT 0
+#define S5P_JPEG_Q_TBL_COMP1_0 (0 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP1_1 (1 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP1_2 (2 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP1_3 (3 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+
+#define S5P_JPEG_Q_TBL_COMP2_SHIFT 2
+#define S5P_JPEG_Q_TBL_COMP2_0 (0 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP2_1 (1 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP2_2 (2 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP2_3 (3 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+
+#define S5P_JPEG_Q_TBL_COMP3_SHIFT 4
+#define S5P_JPEG_Q_TBL_COMP3_0 (0 << S5P_JPEG_Q_TBL_COMP3_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP3_1 (1 << S5P_JPEG_Q_TBL_COMP3_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP3_2 (2 << S5P_JPEG_Q_TBL_COMP3_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP3_3 (3 << S5P_JPEG_Q_TBL_COMP3_SHIFT)
+
+#define S5P_JPEG_HUFF_TBL_COMP1_SHIFT 6
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 (0 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1 (1 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_0 (2 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_1 (3 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+
+#define S5P_JPEG_HUFF_TBL_COMP2_SHIFT 8
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 (0 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_1 (1 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_0 (2 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_1 (3 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+
+#define S5P_JPEG_HUFF_TBL_COMP3_SHIFT 10
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_0 (0 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_1 (1 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_0 (2 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1 (3 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+
+#endif /* __ASM_ARM_REGS_S5P_JPEG_H */
+
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
index 2b6dcff..551ee10 100644
--- a/arch/arm/plat-s5p/include/plat/s5p-clock.h
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -18,6 +18,9 @@
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_bpll clk_ext_xtal_mux
+#define clk_fin_gpll clk_ext_xtal_mux
+#define clk_fin_cpll clk_ext_xtal_mux
#define clk_fin_mpll clk_ext_xtal_mux
#define clk_fin_epll clk_ext_xtal_mux
#define clk_fin_dpll clk_ext_xtal_mux
@@ -47,4 +50,9 @@ extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
extern int s5p_epll_enable(struct clk *clk, int enable);
extern unsigned long s5p_epll_get_rate(struct clk *clk);
+/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */
+extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate);
+extern unsigned long s5p_spdif_get_rate(struct clk *clk);
+
+extern struct clk_ops s5p_sclk_spdif_ops;
#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-iovmm.h b/arch/arm/plat-s5p/include/plat/s5p-iovmm.h
new file mode 100644
index 0000000..2e31ce3
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-iovmm.h
@@ -0,0 +1,55 @@
+/* linux/arch/arm/plat-s5p/include/plat/iovmm.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_IOVMM_H
+#define __ASM_PLAT_IOVMM_H
+
+#ifdef CONFIG_IOVMM
+int iovmm_setup(struct device *dev);
+void iovmm_cleanup(struct device *dev);
+int iovmm_activate(struct device *dev);
+void iovmm_deactivate(struct device *dev);
+
+/* iovmm_map() - Maps a list of physical memory chunks
+ * @dev: the owner of the IO address space where the mapping is created
+ * @sg: list of physical memory chunks to map
+ * @offset: length in bytes where the mapping starts
+ * @size: how much memory to map in bytes. @offset + @size must not exceed
+ * total size of @sg
+ *
+ * This function returns mapped IO address in the address space of @dev.
+ * Returns 0 if mapping fails.
+ *
+ * The caller of this function must ensure that iovmm_cleanup() is not called
+ * while this function is called.
+ *
+ */
+dma_addr_t iovmm_map(struct device *dev, struct scatterlist *sg, off_t offset,
+ size_t size);
+
+/* iovmm_map() - unmaps the given IO address
+ * @dev: the owner of the IO address space where @iova belongs
+ * @iova: IO address that needs to be unmapped and freed.
+ *
+ * The caller of this function must ensure that iovmm_cleanup() is not called
+ * while this function is called.
+ */
+void iovmm_unmap(struct device *dev, dma_addr_t iova);
+
+#else
+#define iovmm_setup(dev) (-ENOSYS)
+#define iovmm_cleanup(dev)
+#define iovmm_activate(dev) (-ENOSYS)
+#define iovmm_deactivate(dev)
+#define iovmm_map(dev, sg) (0)
+#define iovmm_unmap(dev, iova)
+#endif /* CONFIG_IOVMM */
+
+#endif /*__ASM_PLAT_IOVMM_H*/
diff --git a/arch/arm/plat-s5p/include/plat/s5p-mfc.h b/arch/arm/plat-s5p/include/plat/s5p-mfc.h
new file mode 100644
index 0000000..f548b0f
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-mfc.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-mfc.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p mfc support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _S5P_MFC_H
+#define _S5P_MFC_H
+
+#include <linux/platform_device.h>
+
+struct s5p_mfc_platdata {
+ int clock_rate;
+};
+
+extern unsigned int mfc_clk_rate;
+void s5p_mfc_set_platdata(struct s5p_mfc_platdata *pd);
+void s5p_mfc_setname(struct platform_device *pdev,char *name);
+
+int exynos4_mfc_setup_clock(struct device *dev,
+ unsigned long clock_rate);
+
+#endif /* _S5P_MFC_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-otghost.h b/arch/arm/plat-s5p/include/plat/s5p-otghost.h
new file mode 100644
index 0000000..707cf27
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-otghost.h
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-otghost.h
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform header file for Samsung OTG Host driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#ifndef _PLAT_S5P_OTGHOST_H
+#define _PLAT_S5P_OTGHOST_H __FILE__
+
+#include <linux/wakelock.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+/*#define CONFIG_USB_S3C_OTG_HOST_HANDLING_CLOCK*/
+#define CONFIG_USB_S3C_OTG_HOST_DTGDRVVBUS
+
+union port_flags_t {
+ /** raw register data */
+ u32 d32;
+ /** register bits */
+ struct {
+ unsigned port_connect_status_change:1;
+ unsigned port_connect_status:1;
+ unsigned port_reset_change:1;
+ unsigned port_enable_change:1;
+ unsigned port_suspend_change:1;
+ unsigned port_over_current_change:1;
+ unsigned reserved:26;
+ } b;
+};
+
+struct sec_otghost_data {
+ bool clk_usage;
+
+ void (*set_pwr_cb)(int on);
+ void (*host_notify_cb)(int a);
+ int (*start)(u32 reg);
+ int (*stop)(void);
+
+ int (*phy_init)(int mode);
+ int (*phy_exit)(int mode);
+
+ struct platform_device *pdev;
+ struct clk *clk;
+
+ int sec_whlist_table_num;
+ void __iomem *regs;
+};
+
+struct sec_otghost {
+ spinlock_t lock;
+
+ bool ch_halt;
+ union port_flags_t port_flag;
+ struct wake_lock wake_lock;
+
+ struct work_struct work;
+ struct workqueue_struct *wq;
+
+ struct sec_otghost_data *otg_data;
+};
+
+#endif /*_PLAT_S5P_OTGHOST_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-sysmmu.h b/arch/arm/plat-s5p/include/plat/s5p-sysmmu.h
new file mode 100644
index 0000000..ad30a97
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-sysmmu.h
@@ -0,0 +1,120 @@
+/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung System MMU driver for S5P platform
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM__PLAT_SYSMMU_H
+#define __ASM__PLAT_SYSMMU_H __FILE__
+
+#include <linux/list.h>
+#include <linux/atomic.h>
+#include <linux/spinlock.h>
+
+enum S5P_SYSMMU_INTERRUPT_TYPE {
+ SYSMMU_PAGEFAULT,
+ SYSMMU_AR_MULTIHIT,
+ SYSMMU_AW_MULTIHIT,
+ SYSMMU_BUSERROR,
+ SYSMMU_AR_SECURITY,
+ SYSMMU_AR_ACCESS,
+ SYSMMU_AW_SECURITY,
+ SYSMMU_AW_PROTECTION, /* 7 */
+ SYSMMU_FAULT_UNKNOWN,
+ SYSMMU_FAULTS_NUM
+};
+
+/*
+ * @itype: type of fault.
+ * @pgtable_base: the physical address of page table base. This is 0 if @itype
+ * is SYSMMU_BUSERROR.
+ * @fault_addr: the device (virtual) address that the System MMU tried to
+ * translated. This is 0 if @itype is SYSMMU_BUSERROR.
+ */
+typedef int (*s5p_sysmmu_fault_handler_t)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
+ unsigned long pgtable_base, unsigned long fault_addr);
+
+#ifdef CONFIG_S5P_SYSTEM_MMU
+/**
+ * s5p_sysmmu_enable() - enable system mmu
+ * @owner: The device whose System MMU is about to be enabled.
+ * @pgd: Base physical address of the 1st level page table
+ *
+ * This function enable system mmu to transfer address
+ * from virtual address to physical address.
+ * Return non-zero if it fails to enable System MMU.
+ */
+int s5p_sysmmu_enable(struct device *owner, unsigned long pgd);
+
+/**
+ * s5p_sysmmu_disable() - disable sysmmu mmu of ip
+ * @owner: The device whose System MMU is about to be disabled.
+ *
+ * This function disable system mmu to transfer address
+ * from virtual address to physical address
+ */
+void s5p_sysmmu_disable(struct device *owner);
+
+/**
+ * s5p_sysmmu_set_tablebase_pgd() - set page table base to refer page table
+ * @owner: The device whose System MMU.
+ * @pgd: The page table base address.
+ *
+ * This function set page table base address
+ * When system mmu transfer address from virtaul address to physical address,
+ * system mmu refer address information from page table
+ */
+void s5p_sysmmu_set_tablebase_pgd(struct device *owner, unsigned long pgd);
+
+/**
+ * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
+ * @owner: The device whose System MMU.
+ *
+ * This function flush all TLB entry in system mmu
+ */
+void s5p_sysmmu_tlb_invalidate(struct device *owner);
+
+/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
+ * Called when interrupt occurred by the System MMUs
+ * The device drivers of peripheral devices that has a System MMU can implement
+ * a fault handler to resolve address translation fault by System MMU.
+ * The meanings of return value and parameters are described below.
+
+ * return value: non-zero if the fault is correctly resolved.
+ * zero if the fault is not handled.
+ */
+void s5p_sysmmu_set_fault_handler(struct device *sysmmu,
+ s5p_sysmmu_fault_handler_t handler);
+
+/** s5p_sysmmu_set_prefbuf() - Initialize prefetch buffers of System MMU v3
+ * @owner: The device which need to set the prefetch buffers
+ * @base0: The start virtual address of the area of the @owner device that the
+ * first prefetch buffer loads translation descriptors
+ * @size0: The last virtual address of the area of the @owner device that the
+ * first prefetch buffer loads translation descriptors.
+ * @base1: The start virtual address of the area of the @owner device that the
+ * second prefetch buffer loads translation descriptors. This will be
+ * ignored if @size1 is 0 and this function assigns the 2 prefetch
+ * buffers with each half of the area specified by @base0 and @size0
+ * @size1: The last virtual address of the area of the @owner device that the
+ * prefetch buffer loads translation descriptors. This can be 0. See
+ * the description of @base1 for more information with @size1 = 0
+ */
+void s5p_sysmmu_set_prefbuf(struct device *owner,
+ unsigned long base0, unsigned long size0,
+ unsigned long base1, unsigned long size1);
+#else /* !CONFIG_S5P_SYSTEM_MMU */
+#define s5p_sysmmu_enable(owner, pgd) do { } while (0)
+#define s5p_sysmmu_disable(owner) do { } while (0)
+#define s5p_sysmmu_set_tablebase_pgd(owner, pgd) do { } while (0)
+#define s5p_sysmmu_tlb_invalidate(owner) do { } while (0)
+#define s5p_sysmmu_set_fault_handler(sysmmu, handler) do { } while (0)
+#define s5p_sysmmu_set_prefbuf(owner, base, size) do { } while (0)
+#endif
+#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-tmu.h b/arch/arm/plat-s5p/include/plat/s5p-tmu.h
new file mode 100644
index 0000000..24833ed
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-tmu.h
@@ -0,0 +1,108 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-tmu.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p tmu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _S5P_TMU_H
+#define _S5P_TMU_H
+
+#define TMU_SAVE_NUM 10
+
+/*
+ * struct temperature_params have values to manange throttling, tripping
+ * and other software safety control
+ */
+struct temperature_params {
+ unsigned int stop_1st_throttle;
+ unsigned int start_1st_throttle;
+ unsigned int stop_2nd_throttle;
+ unsigned int start_2nd_throttle;
+ unsigned int start_tripping; /* temp to do tripping */
+ unsigned int start_emergency; /* To protect chip,forcely kernel panic */
+ unsigned int stop_mem_throttle;
+ unsigned int start_mem_throttle;
+ unsigned int stop_tc; /* temperature compensationfor sram */
+ unsigned int start_tc;
+};
+
+struct cpufreq_params {
+ unsigned int limit_1st_throttle;
+ unsigned int limit_2nd_throttle;
+};
+
+struct temp_compensate_params {
+ unsigned int arm_volt; /* temperature compensated voltage */
+ unsigned int bus_volt; /* temperature compensated voltage */
+ unsigned int g3d_volt; /* temperature compensated voltage */
+};
+
+struct memory_params {
+ unsigned int rclk;
+ unsigned int period_bank_refresh;
+};
+
+struct tmu_config {
+ unsigned char mode;
+ unsigned char slope;
+ unsigned int sampling_rate;
+ unsigned int monitoring_rate;
+};
+
+struct s5p_platform_tmu {
+ struct temperature_params ts;
+ struct cpufreq_params cpufreq;
+ struct temp_compensate_params temp_compensate;
+ struct memory_params mp;
+ struct tmu_config cfg;
+};
+
+struct s5p_tmu_info {
+ struct device *dev;
+#ifdef CONFIG_BUSFREQ_OPP
+ struct device *bus_dev;
+#endif
+
+ int id;
+ char *s5p_name;
+
+ void __iomem *tmu_base;
+ struct resource *ioarea;
+ int irq;
+
+ int mode;
+ unsigned char te1; /* triminfo_25 */
+ unsigned char te2; /* triminfo_85 */
+ int slope;
+
+ int tmu_state;
+ unsigned int last_temperature;
+
+ unsigned int cpufreq_level_1st_throttle;
+ unsigned int cpufreq_level_2nd_throttle;
+ unsigned int auto_refresh_tq0;
+ unsigned int auto_refresh_normal;
+ /* temperature compensation */
+ unsigned int cpulevel_tc;
+ unsigned int busfreq_tc;
+ unsigned int g3dlevel_tc;
+
+ struct delayed_work monitor;
+ struct delayed_work polling;
+
+ unsigned int monitor_period;
+ unsigned int sampling_rate;
+ unsigned int reg_save[TMU_SAVE_NUM];
+};
+
+void __init s5p_tmu_set_platdata(struct s5p_platform_tmu *pd);
+struct s5p_tmu *s5p_tmu_get_platdata(void);
+int s5p_tmu_get_irqno(int num);
+extern struct platform_device s5p_device_tmu;
+#endif /* _S5P_TMU_H */
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
deleted file mode 100644
index bf5283c..0000000
--- a/arch/arm/plat-s5p/include/plat/sysmmu.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung System MMU driver for S5P platform
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM__PLAT_SYSMMU_H
-#define __ASM__PLAT_SYSMMU_H __FILE__
-
-enum S5P_SYSMMU_INTERRUPT_TYPE {
- SYSMMU_PAGEFAULT,
- SYSMMU_AR_MULTIHIT,
- SYSMMU_AW_MULTIHIT,
- SYSMMU_BUSERROR,
- SYSMMU_AR_SECURITY,
- SYSMMU_AR_ACCESS,
- SYSMMU_AW_SECURITY,
- SYSMMU_AW_PROTECTION, /* 7 */
- SYSMMU_FAULTS_NUM
-};
-
-#ifdef CONFIG_S5P_SYSTEM_MMU
-
-#include <mach/sysmmu.h>
-
-/**
- * s5p_sysmmu_enable() - enable system mmu of ip
- * @ips: The ip connected system mmu.
- * #pgd: Base physical address of the 1st level page table
- *
- * This function enable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_disable() - disable sysmmu mmu of ip
- * @ips: The ip connected system mmu.
- *
- * This function disable system mmu to transfer address
- * from virtual address to physical address
- */
-void s5p_sysmmu_disable(sysmmu_ips ips);
-
-/**
- * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
- * @ips: The ip connected system mmu.
- * @pgd: The page table base address.
- *
- * This function set page table base address
- * When system mmu transfer address from virtaul address to physical address,
- * system mmu refer address information from page table
- */
-void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
-
-/**
- * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
- * @ips: The ip connected system mmu.
- *
- * This function flush all TLB entry in system mmu
- */
-void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
-
-/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
- * @itype: type of fault.
- * @pgtable_base: the physical address of page table base. This is 0 if @ips is
- * SYSMMU_BUSERROR.
- * @fault_addr: the device (virtual) address that the System MMU tried to
- * translated. This is 0 if @ips is SYSMMU_BUSERROR.
- * Called when interrupt occurred by the System MMUs
- * The device drivers of peripheral devices that has a System MMU can implement
- * a fault handler to resolve address translation fault by System MMU.
- * The meanings of return value and parameters are described below.
-
- * return value: non-zero if the fault is correctly resolved.
- * zero if the fault is not handled.
- */
-void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
- int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr));
-#else
-#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
-#define s5p_sysmmu_disable(ips) do { } while (0)
-#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
-#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
-#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
-#endif
-#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/include/plat/system-reset.h b/arch/arm/plat-s5p/include/plat/system-reset.h
index f307f34..9e0a095 100644
--- a/arch/arm/plat-s5p/include/plat/system-reset.h
+++ b/arch/arm/plat-s5p/include/plat/system-reset.h
@@ -12,20 +12,6 @@
* published by the Free Software Foundation.
*/
-#include <plat/watchdog-reset.h>
+extern void (*s5p_reset_hook)(void);
-void (*s5p_reset_hook)(void);
-
-static void arch_reset(char mode, const char *cmd)
-{
- /* SWRESET support in s5p_reset_hook() */
-
- if (s5p_reset_hook)
- s5p_reset_hook();
-
- /* Perform reset using Watchdog reset
- * if there is no s5p_reset_hook()
- */
-
- arch_wdt_reset();
-}
+void arch_reset(char mode, const char *cmd);
diff --git a/arch/arm/plat-s5p/include/plat/tvout.h b/arch/arm/plat-s5p/include/plat/tvout.h
new file mode 100644
index 0000000..e649d69
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/tvout.h
@@ -0,0 +1,49 @@
+/* linux/arch/arm/plat-s5p/include/plat/tvout.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Platform Header file for Samsung TV driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ARM_PLAT_TVOUT_H
+#define __ARM_PLAT_TVOUT_H __FILE__
+
+struct platform_device;
+
+struct s5p_platform_hpd {
+ void (*int_src_hdmi_hpd)(struct platform_device *pdev);
+ void (*int_src_ext_hpd)(struct platform_device *pdev);
+ int (*read_gpio)(struct platform_device *pdev);
+#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+ void (*ext_ic_control)(bool ic_on);
+#endif
+};
+
+extern void s5p_hdmi_hpd_set_platdata(struct s5p_platform_hpd *pd);
+
+/* defined by architecture to configure gpio */
+extern void s5p_int_src_hdmi_hpd(struct platform_device *pdev);
+extern void s5p_int_src_ext_hpd(struct platform_device *pdev);
+extern void s5p_v4l2_int_src_hdmi_hpd(void);
+extern void s5p_v4l2_int_src_ext_hpd(void);
+extern int s5p_hpd_read_gpio(struct platform_device *pdev);
+extern int s5p_v4l2_hpd_read_gpio(void);
+
+struct s5p_platform_cec {
+
+ void (*cfg_gpio)(struct platform_device *pdev);
+};
+
+extern void s5p_hdmi_cec_set_platdata(struct s5p_platform_cec *pd);
+
+/* defined by architecture to configure gpio */
+extern void s5p_cec_cfg_gpio(struct platform_device *pdev);
+
+extern void s5p_tv_setup(void);
+
+#endif /* __ASM_PLAT_TV_HPD_H */
diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-s5p/include/plat/usb-phy.h
index 6dd6bcf..9cd61e6 100644
--- a/arch/arm/plat-s5p/include/plat/usb-phy.h
+++ b/arch/arm/plat-s5p/include/plat/usb-phy.h
@@ -14,9 +14,22 @@
enum s5p_usb_phy_type {
S5P_USB_PHY_DEVICE,
S5P_USB_PHY_HOST,
+ S5P_USB_PHY_DRD,
+ S5P_USB_PHY_OTGHOST,
};
+#if defined(CONFIG_LINK_DEVICE_HSIC) || defined(CONFIG_LINK_DEVICE_USB) || \
+ defined(CONFIG_CDMA_MODEM_MDM6600)
+enum s5p_host_state {
+ S5P_HOST_OFF,
+ S5P_HOST_ON,
+};
+#endif
+
extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_suspend(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_resume(struct platform_device *pdev, int type);
+extern int exynos4_check_usb_op(void);
#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/plat-s5p/include/plat/usb-switch.h b/arch/arm/plat-s5p/include/plat/usb-switch.h
new file mode 100644
index 0000000..f15d24e
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/usb-switch.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_S5P_USB_SWITCH_H
+#define __PLAT_S5P_USB_SWITCH_H
+
+struct s5p_usbswitch_platdata {
+ unsigned gpio_host_detect;
+ unsigned gpio_device_detect;
+ unsigned gpio_host_vbus;
+ unsigned gpio_drd_host_detect;
+ unsigned gpio_drd_device_detect;
+
+ struct device *ehci_dev;
+ struct device *ohci_dev;
+ struct device *xhci_dev;
+
+ struct device *s3c_udc_dev;
+ struct device *exynos_udc_dev;
+};
+
+extern void s5p_usbswitch_set_platdata(struct s5p_usbswitch_platdata *pd);
+#endif /* __PLAT_S5P_USB_SWITCH_H */
diff --git a/arch/arm/plat-s5p/include/plat/usbgadget.h b/arch/arm/plat-s5p/include/plat/usbgadget.h
new file mode 100644
index 0000000..65bd8cf
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/usbgadget.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_S5P_USBGADGET_H
+#define __PLAT_S5P_USBGADGET_H
+
+struct s5p_usbgadget_platdata {
+ int (*phy_init)(struct platform_device *pdev, int type);
+ int (*phy_exit)(struct platform_device *pdev, int type);
+
+#ifdef CONFIG_USB_S3C_OTG_HOST
+ irqreturn_t (*udc_irq)(int irq, void *_dev);
+#endif
+ /* Value of USB PHY tune register */
+ unsigned int phy_tune;
+ /* Mask of USB PHY tune register */
+ unsigned int phy_tune_mask;
+};
+
+extern void s5p_usbgadget_set_platdata(struct s5p_usbgadget_platdata *pd);
+
+#endif /* __PLAT_S5P_EHCI_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index b5bb774..2f08070 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -65,6 +65,7 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
+ struct irq_desc *desc = irq_to_desc(data->irq);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -115,6 +116,11 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
else
printk(KERN_ERR "No such irq number %d", offs);
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ desc->handle_irq = handle_edge_irq;
+ else
+ desc->handle_irq = handle_level_irq;
+
return 0;
}
@@ -123,6 +129,7 @@ static struct irq_chip s5p_irq_eint = {
.irq_mask = s5p_irq_eint_mask,
.irq_unmask = s5p_irq_eint_unmask,
.irq_mask_ack = s5p_irq_eint_maskack,
+ .irq_disable = s5p_irq_eint_maskack,
.irq_ack = s5p_irq_eint_ack,
.irq_set_type = s5p_irq_eint_set_type,
#ifdef CONFIG_PM
@@ -138,11 +145,12 @@ static struct irq_chip s5p_irq_eint = {
*
* Each EINT pend/mask registers handle eight of them.
*/
-static inline void s5p_irq_demux_eint(unsigned int start)
+static inline u32 s5p_irq_demux_eint(unsigned int start)
{
u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
unsigned int irq;
+ u32 action = 0;
status &= ~mask;
status &= 0xff;
@@ -151,13 +159,21 @@ static inline void s5p_irq_demux_eint(unsigned int start)
irq = fls(status) - 1;
generic_handle_irq(irq + start);
status &= ~(1 << irq);
+ ++action;
}
+
+ return action;
}
static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
- s5p_irq_demux_eint(IRQ_EINT(16));
- s5p_irq_demux_eint(IRQ_EINT(24));
+ u32 a16_23, a24_31;
+
+ a16_23 = s5p_irq_demux_eint(IRQ_EINT(16));
+ a24_31 = s5p_irq_demux_eint(IRQ_EINT(24));
+
+ if (!a16_23 && !a24_31)
+ do_bad_IRQ(irq, desc);
}
static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 327ab9f..06c6bfb 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -22,6 +22,10 @@
#include <mach/map.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
+#include <plat/cpu.h>
+
+#include <asm/mach/irq.h>
+#include <mach/regs-gpio.h>
#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u)
@@ -46,22 +50,25 @@ static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = gc->chip_types;
unsigned int shift = (d->irq - gc->irq_base) << 2;
+ struct irq_desc *desc = irq_to_desc(d->irq);
+ unsigned int type_s5p = 0;
+ struct s3c_gpio_chip *chip = gc->private;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
- type = S5P_IRQ_TYPE_EDGE_RISING;
+ type_s5p = S5P_IRQ_TYPE_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
- type = S5P_IRQ_TYPE_EDGE_FALLING;
+ type_s5p = S5P_IRQ_TYPE_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
- type = S5P_IRQ_TYPE_EDGE_BOTH;
+ type_s5p = S5P_IRQ_TYPE_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_HIGH:
- type = S5P_IRQ_TYPE_LEVEL_HIGH;
+ type_s5p = S5P_IRQ_TYPE_LEVEL_HIGH;
break;
case IRQ_TYPE_LEVEL_LOW:
- type = S5P_IRQ_TYPE_LEVEL_LOW;
+ type_s5p = S5P_IRQ_TYPE_LEVEL_LOW;
break;
case IRQ_TYPE_NONE:
default:
@@ -70,29 +77,45 @@ static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
}
gc->type_cache &= ~(0x7 << shift);
- gc->type_cache |= type << shift;
+ gc->type_cache |= type_s5p << shift;
writel(gc->type_cache, gc->reg_base + ct->regs.type);
+
+ pr_info("%s irq:%d is at %s(%d)\n", __func__, d->irq, chip->chip.label,
+ (d->irq - chip->irq_base));
+
+ s3c_gpio_cfgpin(chip->chip.base + (d->irq - chip->irq_base), EINT_MODE);
+
+ if (type & IRQ_TYPE_EDGE_BOTH)
+ desc->handle_irq = handle_edge_irq;
+ else
+ desc->handle_irq = handle_level_irq;
+
return 0;
}
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
- int group, pend_offset, mask_offset;
- unsigned int pend, mask;
+ int group, eint_offset;
+ unsigned int pend, mask, action = 0;
+
+ struct irq_chip *chip = irq_get_chip(irq);
+ chained_irq_enter(chip, desc);
for (group = 0; group < bank->nr_groups; group++) {
struct s3c_gpio_chip *chip = bank->chips[group];
if (!chip)
continue;
-
- pend_offset = REG_OFFSET(group);
- pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
+ if (soc_is_exynos4210() || soc_is_exynos4212()
+ || soc_is_exynos4412()
+ || soc_is_exynos5250())
+ eint_offset = chip->eint_offset;
+ else
+ eint_offset = REG_OFFSET(group);
+ pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + eint_offset);
if (!pend)
continue;
-
- mask_offset = REG_OFFSET(group);
- mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+ mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + eint_offset);
pend &= ~mask;
while (pend) {
@@ -100,28 +123,38 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
int real_irq = chip->irq_base + offset;
generic_handle_irq(real_irq);
pend &= ~BIT(offset);
+ ++action;
}
}
+ chained_irq_exit(chip, desc);
+
+ if (!action)
+ do_bad_IRQ(irq, desc);
}
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
{
static int used_gpioint_groups = 0;
int group = chip->group;
- struct s5p_gpioint_bank *bank = NULL;
+ struct s5p_gpioint_bank *b, *bank = NULL;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
- if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
+ if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT) {
+ WARN(1, "used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT\n");
return -ENOMEM;
+ }
- list_for_each_entry(bank, &banks, list) {
- if (group >= bank->start &&
- group < bank->start + bank->nr_groups)
+ list_for_each_entry(b, &banks, list) {
+ if (group >= b->start && group < b->start + b->nr_groups) {
+ bank = b;
break;
+ }
}
- if (!bank)
+ if (!bank) {
+ WARN(1, "bank not found\n");
return -EINVAL;
+ }
if (!bank->handler) {
bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
@@ -149,16 +182,29 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
(void __iomem *)GPIO_BASE(chip),
handle_level_irq);
- if (!gc)
+ if (!gc) {
+ WARN(1, "irq_alloc_generic_chip failed\n");
return -ENOMEM;
+ }
+
+ gc->private = chip;
+
ct = gc->chip_types;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
- ct->chip.irq_set_type = s5p_gpioint_set_type,
- ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
- ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
- ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+ ct->chip.irq_disable = irq_gc_mask_and_ack_set;
+ ct->chip.irq_set_type = s5p_gpioint_set_type;
+ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412()
+ || soc_is_exynos5250()) {
+ ct->regs.ack = PEND_OFFSET + chip->eint_offset;
+ ct->regs.mask = MASK_OFFSET + chip->eint_offset;
+ ct->regs.type = CON_OFFSET + chip->eint_offset;
+ } else {
+ ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+ }
irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
@@ -189,6 +235,7 @@ int __init s5p_register_gpio_interrupt(int pin)
group);
return my_chip->irq_base + offset;
}
+
return ret;
}
diff --git a/arch/arm/plat-s5p/reserve_mem.c b/arch/arm/plat-s5p/reserve_mem.c
new file mode 100644
index 0000000..5b91823
--- /dev/null
+++ b/arch/arm/plat-s5p/reserve_mem.c
@@ -0,0 +1,307 @@
+/* linux/arch/arm/plat-s5p/reserve_mem.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Reserve mem helper functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/err.h>
+#include <linux/memblock.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/setup.h>
+#include <linux/io.h>
+#include <mach/memory.h>
+#include <plat/media.h>
+#include <mach/media.h>
+
+#ifdef CONFIG_CMA
+#include <linux/cma.h>
+void __init s5p_cma_region_reserve(struct cma_region *regions_normal,
+ struct cma_region *regions_secure,
+ size_t align_secure, const char *map)
+{
+ struct cma_region *reg;
+ phys_addr_t paddr_last = 0xFFFFFFFF;
+
+ for (reg = regions_normal; reg->size != 0; reg++) {
+ phys_addr_t paddr;
+
+ if (!IS_ALIGNED(reg->size, PAGE_SIZE)) {
+ pr_debug("S5P/CMA: size of '%s' is NOT page-aligned\n",
+ reg->name);
+ reg->size = PAGE_ALIGN(reg->size);
+ }
+
+
+ if (reg->reserved) {
+ pr_err("S5P/CMA: '%s' already reserved\n", reg->name);
+ continue;
+ }
+
+ if (reg->alignment) {
+ if ((reg->alignment & ~PAGE_MASK) ||
+ (reg->alignment & ~reg->alignment)) {
+ pr_err("S5P/CMA: Failed to reserve '%s': "
+ "incorrect alignment 0x%08x.\n",
+ reg->name, reg->alignment);
+ continue;
+ }
+ } else {
+ reg->alignment = PAGE_SIZE;
+ }
+
+ if (reg->start) {
+ if (!memblock_is_region_reserved(reg->start, reg->size)
+ && (memblock_reserve(reg->start, reg->size) == 0))
+ reg->reserved = 1;
+ else {
+ pr_err("S5P/CMA: Failed to reserve '%s'\n",
+ reg->name);
+ continue;
+ }
+
+ pr_debug("S5P/CMA: "
+ "Reserved 0x%08x/0x%08x for '%s'\n",
+ reg->start, reg->size, reg->name);
+ paddr = reg->start;
+ } else {
+ paddr = memblock_find_in_range(0,
+ MEMBLOCK_ALLOC_ACCESSIBLE,
+ reg->size, reg->alignment);
+ }
+
+ if (paddr != MEMBLOCK_ERROR) {
+ if (memblock_reserve(paddr, reg->size)) {
+ pr_err("S5P/CMA: Failed to reserve '%s'\n",
+ reg->name);
+ continue;
+ }
+
+ reg->start = paddr;
+ reg->reserved = 1;
+
+ pr_debug("S5P/CMA: Reserved 0x%08x/0x%08x for '%s'\n",
+ reg->start, reg->size, reg->name);
+ } else {
+ pr_err("S5P/CMA: No free space in memory for '%s'\n",
+ reg->name);
+ }
+
+ if (cma_early_region_register(reg)) {
+ pr_err("S5P/CMA: Failed to register '%s'\n",
+ reg->name);
+ memblock_free(reg->start, reg->size);
+ } else {
+ paddr_last = min(paddr, paddr_last);
+ }
+ }
+
+ if (align_secure & ~align_secure) {
+ pr_err("S5P/CMA: "
+ "Wrong alignment requirement for secure region.\n");
+ } else if (regions_secure && regions_secure->size) {
+ size_t size_secure = 0;
+
+ for (reg = regions_secure; reg->size != 0; reg++)
+ size_secure += reg->size;
+
+ reg--;
+
+ /* Entire secure regions will be merged into 2
+ * consecutive regions. */
+ if (align_secure == 0) {
+ size_t size_region2;
+ size_t order_region2;
+ size_t aug_size;
+
+ align_secure = 1 <<
+ (get_order((size_secure + 1) / 2) + PAGE_SHIFT);
+ /* Calculation of a subregion size */
+ size_region2 = size_secure - align_secure;
+ order_region2 = get_order(size_region2) + PAGE_SHIFT;
+ if (order_region2 < 20)
+ order_region2 = 20; /* 1MB */
+ order_region2 -= 3; /* divide by 8 */
+ size_region2 = ALIGN(size_region2, 1 << order_region2);
+
+ aug_size = align_secure + size_region2 - size_secure;
+ if (aug_size > 0) {
+ reg->size += aug_size;
+ size_secure += aug_size;
+ pr_debug("S5P/CMA: "
+ "Augmented size of '%s' by %#x B.\n",
+ reg->name, aug_size);
+ }
+ } else
+ size_secure = ALIGN(size_secure, align_secure);
+
+ pr_debug("S5P/CMA: "
+ "Reserving %#x for secure region aligned by %#x.\n",
+ size_secure, align_secure);
+
+ if (paddr_last >= memblock.current_limit) {
+ paddr_last = memblock_find_in_range(0,
+ MEMBLOCK_ALLOC_ACCESSIBLE,
+ size_secure, reg->alignment);
+ } else {
+ paddr_last -= size_secure;
+ paddr_last = round_down(paddr_last, align_secure);
+ }
+
+ if (paddr_last) {
+ while (memblock_reserve(paddr_last, size_secure))
+ paddr_last -= align_secure;
+
+ do {
+ reg->start = paddr_last;
+ reg->reserved = 1;
+ paddr_last += reg->size;
+
+ pr_info("S5P/CMA: "
+ "Reserved 0x%08x/0x%08x for '%s'\n",
+ reg->start, reg->size, reg->name);
+ if (cma_early_region_register(reg)) {
+ memblock_free(reg->start, reg->size);
+ pr_err("S5P/CMA: "
+ "Failed to register secure region "
+ "'%s'\n", reg->name);
+ } else {
+ size_secure -= reg->size;
+ }
+ } while (reg-- != regions_secure);
+
+ if (size_secure > 0)
+ memblock_free(paddr_last, size_secure);
+ } else {
+ pr_err("S5P/CMA: Failed to reserve secure regions\n");
+ }
+ }
+
+ if (map)
+ cma_set_defaults(NULL, map);
+}
+
+#else
+extern struct s5p_media_device media_devs[];
+extern int nr_media_devs;
+
+static dma_addr_t media_base[NR_BANKS];
+
+static struct s5p_media_device *s5p_get_media_device(int dev_id, int bank)
+{
+ struct s5p_media_device *mdev = NULL;
+ int i = 0, found = 0;
+
+ if (dev_id < 0)
+ return NULL;
+
+ while (!found && (i < nr_media_devs)) {
+ mdev = &media_devs[i];
+ if (mdev->id == dev_id && mdev->bank == bank)
+ found = 1;
+ else
+ i++;
+ }
+
+ if (!found)
+ mdev = NULL;
+
+ return mdev;
+}
+
+dma_addr_t s5p_get_media_memory_bank(int dev_id, int bank)
+{
+ struct s5p_media_device *mdev;
+
+ mdev = s5p_get_media_device(dev_id, bank);
+ if (!mdev) {
+ printk(KERN_ERR "invalid media device\n");
+ return 0;
+ }
+
+ if (!mdev->paddr) {
+ printk(KERN_ERR "no memory for %s\n", mdev->name);
+ return 0;
+ }
+
+ return mdev->paddr;
+}
+EXPORT_SYMBOL(s5p_get_media_memory_bank);
+
+size_t s5p_get_media_memsize_bank(int dev_id, int bank)
+{
+ struct s5p_media_device *mdev;
+
+ mdev = s5p_get_media_device(dev_id, bank);
+ if (!mdev) {
+ printk(KERN_ERR "invalid media device\n");
+ return 0;
+ }
+
+ return mdev->memsize;
+}
+EXPORT_SYMBOL(s5p_get_media_memsize_bank);
+
+dma_addr_t s5p_get_media_membase_bank(int bank)
+{
+ if (bank > meminfo.nr_banks) {
+ printk(KERN_ERR "invalid bank.\n");
+ return -EINVAL;
+ }
+
+ return media_base[bank];
+}
+EXPORT_SYMBOL(s5p_get_media_membase_bank);
+
+void s5p_reserve_mem(size_t boundary)
+{
+ struct s5p_media_device *mdev;
+ u64 start, end;
+ int i, ret;
+
+ for (i = 0; i < meminfo.nr_banks; i++)
+ media_base[i] = meminfo.bank[i].start + meminfo.bank[i].size;
+
+ for (i = 0; i < nr_media_devs; i++) {
+ mdev = &media_devs[i];
+ if (mdev->memsize <= 0)
+ continue;
+
+ if (mdev->bank > meminfo.nr_banks) {
+ pr_err("mdev %s: mdev->bank(%d), max_bank(%d)\n",
+ mdev->name, mdev->bank, meminfo.nr_banks);
+ return;
+ }
+
+ if (!mdev->paddr) {
+ start = meminfo.bank[mdev->bank].start;
+ end = start + meminfo.bank[mdev->bank].size;
+
+ if (boundary && (boundary < end - start))
+ start = end - boundary;
+
+ mdev->paddr = memblock_find_in_range(start, end,
+ mdev->memsize, PAGE_SIZE);
+ }
+
+ ret = memblock_reserve(mdev->paddr, mdev->memsize);
+ if (ret < 0)
+ pr_err("memblock_reserve(%x, %x) failed\n",
+ mdev->paddr, mdev->memsize);
+
+ if (media_base[mdev->bank] > mdev->paddr)
+ media_base[mdev->bank] = mdev->paddr;
+
+ printk(KERN_INFO "s5p: %lu bytes system memory reserved "
+ "for %s at 0x%08x, %d-bank base(0x%08x)\n",
+ (unsigned long) mdev->memsize, mdev->name, mdev->paddr,
+ mdev->bank, media_base[mdev->bank]);
+ }
+}
+#endif /* CONFIG_CMA */
diff --git a/arch/arm/plat-s5p/reset.c b/arch/arm/plat-s5p/reset.c
new file mode 100644
index 0000000..96dfdab
--- /dev/null
+++ b/arch/arm/plat-s5p/reset.c
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5p/include/plat/system-reset.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/system-reset.h
+ *
+ * S5P - System define for arch_reset()
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <plat/system-reset.h>
+#include <plat/watchdog-reset.h>
+
+
+void (*s5p_reset_hook)(void);
+
+void arch_reset(char mode, const char *cmd)
+{
+ /* SWRESET support in s5p_reset_hook() */
+
+ if (s5p_reset_hook)
+ s5p_reset_hook();
+
+ /* Perform reset using Watchdog reset
+ * if there is no s5p_reset_hook()
+ */
+
+ arch_wdt_reset();
+}
diff --git a/arch/arm/plat-s5p/s5p-sysmmu.c b/arch/arm/plat-s5p/s5p-sysmmu.c
new file mode 100644
index 0000000..dae74e1
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p-sysmmu.c
@@ -0,0 +1,582 @@
+/* linux/arch/arm/plat-s5p/sysmmu.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_S5P_SYSTEM_MMU_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+
+#include <mach/map.h>
+#include <mach/regs-sysmmu.h>
+
+#include <plat/s5p-sysmmu.h>
+
+#define CTRL_ENABLE 0x5
+#define CTRL_BLOCK 0x7
+#define CTRL_DISABLE 0x0
+
+static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
+ S5P_PAGE_FAULT_ADDR,
+ S5P_AR_FAULT_ADDR,
+ S5P_AW_FAULT_ADDR,
+ S5P_DEFAULT_SLAVE_ADDR,
+ S5P_AR_FAULT_ADDR,
+ S5P_AR_FAULT_ADDR,
+ S5P_AW_FAULT_ADDR,
+ S5P_AW_FAULT_ADDR
+};
+
+static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
+ "PAGE FAULT",
+ "AR MULTI-HIT FAULT",
+ "AW MULTI-HIT FAULT",
+ "BUS ERROR",
+ "AR SECURITY PROTECTION FAULT",
+ "AR ACCESS PROTECTION FAULT",
+ "AW SECURITY PROTECTION FAULT",
+ "AW ACCESS PROTECTION FAULT",
+ "UNKNOWN FAULT"
+};
+
+struct sysmmu_drvdata {
+ struct list_head node;
+ struct device *dev;
+ struct device *owner;
+ void __iomem *sfrbase;
+ struct clk *clk;
+ int activations;
+ rwlock_t lock;
+ s5p_sysmmu_fault_handler_t fault_handler;
+ unsigned long version;
+};
+
+static LIST_HEAD(sysmmu_list);
+
+static struct sysmmu_drvdata *get_sysmmu_data(struct device *owner,
+ struct sysmmu_drvdata *start)
+{
+ if (start) {
+ list_for_each_entry_continue(start, &sysmmu_list, node)
+ if (start->owner == owner)
+ return start;
+ } else {
+ list_for_each_entry(start, &sysmmu_list, node)
+ if (start->owner == owner)
+ return start;
+ }
+
+ return NULL;
+}
+
+static struct sysmmu_drvdata *get_sysmmu_data_rollback(struct device *owner,
+ struct sysmmu_drvdata *start)
+{
+ if (start) {
+ list_for_each_entry_continue_reverse(start, &sysmmu_list, node)
+ if (start->owner == owner)
+ return start;
+ }
+
+ return NULL;
+}
+
+static int set_sysmmu_active(struct sysmmu_drvdata *mmudata)
+{
+#ifndef CONFIG_S5P_SYSTEM_MMU_REFCOUNT
+ if (WARN_ON(mmudata->activations == 1))
+ return -EBUSY;
+#endif
+ mmudata->activations++;
+
+ return 0;
+}
+
+static bool is_sysmmu_active(struct sysmmu_drvdata *mmudata)
+{
+ return mmudata->activations != 0;
+}
+
+static bool set_sysmmu_inactive(struct sysmmu_drvdata *mmudata)
+{
+ /* return true if the System MMU is needed to be disabled */
+ if (WARN_ON(!is_sysmmu_active(mmudata)))
+ return false;
+
+ mmudata->activations--;
+
+ return !is_sysmmu_active(mmudata);
+}
+
+#ifdef CONFIG_S5P_SYSTEM_MMU_REFCOUNT
+static bool need_sysmmu_initialize(struct sysmmu_drvdata *mmudata)
+{
+ return mmudata->activations == 1;
+}
+#else
+#define need_sysmmu_initialize is_sysmmu_active
+#endif
+
+static void sysmmu_block(void __iomem *sfrbase)
+{
+ __raw_writel(CTRL_BLOCK, sfrbase + S5P_MMU_CTRL);
+}
+
+static void sysmmu_unblock(void __iomem *sfrbase)
+{
+ __raw_writel(CTRL_ENABLE, sfrbase + S5P_MMU_CTRL);
+}
+
+static void __sysmmu_tlb_invalidate(void __iomem *sfrbase)
+{
+ __raw_writel(0x1, sfrbase + S5P_MMU_FLUSH);
+}
+
+static void __sysmmu_set_ptbase(void __iomem *sfrbase,
+ unsigned long pgd)
+{
+ if (unlikely(pgd == 0)) {
+ pgd = page_to_phys(ZERO_PAGE(0));
+ __raw_writel(0x20, sfrbase + S5P_MMU_CFG); /* 4KB LV1 */
+ } else {
+ __raw_writel(0x0, sfrbase + S5P_MMU_CFG); /* 16KB LV1 */
+ }
+
+ __raw_writel(pgd, sfrbase + S5P_PT_BASE_ADDR);
+
+ __sysmmu_tlb_invalidate(sfrbase);
+}
+
+static void __sysmmu_set_prefbuf(void __iomem *sfrbase, unsigned long base,
+ unsigned long size, int idx)
+{
+ __raw_writel(base, sfrbase + S5P_PB0_SADDR + idx * 8);
+ __raw_writel(size - 1 + base, sfrbase + S5P_PB0_EADDR + idx * 8);
+}
+
+void s5p_sysmmu_set_prefbuf(struct device *owner,
+ unsigned long base0, unsigned long size0,
+ unsigned long base1, unsigned long size1)
+{
+ struct sysmmu_drvdata *data = NULL;
+ unsigned long flags;
+
+ BUG_ON((base0 + (size0 - 1)) <= base0);
+ BUG_ON((base1 + (size1 - 1)) <= base1);
+
+ while ((data = get_sysmmu_data(owner, data))) {
+ if (WARN_ON(data->version != 3))
+ continue;
+
+ read_lock_irqsave(&data->lock, flags);
+ if (is_sysmmu_active(data)) {
+ sysmmu_block(data->sfrbase);
+
+ if (size1 == 0) {
+ if (size0 <= SZ_128K) {
+ base1 = base0;
+ size1 = size0;
+ } else {
+ size1 = size0 -
+ ALIGN(size0 / 2, SZ_64K);
+ size0 = size0 - size1;
+ base1 = base0 + size0;
+ }
+ }
+
+ __sysmmu_set_prefbuf(data->sfrbase, base0, size0, 0);
+ __sysmmu_set_prefbuf(data->sfrbase, base1, size1, 1);
+
+ sysmmu_unblock(data->sfrbase);
+ }
+ read_unlock_irqrestore(&data->lock, flags);
+ }
+}
+
+static void __set_fault_handler(struct sysmmu_drvdata *mmudata,
+ s5p_sysmmu_fault_handler_t handler)
+{
+ unsigned long flags;
+
+ write_lock_irqsave(&mmudata->lock, flags);
+ mmudata->fault_handler = handler;
+ write_unlock_irqrestore(&mmudata->lock, flags);
+}
+
+void s5p_sysmmu_set_fault_handler(struct device *owner,
+ s5p_sysmmu_fault_handler_t handler)
+{
+ struct sysmmu_drvdata *data = NULL;
+
+ while ((data = get_sysmmu_data(owner, data)))
+ __set_fault_handler(data, handler);
+}
+
+static int default_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
+ unsigned long pgtable_base,
+ unsigned long fault_addr)
+{
+ unsigned long *ent;
+
+ if ((itype >= SYSMMU_FAULTS_NUM) || (itype < SYSMMU_PAGEFAULT))
+ itype = SYSMMU_FAULT_UNKNOWN;
+
+ pr_err("%s occured at 0x%lx(Page table base: 0x%lx)\n",
+ sysmmu_fault_name[itype], fault_addr, pgtable_base);
+
+ pgtable_base += ((fault_addr & 0xFFF00000) >> 20) * 4;
+
+ ent = page_address(phys_to_page(pgtable_base));
+ ent += offset_in_page(pgtable_base) / sizeof(unsigned long) ;
+
+ if (likely(ent != NULL)) {
+ pr_err("\tLv1 entry: 0x%lx\n", *ent);
+
+ if ((*ent & 0x3) == 0x1) {
+ pgtable_base = *ent & ~0x3FF;
+ ent = page_address(phys_to_page(pgtable_base));
+
+ if (likely(ent != NULL)) {
+ ent += offset_in_page(pgtable_base) /
+ sizeof(unsigned long);
+ ent += (fault_addr & 0xFF000) >> 12;
+ pr_err("\tLv2 entry: 0x%lx\n", *ent);
+ }
+ }
+ }
+
+ pr_err("\t\tGenerating Kernel OOPS... because it is unrecoverable.\n");
+
+ BUG();
+
+ return 0;
+}
+
+static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
+{
+ /* SYSMMU is in blocked when interrupt occurred. */
+ unsigned long base = 0;
+ struct sysmmu_drvdata *mmudata = dev_id;
+ enum S5P_SYSMMU_INTERRUPT_TYPE itype;
+
+ read_lock(&mmudata->lock);
+
+ WARN_ON(!is_sysmmu_active(mmudata));
+
+ itype = (enum S5P_SYSMMU_INTERRUPT_TYPE)
+ __ffs(__raw_readl(mmudata->sfrbase + S5P_INT_STATUS));
+
+ BUG_ON(!((itype >= 0) && (itype < 8)));
+
+ if (mmudata->fault_handler) {
+ unsigned long addr;
+
+ base = __raw_readl(mmudata->sfrbase + S5P_PT_BASE_ADDR);
+ addr = __raw_readl(mmudata->sfrbase + fault_reg_offset[itype]);
+
+ dev_dbg(mmudata->dev, "System MMU %s occurred by %s\n",
+ sysmmu_fault_name[itype], dev_name(mmudata->owner));
+
+ if ((mmudata->version == 3) && ((itype == SYSMMU_AR_MULTIHIT) ||
+ (itype == SYSMMU_AW_MULTIHIT))) {
+ __sysmmu_tlb_invalidate(mmudata->sfrbase);
+ } else if (mmudata->fault_handler(itype, base, addr) != 0) {
+ dev_dbg(mmudata->dev,
+ "%s is resolved. Retrying translation.\n",
+ sysmmu_fault_name[itype]);
+ } else {
+ base = 0;
+ }
+
+ __raw_writel(1 << itype, mmudata->sfrbase + S5P_INT_CLEAR);
+ }
+
+ sysmmu_unblock(mmudata->sfrbase);
+
+ read_unlock(&mmudata->lock);
+
+ if (!base)
+ dev_notice(mmudata->dev, "%s is not handled.\n",
+ sysmmu_fault_name[itype]);
+
+ return IRQ_HANDLED;
+}
+
+void s5p_sysmmu_set_tablebase_pgd(struct device *owner, unsigned long pgd)
+{
+ struct sysmmu_drvdata *mmudata = NULL;
+
+ while ((mmudata = get_sysmmu_data(owner, mmudata))) {
+ unsigned long flags;
+
+ read_lock_irqsave(&mmudata->lock, flags);
+
+ if (is_sysmmu_active(mmudata)) {
+ sysmmu_block(mmudata->sfrbase);
+ __sysmmu_set_ptbase(mmudata->sfrbase, pgd);
+ sysmmu_unblock(mmudata->sfrbase);
+ dev_dbg(mmudata->dev, "New page table base is %p\n",
+ (void *)pgd);
+ } else {
+ dev_dbg(mmudata->dev,
+ "Disabled: Skipping setting page table base.\n");
+ }
+
+ read_unlock_irqrestore(&mmudata->lock, flags);
+ }
+}
+
+static bool __sysmmu_disable(struct sysmmu_drvdata *data)
+{
+ unsigned long flags;
+ bool disabled = false;
+
+ write_lock_irqsave(&data->lock, flags);
+
+ if (set_sysmmu_inactive(data)) {
+ __raw_writel(CTRL_DISABLE, data->sfrbase + S5P_MMU_CTRL);
+ if (data->clk)
+ clk_disable(data->clk);
+ disabled = true;
+ }
+
+ write_unlock_irqrestore(&data->lock, flags);
+
+#ifndef CONFIG_S5P_SYSTEM_MMU_REFCOUNT
+ if (disabled)
+#endif
+ pm_runtime_put_sync(data->dev);
+
+ return disabled;
+}
+
+int s5p_sysmmu_enable(struct device *owner, unsigned long pgd)
+{
+ unsigned long flags;
+ struct sysmmu_drvdata *mmudata = NULL;
+ int ret = -ENODEV;
+
+ /* There are some devices that control more System MMUs than one such
+ * as MFC.
+ */
+ while ((mmudata = get_sysmmu_data(owner, mmudata))) {
+ ret = pm_runtime_get_sync(mmudata->dev);
+ if (ret < 0)
+ break;
+
+ write_lock_irqsave(&mmudata->lock, flags);
+
+ ret = set_sysmmu_active(mmudata);
+ if (!ret && need_sysmmu_initialize(mmudata)) {
+ if (mmudata->clk)
+ clk_enable(mmudata->clk);
+
+ __sysmmu_set_ptbase(mmudata->sfrbase, pgd);
+
+ if (mmudata->version == 0) {
+
+ mmudata->version = readl(
+ mmudata->sfrbase + S5P_MMU_VERSION);
+ mmudata->version >>= 28;
+ }
+
+ if (mmudata->version == 3) {
+ __raw_writel((1 << 12) | (2 << 28),
+ mmudata->sfrbase + S5P_MMU_CFG);
+ __sysmmu_set_prefbuf(mmudata->sfrbase,
+ 0, -1, 0);
+ __sysmmu_set_prefbuf(mmudata->sfrbase,
+ 0, -1, 1);
+ }
+
+ __raw_writel(CTRL_ENABLE,
+ mmudata->sfrbase + S5P_MMU_CTRL);
+
+ dev_dbg(mmudata->dev, "Enabled.\n");
+ } else {
+ dev_dbg(mmudata->dev, "Already enabled.\n");
+ }
+
+ write_unlock_irqrestore(&mmudata->lock, flags);
+
+ if (ret) /* already enabled and no refcount */
+ pm_runtime_put_sync(mmudata->dev);
+ }
+
+ if (ret < 0) {
+ while ((mmudata = get_sysmmu_data_rollback(owner, mmudata))) {
+ __sysmmu_disable(mmudata);
+
+ dev_dbg(mmudata->dev, "Failed to enable.\n");
+ }
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+void s5p_sysmmu_disable(struct device *owner)
+{
+ struct sysmmu_drvdata *mmudata = NULL;
+
+ while ((mmudata = get_sysmmu_data(owner, mmudata))) {
+ if (__sysmmu_disable(mmudata))
+ dev_dbg(mmudata->dev, "Disabled.\n");
+ else
+ dev_dbg(mmudata->dev,
+ "Inactivation request ignorred\n");
+ }
+}
+
+void s5p_sysmmu_tlb_invalidate(struct device *owner)
+{
+ struct sysmmu_drvdata *mmudata = NULL;
+
+ while ((mmudata = get_sysmmu_data(owner, mmudata))) {
+ unsigned long flags;
+
+ read_lock_irqsave(&mmudata->lock, flags);
+
+ if (is_sysmmu_active(mmudata)) {
+ sysmmu_block(mmudata->sfrbase);
+ __sysmmu_tlb_invalidate(mmudata->sfrbase);
+ sysmmu_unblock(mmudata->sfrbase);
+ } else {
+ dev_dbg(mmudata->dev,
+ "Disabled: Skipping invalidating TLB.\n");
+ }
+
+ read_unlock_irqrestore(&mmudata->lock, flags);
+ }
+}
+
+static int s5p_sysmmu_probe(struct platform_device *pdev)
+{
+ struct resource *res, *ioarea;
+ int ret;
+ int irq;
+ struct device *dev;
+ void *sfr;
+ struct sysmmu_drvdata *data;
+
+ dev = &pdev->dev;
+
+ if (!dev_get_platdata(dev)) {
+ dev_dbg(dev, "Skipping probing - No owner device.\n");
+ return -ENODEV;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ dev_err(dev, "Not enough memory for private data.\n");
+ return -ENOMEM;
+ }
+
+ data->owner = dev_get_platdata(dev);
+
+ ret = dev_set_drvdata(dev, data);
+ if (ret) {
+ dev_err(dev, "Unable to set driver's private data.\n");
+ goto err_init;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "Failed to get resource.\n");
+ goto err_init;
+ }
+
+ ioarea = request_mem_region(res->start, resource_size(res),
+ dev_name(dev));
+ if (ioarea == NULL) {
+ dev_err(dev, "Failed to request memory region.\n");
+ goto err_init;
+ }
+
+ sfr = ioremap(res->start, resource_size(res));
+ if (!sfr) {
+ dev_err(dev, "Failed to map IO area\n");
+ ret = -ENOENT;
+ goto err_ioremap;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "Failed to get irq resource.\n");
+ ret = irq;
+ goto err_irq;
+ }
+
+ ret = request_irq(irq, s5p_sysmmu_irq, 0, dev_name(dev), data);
+ if (ret) {
+ dev_err(dev, "Failed to request irq.\n");
+ goto err_irq;
+ }
+
+ data->clk = clk_get(dev, "sysmmu");
+ if (IS_ERR(data->clk)) {
+ dev_dbg(dev, "Clock descriptor not found:"
+ " Skipping clock gating...\n");
+ data->clk = NULL;
+ }
+
+ data->dev = dev;
+ data->sfrbase = sfr;
+ rwlock_init(&data->lock);
+ INIT_LIST_HEAD(&data->node);
+
+ __set_fault_handler(data, &default_fault_handler);
+ list_add(&data->node, &sysmmu_list);
+
+ if (dev->parent)
+ pm_runtime_enable(dev);
+
+ if (to_platform_device(data->owner)->id == -1)
+ dev_info(dev, "Initialized for %s.\n",
+ to_platform_device(data->owner)->name);
+ else
+ dev_info(dev, "Initialized for %s.%d.\n",
+ to_platform_device(data->owner)->name,
+ to_platform_device(data->owner)->id);
+ return 0;
+err_irq:
+ iounmap(sfr);
+err_ioremap:
+ release_resource(ioarea);
+ kfree(ioarea);
+err_init:
+ kfree(data);
+ dev_err(dev, "Probing system MMU failed!");
+ return ret;
+}
+
+static struct platform_driver s5p_sysmmu_driver = {
+ .probe = s5p_sysmmu_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s5p-sysmmu",
+ }
+};
+
+static int __init s5p_sysmmu_init(void)
+{
+ return platform_driver_register(&s5p_sysmmu_driver);
+}
+subsys_initcall(s5p_sysmmu_init);
diff --git a/arch/arm/plat-s5p/s5p_iommu.c b/arch/arm/plat-s5p/s5p_iommu.c
new file mode 100644
index 0000000..a900c84
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p_iommu.c
@@ -0,0 +1,459 @@
+/* linux/drivers/iommu/exynos_iommu.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_S5P_SYSTEM_MMU_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+
+#include <asm/cacheflush.h>
+
+#include <plat/s5p-sysmmu.h>
+
+#ifdef CONFIG_S5P_SYSTEM_MMU_DEBUG
+#define DEBUG /* for dev_dbg() */
+#endif
+
+/* We does not consider super section mapping (16MB) */
+#define S5P_SPAGE_SHIFT 12
+#define S5P_LPAGE_SHIFT 16
+#define S5P_SECTION_SHIFT 20
+
+#define S5P_SPAGE_SIZE (1 << S5P_SPAGE_SHIFT)
+#define S5P_LPAGE_SIZE (1 << S5P_LPAGE_SHIFT)
+#define S5P_SECTION_SIZE (1 << S5P_SECTION_SHIFT)
+
+#define S5P_SPAGE_MASK (~(S5P_SPAGE_SIZE - 1))
+#define S5P_LPAGE_MASK (~(S5P_LPAGE_SIZE - 1))
+#define S5P_SECTION_MASK (~(S5P_SECTION_SIZE - 1))
+
+#define S5P_SPAGE_ORDER (S5P_SPAGE_SHIFT - PAGE_SHIFT)
+#define S5P_LPAGE_ORDER (S5P_LPAGE_SHIFT - S5P_SPAGE_SHIFT)
+#define S5P_SECTION_ORDER (S5P_SECTION_SHIFT - S5P_SPAGE_SHIFT)
+
+#define S5P_LV1TABLE_ENTRIES (1 << (BITS_PER_LONG - S5P_SECTION_SHIFT))
+#define S5P_LV1TABLE_ORDER 2 /* get_order(S5P_LV1TABLE_ENTRIES) */
+
+#define S5P_LV2TABLE_ENTRIES (1 << S5P_SECTION_ORDER)
+#define S5P_LV2TABLE_SIZE (S5P_LV2TABLE_ENTRIES * sizeof(long))
+#define S5P_LV2TABLE_MASK (~(S5P_LV2TABLE_SIZE - 1)) /* 0xFFFFFC00 */
+
+#define S5P_SECTION_LV1_ENTRY(entry) ((entry & 0x40003) == 2)
+#define S5P_SUPSECT_LV1_ENTRY(entry) ((entry & 0x40003) == 0x40002)
+#define S5P_PAGE_LV1_ENTRY(entry) ((entry & 3) == 1)
+#define S5P_FAULT_LV1_ENTRY(entry) (((entry & 3) == 0) || (entry & 3) == 3)
+
+#define S5P_LPAGE_LV2_ENTRY(entry) ((entry & 3) == 1)
+#define S5P_SPAGE_LV2_ENTRY(entry) ((entry & 2) == 2)
+#define S5P_FAULT_LV2_ENTRY(entry) ((entry & 3) == 0)
+
+#define MAKE_FAULT_ENTRY(entry) do { entry = 0; } while (0)
+#define MAKE_SECTION_ENTRY(entry, pa) do { entry = pa | 2; } while (0)
+#define MAKE_SUPSECT_ENTRY(entry, pa) do { entry = pa | 0x40002; } while (0)
+#define MAKE_LV2TABLE_ENTRY(entry, pa) do { entry = pa | 1; } while (0)
+
+#define MAKE_LPAGE_ENTRY(entry, pa) do { entry = pa | 1; } while (0)
+#define MAKE_SPAGE_ENTRY(entry, pa) do { entry = pa | 3; } while (0)
+
+#define GET_LV2ENTRY(entry, iova) (\
+ (unsigned long *)phys_to_virt(entry & S5P_LV2TABLE_MASK) +\
+ ((iova & (~S5P_SECTION_MASK)) >> S5P_SPAGE_SHIFT))
+
+struct s5p_iommu_domain {
+ struct device *dev;
+ unsigned long *pgtable;
+ struct mutex lock;
+};
+
+/* slab cache for level 2 page tables */
+static struct kmem_cache *l2table_cachep;
+
+static inline void pgtable_flush(void *vastart, void *vaend)
+{
+ dmac_flush_range(vastart, vaend);
+ outer_flush_range(virt_to_phys(vastart),
+ virt_to_phys(vaend));
+}
+
+static int s5p_iommu_domain_init(struct iommu_domain *domain)
+{
+ struct s5p_iommu_domain *priv;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
+ S5P_LV1TABLE_ORDER);
+ if (!priv->pgtable) {
+ kfree(priv);
+ return -ENOMEM;
+ }
+
+ memset(priv->pgtable, 0, S5P_LV1TABLE_ENTRIES * sizeof(unsigned long));
+ pgtable_flush(priv->pgtable, priv->pgtable + S5P_LV1TABLE_ENTRIES);
+
+ mutex_init(&priv->lock);
+
+ domain->priv = priv;
+ pr_debug("%s: Allocated IOMMU domain %p with pgtable @ %#lx\n",
+ __func__, domain, __pa(priv->pgtable));
+ return 0;
+}
+
+static void s5p_iommu_domain_destroy(struct iommu_domain *domain)
+{
+ struct s5p_iommu_domain *priv = domain->priv;
+
+ free_pages((unsigned long)priv->pgtable, S5P_LV1TABLE_ORDER);
+ kfree(domain->priv);
+ domain->priv = NULL;
+}
+
+static int s5p_iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ int ret;
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+
+ if (s5p_domain->dev) {
+ pr_debug("%s: %s is already attached to doamin %p\n", __func__,
+ dev_name(s5p_domain->dev), domain);
+ BUG_ON(s5p_domain->dev != dev);
+ return -EBUSY;
+ }
+
+ ret = s5p_sysmmu_enable(dev, virt_to_phys(s5p_domain->pgtable));
+ if (ret)
+ return ret;
+
+ mutex_lock(&s5p_domain->lock);
+ s5p_domain->dev = dev;
+ mutex_unlock(&s5p_domain->lock);
+
+ return 0;
+}
+
+static void s5p_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+
+ mutex_lock(&s5p_domain->lock);
+
+ if (s5p_domain->dev == dev) {
+ mutex_unlock(&s5p_domain->lock);
+
+ s5p_sysmmu_disable(s5p_domain->dev);
+
+ s5p_domain->dev = NULL;
+ } else {
+ pr_debug("%s: %s is not attached to domain of pgtable @ %#lx\n",
+ __func__, dev_name(dev), __pa(s5p_domain->pgtable));
+ mutex_unlock(&s5p_domain->lock);
+ }
+
+}
+
+static bool section_available(struct iommu_domain *domain,
+ unsigned long *lv1entry)
+{
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+
+ if (S5P_SECTION_LV1_ENTRY(*lv1entry)) {
+ pr_err("1MB entry alread exists at %#x // pgtable %#lx\n",
+ (lv1entry - s5p_domain->pgtable) * SZ_1M,
+ __pa(s5p_domain->pgtable));
+ return false;
+ }
+
+ if (S5P_PAGE_LV1_ENTRY(*lv1entry)) {
+ unsigned long *lv2end, *lv2base;
+
+ lv2base = phys_to_virt(*lv1entry & S5P_LV2TABLE_MASK);
+ lv2end = lv2base + S5P_LV2TABLE_ENTRIES;
+ while (lv2base != lv2end) {
+ if (!S5P_FAULT_LV2_ENTRY(*lv2base)) {
+ pr_err("Failed to free L2 page table for"
+ "section mapping. // pgtalle %#lx\n",
+ __pa(s5p_domain->pgtable));
+ return false;
+ }
+ lv2base++;
+ }
+
+ kmem_cache_free(l2table_cachep,
+ phys_to_virt(*lv1entry & S5P_LV2TABLE_MASK));
+
+ MAKE_FAULT_ENTRY(*lv1entry);
+ }
+
+ return true;
+}
+
+static bool write_lpage(unsigned long *head_entry, unsigned long phys_addr)
+{
+ unsigned long *entry, *end;
+
+ entry = head_entry;
+ end = entry + (1 << S5P_LPAGE_ORDER);
+
+ while (entry != end) {
+ if (!S5P_FAULT_LV2_ENTRY(*entry))
+ break;
+
+ MAKE_LPAGE_ENTRY(*entry, phys_addr);
+
+ entry++;
+ }
+
+ if (entry != end) {
+ end = entry;
+ while (entry != head_entry)
+ MAKE_FAULT_ENTRY(*(--entry));
+
+ return false;
+ }
+
+ return true;
+}
+
+static int s5p_iommu_map(struct iommu_domain *domain, unsigned long iova,
+ phys_addr_t paddr, int gfp_order, int prot)
+{
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+ unsigned long *start_entry, *entry, *end_entry;
+ int num_entry;
+ int ret = 0;
+
+ BUG_ON(s5p_domain->pgtable== NULL);
+
+ mutex_lock(&s5p_domain->lock);
+
+ start_entry = entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT);
+
+ if (gfp_order >= S5P_SECTION_ORDER) {
+ BUG_ON((paddr | iova) & ~S5P_SECTION_MASK);
+ /* 1MiB mapping */
+
+ num_entry = 1 << (gfp_order - S5P_SECTION_ORDER);
+ end_entry = entry + num_entry;
+
+ while (entry != end_entry) {
+ if (!section_available(domain, entry))
+ break;
+
+ MAKE_SECTION_ENTRY(*entry, paddr);
+
+ paddr += S5P_SECTION_SIZE;
+ entry++;
+ }
+
+ if (entry != end_entry)
+ goto mapping_error;
+
+ pgtable_flush(start_entry, entry);
+ goto mapping_done;
+ }
+
+ if (S5P_FAULT_LV1_ENTRY(*entry)) {
+ unsigned long *l2table;
+
+ l2table = kmem_cache_zalloc(l2table_cachep, GFP_KERNEL);
+ if (!l2table) {
+ ret = -ENOMEM;
+ goto nomem_error;
+ }
+
+ pgtable_flush(l2table, l2table + S5P_LV2TABLE_ENTRIES);
+
+ MAKE_LV2TABLE_ENTRY(*entry, virt_to_phys(l2table));
+ pgtable_flush(entry, entry + 1);
+ }
+
+ /* 'entry' points level 2 entries, hereafter */
+ entry = GET_LV2ENTRY(*entry, iova);
+
+ start_entry = entry;
+ num_entry = 1 << gfp_order;
+ end_entry = entry + num_entry;
+
+ if (gfp_order >= S5P_LPAGE_ORDER) {
+ /* large page(64KiB) mapping */
+ BUG_ON((paddr | iova) & ~S5P_LPAGE_MASK);
+
+ while (entry != end_entry) {
+ if (!write_lpage(entry, paddr)) {
+ pr_err("%s: Failed to allocate large page"
+ "for IOVA %#lx entry.\n",
+ __func__, iova);
+ ret = -EADDRINUSE;
+ break;
+ }
+
+ paddr += S5P_LPAGE_SIZE;
+ entry += (1 << S5P_LPAGE_ORDER);
+ }
+
+ if (entry != end_entry) {
+ entry -= 1 << S5P_LPAGE_ORDER;
+ goto mapping_error;
+ }
+ } else {
+ /* page (4KiB) mapping */
+ while (entry != end_entry && S5P_FAULT_LV2_ENTRY(*entry)) {
+
+ MAKE_SPAGE_ENTRY(*entry, paddr);
+
+ entry++;
+ paddr += S5P_SPAGE_SIZE;
+ }
+
+ if (entry != end_entry) {
+ pr_err("%s: Failed to allocate small page entry"
+ " for IOVA %#lx.\n", __func__, iova);
+ ret = -EADDRINUSE;
+
+ goto mapping_error;
+ }
+ }
+
+ pgtable_flush(start_entry, entry);
+mapping_error:
+ if (entry != end_entry) {
+ unsigned long *current_entry = entry;
+ while (entry != start_entry)
+ MAKE_FAULT_ENTRY(*(--entry));
+ pgtable_flush(start_entry, current_entry);
+ ret = -EADDRINUSE;
+ }
+
+nomem_error:
+mapping_done:
+ mutex_unlock(&s5p_domain->lock);
+
+ return ret;
+}
+
+static int s5p_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+ int gfp_order)
+{
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+ unsigned long *entry;
+ int num_entry;
+
+ BUG_ON(s5p_domain->pgtable == NULL);
+
+ mutex_lock(&s5p_domain->lock);
+
+ entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT);
+
+ if (gfp_order >= S5P_SECTION_ORDER) {
+ num_entry = 1 << (gfp_order - S5P_SECTION_ORDER);
+ while (num_entry--) {
+ if (S5P_SECTION_LV1_ENTRY(*entry)) {
+ MAKE_FAULT_ENTRY(*entry);
+ } else if (S5P_PAGE_LV1_ENTRY(*entry)) {
+ unsigned long *lv2beg, *lv2end;
+ lv2beg = phys_to_virt(
+ *entry & S5P_LV2TABLE_MASK);
+ lv2end = lv2beg + S5P_LV2TABLE_ENTRIES;
+ while (lv2beg != lv2end) {
+ MAKE_FAULT_ENTRY(*lv2beg);
+ lv2beg++;
+ }
+ }
+ entry++;
+ }
+ } else {
+ entry = GET_LV2ENTRY(*entry, iova);
+
+ BUG_ON(S5P_LPAGE_LV2_ENTRY(*entry) &&
+ (gfp_order < S5P_LPAGE_ORDER));
+
+ num_entry = 1 << gfp_order;
+
+ while (num_entry--) {
+ MAKE_FAULT_ENTRY(*entry);
+ entry++;
+ }
+ }
+
+ mutex_unlock(&s5p_domain->lock);
+
+ if (s5p_domain->dev)
+ s5p_sysmmu_tlb_invalidate(s5p_domain->dev);
+
+ return 0;
+}
+
+static phys_addr_t s5p_iommu_iova_to_phys(struct iommu_domain *domain,
+ unsigned long iova)
+{
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+ unsigned long *entry;
+ unsigned long offset;
+
+ entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT);
+
+ if (S5P_FAULT_LV1_ENTRY(*entry))
+ return 0;
+
+ offset = iova & ~S5P_SECTION_MASK;
+
+ if (S5P_SECTION_LV1_ENTRY(*entry))
+ return (*entry & S5P_SECTION_MASK) + offset;
+
+ entry = GET_LV2ENTRY(*entry, iova);
+
+ if (S5P_SPAGE_LV2_ENTRY(*entry))
+ return (*entry & S5P_SPAGE_MASK) + (iova & ~S5P_SPAGE_MASK);
+
+ if (S5P_LPAGE_LV2_ENTRY(*entry))
+ return (*entry & S5P_LPAGE_MASK) + (iova & ~S5P_LPAGE_MASK);
+
+ return 0;
+}
+
+static int s5p_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return 0;
+}
+
+static struct iommu_ops s5p_iommu_ops = {
+ .domain_init = &s5p_iommu_domain_init,
+ .domain_destroy = &s5p_iommu_domain_destroy,
+ .attach_dev = &s5p_iommu_attach_device,
+ .detach_dev = &s5p_iommu_detach_device,
+ .map = &s5p_iommu_map,
+ .unmap = &s5p_iommu_unmap,
+ .iova_to_phys = &s5p_iommu_iova_to_phys,
+ .domain_has_cap = &s5p_iommu_domain_has_cap,
+};
+
+static int __init s5p_iommu_init(void)
+{
+ l2table_cachep = kmem_cache_create("SysMMU Lv2 Tables",
+ S5P_LV2TABLE_SIZE, S5P_LV2TABLE_SIZE, 0, NULL);
+ if (!l2table_cachep)
+ return -ENOMEM;
+
+ register_iommu(&s5p_iommu_ops);
+ return 0;
+}
+arch_initcall(s5p_iommu_init);
diff --git a/arch/arm/plat-s5p/s5p_iovmm.c b/arch/arm/plat-s5p/s5p_iovmm.c
new file mode 100644
index 0000000..a56ccef
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p_iovmm.c
@@ -0,0 +1,365 @@
+/* linux/arch/arm/plat-s5p/s5p_iovmm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/ion.h>
+#include <linux/iommu.h>
+#include <linux/genalloc.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+
+#include <plat/s5p-iovmm.h>
+
+struct s5p_vm_region {
+ struct list_head node;
+ dma_addr_t start;
+ size_t size;
+};
+
+struct s5p_iovmm {
+ struct list_head node; /* element of s5p_iovmm_list */
+ struct iommu_domain *domain;
+ struct device *dev;
+ struct gen_pool *vmm_pool;
+ struct list_head regions_list; /* list of s5p_vm_region */
+ bool active;
+ struct mutex lock;
+};
+
+static DEFINE_RWLOCK(iovmm_list_lock);
+static LIST_HEAD(s5p_iovmm_list);
+
+static struct s5p_iovmm *find_iovmm(struct device *dev)
+{
+ struct list_head *pos;
+ struct s5p_iovmm *vmm = NULL;
+
+ read_lock(&iovmm_list_lock);
+ list_for_each(pos, &s5p_iovmm_list) {
+ vmm = list_entry(pos, struct s5p_iovmm, node);
+ if (vmm->dev == dev)
+ break;
+ }
+ read_unlock(&iovmm_list_lock);
+ return vmm;
+}
+
+static struct s5p_vm_region *find_region(struct s5p_iovmm *vmm, dma_addr_t iova)
+{
+ struct list_head *pos;
+ struct s5p_vm_region *region;
+
+ list_for_each(pos, &vmm->regions_list) {
+ region = list_entry(pos, struct s5p_vm_region, node);
+ if (region->start == iova)
+ return region;
+ }
+ return NULL;
+}
+
+int iovmm_setup(struct device *dev)
+{
+ struct s5p_iovmm *vmm;
+ int ret;
+
+ vmm = kzalloc(sizeof(*vmm), GFP_KERNEL);
+ if (!vmm) {
+ ret = -ENOMEM;
+ goto err_setup_alloc;
+ }
+
+ vmm->vmm_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!vmm->vmm_pool) {
+ ret = -ENOMEM;
+ goto err_setup_genalloc;
+ }
+
+ /* 1GB addr space from 0x80000000 */
+ ret = gen_pool_add(vmm->vmm_pool, 0x80000000, 0x40000000, -1);
+ if (ret)
+ goto err_setup_domain;
+
+ vmm->domain = iommu_domain_alloc();
+ if (!vmm->domain) {
+ ret = -ENOMEM;
+ goto err_setup_domain;
+ }
+
+ vmm->dev = dev;
+
+ mutex_init(&vmm->lock);
+
+ INIT_LIST_HEAD(&vmm->node);
+ INIT_LIST_HEAD(&vmm->regions_list);
+
+ write_lock(&iovmm_list_lock);
+ list_add(&vmm->node, &s5p_iovmm_list);
+ write_unlock(&iovmm_list_lock);
+
+ return 0;
+err_setup_domain:
+ gen_pool_destroy(vmm->vmm_pool);
+err_setup_genalloc:
+ kfree(vmm);
+err_setup_alloc:
+ return ret;
+}
+
+void iovmm_cleanup(struct device *dev)
+{
+ struct s5p_iovmm *vmm;
+
+ vmm = find_iovmm(dev);
+
+ WARN_ON(!vmm);
+ if (vmm) {
+ struct list_head *pos, *tmp;
+
+ if (vmm->active)
+ iommu_detach_device(vmm->domain, dev);
+
+ iommu_domain_free(vmm->domain);
+
+ list_for_each_safe(pos, tmp, &vmm->regions_list) {
+ struct s5p_vm_region *region;
+
+ region = list_entry(pos, struct s5p_vm_region, node);
+
+ /* No need to unmap the region because
+ * iommu_domain_free() frees the page table */
+ gen_pool_free(vmm->vmm_pool, region->start,
+ region->size);
+
+ kfree(list_entry(pos, struct s5p_vm_region, node));
+ }
+
+ gen_pool_destroy(vmm->vmm_pool);
+
+ write_lock(&iovmm_list_lock);
+ list_del(&vmm->node);
+ write_unlock(&iovmm_list_lock);
+
+ kfree(vmm);
+ }
+}
+
+int iovmm_activate(struct device *dev)
+{
+ struct s5p_iovmm *vmm;
+ int ret = 0;
+
+ vmm = find_iovmm(dev);
+ if (WARN_ON(!vmm))
+ return -EINVAL;
+
+ mutex_lock(&vmm->lock);
+
+ ret = iommu_attach_device(vmm->domain, vmm->dev);
+ if (!ret)
+ vmm->active = true;
+
+ mutex_unlock(&vmm->lock);
+
+ return ret;
+}
+
+void iovmm_deactivate(struct device *dev)
+{
+ struct s5p_iovmm *vmm;
+
+ vmm = find_iovmm(dev);
+ if (WARN_ON(!vmm))
+ return;
+
+ iommu_detach_device(vmm->domain, vmm->dev);
+
+ vmm->active = false;
+}
+
+dma_addr_t iovmm_map(struct device *dev, struct scatterlist *sg, off_t offset,
+ size_t size)
+{
+ off_t start_off;
+ dma_addr_t addr, start = 0;
+ size_t mapped_size = 0;
+ struct s5p_vm_region *region;
+ struct s5p_iovmm *vmm;
+ int order;
+#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR
+ size_t iova_size = 0;
+#endif
+
+ BUG_ON(!sg);
+
+ vmm = find_iovmm(dev);
+ if (WARN_ON(!vmm))
+ goto err_map_nomem;
+
+ for (; sg_dma_len(sg) < offset; sg = sg_next(sg))
+ offset -= sg_dma_len(sg);
+
+ mutex_lock(&vmm->lock);
+
+ start_off = offset_in_page(sg_phys(sg) + offset);
+ size = PAGE_ALIGN(size + start_off);
+
+ order = __fls(min(size, (size_t)SZ_1M));
+#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR
+ iova_size = ALIGN(size, SZ_64K);
+ start = (dma_addr_t)gen_pool_alloc_aligned(vmm->vmm_pool, iova_size,
+ order);
+#else
+ start = (dma_addr_t)gen_pool_alloc_aligned(vmm->vmm_pool, size, order);
+#endif
+ if (!start)
+ goto err_map_nomem_lock;
+
+ addr = start;
+ do {
+ phys_addr_t phys;
+ size_t len;
+
+ phys = sg_phys(sg);
+ len = sg_dma_len(sg);
+
+ if (offset > 0) {
+ len -= offset;
+ phys += offset;
+ offset = 0;
+ }
+
+ if (offset_in_page(phys)) {
+ len += offset_in_page(phys);
+ phys = round_down(phys, PAGE_SIZE);
+ }
+
+ len = PAGE_ALIGN(len);
+
+ if (len > (size - mapped_size))
+ len = size - mapped_size;
+
+ while (len > 0) {
+ order = min3(__ffs(phys), __ffs(addr), __fls(len));
+
+ if (iommu_map(vmm->domain, addr, phys,
+ order - PAGE_SHIFT, 0))
+ goto err_map_map;
+
+ addr += (1 << order);
+ phys += (1 << order);
+ len -= (1 << order);
+ mapped_size += (1 << order);
+ }
+ } while ((sg = sg_next(sg)) && (mapped_size < size));
+
+ BUG_ON(mapped_size > size);
+
+ if (mapped_size < size)
+ goto err_map_map;
+
+#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR
+ if (iova_size != size) {
+ /* System MMU v3 support in SMDK5250 EVT0 */
+ addr = start + size;
+ size = iova_size;
+
+ for (; addr < start + size; addr += PAGE_SIZE) {
+ if (iommu_map(vmm->domain, addr,
+ page_to_phys(ZERO_PAGE(0)), 0, 0)) {
+ goto err_map_map;
+ }
+ mapped_size += PAGE_SIZE;
+ }
+ }
+#endif
+ region = kmalloc(sizeof(*region), GFP_KERNEL);
+ if (!region)
+ goto err_map_map;
+
+ region->start = start + start_off;
+ region->size = size;
+ INIT_LIST_HEAD(&region->node);
+
+ list_add(&region->node, &vmm->regions_list);
+
+ mutex_unlock(&vmm->lock);
+
+ return region->start;
+err_map_map:
+ while (addr >= start) {
+ int order;
+ mapped_size = addr - start;
+
+ if (mapped_size == 0) /* Mapping failed at the first page */
+ mapped_size = size;
+
+ BUG_ON(mapped_size < PAGE_SIZE);
+
+ order = min(__fls(mapped_size), __ffs(start));
+
+ iommu_unmap(vmm->domain, start, order - PAGE_SHIFT);
+
+ start += 1 << order;
+ mapped_size -= 1 << order;
+ }
+ gen_pool_free(vmm->vmm_pool, start, size);
+
+err_map_nomem_lock:
+ mutex_unlock(&vmm->lock);
+err_map_nomem:
+ return (dma_addr_t)0;
+}
+
+void iovmm_unmap(struct device *dev, dma_addr_t iova)
+{
+ struct s5p_vm_region *region;
+ struct s5p_iovmm *vmm;
+
+ vmm = find_iovmm(dev);
+
+ if (WARN_ON(!vmm))
+ return;
+
+ mutex_lock(&vmm->lock);
+
+ region = find_region(vmm, iova);
+ if (WARN_ON(!region))
+ goto err_region_not_found;
+
+ region->start = round_down(region->start, PAGE_SIZE);
+
+ gen_pool_free(vmm->vmm_pool, region->start, region->size);
+ list_del(&region->node);
+
+ while (region->size != 0) {
+ int order;
+
+ order = min(__fls(region->size), __ffs(region->start));
+
+ iommu_unmap(vmm->domain, region->start, order - PAGE_SHIFT);
+
+ region->start += 1 << order;
+ region->size -= 1 << order;
+ }
+
+ kfree(region);
+
+err_region_not_found:
+ mutex_unlock(&vmm->lock);
+}
+
+static int __init s5p_iovmm_init(void)
+{
+ return 0;
+}
+arch_initcall(s5p_iovmm_init);
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
deleted file mode 100644
index 54f5edd..0000000
--- a/arch/arm/plat-s5p/sysmmu.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/* linux/arch/arm/plat-s5p/sysmmu.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-
-#include <asm/pgtable.h>
-
-#include <mach/map.h>
-#include <mach/regs-sysmmu.h>
-#include <plat/sysmmu.h>
-
-#define CTRL_ENABLE 0x5
-#define CTRL_BLOCK 0x7
-#define CTRL_DISABLE 0x0
-
-static struct device *dev;
-
-static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
- S5P_PAGE_FAULT_ADDR,
- S5P_AR_FAULT_ADDR,
- S5P_AW_FAULT_ADDR,
- S5P_DEFAULT_SLAVE_ADDR,
- S5P_AR_FAULT_ADDR,
- S5P_AR_FAULT_ADDR,
- S5P_AW_FAULT_ADDR,
- S5P_AW_FAULT_ADDR
-};
-
-static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
- "PAGE FAULT",
- "AR MULTI-HIT FAULT",
- "AW MULTI-HIT FAULT",
- "BUS ERROR",
- "AR SECURITY PROTECTION FAULT",
- "AR ACCESS PROTECTION FAULT",
- "AW SECURITY PROTECTION FAULT",
- "AW ACCESS PROTECTION FAULT"
-};
-
-static int (*fault_handlers[S5P_SYSMMU_TOTAL_IPNUM])(
- enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr);
-
-/*
- * If adjacent 2 bits are true, the system MMU is enabled.
- * The system MMU is disabled, otherwise.
- */
-static unsigned long sysmmu_states;
-
-static inline void set_sysmmu_active(sysmmu_ips ips)
-{
- sysmmu_states |= 3 << (ips * 2);
-}
-
-static inline void set_sysmmu_inactive(sysmmu_ips ips)
-{
- sysmmu_states &= ~(3 << (ips * 2));
-}
-
-static inline int is_sysmmu_active(sysmmu_ips ips)
-{
- return sysmmu_states & (3 << (ips * 2));
-}
-
-static void __iomem *sysmmusfrs[S5P_SYSMMU_TOTAL_IPNUM];
-
-static inline void sysmmu_block(sysmmu_ips ips)
-{
- __raw_writel(CTRL_BLOCK, sysmmusfrs[ips] + S5P_MMU_CTRL);
- dev_dbg(dev, "%s is blocked.\n", sysmmu_ips_name[ips]);
-}
-
-static inline void sysmmu_unblock(sysmmu_ips ips)
-{
- __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
- dev_dbg(dev, "%s is unblocked.\n", sysmmu_ips_name[ips]);
-}
-
-static inline void __sysmmu_tlb_invalidate(sysmmu_ips ips)
-{
- __raw_writel(0x1, sysmmusfrs[ips] + S5P_MMU_FLUSH);
- dev_dbg(dev, "TLB of %s is invalidated.\n", sysmmu_ips_name[ips]);
-}
-
-static inline void __sysmmu_set_ptbase(sysmmu_ips ips, unsigned long pgd)
-{
- if (unlikely(pgd == 0)) {
- pgd = (unsigned long)ZERO_PAGE(0);
- __raw_writel(0x20, sysmmusfrs[ips] + S5P_MMU_CFG); /* 4KB LV1 */
- } else {
- __raw_writel(0x0, sysmmusfrs[ips] + S5P_MMU_CFG); /* 16KB LV1 */
- }
-
- __raw_writel(pgd, sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
-
- dev_dbg(dev, "Page table base of %s is initialized with 0x%08lX.\n",
- sysmmu_ips_name[ips], pgd);
- __sysmmu_tlb_invalidate(ips);
-}
-
-void sysmmu_set_fault_handler(sysmmu_ips ips,
- int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
- unsigned long pgtable_base,
- unsigned long fault_addr))
-{
- BUG_ON(!((ips >= SYSMMU_MDMA) && (ips < S5P_SYSMMU_TOTAL_IPNUM)));
- fault_handlers[ips] = handler;
-}
-
-static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
-{
- /* SYSMMU is in blocked when interrupt occurred. */
- unsigned long base = 0;
- sysmmu_ips ips = (sysmmu_ips)dev_id;
- enum S5P_SYSMMU_INTERRUPT_TYPE itype;
-
- itype = (enum S5P_SYSMMU_INTERRUPT_TYPE)
- __ffs(__raw_readl(sysmmusfrs[ips] + S5P_INT_STATUS));
-
- BUG_ON(!((itype >= 0) && (itype < 8)));
-
- dev_alert(dev, "%s occurred by %s.\n", sysmmu_fault_name[itype],
- sysmmu_ips_name[ips]);
-
- if (fault_handlers[ips]) {
- unsigned long addr;
-
- base = __raw_readl(sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
- addr = __raw_readl(sysmmusfrs[ips] + fault_reg_offset[itype]);
-
- if (fault_handlers[ips](itype, base, addr)) {
- __raw_writel(1 << itype,
- sysmmusfrs[ips] + S5P_INT_CLEAR);
- dev_notice(dev, "%s from %s is resolved."
- " Retrying translation.\n",
- sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
- } else {
- base = 0;
- }
- }
-
- sysmmu_unblock(ips);
-
- if (!base)
- dev_notice(dev, "%s from %s is not handled.\n",
- sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
-
- return IRQ_HANDLED;
-}
-
-void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
-{
- if (is_sysmmu_active(ips)) {
- sysmmu_block(ips);
- __sysmmu_set_ptbase(ips, pgd);
- sysmmu_unblock(ips);
- } else {
- dev_dbg(dev, "%s is disabled. "
- "Skipping initializing page table base.\n",
- sysmmu_ips_name[ips]);
- }
-}
-
-void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd)
-{
- if (!is_sysmmu_active(ips)) {
- sysmmu_clk_enable(ips);
-
- __sysmmu_set_ptbase(ips, pgd);
-
- __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
-
- set_sysmmu_active(ips);
- dev_dbg(dev, "%s is enabled.\n", sysmmu_ips_name[ips]);
- } else {
- dev_dbg(dev, "%s is already enabled.\n", sysmmu_ips_name[ips]);
- }
-}
-
-void s5p_sysmmu_disable(sysmmu_ips ips)
-{
- if (is_sysmmu_active(ips)) {
- __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
- set_sysmmu_inactive(ips);
- sysmmu_clk_disable(ips);
- dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]);
- } else {
- dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]);
- }
-}
-
-void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
-{
- if (is_sysmmu_active(ips)) {
- sysmmu_block(ips);
- __sysmmu_tlb_invalidate(ips);
- sysmmu_unblock(ips);
- } else {
- dev_dbg(dev, "%s is disabled. "
- "Skipping invalidating TLB.\n", sysmmu_ips_name[ips]);
- }
-}
-
-static int s5p_sysmmu_probe(struct platform_device *pdev)
-{
- int i, ret;
- struct resource *res, *mem;
-
- dev = &pdev->dev;
-
- for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
- int irq;
-
- sysmmu_clk_init(dev, i);
- sysmmu_clk_disable(i);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
- if (!res) {
- dev_err(dev, "Failed to get the resource of %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENODEV;
- goto err_res;
- }
-
- mem = request_mem_region(res->start,
- ((res->end) - (res->start)) + 1, pdev->name);
- if (!mem) {
- dev_err(dev, "Failed to request the memory region of %s.\n",
- sysmmu_ips_name[i]);
- ret = -EBUSY;
- goto err_res;
- }
-
- sysmmusfrs[i] = ioremap(res->start, res->end - res->start + 1);
- if (!sysmmusfrs[i]) {
- dev_err(dev, "Failed to ioremap() for %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENXIO;
- goto err_reg;
- }
-
- irq = platform_get_irq(pdev, i);
- if (irq <= 0) {
- dev_err(dev, "Failed to get the IRQ resource of %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENOENT;
- goto err_map;
- }
-
- if (request_irq(irq, s5p_sysmmu_irq, IRQF_DISABLED,
- pdev->name, (void *)i)) {
- dev_err(dev, "Failed to request IRQ for %s.\n",
- sysmmu_ips_name[i]);
- ret = -ENOENT;
- goto err_map;
- }
- }
-
- return 0;
-
-err_map:
- iounmap(sysmmusfrs[i]);
-err_reg:
- release_mem_region(mem->start, resource_size(mem));
-err_res:
- return ret;
-}
-
-static int s5p_sysmmu_remove(struct platform_device *pdev)
-{
- return 0;
-}
-int s5p_sysmmu_runtime_suspend(struct device *dev)
-{
- return 0;
-}
-
-int s5p_sysmmu_runtime_resume(struct device *dev)
-{
- return 0;
-}
-
-const struct dev_pm_ops s5p_sysmmu_pm_ops = {
- .runtime_suspend = s5p_sysmmu_runtime_suspend,
- .runtime_resume = s5p_sysmmu_runtime_resume,
-};
-
-static struct platform_driver s5p_sysmmu_driver = {
- .probe = s5p_sysmmu_probe,
- .remove = s5p_sysmmu_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "s5p-sysmmu",
- .pm = &s5p_sysmmu_pm_ops,
- }
-};
-
-static int __init s5p_sysmmu_init(void)
-{
- return platform_driver_register(&s5p_sysmmu_driver);
-}
-arch_initcall(s5p_sysmmu_init);
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 4d79519..8c0b49f 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -15,6 +15,17 @@ config PLAT_SAMSUNG
if PLAT_SAMSUNG
+# vmalloc area and io map configurations
+
+comment "Base Address for SFR mapping"
+
+config S3C_ADDR_BASE
+ hex "S3C Base Address for SFR mapping"
+ default 0xF6000000
+ help
+ This value will be base address for S3C SFR mapping and
+ VMALLC_END should be less or euqal to this value.
+
# boot configurations
comment "Boot options"
@@ -149,6 +160,23 @@ config S3C_ADC
Core support for the ADC block found in the Samsung SoC systems
for drivers such as the touchscreen and hwmon to use to share
this resource.
+choice
+ prompt "Select ADC Number"
+ depends on S3C_ADC
+ default S3C_DEV_ADC
+
+config S3C_DEV_ADC
+ bool "ADC 0 selection"
+ depends on S3C_ADC
+ help
+ Say Y here if you want to use S3C SMDK ADC 0.
+
+config S3C_DEV_ADC1
+ bool "ADC 1 selection"
+ depends on S3C_ADC
+ help
+ Say Y here if you want to use S3C SMDK ADC 1.
+endchoice
# device definitions to compile in
@@ -172,6 +200,11 @@ config S3C_DEV_HSMMC3
help
Compile in platform device definitions for HSMMC channel 3
+config EXYNOS4_DEV_MSHC
+ bool
+ help
+ Compile in platform device definitions for MSHC
+
config S3C_DEV_HWMON
bool
help
@@ -212,6 +245,36 @@ config S3C_DEV_I2C7
help
Compile in platform device definition for I2C controller 7
+config S3C_DEV_I2C8_EMUL
+ depends on CPU_EXYNOS4210
+ bool "I2C8 Information GPIO bitbanging emulation"
+ help
+ Compile in platform device definitions for I2C channel 8
+
+config S3C_DEV_I2C9_EMUL
+ bool "I2C9 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 9
+
+config S3C_DEV_I2C11_EMUL
+ bool "I2C11 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 11
+
+config S3C_DEV_I2C14_EMUL
+ bool "I2C14 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 14
+
+config S3C_DEV_I2C16_EMUL
+ bool "I2C16 Information GPIO bitbanging emulation"
+ depends on CPU_EXYNOS4210
+ help
+ Compile in platform device definitions for I2C channel 16
+
config S3C_DEV_FB
bool
help
@@ -227,6 +290,12 @@ config S3C_DEV_USB_HSOTG
help
Compile in platform device definition for USB high-speed OtG
+config EXYNOS_DEV_SS_UDC
+ bool
+ help
+ Compile in platform device definition for EXYNOS SuperSpeed USB 3.0
+ Device controller
+
config S3C_DEV_WDT
bool
default y if ARCH_S3C2410
@@ -260,6 +329,7 @@ config SAMSUNG_DEV_IDE
config S3C64XX_DEV_SPI
bool
+ default y if SPI_S3C64XX
help
Compile in platform device definitions for S3C64XX's type
SPI controllers.
@@ -267,7 +337,12 @@ config S3C64XX_DEV_SPI
config SAMSUNG_DEV_TS
bool
help
- Common in platform device definitions for touchscreen device
+ Common in platform device definitions for touchscreen device
+
+config SAMSUNG_DEV_TS1
+ bool
+ help
+ Common in platform device definitions for touchscreen-1 device
config SAMSUNG_DEV_KEYPAD
bool
@@ -280,6 +355,12 @@ config SAMSUNG_DEV_PWM
help
Compile in platform device definition for PWM Timer
+config SAMSUNG_DEV_BACKLIGHT
+ bool
+ depends on SAMSUNG_DEV_PWM
+ help
+ Compile in platform device definition LCD backlight with PWM Timer
+
config S3C24XX_PWM
bool "PWM device support"
select HAVE_PWM
@@ -300,6 +381,12 @@ config S3C_PL330_DMA
help
S3C DMA API Driver for PL330 DMAC.
+config DMA_M2M_TEST
+ tristate "S3C DMA API Test client"
+ help
+ Samsung DMA API test client. Say N unless you're debugging a
+ DMA Device driver.
+
comment "Power management"
config SAMSUNG_PM_DEBUG
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 53eb15b..ab0fa91 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -11,7 +11,7 @@ obj- :=
# Objects we always build independent of SoC choice
-obj-y += init.o
+obj-y += init.o cpu.o
obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
obj-y += clock.o
obj-y += pwm-clock.o
@@ -36,6 +36,7 @@ obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o
+obj-$(CONFIG_EXYNOS4_DEV_MSHC) += dev-mshc.o
obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
@@ -50,6 +51,7 @@ obj-y += dev-uart.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
obj-$(CONFIG_S3C_DEV_WDT) += dev-wdt.o
+obj-$(CONFIG_EXYNOS_DEV_SS_UDC) += dev-usb3-exynos-drd.o
obj-$(CONFIG_S3C_DEV_NAND) += dev-nand.o
obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
@@ -57,8 +59,10 @@ obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o
obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o
obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o
+obj-$(CONFIG_SAMSUNG_DEV_TS1) += dev-ts1.o
obj-$(CONFIG_SAMSUNG_DEV_KEYPAD) += dev-keypad.o
-obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o
+obj-$(CONFIG_HAVE_PWM) += dev-pwm.o
+obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
# DMA support
@@ -66,6 +70,8 @@ obj-$(CONFIG_S3C_DMA) += dma.o
obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
+obj-$(CONFIG_DMA_M2M_TEST) += dma_m2m_test.o
+
# PM support
obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index e8f2be2..389e7e0 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -39,24 +39,28 @@
*/
enum s3c_cpu_type {
- TYPE_S3C24XX,
- TYPE_S3C64XX
+ TYPE_ADCV1, /* S3C24XX */
+ TYPE_ADCV2, /* S3C64XX, S5P64X0, S5PC100 */
+ TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
+ TYPE_ADCV4, /* EXYNOS4412, EXYNOS5250 */
};
struct s3c_adc_client {
struct platform_device *pdev;
- struct list_head pend;
+ struct list_head pend;
wait_queue_head_t *wait;
- unsigned int nr_samples;
- int result;
- unsigned char is_ts;
- unsigned char channel;
+ unsigned int nr_samples;
+ int result;
+ unsigned char is_ts;
+ unsigned char channel;
void (*select_cb)(struct s3c_adc_client *c, unsigned selected);
void (*convert_cb)(struct s3c_adc_client *c,
unsigned val1, unsigned val2,
unsigned *samples_left);
+ atomic_t running;
+ int error_count;
};
struct adc_device {
@@ -91,30 +95,37 @@ static inline void s3c_adc_select(struct adc_device *adc,
struct s3c_adc_client *client)
{
unsigned con = readl(adc->regs + S3C2410_ADCCON);
+ enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
client->select_cb(client, 1);
con &= ~S3C2410_ADCCON_MUXMASK;
con &= ~S3C2410_ADCCON_STDBM;
con &= ~S3C2410_ADCCON_STARTMASK;
-
- if (!client->is_ts)
- con |= S3C2410_ADCCON_SELMUX(client->channel);
+ con |= S3C2410_ADCCON_PRSCEN;
+
+ if (!client->is_ts) {
+ if (cpu >= TYPE_ADCV3)
+ writel(S5PV210_ADCCON_SELMUX(client->channel),
+ adc->regs + S5P_ADCMUX);
+ else
+ con |= S3C2410_ADCCON_SELMUX(client->channel);
+ }
writel(con, adc->regs + S3C2410_ADCCON);
}
static void s3c_adc_dbgshow(struct adc_device *adc)
{
- adc_dbg(adc, "CON=%08x, TSC=%08x, DLY=%08x\n",
+ adc_dbg(adc, "CON=%08x, DLY=%08x\n",
readl(adc->regs + S3C2410_ADCCON),
- readl(adc->regs + S3C2410_ADCTSC),
readl(adc->regs + S3C2410_ADCDLY));
}
static void s3c_adc_try(struct adc_device *adc)
{
struct s3c_adc_client *next = adc->ts_pend;
+ unsigned int con = readl(adc->regs + S3C2410_ADCCON);
if (!next && !list_empty(&adc_pending)) {
next = list_first_entry(&adc_pending,
@@ -129,25 +140,43 @@ static void s3c_adc_try(struct adc_device *adc)
s3c_adc_select(adc, next);
s3c_adc_convert(adc);
s3c_adc_dbgshow(adc);
+ } else {
+ con &= ~S3C2410_ADCCON_PRSCEN;
+ con |= S3C2410_ADCCON_STDBM;
+ writel(con, adc->regs + S3C2410_ADCCON);
}
}
+static void s3c_convert_done(struct s3c_adc_client *client,
+ unsigned v, unsigned u, unsigned *left)
+{
+ client->result = v;
+ wake_up(client->wait);
+}
+
int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples)
+ unsigned int channel, unsigned int nr_samples,
+ wait_queue_head_t *pwake)
{
struct adc_device *adc = adc_dev;
unsigned long flags;
- if (!adc) {
- printk(KERN_ERR "%s: failed to find adc\n", __func__);
- return -EINVAL;
- }
+ BUG_ON(!adc);
if (client->is_ts && adc->ts_pend)
return -EAGAIN;
+ if (atomic_xchg(&client->running, 1)) {
+ WARN(1, "%s: %p is already running\n", __func__, client);
+ return -EAGAIN;
+ }
+
spin_lock_irqsave(&adc->lock, flags);
+ client->convert_cb = s3c_convert_done;
+ client->wait = pwake;
+ client->result = -1;
+
client->channel = channel;
client->nr_samples = nr_samples;
@@ -165,30 +194,68 @@ int s3c_adc_start(struct s3c_adc_client *client,
}
EXPORT_SYMBOL_GPL(s3c_adc_start);
-static void s3c_convert_done(struct s3c_adc_client *client,
- unsigned v, unsigned u, unsigned *left)
+static void s3c_adc_stop(struct s3c_adc_client *client)
{
- client->result = v;
- wake_up(client->wait);
+ unsigned long flags;
+
+ spin_lock_irqsave(&adc_dev->lock, flags);
+
+ /* We should really check that nothing is in progress. */
+ if (adc_dev->cur == client)
+ adc_dev->cur = NULL;
+ if (adc_dev->ts_pend == client)
+ adc_dev->ts_pend = NULL;
+ else {
+ struct list_head *p, *n;
+ struct s3c_adc_client *tmp;
+
+ list_for_each_safe(p, n, &adc_pending) {
+ tmp = list_entry(p, struct s3c_adc_client, pend);
+ if (tmp == client)
+ list_del(&tmp->pend);
+ }
+ }
+
+ if (!atomic_xchg(&client->running, 0))
+ WARN(1, "%s: %p is already stopped\n", __func__, client);
+
+ if (adc_dev->cur == NULL)
+ s3c_adc_try(adc_dev);
+
+ spin_unlock_irqrestore(&adc_dev->lock, flags);
}
int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+ struct adc_device *adc = adc_dev;
+ unsigned long flags;
int ret;
- client->convert_cb = s3c_convert_done;
- client->wait = &wake;
- client->result = -1;
-
- ret = s3c_adc_start(client, ch, 1);
+ ret = s3c_adc_start(client, ch, 1, &wake);
if (ret < 0)
goto err;
ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
if (client->result < 0) {
+ s3c_adc_stop(client);
+ dev_warn(&adc_dev->pdev->dev, "%s: %p is timed out\n",
+ __func__, client);
+ ++client->error_count;
+ BUG_ON(client->error_count > 10);
ret = -ETIMEDOUT;
goto err;
+ } else {
+ client->error_count = 0;
+
+ spin_lock_irqsave(&adc->lock, flags);
+ /* client->result >=0 means s3c_adc_irq ->
+ s3c_convert_done is running or finished. Make sure
+ it is *finished* (not running) by lock/unlocking
+ spin lock. Otherwise, after return of this
+ function, wake_up() on destroyed 'wake' may be
+ executed which will destroy stack */
+ spin_unlock_irqrestore(&adc->lock, flags);
}
client->convert_cb = NULL;
@@ -239,30 +306,7 @@ EXPORT_SYMBOL_GPL(s3c_adc_register);
void s3c_adc_release(struct s3c_adc_client *client)
{
- unsigned long flags;
-
- spin_lock_irqsave(&adc_dev->lock, flags);
-
- /* We should really check that nothing is in progress. */
- if (adc_dev->cur == client)
- adc_dev->cur = NULL;
- if (adc_dev->ts_pend == client)
- adc_dev->ts_pend = NULL;
- else {
- struct list_head *p, *n;
- struct s3c_adc_client *tmp;
-
- list_for_each_safe(p, n, &adc_pending) {
- tmp = list_entry(p, struct s3c_adc_client, pend);
- if (tmp == client)
- list_del(&tmp->pend);
- }
- }
-
- if (adc_dev->cur == NULL)
- s3c_adc_try(adc_dev);
-
- spin_unlock_irqrestore(&adc_dev->lock, flags);
+ s3c_adc_stop(client);
kfree(client);
}
EXPORT_SYMBOL_GPL(s3c_adc_release);
@@ -272,50 +316,60 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
struct adc_device *adc = pw;
struct s3c_adc_client *client = adc->cur;
enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
- unsigned data0, data1;
+ unsigned data0 = 0, data1 = 0;
- if (!client) {
+ spin_lock(&adc->lock);
+
+ if (!client || !client->nr_samples) {
dev_warn(&adc->pdev->dev, "%s: no adc pending\n", __func__);
goto exit;
}
data0 = readl(adc->regs + S3C2410_ADCDAT0);
- data1 = readl(adc->regs + S3C2410_ADCDAT1);
+ if (cpu != TYPE_ADCV4)
+ data1 = readl(adc->regs + S3C2410_ADCDAT1);
+
adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
- client->nr_samples--;
+ if (client->nr_samples > 0)
+ client->nr_samples--;
- if (cpu == TYPE_S3C64XX) {
- /* S3C64XX ADC resolution is 12-bit */
- data0 &= 0xfff;
- data1 &= 0xfff;
- } else {
+ if (cpu == TYPE_ADCV1) {
data0 &= 0x3ff;
data1 &= 0x3ff;
+ } else {
+ /* S3C64XX/S5P ADC resolution is 12-bit */
+ data0 &= 0xfff;
+ data1 &= 0xfff;
}
if (client->convert_cb)
(client->convert_cb)(client, data0, data1, &client->nr_samples);
if (client->nr_samples > 0) {
- /* fire another conversion for this */
-
- client->select_cb(client, 1);
+ /* fire another conversion for this client */
+ (client->select_cb)(client, 1);
s3c_adc_convert(adc);
} else {
- spin_lock(&adc->lock);
+ /* finish conversion for this client */
(client->select_cb)(client, 0);
- adc->cur = NULL;
+ if (!atomic_xchg(&client->running, 0))
+ WARN(1, "%s: %p is already stopped\n", __func__,
+ client);
+ /* fire conversion for next client if any */
+ adc->cur = NULL;
s3c_adc_try(adc);
- spin_unlock(&adc->lock);
}
exit:
- if (cpu == TYPE_S3C64XX) {
+ if (cpu != TYPE_ADCV1) {
/* Clear ADC interrupt */
writel(0, adc->regs + S3C64XX_ADCCLRINT);
}
+
+ spin_unlock(&adc->lock);
+
return IRQ_HANDLED;
}
@@ -324,11 +378,12 @@ static int s3c_adc_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct adc_device *adc;
struct resource *regs;
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
int ret;
unsigned tmp;
adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
- if (adc == NULL) {
+ if (unlikely(adc == NULL)) {
dev_err(dev, "failed to allocate adc_device\n");
return -ENOMEM;
}
@@ -338,35 +393,22 @@ static int s3c_adc_probe(struct platform_device *pdev)
adc->pdev = pdev;
adc->prescale = S3C2410_ADCCON_PRSCVL(49);
- adc->irq = platform_get_irq(pdev, 1);
- if (adc->irq <= 0) {
- dev_err(dev, "failed to get adc irq\n");
- ret = -ENOENT;
- goto err_alloc;
- }
-
- ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
- if (ret < 0) {
- dev_err(dev, "failed to attach adc irq\n");
- goto err_alloc;
- }
-
- adc->clk = clk_get(dev, "adc");
- if (IS_ERR(adc->clk)) {
+ adc->clk = clk_get(NULL, "adc");
+ if (unlikely(IS_ERR(adc->clk))) {
dev_err(dev, "failed to get adc clock\n");
ret = PTR_ERR(adc->clk);
- goto err_irq;
+ goto err_alloc;
}
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
+ if (unlikely(!regs)) {
dev_err(dev, "failed to find registers\n");
ret = -ENXIO;
goto err_clk;
}
adc->regs = ioremap(regs->start, resource_size(regs));
- if (!adc->regs) {
+ if (unlikely(!adc->regs)) {
dev_err(dev, "failed to map registers\n");
ret = -ENXIO;
goto err_clk;
@@ -374,13 +416,35 @@ static int s3c_adc_probe(struct platform_device *pdev)
clk_enable(adc->clk);
+#if defined(CONFIG_S3C_DEV_ADC1)
+ tmp = readl(adc->regs + S3C2410_ADCCON);
+ tmp |= S3C64XX_ADCCON_TSSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->regs += 0x1000;
+#endif
+
tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
- if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
- /* Enable 12-bit ADC resolution */
+
+ /* Enable 12-bit ADC resolution */
+ if (cpu != TYPE_ADCV1) {
tmp |= S3C64XX_ADCCON_RESSEL;
}
+ tmp |= S3C2410_ADCCON_STDBM;
writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->irq = platform_get_irq(pdev, 1);
+ if (unlikely(adc->irq <= 0)) {
+ dev_err(dev, "failed to get adc irq\n");
+ ret = -ENOENT;
+ goto err_clk;
+ }
+
+ ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);
+ if (unlikely(ret < 0)) {
+ dev_err(dev, "failed to attach adc irq\n");
+ goto err_clk;
+ }
+
dev_info(dev, "attached adc driver\n");
platform_set_drvdata(pdev, adc);
@@ -391,9 +455,6 @@ static int s3c_adc_probe(struct platform_device *pdev)
err_clk:
clk_put(adc->clk);
- err_irq:
- free_irq(adc->irq, adc);
-
err_alloc:
kfree(adc);
return ret;
@@ -435,12 +496,24 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
static int s3c_adc_resume(struct platform_device *pdev)
{
struct adc_device *adc = platform_get_drvdata(pdev);
+ enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data;
+ unsigned int tmp = 0;
clk_enable(adc->clk);
enable_irq(adc->irq);
- writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
- adc->regs + S3C2410_ADCCON);
+#if defined(CONFIG_S3C_DEV_ADC1)
+ adc->regs -= 0x1000;
+ tmp = readl(adc->regs + S3C2410_ADCCON);
+ tmp |= S3C64XX_ADCCON_TSSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+ adc->regs += 0x1000;
+#endif
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+ /* Enable 12-bit ADC resolution */
+ if (cpu != TYPE_ADCV1)
+ tmp |= S3C64XX_ADCCON_RESSEL;
+ writel(tmp, adc->regs + S3C2410_ADCCON);
return 0;
}
@@ -452,11 +525,17 @@ static int s3c_adc_resume(struct platform_device *pdev)
static struct platform_device_id s3c_adc_driver_ids[] = {
{
- .name = "s3c24xx-adc",
- .driver_data = TYPE_S3C24XX,
+ .name = "s3c24xx-adc",
+ .driver_data = TYPE_ADCV1,
+ }, {
+ .name = "s3c64xx-adc",
+ .driver_data = TYPE_ADCV2,
+ }, {
+ .name = "samsung-adc-v3",
+ .driver_data = TYPE_ADCV3,
}, {
- .name = "s3c64xx-adc",
- .driver_data = TYPE_S3C64XX,
+ .name = "samsung-adc-v4",
+ .driver_data = TYPE_ADCV4,
},
{ }
};
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 7728928..40454d7 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -27,7 +27,6 @@
*/
#include <linux/init.h>
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
@@ -64,108 +63,55 @@ static LIST_HEAD(clocks);
*/
DEFINE_SPINLOCK(clocks_lock);
-/* enable and disable calls for use with the clk struct */
-
-static int clk_null_enable(struct clk *clk, int enable)
-{
- return 0;
-}
-
-static int dev_is_s3c_uart(struct device *dev)
+/* Global watchdog clock used by arch_wtd_reset() callback */
+struct clk *s3c2410_wdtclk;
+static int __init s3c_wdt_reset_init(void)
{
- struct platform_device **pdev = s3c24xx_uart_devs;
- int i;
- for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
- if (*pdev && dev == &(*pdev)->dev)
- return 1;
+ s3c2410_wdtclk = clk_get(NULL, "watchdog");
+ if (IS_ERR(s3c2410_wdtclk))
+ printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
return 0;
}
+arch_initcall(s3c_wdt_reset_init);
-/*
- * Serial drivers call get_clock() very early, before platform bus
- * has been set up, this requires a special check to let them get
- * a proper clock
- */
-
-static int dev_is_platform_device(struct device *dev)
-{
- return dev->bus == &platform_bus_type ||
- (dev->bus == NULL && dev_is_s3c_uart(dev));
-}
-
-/* Clock API calls */
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
- struct clk *p;
- struct clk *clk = ERR_PTR(-ENOENT);
- int idno;
-
- if (dev == NULL || !dev_is_platform_device(dev))
- idno = -1;
- else
- idno = to_platform_device(dev)->id;
-
- spin_lock(&clocks_lock);
-
- list_for_each_entry(p, &clocks, list) {
- if (p->id == idno &&
- strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
-
- /* check for the case where a device was supplied, but the
- * clock that was being searched for is not device specific */
-
- if (IS_ERR(clk)) {
- list_for_each_entry(p, &clocks, list) {
- if (p->id == -1 && strcmp(id, p->name) == 0 &&
- try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
- }
-
- spin_unlock(&clocks_lock);
- return clk;
-}
+/* enable and disable calls for use with the clk struct */
-void clk_put(struct clk *clk)
+static int clk_null_enable(struct clk *clk, int enable)
{
- module_put(clk->owner);
+ return 0;
}
int clk_enable(struct clk *clk)
{
+ unsigned long flags;
+
if (IS_ERR(clk) || clk == NULL)
return -EINVAL;
clk_enable(clk->parent);
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if ((clk->usage++) == 0)
(clk->enable)(clk, 1);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
void clk_disable(struct clk *clk)
{
+ unsigned long flags;
+
if (IS_ERR(clk) || clk == NULL)
return;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if ((--clk->usage) == 0)
(clk->enable)(clk, 0);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
clk_disable(clk->parent);
}
@@ -197,6 +143,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ unsigned long flags;
int ret;
if (IS_ERR(clk))
@@ -212,9 +159,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
if (clk->ops == NULL || clk->ops->set_rate == NULL)
return -EINVAL;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
ret = (clk->ops->set_rate)(clk, rate);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return ret;
}
@@ -226,23 +173,22 @@ struct clk *clk_get_parent(struct clk *clk)
int clk_set_parent(struct clk *clk, struct clk *parent)
{
+ unsigned long flags;
int ret = 0;
if (IS_ERR(clk))
return -EINVAL;
- spin_lock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
if (clk->ops && clk->ops->set_parent)
ret = (clk->ops->set_parent)(clk, parent);
- spin_unlock(&clocks_lock);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return ret;
}
-EXPORT_SYMBOL(clk_get);
-EXPORT_SYMBOL(clk_put);
EXPORT_SYMBOL(clk_enable);
EXPORT_SYMBOL(clk_disable);
EXPORT_SYMBOL(clk_get_rate);
@@ -343,17 +289,20 @@ struct clk s3c24xx_uclk = {
*/
int s3c24xx_register_clock(struct clk *clk)
{
+ unsigned long flags;
+
if (clk->enable == NULL)
clk->enable = clk_null_enable;
- /* add to the list of available clocks */
+ /* fill up the clk_lookup structure and register it*/
+ clk->lookup.dev_id = clk->devname;
+ clk->lookup.con_id = clk->name;
+ clk->lookup.clk = clk;
+ clkdev_add(&clk->lookup);
- /* Quick check to see if this clock has already been registered. */
- BUG_ON(clk->list.prev != clk->list.next);
-
- spin_lock(&clocks_lock);
- list_add(&clk->list, &clocks);
- spin_unlock(&clocks_lock);
+ spin_lock_irqsave(&clocks_lock, flags);
+ list_add_tail(&clk->list, &clocks);
+ spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
@@ -458,15 +407,12 @@ static struct dentry *clk_debugfs_root;
static int clk_debugfs_register_one(struct clk *c)
{
int err;
- struct dentry *d, *child, *child_tmp;
+ struct dentry *d;
struct clk *pa = c->parent;
char s[255];
char *p = s;
- p += sprintf(p, "%s", c->name);
-
- if (c->id >= 0)
- sprintf(p, ":%d", c->id);
+ p += sprintf(p, "%s", c->devname ?: c->name);
d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
if (!d)
@@ -488,10 +434,7 @@ static int clk_debugfs_register_one(struct clk *c)
return 0;
err_out:
- d = c->dent;
- list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
- debugfs_remove(child);
- debugfs_remove(c->dent);
+ debugfs_remove_recursive(c->dent);
return err;
}
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
new file mode 100644
index 0000000..81c06d4
--- /dev/null
+++ b/arch/arm/plat-samsung/cpu.c
@@ -0,0 +1,58 @@
+/* linux/arch/arm/plat-samsung/cpu.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CPU Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+
+unsigned long samsung_cpu_id;
+static unsigned int samsung_cpu_rev;
+
+unsigned int samsung_rev(void)
+{
+ return samsung_cpu_rev;
+}
+EXPORT_SYMBOL(samsung_rev);
+
+void __init s3c24xx_init_cpu(void)
+{
+ /* nothing here yet */
+
+ samsung_cpu_rev = 0;
+}
+
+void __init s3c64xx_init_cpu(void)
+{
+ samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0x118);
+ if (!samsung_cpu_id) {
+ /*
+ * S3C6400 has the ID register in a different place,
+ * and needs a write before it can be read.
+ */
+ __raw_writel(0x0, S3C_VA_SYS + 0xA1C);
+ samsung_cpu_id = __raw_readl(S3C_VA_SYS + 0xA1C);
+ }
+
+ samsung_cpu_rev = 0;
+}
+
+void __init s5p_init_cpu(void __iomem *cpuid_addr)
+{
+ samsung_cpu_id = __raw_readl(cpuid_addr);
+ samsung_cpu_rev = samsung_cpu_id & 0xFF;
+}
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
index 9d903d4..d9d0357 100644
--- a/arch/arm/plat-samsung/dev-adc.c
+++ b/arch/arm/plat-samsung/dev-adc.c
@@ -23,12 +23,14 @@
static struct resource s3c_adc_resource[] = {
[0] = {
.start = SAMSUNG_PA_ADC,
- .end = SAMSUNG_PA_ADC + SZ_256 - 1,
+ .end = SAMSUNG_PA_ADC + SZ_8K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+#if defined(CONFIG_TOUCHSCREEN_S3C2410)
.start = IRQ_TC,
.end = IRQ_TC,
+#endif
.flags = IORESOURCE_IRQ,
},
[2] = {
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
index a068c4f..aabee5e 100644
--- a/arch/arm/plat-samsung/dev-asocdma.c
+++ b/arch/arm/plat-samsung/dev-asocdma.c
@@ -23,3 +23,17 @@ struct platform_device samsung_asoc_dma = {
}
};
EXPORT_SYMBOL(samsung_asoc_dma);
+
+#ifndef CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER
+static u64 audio_idmamask = DMA_BIT_MASK(32);
+
+struct platform_device samsung_asoc_idma = {
+ .name = "samsung-audio-idma",
+ .id = -1,
+ .dev = {
+ .dma_mask = &audio_idmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+EXPORT_SYMBOL(samsung_asoc_idma);
+#endif \ No newline at end of file
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
new file mode 100644
index 0000000..8ebb41c
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -0,0 +1,149 @@
+/* linux/arch/arm/plat-samsung/dev-backlight.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Common infrastructure for PWM Backlight for Samsung boards
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/pwm_backlight.h>
+
+#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
+#include <plat/backlight.h>
+
+static int samsung_bl_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *timer_dev =
+ container_of(dev->parent, struct platform_device, dev);
+ struct samsung_bl_gpio_info *bl_gpio_info =
+ timer_dev->dev.platform_data;
+
+ ret = gpio_request(bl_gpio_info->no, "Backlight");
+ if (ret) {
+ printk(KERN_ERR "failed to request GPIO for LCD Backlight\n");
+ return ret;
+ }
+
+ /* Configure GPIO pin with specific GPIO function for PWM timer */
+ s3c_gpio_cfgpin(bl_gpio_info->no, bl_gpio_info->func);
+
+ return 0;
+}
+
+static void samsung_bl_exit(struct device *dev)
+{
+ struct platform_device *timer_dev =
+ container_of(dev->parent, struct platform_device, dev);
+ struct samsung_bl_gpio_info *bl_gpio_info =
+ timer_dev->dev.platform_data;
+
+ s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT);
+ gpio_free(bl_gpio_info->no);
+}
+
+/* Initialize few important fields of platform_pwm_backlight_data
+ * structure with default values. These fields can be overridden by
+ * board-specific values sent from machine file.
+ * For ease of operation, these fields are initialized with values
+ * used by most samsung boards.
+ * Users has the option of sending info about other parameters
+ * for their specific boards
+ */
+
+static struct platform_pwm_backlight_data samsung_dfl_bl_data = {
+ .max_brightness = 255,
+ .dft_brightness = 255,
+ .pwm_period_ns = 78770,
+ .init = samsung_bl_init,
+ .exit = samsung_bl_exit,
+};
+
+static struct platform_device samsung_dfl_bl_device = {
+ .name = "pwm-backlight",
+};
+
+/* samsung_bl_set - Set board specific data (if any) provided by user for
+ * PWM Backlight control and register specific PWM and backlight device.
+ * @gpio_info: structure containing GPIO info for PWM timer
+ * @bl_data: structure containing Backlight control data
+ */
+void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+ struct platform_pwm_backlight_data *bl_data)
+{
+ int ret = 0;
+ struct platform_device *samsung_bl_device;
+ struct platform_pwm_backlight_data *samsung_bl_data;
+
+ samsung_bl_device = kmemdup(&samsung_dfl_bl_device,
+ sizeof(struct platform_device), GFP_KERNEL);
+ if (!samsung_bl_device) {
+ printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
+ return;
+ }
+
+ samsung_bl_data = s3c_set_platdata(&samsung_dfl_bl_data,
+ sizeof(struct platform_pwm_backlight_data), samsung_bl_device);
+ if (!samsung_bl_data) {
+ printk(KERN_ERR "%s: no memory for platform dev\n", __func__);
+ goto err_data;
+ }
+
+ /* Copy board specific data provided by user */
+ samsung_bl_data->pwm_id = bl_data->pwm_id;
+ samsung_bl_device->dev.parent =
+ &s3c_device_timer[samsung_bl_data->pwm_id].dev;
+
+ if (bl_data->max_brightness)
+ samsung_bl_data->max_brightness = bl_data->max_brightness;
+ if (bl_data->dft_brightness)
+ samsung_bl_data->dft_brightness = bl_data->dft_brightness;
+ if (bl_data->lth_brightness)
+ samsung_bl_data->lth_brightness = bl_data->lth_brightness;
+ if (bl_data->pwm_period_ns)
+ samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns;
+ if (bl_data->init)
+ samsung_bl_data->init = bl_data->init;
+ if (bl_data->notify)
+ samsung_bl_data->notify = bl_data->notify;
+ if (bl_data->exit)
+ samsung_bl_data->exit = bl_data->exit;
+ if (bl_data->check_fb)
+ samsung_bl_data->check_fb = bl_data->check_fb;
+
+ /* Keep the GPIO info for future use */
+ s3c_device_timer[samsung_bl_data->pwm_id].dev.platform_data = gpio_info;
+
+ /* Register the specific PWM timer dev for Backlight control */
+ ret = platform_device_register(
+ &s3c_device_timer[samsung_bl_data->pwm_id]);
+ if (ret) {
+ printk(KERN_ERR "failed to register pwm timer for backlight: %d\n", ret);
+ goto err_plat_reg1;
+ }
+
+ /* Register the Backlight dev */
+ ret = platform_device_register(samsung_bl_device);
+ if (ret) {
+ printk(KERN_ERR "failed to register backlight device: %d\n", ret);
+ goto err_plat_reg2;
+ }
+
+ return;
+
+err_plat_reg2:
+ platform_device_unregister(&s3c_device_timer[samsung_bl_data->pwm_id]);
+err_plat_reg1:
+ kfree(samsung_bl_data);
+err_data:
+ kfree(samsung_bl_device);
+ return;
+}
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
index bf60204..49a1362 100644
--- a/arch/arm/plat-samsung/dev-fb.c
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -58,16 +58,6 @@ struct platform_device s3c_device_fb = {
void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
{
- struct s3c_fb_platdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_fb_platdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_fb.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
+ &s3c_device_fb);
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index db7a65c..e5ee2df 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -65,7 +65,10 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index 2497321..40160c6 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -65,6 +65,7 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
if (pd->max_width)
set->max_width = pd->max_width;
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index f60aedb..27bd631 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -20,6 +20,7 @@
#include <mach/map.h>
#include <plat/sdhci.h>
#include <plat/devs.h>
+#include <plat/gpio-cfg.h>
#define S3C_SZ_HSMMC (0x1000)
@@ -65,8 +66,15 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
+ /* if it uses eint as cd pin, pull up/down value of eint port
+ should be NONE */
+ if (pd->ext_cd_gpio)
+ s3c_gpio_setpull(pd->ext_cd_gpio, S3C_GPIO_PULL_NONE);
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index ede776f..1973ef4 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -69,6 +69,13 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->pm_flags = pd->pm_flags;
+
+ if (pd->vmmc_name)
+ set->vmmc_name = pd->vmmc_name;
+#ifdef CONFIG_MACH_PX
+ set->ext_pdev = pd->ext_pdev;
+#endif
if (pd->max_width)
set->max_width = pd->max_width;
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
index b3ffb95..c91a79c 100644
--- a/arch/arm/plat-samsung/dev-hwmon.c
+++ b/arch/arm/plat-samsung/dev-hwmon.c
@@ -27,16 +27,6 @@ struct platform_device s3c_device_hwmon = {
void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
{
- struct s3c_hwmon_pdata *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_hwmon.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c_hwmon_pdata),
+ &s3c_device_hwmon);
}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
index 3a601c1..1edd343 100644
--- a/arch/arm/plat-samsung/dev-i2c0.c
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -48,10 +48,10 @@ struct platform_device s3c_device_i2c0 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
+struct s3c2410_platform_i2c default_i2c_data __initdata = {
.flags = 0,
.slave_addr = 0x10,
- .frequency = 100*1000,
+ .frequency = 400*1000,
.sda_delay = 100,
};
@@ -60,13 +60,11 @@ void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
struct s3c2410_platform_i2c *npd;
if (!pd)
- pd = &default_i2c_data0;
+ pd = &default_i2c_data;
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c0_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c0);
- s3c_device_i2c0.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c0_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
index 858ee2a..3b7c7be 100644
--- a/arch/arm/plat-samsung/dev-i2c1.c
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -44,26 +44,18 @@ struct platform_device s3c_device_i2c1 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data1 __initdata = {
- .flags = 0,
- .bus_num = 1,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data1;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 1;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c1_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c1);
- s3c_device_i2c1.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c1_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
index ff4ba69..07e9fd0 100644
--- a/arch/arm/plat-samsung/dev-i2c2.c
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -45,26 +45,18 @@ struct platform_device s3c_device_i2c2 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data2 __initdata = {
- .flags = 0,
- .bus_num = 2,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data2;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 2;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c2_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c2);
- s3c_device_i2c2.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c2_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
index 8586a10..d48efa9 100644
--- a/arch/arm/plat-samsung/dev-i2c3.c
+++ b/arch/arm/plat-samsung/dev-i2c3.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c3 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
- .flags = 0,
- .bus_num = 3,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data3;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 3;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c3);
- s3c_device_i2c3.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c3_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
index df2159e..07e2644 100644
--- a/arch/arm/plat-samsung/dev-i2c4.c
+++ b/arch/arm/plat-samsung/dev-i2c4.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c4 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
- .flags = 0,
- .bus_num = 4,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data4;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 4;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c4);
- s3c_device_i2c4.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c4_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
index 0499c2c..f496557 100644
--- a/arch/arm/plat-samsung/dev-i2c5.c
+++ b/arch/arm/plat-samsung/dev-i2c5.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c5 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
- .flags = 0,
- .bus_num = 5,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data5;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 5;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c5);
- s3c_device_i2c5.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c5_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
index 4083108..141d799 100644
--- a/arch/arm/plat-samsung/dev-i2c6.c
+++ b/arch/arm/plat-samsung/dev-i2c6.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c6 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
- .flags = 0,
- .bus_num = 6,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data6;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 6;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c6);
- s3c_device_i2c6.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c6_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
index 1182451..9dddcd1 100644
--- a/arch/arm/plat-samsung/dev-i2c7.c
+++ b/arch/arm/plat-samsung/dev-i2c7.c
@@ -43,26 +43,18 @@ struct platform_device s3c_device_i2c7 = {
.resource = s3c_i2c_resource,
};
-static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
- .flags = 0,
- .bus_num = 7,
- .slave_addr = 0x10,
- .frequency = 100*1000,
- .sda_delay = 100,
-};
-
void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
- if (!pd)
- pd = &default_i2c_data7;
+ if (!pd) {
+ pd = &default_i2c_data;
+ pd->bus_num = 7;
+ }
- npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
- else if (!npd->cfg_gpio)
- npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+ npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
+ &s3c_device_i2c7);
- s3c_device_i2c7.dev.platform_data = npd;
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c7_cfg_gpio;
}
diff --git a/arch/arm/plat-samsung/dev-mshc.c b/arch/arm/plat-samsung/dev-mshc.c
new file mode 100644
index 0000000..ca2cbf8
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-mshc.c
@@ -0,0 +1,101 @@
+/* linux/arch/arm/plat-samsung/dev-mshc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Based on arch/arm/plat-samsung/dev-hsmmc1.c
+ *
+ * Device definition for mshc devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/mshci.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/exynos4.h>
+
+#define S5P_SZ_MSHC (0x1000)
+
+static struct resource s3c_mshci_resource[] = {
+ [0] = {
+ .start = EXYNOS_PA_DWMCI,
+ .end = EXYNOS_PA_DWMCI + S5P_SZ_MSHC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DWMCI,
+ .end = IRQ_DWMCI,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
+
+struct s3c_mshci_platdata s3c_mshci_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_mshci = {
+ .name = "dw_mmc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_mshci_resource),
+ .resource = s3c_mshci_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_mshci_def_platdata,
+ },
+};
+
+
+void s3c_mshci_set_platdata(struct s3c_mshci_platdata *pd)
+{
+ struct s3c_mshci_platdata *set = &s3c_mshci_def_platdata;
+
+ set->cd_type = pd->cd_type;
+ set->ext_cd_init = pd->ext_cd_init;
+ set->ext_cd_cleanup = pd->ext_cd_cleanup;
+ set->ext_cd_gpio = pd->ext_cd_gpio;
+ set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
+ set->wp_gpio = pd->wp_gpio;
+ set->has_wp_gpio = pd->has_wp_gpio;
+ set->int_power_gpio = pd->int_power_gpio;
+ if(pd->fifo_depth)
+ set->fifo_depth = pd->fifo_depth;
+ else
+ set->fifo_depth = 0x20; /* exynos4210 size. */
+
+ if (pd->max_width)
+ set->max_width = pd->max_width;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->host_caps2)
+ set->host_caps2 |= pd->host_caps2;
+ if (soc_is_exynos4210()) {
+ if (pd->host_caps && samsung_rev() < EXYNOS4210_REV_1_1) {
+ printk(KERN_INFO "MSHC: This exynos4 is EVT1.0. "
+ "Disable DDR R/W for eMMC.\n");
+ set->host_caps &= ~(MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50);
+ }
+ }
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+ if (pd->cfg_ddr)
+ set->cfg_ddr = pd->cfg_ddr;
+ if (pd->init_card)
+ set->init_card = pd->init_card;
+}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
index 6927ae8..b8e30ec 100644
--- a/arch/arm/plat-samsung/dev-nand.c
+++ b/arch/arm/plat-samsung/dev-nand.c
@@ -91,11 +91,10 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
* time then there is little chance the system is going to run.
*/
- npd = kmemdup(nand, sizeof(struct s3c2410_platform_nand), GFP_KERNEL);
- if (!npd) {
- printk(KERN_ERR "%s: failed copying platform data\n", __func__);
+ npd = s3c_set_platdata(nand, sizeof(struct s3c2410_platform_nand),
+ &s3c_device_nand);
+ if (!npd)
return;
- }
/* now see if we need to copy any of the nand set data */
@@ -123,6 +122,4 @@ void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
to++;
}
}
-
- s3c_device_nand.dev.platform_data = npd;
}
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
index dab47b0..cda8e47 100644
--- a/arch/arm/plat-samsung/dev-pwm.c
+++ b/arch/arm/plat-samsung/dev-pwm.c
@@ -20,6 +20,7 @@
#include <mach/irqs.h>
#include <plat/devs.h>
+#include <mach/gpio.h>
#define TIMER_RESOURCE_SIZE (1)
@@ -32,22 +33,88 @@
} \
}
-#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
- .name = "s3c24xx-pwm", \
- .id = _tmr_no, \
- .num_resources = TIMER_RESOURCE_SIZE, \
- .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+#define DEFINE_S3C_TIMER(_tmr_no, _irq, _plat_data) \
+ .name = "s3c24xx-pwm", \
+ .id = _tmr_no, \
+ .num_resources = TIMER_RESOURCE_SIZE, \
+ .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+ .dev = { \
+ .platform_data = _plat_data, \
+ }
+
+#define GPD0_0_TOUT (0x2 << 0)
+#ifdef CONFIG_FB_MDNIE_PWM
+#define GPD0_1_TOUT (0x3 << 4)
+#else
+#define GPD0_1_TOUT (0x2 << 4)
+#endif
+#define GPD0_2_TOUT (0x2 << 8)
+#define GPD0_3_TOUT (0x2 << 12)
-/*
- * since we already have an static mapping for the timer,
- * we do not bother setting any IO resource for the base.
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
*/
+struct s3c_pwm_pdata {
+ /* PWM output port */
+ int gpio_no;
+ const char *gpio_name;
+ int gpio_set_value;
+};
+
+struct s3c_pwm_pdata pwm_data[] = {
+#ifdef CONFIG_ARCH_EXYNOS5
+ {
+ .gpio_no = EXYNOS5_GPB2(0),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_0_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(1),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_1_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(2),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_2_TOUT,
+ }, {
+ .gpio_no = EXYNOS5_GPB2(3),
+ .gpio_name = "GPB",
+ .gpio_set_value = GPD0_3_TOUT,
+ }, {
+ .gpio_no = 0,
+ .gpio_name = NULL,
+ .gpio_set_value = 0,
+ }
+#else
+ {
+ .gpio_no = EXYNOS4_GPD0(0),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_0_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(1),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_1_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(2),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_2_TOUT,
+ }, {
+ .gpio_no = EXYNOS4_GPD0(3),
+ .gpio_name = "GPD",
+ .gpio_set_value = GPD0_3_TOUT,
+ }, {
+ .gpio_no = 0,
+ .gpio_name = NULL,
+ .gpio_set_value = 0,
+ }
+#endif
+};
+
struct platform_device s3c_device_timer[] = {
- [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
- [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
- [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
- [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
- [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+ [0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0, &pwm_data[0]) },
+ [1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1, &pwm_data[1]) },
+ [2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2, &pwm_data[2]) },
+ [3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3, &pwm_data[3]) },
+ [4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4, &pwm_data[4]) },
};
EXPORT_SYMBOL(s3c_device_timer);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
index 3e4bd81..f9af090 100644
--- a/arch/arm/plat-samsung/dev-ts.c
+++ b/arch/arm/plat-samsung/dev-ts.c
@@ -38,23 +38,13 @@ static struct resource s3c_ts_resource[] = {
struct platform_device s3c_device_ts = {
.name = "s3c64xx-ts",
- .id = -1,
+ .id = 0,
.num_resources = ARRAY_SIZE(s3c_ts_resource),
.resource = s3c_ts_resource,
};
void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
{
- struct s3c2410_ts_mach_info *npd;
-
- if (!pd) {
- printk(KERN_ERR "%s: no platform data\n", __func__);
- return;
- }
-
- npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_ts.dev.platform_data = npd;
+ s3c_set_platdata(pd, sizeof(struct s3c2410_ts_mach_info),
+ &s3c_device_ts);
}
diff --git a/arch/arm/plat-samsung/dev-ts1.c b/arch/arm/plat-samsung/dev-ts1.c
new file mode 100644
index 0000000..99cc63f
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ts1.c
@@ -0,0 +1,60 @@
+/* linux/arch/arm/plat-samsung/dev-ts1.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Adapted by Maurus Cuelenaere for s3c64xx
+ *
+ * S3C64XX series device definition for touchscreen device
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/ts.h>
+
+static struct resource s3c_ts_resource[] = {
+ [0] = {
+ .start = SAMSUNG_PA_ADC1,
+ .end = SAMSUNG_PA_ADC1 + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PEN1,
+ .end = IRQ_PEN1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_ts1 = {
+ .name = "s3c64xx-ts",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_ts_resource),
+ .resource = s3c_ts_resource,
+};
+
+void __init s3c24xx_ts1_set_platdata(struct s3c2410_ts_mach_info *pd)
+{
+ struct s3c2410_ts_mach_info *npd;
+
+ if (!pd) {
+ printk(KERN_ERR "%s: no platform data\n", __func__);
+ return;
+ }
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+ s3c_device_ts1.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
index 0e0a3bf..33fbaa9 100644
--- a/arch/arm/plat-samsung/dev-usb.c
+++ b/arch/arm/plat-samsung/dev-usb.c
@@ -60,11 +60,6 @@ EXPORT_SYMBOL(s3c_device_ohci);
*/
void __init s3c_ohci_set_platdata(struct s3c2410_hcd_info *info)
{
- struct s3c2410_hcd_info *npd;
-
- npd = kmemdup(info, sizeof(struct s3c2410_hcd_info), GFP_KERNEL);
- if (!npd)
- printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-
- s3c_device_ohci.dev.platform_data = npd;
+ s3c_set_platdata(info, sizeof(struct s3c2410_hcd_info),
+ &s3c_device_ohci);
}
diff --git a/arch/arm/plat-samsung/dev-usb3-exynos-drd.c b/arch/arm/plat-samsung/dev-usb3-exynos-drd.c
new file mode 100644
index 0000000..6ce72c4
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb3-exynos-drd.c
@@ -0,0 +1,103 @@
+/* arch/arm/plat-samsung/dev-usb3-dwc-drd.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co. Ltd
+ * Author: Anton Tikhomirov <av.tikhomirov@samsung.com>
+ *
+ * Device definition for EXYNOS SuperSpeed USB 3.0 DRD Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/platform_data/exynos_usb3_drd.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/usb-phy.h>
+
+static struct resource exynos_ss_udc_resources[] = {
+ [0] = {
+ .start = EXYNOS5_PA_SS_DRD,
+ .end = EXYNOS5_PA_SS_DRD + 0x100000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB3_DRD,
+ .end = IRQ_USB3_DRD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource exynos_xhci_resources[] = {
+ [0] = {
+ .start = EXYNOS5_PA_SS_DRD,
+ .end = EXYNOS5_PA_SS_DRD + 0x100000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB3_DRD,
+ .end = IRQ_USB3_DRD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 exynos_ss_udc_dmamask = DMA_BIT_MASK(32);
+static u64 exynos_xhci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos_device_ss_udc = {
+ .name = "exynos-ss-udc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_ss_udc_resources),
+ .resource = exynos_ss_udc_resources,
+ .dev = {
+ .dma_mask = &exynos_ss_udc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device exynos_device_xhci = {
+ .name = "exynos-xhci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(exynos_xhci_resources),
+ .resource = exynos_xhci_resources,
+ .dev = {
+ .dma_mask = &exynos_xhci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init exynos_ss_udc_set_platdata(struct exynos_usb3_drd_pdata *pd)
+{
+ struct exynos_usb3_drd_pdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct exynos_usb3_drd_pdata),
+ &exynos_device_ss_udc);
+
+ npd->phy_type = S5P_USB_PHY_DRD;
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+}
+
+void __init exynos_xhci_set_platdata(struct exynos_usb3_drd_pdata *pd)
+{
+ struct exynos_usb3_drd_pdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct exynos_usb3_drd_pdata),
+ &exynos_device_xhci);
+
+ npd->phy_type = S5P_USB_PHY_DRD;
+ if (!npd->phy_init)
+ npd->phy_init = s5p_usb_phy_init;
+ if (!npd->phy_exit)
+ npd->phy_exit = s5p_usb_phy_exit;
+}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
index 019b5b8..c9d8f2c 100644
--- a/arch/arm/plat-samsung/dev-wdt.c
+++ b/arch/arm/plat-samsung/dev-wdt.c
@@ -21,7 +21,7 @@
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C_PA_WDT,
- .end = S3C_PA_WDT + SZ_1K,
+ .end = S3C_PA_WDT + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/plat-samsung/dma_m2m_test.c b/arch/arm/plat-samsung/dma_m2m_test.c
new file mode 100644
index 0000000..b1ca128
--- /dev/null
+++ b/arch/arm/plat-samsung/dma_m2m_test.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * MemToMem DMA Xfer Test Driver for S3C DMA API
+ *
+ */
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/dma.h>
+
+#define XFER_UNIT 1024
+
+static unsigned int xfer_size = 256;
+module_param(xfer_size, uint, S_IRUGO);
+MODULE_PARM_DESC(xfer_size, "Size of each DMA enqueue request in KB");
+
+#define DMATEST_BRSTSZ 1
+static unsigned short burst = 1;
+module_param(burst, ushort, S_IRUGO);
+MODULE_PARM_DESC(burst, "For which parts of API to calc performance");
+
+static unsigned short perf_test = 1;
+module_param(perf_test, ushort, S_IRUGO);
+MODULE_PARM_DESC(perf_test, "For which parts of API to calc performance");
+
+static unsigned int sec = 60 * 60; /* 1 hour by default */
+module_param(sec, uint, S_IRUGO);
+MODULE_PARM_DESC(sec, "Number of seconds to run the test (default: 24hr)");
+
+static unsigned int channels = 10000; /* Use all channels by default */
+module_param(channels, uint, S_IRUGO);
+MODULE_PARM_DESC(channels, "Number of channels to test (default: 8)");
+
+struct s3cdma_thread {
+ unsigned id; /* For Channel index */
+ struct task_struct *task;
+#define SRC 0
+#define DST 1
+ void *buff_cpu[2]; /* CPU address of the Source & Destination buffer */
+ dma_addr_t buff_phys[2]; /* Physical address of the Source & Destination buffer */
+ unsigned long jiffies;
+ int stopped;
+ enum s3c2410_dma_buffresult res;
+ int size;
+ unsigned done;
+ struct s3c2410_dma_client cl;
+ struct completion xfer_cmplt;
+ struct list_head node;
+};
+
+static unsigned int delta;
+static unsigned long cycles, maxtime;
+static LIST_HEAD(channel_list);
+
+void s3cdma_cb(struct s3c2410_dma_chan *chan, void *buf_id,
+ int size, enum s3c2410_dma_buffresult res)
+{
+ struct s3cdma_thread *thread = buf_id;
+
+ thread->res = res;
+ thread->size = size;
+
+ complete(&thread->xfer_cmplt);
+}
+
+static void dmatest_init_buf(u32 buf[], int clr, unsigned int bytes)
+{
+ unsigned int i;
+
+ for (i = 0; i < bytes / 4; i++)
+ buf[i] = clr ? 0 : i;
+}
+
+static bool dmatest_buf_same(u32 src[], u32 dst[], unsigned int bytes)
+{
+ unsigned int i;
+
+ for (i = 0; i < (bytes - delta) / 4; i++)
+ if (src[i] != dst[i])
+ return false;
+
+ for (; i < bytes / 4; i++)
+ if (dst[i])
+ return false;
+
+ return true;
+}
+
+static int dmatest_func(void *data)
+{
+ struct s3cdma_thread *thread = data;
+ enum dma_ch chan = DMACH_MTOM_0 + thread->id;
+ unsigned long tout = jiffies + msecs_to_jiffies(sec * 1000);
+ int src_idx = 0;
+ unsigned val;
+
+ thread->jiffies = jiffies;
+ thread->done = 0;
+
+ while (!kthread_should_stop() && time_before(jiffies, tout)) {
+
+ u32 *srcbuf = thread->buff_cpu[src_idx];
+ u32 *dstbuf = thread->buff_cpu[1 - src_idx];
+
+ if (!perf_test) {
+ dmatest_init_buf(srcbuf, 0, xfer_size);
+ dmatest_init_buf(dstbuf, 1, xfer_size);
+ delta = 1024;
+ }
+
+ s3c2410_dma_devconfig(chan, S3C_DMA_MEM2MEM,
+ thread->buff_phys[src_idx]);
+
+ s3c2410_dma_enqueue(chan, (void *)thread,
+ thread->buff_phys[1 - src_idx], xfer_size - delta);
+
+ s3c2410_dma_ctrl(chan, S3C2410_DMAOP_START);
+
+ val = wait_for_completion_timeout(&thread->xfer_cmplt, msecs_to_jiffies(5*1000));
+ if (!val) {
+ dma_addr_t src, dst;
+ s3c2410_dma_getposition(DMACH_MTOM_0 + thread->id,
+ &src, &dst);
+
+ printk("\n%s:%d Thrd-%u Done-%u <%x,%x>/<%x,%x>\n",
+ __func__, __LINE__, thread->id, thread->done,
+ src, dst, thread->buff_phys[src_idx], thread->buff_phys[1 - src_idx]);
+ break;
+ }
+
+ if (thread->res != S3C2410_RES_OK
+ || thread->size != xfer_size - delta) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u: Cycle-%u Res-%u Xfer_size-%d!\n",
+ thread->id, thread->done, thread->res, thread->size);
+ } else {
+ thread->done++;
+ }
+
+ if (!perf_test &&
+ !dmatest_buf_same(srcbuf, dstbuf, xfer_size)) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u: Cycle-%u Xfer_cmp failed!\n",
+ thread->id, thread->done);
+ break;
+ }
+
+ src_idx = 1 - src_idx;
+ }
+
+ thread->jiffies = jiffies - thread->jiffies;
+
+ thread->stopped = 1;
+
+ return 0;
+}
+
+static int __init dmatest_init(void)
+{
+ struct s3cdma_thread *thread;
+ int ret, i = 0;
+
+ xfer_size *= XFER_UNIT;
+
+ if (sec < 5) {
+ sec = 5;
+ printk(KERN_INFO "S3C DMA M2M Test: Using 5secs test time\n");
+ }
+
+ while (i < 10) {
+ if (burst == (1 << i))
+ break;
+ i++;
+ }
+ /* If invalid burst value provided */
+ if (i == 10) {
+ burst = 1;
+ printk(KERN_INFO "S3C DMA M2M Test: Using 1 burst size\n");
+ }
+
+ for (i = 0; i < channels; i++) {
+ thread = kzalloc(sizeof(struct s3cdma_thread), GFP_KERNEL);
+ if (!thread) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u No memory for channel\n", i);
+ goto thrd_alloc_err;
+ }
+
+ thread->buff_cpu[SRC] = dma_alloc_coherent(NULL, xfer_size,
+ &thread->buff_phys[SRC], GFP_KERNEL);
+ if (!thread->buff_cpu[SRC]) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u No memory for src buff\n", i);
+ goto src_alloc_err;
+ }
+
+ thread->buff_cpu[DST] = dma_alloc_coherent(NULL, xfer_size,
+ &thread->buff_phys[DST], GFP_KERNEL);
+ if (!thread->buff_cpu[DST]) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u No memory for dst buff\n", i);
+ goto dst_alloc_err;
+ }
+
+ dmatest_init_buf(thread->buff_cpu[SRC], 0, xfer_size);
+ dmatest_init_buf(thread->buff_cpu[DST], 1, xfer_size);
+
+ thread->id = i;
+ thread->cl.name = (char *) thread;
+ thread->stopped = 0;
+
+ init_completion(&thread->xfer_cmplt);
+
+ ret = s3c2410_dma_request(DMACH_MTOM_0 + thread->id,
+ &thread->cl, NULL);
+ if (ret) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%d acq(%d)\n", i, ret);
+ goto thrd_dma_acq_err;
+ }
+
+ s3c2410_dma_set_buffdone_fn(DMACH_MTOM_0 + thread->id, s3cdma_cb);
+
+ ret = s3c2410_dma_config(DMACH_MTOM_0 + thread->id, burst);
+ if (ret) {
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%d config(%d)\n", i, ret);
+ goto thrd_dma_cfg_err;
+ }
+
+ thread->task = kthread_run(dmatest_func, thread,
+ "dma-m2m-test%u", i);
+ if (IS_ERR(thread->task)) {
+ printk(KERN_INFO "S3C DMA M2M Test: Failed to run thread dma-m2m-test%u\n", i);
+ goto thrd_run_err;
+ }
+
+ list_add_tail(&thread->node, &channel_list);
+
+ continue;
+
+thrd_run_err:
+thrd_dma_cfg_err:
+ s3c2410_dma_free(DMACH_MTOM_0 + thread->id, &thread->cl);
+thrd_dma_acq_err:
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[DST], thread->buff_phys[DST]);
+dst_alloc_err:
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[SRC], thread->buff_phys[SRC]);
+src_alloc_err:
+ kfree(thread);
+thrd_alloc_err:
+ break;
+ }
+
+ printk(KERN_INFO "S3C DMA M2M Test: Testing with %u Channels\n", i);
+
+ return 0;
+}
+module_init(dmatest_init);
+
+static void __exit dmatest_exit(void)
+{
+ struct s3cdma_thread *thread;
+
+ while (!list_empty(&channel_list)) {
+ thread = list_entry(channel_list.next,
+ struct s3cdma_thread, node);
+
+ list_del(&thread->node);
+
+ if (perf_test && !dmatest_buf_same(thread->buff_cpu[SRC],
+ thread->buff_cpu[DST], xfer_size))
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u: Xfer_cmp failed!\n", thread->id);
+
+ if (!thread->stopped)
+ kthread_stop(thread->task);
+
+ if (jiffies_to_msecs(thread->jiffies) > maxtime)
+ maxtime = jiffies_to_msecs(thread->jiffies);
+
+ cycles += thread->done;
+
+ printk(KERN_INFO "S3C DMA M2M Test: Thrd-%u %ux%u Kb in %ums\n",
+ thread->id, thread->done, xfer_size / XFER_UNIT,
+ jiffies_to_msecs(thread->jiffies));
+
+ s3c2410_dma_free(DMACH_MTOM_0 + thread->id, &thread->cl);
+
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[DST], thread->buff_phys[DST]);
+
+ dma_free_coherent(NULL, xfer_size,
+ thread->buff_cpu[SRC], thread->buff_phys[SRC]);
+
+ kfree(thread);
+ }
+
+ printk(KERN_INFO "S3C DMA M2M Test: Overall %lux%u Kb in %lums\n",
+ cycles, xfer_size / XFER_UNIT, maxtime);
+ printk(KERN_INFO "S3C DMA M2M Test: %lu MB/Sec\n",
+ cycles * 1000 / maxtime * xfer_size / XFER_UNIT / 1024);
+}
+module_exit(dmatest_exit);
+
+MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("S3C DMA MemToMem Test Driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 1c0b040..712ec09 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -429,3 +429,99 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
}
EXPORT_SYMBOL(s5p_gpio_set_drvstr);
#endif /* CONFIG_S5P_GPIO_DRVSTR */
+
+s5p_gpio_pd_cfg_t s5p_gpio_get_pd_cfg(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 pd_cfg;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x10;
+
+ pd_cfg = __raw_readl(reg);
+ pd_cfg = pd_cfg >> shift;
+ pd_cfg &= 0x3;
+
+ return (__force s5p_gpio_pd_cfg_t)pd_cfg;
+}
+EXPORT_SYMBOL(s5p_gpio_get_pd_cfg);
+
+int s5p_gpio_set_pd_cfg(unsigned int pin, s5p_gpio_pd_cfg_t pd_cfg)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 tmp;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x10;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= pd_cfg << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_pd_cfg);
+
+s5p_gpio_pd_pull_t s5p_gpio_get_pd_pull(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 pd_pull;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x14;
+
+ pd_pull = __raw_readl(reg);
+ pd_pull = pd_pull >> shift;
+ pd_pull &= 0x3;
+
+ return (__force s5p_gpio_pd_pull_t)pd_pull;
+}
+EXPORT_SYMBOL(s5p_gpio_get_pd_pull);
+
+int s5p_gpio_set_pd_pull(unsigned int pin, s5p_gpio_pd_pull_t pd_pull)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 tmp;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x14;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= pd_pull << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_pd_pull);
diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h
index b258a08..449f409 100644
--- a/arch/arm/plat-samsung/include/plat/adc.h
+++ b/arch/arm/plat-samsung/include/plat/adc.h
@@ -17,7 +17,8 @@
struct s3c_adc_client;
extern int s3c_adc_start(struct s3c_adc_client *client,
- unsigned int channel, unsigned int nr_samples);
+ unsigned int channel, unsigned int nr_samples,
+ wait_queue_head_t *pwake);
extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
index a0826ed..bfee644 100644
--- a/arch/arm/plat-samsung/include/plat/audio.h
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -36,6 +36,10 @@ struct samsung_i2s {
*/
#define QUIRK_NO_MUXPSR (1 << 2)
#define QUIRK_NEED_RSTCLR (1 << 3)
+/* If the idma will be enabled */
+#define QUIRK_ENABLED_IDMA (1 << 4)
+/* If the srp will be enabled */
+#define QUIRK_ENABLED_SRP (1 << 5)
/* Quirks of the I2S controller */
u32 quirks;
@@ -56,3 +60,5 @@ struct s3c_audio_pdata {
struct samsung_i2s i2s;
} type;
};
+
+extern void __init exynos4_i2sv3_setup_resource(void);
diff --git a/arch/arm/plat-samsung/include/plat/backlight.h b/arch/arm/plat-samsung/include/plat/backlight.h
new file mode 100644
index 0000000..ad530c7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/backlight.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/plat-samsung/include/plat/backlight.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_BACKLIGHT_H
+#define __ASM_PLAT_BACKLIGHT_H __FILE__
+
+/* samsung_bl_gpio_info - GPIO info for PWM Backlight control
+ * @no: GPIO number for PWM timer out
+ * @func: Special function of GPIO line for PWM timer
+ */
+struct samsung_bl_gpio_info {
+ int no;
+ int func;
+};
+
+extern void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
+ struct platform_pwm_backlight_data *bl_data);
+
+#endif /* __ASM_PLAT_BACKLIGHT_H */
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index 983c578..76198a7 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -9,7 +9,11 @@
* published by the Free Software Foundation.
*/
+#ifndef __ASM_PLAT_CLOCK_H
+#define __ASM_PLAT_CLOCK_H __FILE__
+
#include <linux/spinlock.h>
+#include <linux/clkdev.h>
struct clk;
@@ -40,6 +44,7 @@ struct clk {
struct module *owner;
struct clk *parent;
const char *name;
+ const char *devname;
int id;
int usage;
unsigned long rate;
@@ -47,6 +52,7 @@ struct clk {
struct clk_ops *ops;
int (*enable)(struct clk *, int enable);
+ struct clk_lookup lookup;
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
#endif
@@ -78,6 +84,7 @@ extern struct clk clk_h2;
extern struct clk clk_27m;
extern struct clk clk_48m;
extern struct clk clk_xusbxti;
+extern struct clk clk_xxti;
extern int clk_default_setrate(struct clk *clk, unsigned long rate);
extern struct clk_ops clk_ops_def_setrate;
@@ -118,3 +125,8 @@ extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
extern void s3c_pwmclk_init(void);
+/* Global watchdog clock used by arch_wtd_reset() callback */
+
+extern struct clk *s3c2410_wdtclk;
+
+#endif /* __ASM_PLAT_CLOCK_H */
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index c0a5741..f68c5a6 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -1,9 +1,12 @@
/* linux/arch/arm/plat-samsung/include/plat/cpu.h
*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * Header file for S3C24XX CPU support
+ * Header file for Samsung CPU support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,6 +18,139 @@
#ifndef __SAMSUNG_PLAT_CPU_H
#define __SAMSUNG_PLAT_CPU_H
+extern unsigned long samsung_cpu_id;
+
+#define S3C24XX_CPU_ID 0x32400000
+#define S3C24XX_CPU_MASK 0xFFF00000
+
+#define S3C6400_CPU_ID 0x36400000
+#define S3C6410_CPU_ID 0x36410000
+#define S3C64XX_CPU_ID (S3C6400_CPU_ID & S3C6410_CPU_ID)
+#define S3C64XX_CPU_MASK 0x1FF40000
+
+#define S5P6440_CPU_ID 0x56440000
+#define S5P6450_CPU_ID 0x36450000
+#define S5P64XX_CPU_MASK 0x1FF40000
+
+#define S5PC100_CPU_ID 0x43100000
+#define S5PC100_CPU_MASK 0xFFFFF000
+
+#define S5PV210_CPU_ID 0x43110000
+#define S5PV210_CPU_MASK 0xFFFFF000
+
+#define EXYNOS4210_CPU_ID 0x43210000
+#define EXYNOS4212_CPU_ID 0x43220000
+#define EXYNOS4412_CPU_ID 0xE4412200
+#define EXYNOS5210_CPU_ID 0x43510000
+#define EXYNOS5250_CPU_ID 0x43520000
+#define EXYNOS_CPU_MASK 0xFFFE0000
+
+#define IS_SAMSUNG_CPU(name, id, mask) \
+static inline int is_samsung_##name(void) \
+{ \
+ return ((samsung_cpu_id & mask) == (id & mask)); \
+}
+
+IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
+IS_SAMSUNG_CPU(s3c64xx, S3C64XX_CPU_ID, S3C64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5p6450, S5P6450_CPU_ID, S5P64XX_CPU_MASK)
+IS_SAMSUNG_CPU(s5pc100, S5PC100_CPU_ID, S5PC100_CPU_MASK)
+IS_SAMSUNG_CPU(s5pv210, S5PV210_CPU_ID, S5PV210_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5210, EXYNOS5210_CPU_ID, EXYNOS_CPU_MASK)
+IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_CPU_ID, EXYNOS_CPU_MASK)
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
+ defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2440) || \
+ defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
+ defined(CONFIG_CPU_S3C2443)
+# define soc_is_s3c24xx() is_samsung_s3c24xx()
+#else
+# define soc_is_s3c24xx() 0
+#endif
+
+#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
+# define soc_is_s3c64xx() is_samsung_s3c64xx()
+#else
+# define soc_is_s3c64xx() 0
+#endif
+
+#if defined(CONFIG_CPU_S5P6440)
+# define soc_is_s5p6440() is_samsung_s5p6440()
+#else
+# define soc_is_s5p6440() 0
+#endif
+
+#if defined(CONFIG_CPU_S5P6450)
+# define soc_is_s5p6450() is_samsung_s5p6450()
+#else
+# define soc_is_s5p6450() 0
+#endif
+
+#if defined(CONFIG_CPU_S5PC100)
+# define soc_is_s5pc100() is_samsung_s5pc100()
+#else
+# define soc_is_s5pc100() 0
+#endif
+
+#if defined(CONFIG_CPU_S5PV210)
+# define soc_is_s5pv210() is_samsung_s5pv210()
+#else
+# define soc_is_s5pv210() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4210)
+# define soc_is_exynos4210() is_samsung_exynos4210()
+#else
+# define soc_is_exynos4210() 0
+#endif
+
+#define EXYNOS4210_REV_0 (0x0)
+#define EXYNOS4210_REV_1_0 (0x10)
+#define EXYNOS4210_REV_1_1 (0x11)
+#define EXYNOS4210_REV_1_2 (0x12)
+
+#if defined(CONFIG_CPU_EXYNOS4212)
+# define soc_is_exynos4212() is_samsung_exynos4212()
+#else
+# define soc_is_exynos4212() 0
+#endif
+
+#define EXYNOS4212_REV_0 (0x0)
+#define EXYNOS4212_REV_1_0 (0x10)
+
+#if defined(CONFIG_CPU_EXYNOS4412)
+# define soc_is_exynos4412() is_samsung_exynos4412()
+#else
+# define soc_is_exynos4412() 0
+#endif
+
+#define EXYNOS4412_REV_0 (0x0)
+#define EXYNOS4412_REV_0_1 (0x01)
+#define EXYNOS4412_REV_1_0 (0x10)
+#define EXYNOS4412_REV_1_1 (0x11)
+
+#if defined(CONFIG_CPU_EXYNOS5210)
+# define soc_is_exynos5210() is_samsung_exynos5210()
+#else
+# define soc_is_exynos5210() 0
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS5250)
+# define soc_is_exynos5250() is_samsung_exynos5250()
+# define soc_is_exynos5250_rev1 (soc_is_exynos5250() && \
+ samsung_rev() >= EXYNOS5250_REV_1_0)
+#else
+# define soc_is_exynos5250() 0
+# define soc_is_exynos5250_rev1 0
+#endif
+
+#define EXYNOS5250_REV_0 (0x0)
+#define EXYNOS5250_REV_1_0 (0x10)
+
#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
#ifndef MHZ
@@ -55,6 +191,12 @@ extern void s3c64xx_init_io(struct map_desc *mach_desc, int size);
extern void s5p_init_io(struct map_desc *mach_desc,
int size, void __iomem *cpuid_addr);
+extern void s3c24xx_init_cpu(void);
+extern void s3c64xx_init_cpu(void);
+extern void s5p_init_cpu(void __iomem *cpuid_addr);
+
+extern unsigned int samsung_rev(void);
+
extern void s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c24xx_init_clocks(int xtal);
@@ -88,6 +230,7 @@ extern struct sysdev_class s3c64xx_sysclass;
extern struct sysdev_class s5p64x0_sysclass;
extern struct sysdev_class s5pv210_sysclass;
extern struct sysdev_class exynos4_sysclass;
+extern struct sysdev_class exynos5_sysclass;
extern void (*s5pc1xx_idle)(void);
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e3b31c2..1321d7b 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -17,6 +17,7 @@
#define __PLAT_DEVS_H __FILE__
#include <linux/platform_device.h>
+#include <linux/platform_data/exynos_usb3_drd.h>
struct s3c24xx_uart_resources {
struct resource *resources;
@@ -40,6 +41,7 @@ extern struct platform_device s3c64xx_device_spi0;
extern struct platform_device s3c64xx_device_spi1;
extern struct platform_device samsung_asoc_dma;
+extern struct platform_device samsung_asoc_idma;
extern struct platform_device s3c64xx_device_pcm0;
extern struct platform_device s3c64xx_device_pcm1;
@@ -47,8 +49,16 @@ extern struct platform_device s3c64xx_device_pcm1;
extern struct platform_device s3c64xx_device_ac97;
extern struct platform_device s3c_device_ts;
+extern struct platform_device s3c_device_ts1;
extern struct platform_device s3c_device_fb;
+#ifdef CONFIG_FB_S5P_EXTDSP
+extern struct platform_device s3c_device_extdsp;
+#endif
+extern struct platform_device s5p_device_fimd0;
+extern struct platform_device s5p_device_fimd1;
+extern struct platform_device s5p_device_mipi_dsim0;
+extern struct platform_device s5p_device_mipi_dsim1;
extern struct platform_device s3c_device_ohci;
extern struct platform_device s3c_device_lcd;
extern struct platform_device s3c_device_wdt;
@@ -60,6 +70,7 @@ extern struct platform_device s3c_device_i2c4;
extern struct platform_device s3c_device_i2c5;
extern struct platform_device s3c_device_i2c6;
extern struct platform_device s3c_device_i2c7;
+extern struct platform_device s5p_device_i2c_hdmiphy;
extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_sdi;
@@ -69,6 +80,7 @@ extern struct platform_device s3c_device_hsmmc0;
extern struct platform_device s3c_device_hsmmc1;
extern struct platform_device s3c_device_hsmmc2;
extern struct platform_device s3c_device_hsmmc3;
+extern struct platform_device s3c_device_mshci;
extern struct platform_device s3c_device_cfcon;
extern struct platform_device s3c_device_spi0;
@@ -81,6 +93,9 @@ extern struct platform_device s5pv210_device_spi0;
extern struct platform_device s5pv210_device_spi1;
extern struct platform_device s5p64x0_device_spi0;
extern struct platform_device s5p64x0_device_spi1;
+extern struct platform_device exynos_device_spi0;
+extern struct platform_device exynos_device_spi1;
+extern struct platform_device exynos_device_spi2;
extern struct platform_device s3c_device_hwmon;
@@ -92,6 +107,13 @@ extern struct platform_device s5p_device_onenand;
extern struct platform_device s3c_device_usbgadget;
extern struct platform_device s3c_device_usb_hsudc;
extern struct platform_device s3c_device_usb_hsotg;
+extern struct platform_device s3c_device_usb_hsudc;
+extern struct platform_device s3c_device_android_usb;
+extern struct platform_device s3c_device_usb_mass_storage;
+#ifdef CONFIG_USB_ANDROID_RNDIS
+extern struct platform_device s3c_device_rndis;
+#endif
+extern struct platform_device s5p_device_usbswitch;
extern struct platform_device s5pv210_device_ac97;
extern struct platform_device s5pv210_device_pcm0;
@@ -101,17 +123,45 @@ extern struct platform_device s5pv210_device_iis0;
extern struct platform_device s5pv210_device_iis1;
extern struct platform_device s5pv210_device_iis2;
extern struct platform_device s5pv210_device_spdif;
-
-extern struct platform_device exynos4_device_ac97;
-extern struct platform_device exynos4_device_pcm0;
-extern struct platform_device exynos4_device_pcm1;
-extern struct platform_device exynos4_device_pcm2;
-extern struct platform_device exynos4_device_i2s0;
-extern struct platform_device exynos4_device_i2s1;
-extern struct platform_device exynos4_device_i2s2;
-extern struct platform_device exynos4_device_spdif;
+extern struct platform_device s5pv210_device_cpufreq;
+extern struct platform_device s5pv210_device_pdma0;
+extern struct platform_device s5pv210_device_pdma1;
+extern struct platform_device s5pv210_device_mdma;
+
+extern struct platform_device exynos_device_ac97;
+extern struct platform_device exynos_device_pcm0;
+extern struct platform_device exynos_device_pcm1;
+extern struct platform_device exynos_device_pcm2;
+extern struct platform_device exynos_device_i2s0;
+extern struct platform_device exynos_device_i2s1;
+extern struct platform_device exynos_device_i2s2;
+extern struct platform_device exynos_device_spdif;
+extern struct platform_device exynos_device_srp;
extern struct platform_device exynos4_device_pd[];
extern struct platform_device exynos4_device_ahci;
+extern struct platform_device exynos_device_pdma0;
+extern struct platform_device exynos_device_pdma1;
+extern struct platform_device exynos_device_mdma;
+extern struct platform_device exynos_device_dwmci;
+extern struct platform_device exynos_device_dwmci0;
+extern struct platform_device exynos_device_dwmci1;
+extern struct platform_device exynos_device_dwmci2;
+extern struct platform_device exynos_device_dwmci3;
+extern struct platform_device exynos_device_flite0;
+extern struct platform_device exynos_device_flite1;
+extern struct platform_device exynos4_device_c2c;
+extern struct platform_device exynos_device_flite2;
+extern struct platform_device exynos4_device_fimc_is;
+extern struct platform_device exynos5_device_fimc_is;
+extern struct platform_device exynos5_device_pd[];
+extern struct platform_device exynos5_device_gsc0;
+extern struct platform_device exynos5_device_gsc1;
+extern struct platform_device exynos5_device_gsc2;
+extern struct platform_device exynos5_device_gsc3;
+extern struct platform_device exynos5_device_ahci;
+extern struct platform_device exynos_device_c2c;
+extern struct platform_device exynos_device_ss_udc;
+extern struct platform_device exynos_device_xhci;
extern struct platform_device s5p6440_device_pcm;
extern struct platform_device s5p6440_device_iis;
@@ -130,18 +180,57 @@ extern struct platform_device s5pc100_device_iis2;
extern struct platform_device s5pc100_device_spdif;
extern struct platform_device samsung_device_keypad;
-
+#ifndef CONFIG_VIDEO_FIMC
extern struct platform_device s5p_device_fimc0;
extern struct platform_device s5p_device_fimc1;
extern struct platform_device s5p_device_fimc2;
extern struct platform_device s5p_device_fimc3;
-
+#else
+extern struct platform_device s3c_device_fimc0;
+extern struct platform_device s3c_device_fimc1;
+extern struct platform_device s3c_device_fimc2;
+extern struct platform_device s3c_device_fimc3;
+#endif
+#ifndef CONFIG_VIDEO_FIMC_MIPI
extern struct platform_device s5p_device_mipi_csis0;
extern struct platform_device s5p_device_mipi_csis1;
+#else
+extern struct platform_device s3c_device_csis0;
+extern struct platform_device s3c_device_csis1;
+#endif
+extern struct platform_device s5p_device_dp;
+
+extern struct platform_device s5p_device_jpeg;
+extern struct platform_device s5p_device_tvout;
+extern struct platform_device s5p_device_cec;
+extern struct platform_device s5p_device_hpd;
+extern struct platform_device s5p_device_ace;
+extern struct platform_device s5p_device_fimg2d;
+extern struct platform_device exynos_device_rotator;
extern struct platform_device s5p_device_ehci;
+extern struct platform_device s5p_device_ohci;
+#ifdef CONFIG_USB_HOST_NOTIFY
+extern struct platform_device host_notifier_device;
+#endif
-extern struct platform_device exynos4_device_sysmmu;
+extern struct platform_device exynos_device_sysmmu[];
+
+extern struct platform_device s5p_device_mfc;
+extern struct platform_device s5p_device_mipi_dsim;
+extern struct platform_device s5p_device_dsim;
+
+extern struct platform_device s5p_device_hdmi;
+extern struct platform_device s5p_device_mixer;
+extern struct platform_device s5p_device_sdo;
+
+#ifdef CONFIG_FB_S5P_MIPI_DSIM
+extern struct platform_device s5p_device_dsim;
+#endif
+
+#ifdef CONFIG_SENSORS_EXYNOS4_TMU
+extern struct platform_device exynos4_device_tmu;
+#endif
/* s3c2440 specific devices */
@@ -152,6 +241,13 @@ extern struct platform_device s3c_device_ac97;
#endif
+#if defined(CONFIG_VIDEO_TSI)
+extern struct platform_device s3c_device_tsi;
+#endif
+
+extern void exynos_ss_udc_set_platdata(struct exynos_usb3_drd_pdata *pd);
+extern void exynos_xhci_set_platdata(struct exynos_usb3_drd_pdata *pd);
+
/**
* s3c_set_platdata() - helper for setting platform data
* @pd: The default platform data for this device.
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
index 8c273b7..816d505 100644
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -18,7 +18,9 @@ enum s3c2410_dma_buffresult {
enum s3c2410_dmasrc {
S3C2410_DMASRC_HW, /* source is memory */
- S3C2410_DMASRC_MEM /* source is hardware */
+ S3C2410_DMASRC_MEM, /* source is hardware */
+ S3C_DMA_MEM2MEM,
+ S3C_DMA_MEM2MEM_SET,
};
/* enum s3c2410_chan_op
@@ -96,8 +98,18 @@ extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);
* drained before the buffer is given to the DMA system.
*/
-extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
- dma_addr_t data, int size);
+#define s3c2410_dma_enqueue(id, token, addr, size) \
+ s3c2410_dma_enqueue_ring(id, token, addr, size, 0)
+
+/* s3c2410_dma_enqueue_ring
+ *
+ * place the given buffer onto the queue of operations for the channel.
+ * The buffer must be allocated from dma coherent memory, or the Dcache/WB
+ * drained before the buffer is given to the DMA system.
+*/
+
+extern int s3c2410_dma_enqueue_ring(enum dma_ch channel, void *id,
+ dma_addr_t data, int size, int numofblock);
/* s3c2410_dma_config
*
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
index bca383e..4335840 100644
--- a/arch/arm/plat-samsung/include/plat/fb-core.h
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -26,4 +26,25 @@ static inline void s3c_fb_setname(char *name)
#endif
}
+/* Re-define device name depending on support. */
+static inline void s5p_fb_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMD0
+ case 0:
+ s5p_device_fimd0.name = name;
+ break;
+#endif
+
+#ifdef CONFIG_S5P_DEV_FIMD1
+ case 1:
+ s5p_device_fimd1.name = name;
+ break;
+#endif
+ default:
+ printk(KERN_ERR "%s: invalid device id(%d)\n", __func__, id);
+ break;
+ }
+}
+
#endif /* __ASM_PLAT_FB_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h
index cb3ca3a..2e1813f 100644
--- a/arch/arm/plat-samsung/include/plat/fb.h
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -15,6 +15,8 @@
#ifndef __PLAT_S3C_FB_H
#define __PLAT_S3C_FB_H __FILE__
+#include <plat/gpio-cfg.h>
+
/* S3C_FB_MAX_WIN
* Set to the maximum number of windows that any of the supported hardware
* can use. Since the platform data uses this for an array size, having it
@@ -22,11 +24,28 @@
*/
#define S3C_FB_MAX_WIN (5)
+#if defined(CONFIG_MACH_P11) || defined(CONFIG_MACH_P10)
+/* IOCTL commands */
+#define S3CFB_WIN_POSITION _IOW('F', 203, \
+ struct s3c_fb_user_window)
+#define S3CFB_WIN_SET_PLANE_ALPHA _IOW('F', 204, \
+ struct s3c_fb_user_plane_alpha)
+#define S3CFB_WIN_SET_CHROMA _IOW('F', 205, \
+ struct s3c_fb_user_chroma)
+#define S3CFB_SET_VSYNC_INT _IOW('F', 206, u32)
+
+#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, \
+ struct s3c_fb_user_ion_client)
+#define S3CFB_PAN_DISPLAY_INDEX _IOW('F', 209, __u32)
+
+#endif
/**
* struct s3c_fb_pd_win - per window setup data
* @win_mode: The display parameters to initialise (not for window 0)
* @virtual_x: The virtual X size.
* @virtual_y: The virtual Y size.
+ * @width: The width of display in mm
+ * @height: The height of display in mm
*/
struct s3c_fb_pd_win {
struct fb_videomode win_mode;
@@ -35,6 +54,8 @@ struct s3c_fb_pd_win {
unsigned short max_bpp;
unsigned short virtual_x;
unsigned short virtual_y;
+ unsigned short width;
+ unsigned short height;
};
/**
@@ -74,6 +95,22 @@ struct s3c_fb_platdata {
extern void s3c_fb_set_platdata(struct s3c_fb_platdata *pd);
/**
+ * s5p_fimd0_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
+ * s5p_fimd1_set_platdata() - Setup the FB device with platform data.
+ * @pd: The platform data to set. The data is copied from the passed structure
+ * so the machine data can mark the data __initdata so that any unused
+ * machines will end up dumping their data at runtime.
+ */
+extern void s5p_fimd1_set_platdata(struct s3c_fb_platdata *pd);
+
+/**
* s3c64xx_fb_gpio_setup_24bpp() - S3C64XX setup function for 24bpp LCD
*
* Initialise the GPIO for an 24bpp LCD display on the RGB interface.
@@ -94,4 +131,30 @@ extern void s5pc100_fb_gpio_setup_24bpp(void);
*/
extern void s5pv210_fb_gpio_setup_24bpp(void);
+/**
+ * exynos4_fimd0_gpio_setup_24bpp() - Exynos4 setup function for 24bpp LCD0
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface 0.
+ */
+extern void exynos4_fimd0_gpio_setup_24bpp(void);
+
+/**
+ * exynos4_fimd_cfg_gpios() - Exynos4 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void exynos4_fimd_cfg_gpios(unsigned int base, unsigned int nr,
+ unsigned int cfg, s5p_gpio_drvstr_t drvstr);
+
+/**
+ * exynos4_fimd0_setup_clock() = Exynos4 setup function for parent clock.
+ * @dev: device pointer
+ * @parent: parent clock used for LCD pixel clock
+ * @clk_rate: clock rate for parent clock
+ */
+int __init exynos4_fimd0_setup_clock(struct device *dev, const char *parent,
+ unsigned long clk_rate);
+
+int __init exynos4_fimd_setup_clock(struct device *dev, const char *bus_clk,
+ const char *parent, unsigned long clk_rate);
#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-samsung/include/plat/fimd_lite_ext.h b/arch/arm/plat-samsung/include/plat/fimd_lite_ext.h
new file mode 100644
index 0000000..b4e131a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fimd_lite_ext.h
@@ -0,0 +1,99 @@
+/* linux/arch/arm/plat/mdnie_ext.h
+ *
+ * Samsung SoC FIMD Extension Framework Header.
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct s5p_fimd_ext_device;
+
+#define fimd_ext_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
+#define fimd_ext_set_drvdata(_dev, data) dev_set_drvdata(&(_dev)->dev, (data))
+
+struct s5p_fimd_dynamic_refresh {
+ void __iomem *regs;
+ unsigned int dynamic_refresh;
+ unsigned int clkdiv;
+};
+
+/**
+ * driver structure for fimd extension based driver.
+ *
+ * this structure should be registered by any extension driver.
+ * fimd extension driveer seeks a driver registered through name field
+ * and calls these callback functions in appropriate time.
+ */
+struct s5p_fimd_ext_driver {
+ struct device_driver driver;
+
+ void (*change_clock)(struct s5p_fimd_dynamic_refresh *fimd_refresh,
+ struct s5p_fimd_ext_device *fx_dev);
+ void (*set_clock)(struct s5p_fimd_ext_device *fx_dev);
+ int (*setup)(struct s5p_fimd_ext_device *fx_dev,
+ unsigned int enable);
+ void (*power_on)(struct s5p_fimd_ext_device *fx_dev);
+ void (*power_off)(struct s5p_fimd_ext_device *fx_dev);
+ int (*start)(struct s5p_fimd_ext_device *fx_dev);
+ void (*stop)(struct s5p_fimd_ext_device *fx_dev);
+ int (*probe)(struct s5p_fimd_ext_device *fx_dev);
+ int (*remove)(struct s5p_fimd_ext_device *fx_dev);
+ int (*suspend)(struct s5p_fimd_ext_device *fx_dev);
+ int (*resume)(struct s5p_fimd_ext_device *fx_dev);
+};
+
+/**
+ * device structure for fimd extension based driver.
+ *
+ * @name: platform device name.
+ * @dev: driver model representation of the device.
+ * @id: id of device registered and when device is registered
+ * id would be counted.
+ * @num_resources: hardware resource count.
+ * @resource: a pointer to hardware resource definitions.
+ * @modalias: name of the driver to use with the device, or an
+ * alias for that name.
+ */
+struct s5p_fimd_ext_device {
+ char *name;
+ struct device dev;
+ int id;
+ unsigned int num_resources;
+ struct resource *resource;
+ bool mdnie_enabled;
+ bool enabled;
+};
+
+struct mdnie_platform_data {
+ unsigned int width;
+ unsigned int height;
+};
+
+/* workaround: fix it later */
+void s6e8aa0_panel_cond(int high_freq);
+
+#ifdef CONFIG_MDNIE_SUPPORT
+/**
+ * register extension driver to fimd extension framework.
+ */
+int s5p_fimd_ext_register(struct s5p_fimd_ext_driver *fx_drv);
+int s5p_fimd_ext_device_register(struct s5p_fimd_ext_device *fx_dev);
+
+/**
+ * find a driver object registered to fimd extension framework.
+ */
+struct s5p_fimd_ext_device *s5p_fimd_ext_find_device(const char *name);
+
+/**
+ * convert device driver object to fimd extension device.
+ */
+struct s5p_fimd_ext_driver *to_fimd_ext_driver(struct device_driver *drv);
+#else
+#define s5p_fimd_ext_register(dev) NULL
+#define s5p_fimd_ext_device_register(dev) NULL
+#define s5p_fimd_ext_find_device(name) NULL
+#define to_fimd_ext_driver(drv) NULL
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
index 1762dcb..943789c 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -26,6 +26,8 @@
typedef unsigned int __bitwise__ s3c_gpio_pull_t;
typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+typedef unsigned int __bitwise__ s5p_gpio_pd_cfg_t;
+typedef unsigned int __bitwise__ s5p_gpio_pd_pull_t;
/* forward declaration if gpio-core.h hasn't been included */
struct s3c_gpio_chip;
@@ -125,12 +127,30 @@ extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
*
* These values control the state of the weak pull-{up,down} resistors
* available on most pins on the S3C series. Not all chips support both
- * up or down settings, and it may be dependent on the chip that is being
+ * up or down settings, and it may be dependant on the chip that is being
* used to whether the particular mode is available.
*/
+#if defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_EXYNOS)
+#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x03)
+#else
#define S3C_GPIO_PULL_NONE ((__force s3c_gpio_pull_t)0x00)
#define S3C_GPIO_PULL_DOWN ((__force s3c_gpio_pull_t)0x01)
#define S3C_GPIO_PULL_UP ((__force s3c_gpio_pull_t)0x02)
+#endif
+
+#if defined(CONFIG_ARCH_S5PV310) || defined(CONFIG_ARCH_EXYNOS)
+/* need to move to mach/gpio.h */
+#define S3C_GPIO_SLP_OUT0 ((__force s3c_gpio_pull_t)0x00)
+#define S3C_GPIO_SLP_OUT1 ((__force s3c_gpio_pull_t)0x01)
+#define S3C_GPIO_SLP_INPUT ((__force s3c_gpio_pull_t)0x02)
+#define S3C_GPIO_SLP_PREV ((__force s3c_gpio_pull_t)0x03)
+
+#define S3C_GPIO_SETPIN_ZERO 0
+#define S3C_GPIO_SETPIN_ONE 1
+#define S3C_GPIO_SETPIN_NONE 2
+#endif
/**
* s3c_gpio_setpull() - set the state of a gpio pin pull resistor
@@ -207,6 +227,65 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
*/
extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+/* Define values for the power down configuration available for each gpio pin.
+ *
+ * These values control the state of the power down configuration resistors
+ * available on most pins on the S5P series.
+ */
+#define S5P_GPIO_PD_OUTPUT0 ((__force s5p_gpio_pd_cfg_t)0x00)
+#define S5P_GPIO_PD_OUTPUT1 ((__force s5p_gpio_pd_cfg_t)0x01)
+#define S5P_GPIO_PD_INPUT ((__force s5p_gpio_pd_cfg_t)0x02)
+#define S5P_GPIO_PD_PREV_STATE ((__force s5p_gpio_pd_cfg_t)0x03)
+
+/**
+ * s5p_gpio_set_pd_cfg() - set the configuration of a gpio power down mode
+ * @pin: The pin number to configure the pull resistor.
+ * @pd_cfg: The configuration for the pwer down mode configuration register.
+ *
+ * This function sets the configuration of the power down mode resistor for the
+ * specified pin. It will return 0 if successful, or a negative error
+ * code if the pin cannot support the requested power down mode.
+ *
+*/
+extern int s5p_gpio_set_pd_cfg(unsigned int pin, s5p_gpio_pd_cfg_t pd_cfg);
+
+/**
+ * s5p_gpio_get_pd_cfg() - get the power down mode configuration of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the power down mode resistor value for the specified pin.
+*/
+extern s5p_gpio_pd_cfg_t s5p_gpio_get_pd_cfg(unsigned int pin);
+
+/* Define values for the power down pull-{up,down} available for each gpio pin.
+ *
+ * These values control the state of the power down mode pull-{up,down}
+ * resistors available on most pins on the S5P series.
+ */
+#define S5P_GPIO_PD_UPDOWN_DISABLE ((__force s5p_gpio_pd_pull_t)0x00)
+#define S5P_GPIO_PD_DOWN_ENABLE ((__force s5p_gpio_pd_pull_t)0x01)
+#define S5P_GPIO_PD_UP_ENABLE ((__force s5p_gpio_pd_pull_t)0x03)
+
+/**
+ * s5p_gpio_set_pd_pull() - set the pull-{up,down} of a gpio pin power down mode
+ * @pin: The pin number to configure the pull resistor.
+ * @pd_pull: The configuration for the power down mode pull resistor.
+ *
+ * This function sets the configuration of the pull-{up,down} resistor for the
+ * specified pin. It will return 0 if successful, or a negative error
+ * code if the pin cannot support the requested pull setting.
+ *
+*/
+extern int s5p_gpio_set_pd_pull(unsigned int pin, s5p_gpio_pd_pull_t pd_pull);
+
+/**
+ * s5p_gpio_get_pd_pull() - get the power down pull resistor config of gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the power mode pull resistor value for the specified pin.
+*/
+extern s5p_gpio_pd_pull_t s5p_gpio_get_pd_pull(unsigned int pin);
+
/**
* s5p_register_gpio_interrupt() - register interrupt support for a gpio group
* @pin: The pin number from the group to be registered
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index 8cad4cf..792fdb0 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -67,7 +67,8 @@ struct s3c_gpio_chip {
void __iomem *base;
int irq_base;
int group;
- spinlock_t lock;
+ unsigned int eint_offset;
+ spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
#endif
@@ -116,6 +117,8 @@ extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
*/
extern void samsung_gpiolib_add_4bit_chips(struct s3c_gpio_chip *chip,
int nr_chips);
+extern void samsung_gpiolib_add_4bit_chips_no_pm(struct s3c_gpio_chip *chip,
+ int nr_chips);
extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
int nr_chips);
extern void samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
@@ -141,9 +144,9 @@ extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
#ifdef CONFIG_S3C_GPIO_TRACK
extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
-static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
{
- return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+ return (pin < S3C_GPIO_END) ? s3c_gpios[pin] : NULL;
}
#else
/* machine specific code should provide s3c_gpiolib_getchip */
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
index 1543da8..51d52e7 100644
--- a/arch/arm/plat-samsung/include/plat/iic.h
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -60,6 +60,7 @@ extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s5p_i2c_hdmiphy_set_platdata(struct s3c2410_platform_i2c *i2c);
/* defined by architecture to configure gpio */
extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
@@ -71,4 +72,6 @@ extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
+extern struct s3c2410_platform_i2c default_i2c_data;
+
#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/iovmm.h b/arch/arm/plat-samsung/include/plat/iovmm.h
new file mode 100644
index 0000000..53d2e77
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/iovmm.h
@@ -0,0 +1,76 @@
+/* linux/arch/arm/plat-s5p/include/plat/iovmm.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_IOVMM_H
+#define __ASM_PLAT_IOVMM_H
+
+#ifdef CONFIG_EXYNOS_IOVMM
+
+struct scatterlist;
+
+int iovmm_setup(struct device *dev);
+void iovmm_cleanup(struct device *dev);
+int iovmm_activate(struct device *dev);
+void iovmm_deactivate(struct device *dev);
+
+/* iovmm_map() - Maps a list of physical memory chunks
+ * @dev: the owner of the IO address space where the mapping is created
+ * @sg: list of physical memory chunks to map
+ * @offset: length in bytes where the mapping starts
+ * @size: how much memory to map in bytes. @offset + @size must not exceed
+ * total size of @sg
+ *
+ * This function returns mapped IO address in the address space of @dev.
+ * Returns 0 if mapping fails.
+ *
+ * The caller of this function must ensure that iovmm_cleanup() is not called
+ * while this function is called.
+ *
+ */
+dma_addr_t iovmm_map(struct device *dev, struct scatterlist *sg, off_t offset,
+ size_t size);
+
+/* iovmm_map() - unmaps the given IO address
+ * @dev: the owner of the IO address space where @iova belongs
+ * @iova: IO address that needs to be unmapped and freed.
+ *
+ * The caller of this function must ensure that iovmm_cleanup() is not called
+ * while this function is called.
+ */
+void iovmm_unmap(struct device *dev, dma_addr_t iova);
+
+/* iovmm_map_oto - create one to one mapping for the given physical address
+ * @dev: the owner of the IO address space to map
+ * @phys: physical address to map
+ * @size: size of the mapping to create
+ *
+ * This function return 0 if mapping is successful. Otherwise, minus error
+ * value.
+ */
+int iovmm_map_oto(struct device *dev, phys_addr_t phys, size_t size);
+
+/* iovmm_unmap_oto - remove one to one mapping
+ * @dev: the owner ofthe IO address space
+ * @phys: physical address to remove mapping
+ */
+void iovmm_unmap_oto(struct device *dev, phys_addr_t phys);
+
+#else
+#define iovmm_setup(dev) (-ENOSYS)
+#define iovmm_cleanup(dev) do { } while (0)
+#define iovmm_activate(dev) (-ENOSYS)
+#define iovmm_deactivate(dev) do { } while (0)
+#define iovmm_map(dev, sg) (0)
+#define iovmm_unmap(dev, iova) do { } while (0)
+#define iovmm_map_oto(dev, phys, size) (0)
+#define iovmm_unmap_oto(dev, phys) do { } while (0)
+#endif /* CONFIG_EXYNOS_IOVMM */
+
+#endif /*__ASM_PLAT_IOVMM_H*/
diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
index 3ffac4d..ec28c99 100644
--- a/arch/arm/plat-samsung/include/plat/map-base.h
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -14,15 +14,15 @@
#ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__
-/* Fit all our registers in at 0xF6000000 upwards, trying to use as
- * little of the VA space as possible so vmalloc and friends have a
- * better chance of getting memory.
+/* Fit all our registers in at CONFIG_S3C_BASE_ADDR upwards, trying to
+ * use as little of the VA space as possible so vmalloc and friends
+ * have a better chance of getting memory.
*
* we try to ensure stuff like the IRQ registers are available for
* an single MOVS instruction (ie, only 8 bits of set data)
*/
-#define S3C_ADDR_BASE 0xF6000000
+#define S3C_ADDR_BASE CONFIG_S3C_ADDR_BASE
#ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
@@ -35,8 +35,14 @@
#define S3C_VA_MEM S3C_ADDR(0x00200000) /* memory control */
#define S3C_VA_TIMER S3C_ADDR(0x00300000) /* timer block */
#define S3C_VA_WATCHDOG S3C_ADDR(0x00400000) /* watchdog */
+#define S3C_VA_HSOTG S3C_ADDR(0x00E00000) /* OTG */
+#define S3C_VA_HSPHY S3C_ADDR(0x00F00000) /* OTG PHY */
#define S3C_VA_UART S3C_ADDR(0x01000000) /* UART */
+#define S3C_VA_KLOG_BUF S3C_ADDR(0x01100000) /* non-cached log buf */
+#define S3C_VA_SLOG_BUF S3C_ADDR(0x01400000) /* non-cached sched log buf */
+#define S3C_VA_AUXLOG_BUF S3C_ADDR(0x01600000) /* auxiliary log buf */
+
/* This is used for the CPU specific mappings that may be needed, so that
* they do not need to directly used S3C_ADDR() and thus make it easier to
* modify the space for mapping.
diff --git a/arch/arm/plat-samsung/include/plat/mshci.h b/arch/arm/plat-samsung/include/plat/mshci.h
new file mode 100644
index 0000000..0333500
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/mshci.h
@@ -0,0 +1,161 @@
+/* linux/arch/arm/plat-samsung/include/plat/mshci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * EXYNOS4 - MSHCI (HSMMC) platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C_MSHCI_H
+#define __PLAT_S3C_MSHCI_H __FILE__
+
+struct platform_device;
+struct mmc_host;
+struct mmc_card;
+struct mmc_ios;
+
+enum ms_cd_types {
+ S3C_MSHCI_CD_INTERNAL, /* use mmc internal CD line */
+ S3C_MSHCI_CD_EXTERNAL, /* use external callback */
+ S3C_MSHCI_CD_GPIO, /* use external gpio pin for CD line */
+ S3C_MSHCI_CD_NONE, /* no CD line, use polling to detect card */
+ S3C_MSHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
+};
+
+/**
+ * struct s3c_mshci_platdata() - Platform device data for Samsung MSHCI
+ * @max_width: The maximum number of data bits supported.
+ * @host_caps: Standard MMC host capabilities bit field.
+ * @cd_type: Type of Card Detection method (see cd_types enum above)
+ * @wp_gpio: The gpio number using for WP.
+ * @has_wp_gpio: Check using wp_gpio or not.
+ * @ext_cd_init: Initialize external card detect subsystem. Called on
+ * mshci-s3c driver probe when cd_type == S3C_MSHCI_CD_EXTERNAL.
+ * notify_func argument is a callback to the mshci-s3c driver
+ * that triggers the card detection event. Callback arguments:
+ * dev is pointer to platform device of the host controller,
+ * state is new state of the card (0 - removed, 1 - inserted).
+ * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on
+ * mshci-s3c driver remove when cd_type == S3C_MSHCI_CD_EXTERNAL.
+ * notify_func argument is the same callback as for ext_cd_init.
+ * @ext_cd_gpio: gpio pin used for external CD line, valid only if
+ * cd_type == S3C_MSHCI_CD_GPIO
+ * @ext_cd_gpio_invert: invert values for external CD gpio line
+ * @cfg_gpio: Configure the GPIO for a specific card bit-width
+ * @cfg_card: Configure the interface for a specific card and speed. This
+ * is necessary the controllers and/or GPIO blocks require the
+ * changing of driver-strength and other controls dependant on
+ * the card and speed of operation.
+ *
+ * Initialisation data specific to either the machine or the platform
+ * for the device driver to use or call-back when configuring gpio or
+ * card speed information.
+*/
+struct s3c_mshci_platdata {
+ unsigned int max_width;
+ unsigned int host_caps;
+ unsigned int host_caps2;
+ enum ms_cd_types cd_type;
+
+ char **clocks; /* set of clock sources */
+
+ int wp_gpio;
+ int ext_cd_gpio;
+ int int_power_gpio;
+ int fifo_depth;
+ bool ext_cd_gpio_invert;
+ bool has_wp_gpio;
+ int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
+ int state));
+ int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
+ int state));
+
+ void (*cfg_gpio)(struct platform_device *dev, int width);
+ void (*cfg_ddr)(struct platform_device *dev, int ddr);
+ void (*init_card)(struct platform_device *dev);
+ void (*set_power)(struct platform_device *dev, int en);
+ void (*cfg_card)(struct platform_device *dev,
+ void __iomem *regbase,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+ void (*shutdown)(void);
+};
+
+/**
+ * s3c_mshci_set_platdata - Set platform data for S3C MSHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C MSHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void s3c_mshci_set_platdata(struct s3c_mshci_platdata *pd);
+
+/* Default platform data, exported so that per-cpu initialisation can
+ * set the correct one when there are more than one cpu type selected.
+*/
+
+extern struct s3c_mshci_platdata s3c_mshci_def_platdata;
+
+/* Helper function availablity */
+
+extern void s5p6450_setup_mshci_cfg_gpio(struct platform_device *, int w);
+
+/* S5P6450 MSHCI setup */
+extern char *s5p6450_mshc_clksrcs[1];
+
+extern void s5p6450_setup_mshci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s5p6450_default_mshci(void)
+{
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+ s3c_mshci_def_platdata.clocks = s5p6450_mshc_clksrcs;
+ s3c_mshci_def_platdata.cfg_gpio = s5p6450_setup_mshci_cfg_gpio;
+ s3c_mshci_def_platdata.cfg_card = s5p6450_setup_mshci_cfg_card;
+#endif /* CONFIG_EXYNOS4_DEV_MSHC */
+}
+
+extern void exynos4_setup_mshci_cfg_gpio(struct platform_device *, int w);
+
+/* EXYNOS4 MSHCI setup */
+#ifdef CONFIG_EXYNOS4_SETUP_MSHCI
+extern char *exynos4_mshci_clksrcs[1];
+#endif
+
+extern void exynos4_setup_mshci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+extern void exynos4_setup_mshci_cfg_ddr(struct platform_device *dev,
+ int ddr);
+extern void exynos4_setup_mshci_init_card(struct platform_device *dev);
+extern void exynos4_setup_mshci_shutdown(void);
+
+extern void exynos4_setup_mshci_set_power(struct platform_device *dev, int en);
+
+#ifdef CONFIG_EXYNOS4_DEV_MSHC
+static inline void exynos4_default_mshci(void)
+{
+ s3c_mshci_def_platdata.clocks = exynos4_mshci_clksrcs;
+ s3c_mshci_def_platdata.cfg_gpio = exynos4_setup_mshci_cfg_gpio;
+ s3c_mshci_def_platdata.cfg_card = exynos4_setup_mshci_cfg_card;
+ s3c_mshci_def_platdata.cfg_ddr = exynos4_setup_mshci_cfg_ddr;
+ s3c_mshci_def_platdata.init_card = exynos4_setup_mshci_init_card;
+ s3c_mshci_def_platdata.set_power = exynos4_setup_mshci_set_power;
+ s3c_mshci_def_platdata.shutdown = exynos4_setup_mshci_shutdown;
+}
+#else
+static inline void exynos4_default_mshci(void) { }
+#endif /* CONFIG_EXYNOS4_DEV_MSHC */
+
+#endif /* __PLAT_S3C_MSHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h
index abb4bc3..832a403 100644
--- a/arch/arm/plat-samsung/include/plat/pd.h
+++ b/arch/arm/plat-samsung/include/plat/pd.h
@@ -11,20 +11,41 @@
#ifndef __ASM_PLAT_SAMSUNG_PD_H
#define __ASM_PLAT_SAMSUNG_PD_H __FILE__
-struct samsung_pd_info {
- int (*enable)(struct device *dev);
- int (*disable)(struct device *dev);
- void __iomem *base;
-};
-
-enum exynos4_pd_block {
+enum exynos_pd_block {
PD_MFC,
PD_G3D,
PD_LCD0,
PD_LCD1,
PD_TV,
PD_CAM,
- PD_GPS
+ PD_GPS,
+ PD_GPS_ALIVE,
+ PD_ISP,
+ PD_MAUDIO,
+ PD_GSCL,
+ PD_DISP1,
+ PD_TOP,
+};
+
+struct samsung_pd_info {
+ int (*init)(struct device *dev);
+ int (*enable)(struct device *dev);
+ int (*disable)(struct device *dev);
+ int (*save)(struct device *dev);
+ int (*restore)(struct device *dev);
+ void __iomem *base;
+ void *data;
+ enum exynos_pd_block id;
+};
+
+struct exynos_pd_data {
+ void __iomem *clk_base;
+ void __iomem *clksrc_base;
+ void __iomem *read_base;
+ unsigned long read_phy_addr;
};
+int exynos_pd_init(struct device *dev);
+int exynos_pd_enable(struct device *dev);
+int exynos_pd_disable(struct device *dev);
#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 7fb6f6b..c306634 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -43,6 +43,9 @@ extern unsigned long s3c_irqwake_eintallow;
extern void (*pm_cpu_prep)(void);
extern void (*pm_cpu_sleep)(void);
+extern void (*pm_cpu_restore)(void);
+extern int (*pm_prepare)(void);
+extern void (*pm_finish)(void);
/* Flags for PM Control */
@@ -102,10 +105,12 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
#ifdef CONFIG_PM
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
extern int s3c24xx_irq_suspend(void);
extern void s3c24xx_irq_resume(void);
#else
+#define s3c_irq_wake NULL
#define s3c_irqext_wake NULL
#define s3c24xx_irq_suspend NULL
#define s3c24xx_irq_resume NULL
@@ -128,7 +133,7 @@ extern void s3c_pm_dbg(const char *msg, ...);
#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
#else
-#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
+#define S3C_PMDBG(fmt...) pr_debug(fmt)
#endif
#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
@@ -151,10 +156,10 @@ extern void s3c_pm_check_restore(void);
extern void s3c_pm_check_cleanup(void);
extern void s3c_pm_check_store(void);
#else
-#define s3c_pm_check_prepare() do { } while(0)
-#define s3c_pm_check_restore() do { } while(0)
-#define s3c_pm_check_cleanup() do { } while(0)
-#define s3c_pm_check_store() do { } while(0)
+#define s3c_pm_check_prepare() do { } while (0)
+#define s3c_pm_check_restore() do { } while (0)
+#define s3c_pm_check_cleanup() do { } while (0)
+#define s3c_pm_check_store() do { } while (0)
#endif
/**
@@ -183,3 +188,5 @@ extern void s3c_pm_save_gpios(void);
extern void s3c_pm_save_core(void);
extern void s3c_pm_restore_core(void);
+
+extern unsigned long s3c_suspend_wakeup_stat;
diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h
index 7554c4f..b0759b1 100644
--- a/arch/arm/plat-samsung/include/plat/regs-adc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -21,16 +21,19 @@
#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14)
#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
+#define S5P_ADCMUX S3C2410_ADCREG(0x1C)
#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20)
/* ADCCON Register Bits */
+#define S3C64XX_ADCCON_TSSEL (1<<17)
#define S3C64XX_ADCCON_RESSEL (1<<16)
#define S3C2410_ADCCON_ECFLG (1<<15)
#define S3C2410_ADCCON_PRSCEN (1<<14)
#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
+#define S5PV210_ADCCON_SELMUX(x) (((x)&0xF)<<0)
#define S3C2410_ADCCON_MUXMASK (0x7<<3)
#define S3C2410_ADCCON_STDBM (1<<2)
#define S3C2410_ADCCON_READ_START (1<<1)
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
index 4c3647f..9c5534e 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
@@ -30,9 +30,17 @@
#define VIDCON1_FSTATUS_EVEN (1 << 15)
/* Video timing controls */
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDTCON0 (0x20010)
+#define VIDTCON1 (0x20014)
+#define VIDTCON2 (0x20018)
+#define VIDTCON3 (0x2001C)
+#else
#define VIDTCON0 (0x10)
#define VIDTCON1 (0x14)
#define VIDTCON2 (0x18)
+#define VIDTCON3 (0x1C)
+#endif
/* Window position controls */
@@ -43,9 +51,12 @@
#define VIDOSD_BASE (0x40)
#define VIDINTCON0 (0x130)
+#define VIDINTCON1 (0x134)
/* WINCONx */
+#define WINCONx_CSC_CON_EQ709 (1 << 28)
+#define WINCONx_CSC_CON_EQ601 (0 << 28)
#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
#define WINCONx_CSCWIDTH_SHIFT (26)
#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
index 8f39aa5..f6c450b 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -32,12 +32,27 @@
#define VIDCON0 (0x00)
#define VIDCON0_INTERLACE (1 << 29)
-#define VIDCON0_VIDOUT_MASK (0x3 << 26)
+
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDOUT_CON_VIDOUT_UP_MASK (0x1 << 16)
+#define VIDOUT_CON_VIDOUT_UP_SHIFT (16)
+#define VIDOUT_CON_VIDOUT_UP_ALWAYS (0x0 << 16)
+#define VIDOUT_CON_VIDOUT_UP_START_FRAME (0x1 << 16)
+#define VIDOUT_CON_VIDOUT_F_MASK (0x7 << 8)
+#define VIDOUT_CON_VIDOUT_F_SHIFT (8)
+#define VIDOUT_CON_VIDOUT_F_RGB (0x0 << 8)
+#define VIDOUT_CON_VIDOUT_F_I80_LDI0 (0x2 << 8)
+#define VIDOUT_CON_VIDOUT_F_I80_LDI1 (0x3 << 8)
+#define VIDOUT_CON_VIDOUT_F_WB (0x4 << 8)
+#endif
+
+#define VIDCON0_VIDOUT_MASK (0x7 << 26)
#define VIDCON0_VIDOUT_SHIFT (26)
#define VIDCON0_VIDOUT_RGB (0x0 << 26)
#define VIDCON0_VIDOUT_TV (0x1 << 26)
#define VIDCON0_VIDOUT_I80_LDI0 (0x2 << 26)
#define VIDCON0_VIDOUT_I80_LDI1 (0x3 << 26)
+#define VIDCON0_VIDOUT_WB (0x4 << 26)
#define VIDCON0_L1_DATA_MASK (0x7 << 23)
#define VIDCON0_L1_DATA_SHIFT (23)
@@ -81,7 +96,17 @@
#define VIDCON0_ENVID (1 << 1)
#define VIDCON0_ENVID_F (1 << 0)
+#ifdef CONFIG_FB_EXYNOS_FIMD_V8
+#define VIDOUT_CON (0x20000)
+#define VIDCON1 (0x20004)
+#define REG_TIME2INIT (0x01b4)
+#define REG_TIME2SNP (0x01b8)
+#define DP_MIE_CLKCON (0x027c)
+#define FREERUNCON (0x005c)
+#else
#define VIDCON1 (0x04)
+#endif
+
#define VIDCON1_LINECNT_MASK (0x7ff << 16)
#define VIDCON1_LINECNT_SHIFT (16)
#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
@@ -90,7 +115,11 @@
#define VIDCON1_VSTATUS_VSYNC (0x0 << 13)
#define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13)
#define VIDCON1_VSTATUS_ACTIVE (0x2 << 13)
-#define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13)
+#define VIDCON1_VSTATUS_FRONTPORCH (0x3 << 13)
+#define VIDCON1_VSTATUS_MASK (0x3 << 13)
+#define VIDCON1_VCLK_MASK (0x3 << 9)
+#define VIDCON1_VCLK_HOLD (0x0 << 9)
+#define VIDCON1_VCLK_RUN (0x1 << 9)
#define VIDCON1_INV_VCLK (1 << 7)
#define VIDCON1_INV_HSYNC (1 << 6)
@@ -99,18 +128,27 @@
/* VIDCON2 */
-#define VIDCON2 (0x08)
-#define VIDCON2_EN601 (1 << 23)
-#define VIDCON2_TVFMTSEL_SW (1 << 14)
-
-#define VIDCON2_TVFMTSEL1_MASK (0x3 << 12)
-#define VIDCON2_TVFMTSEL1_SHIFT (12)
-#define VIDCON2_TVFMTSEL1_RGB (0x0 << 12)
-#define VIDCON2_TVFMTSEL1_YUV422 (0x1 << 12)
-#define VIDCON2_TVFMTSEL1_YUV444 (0x2 << 12)
-
-#define VIDCON2_ORGYCbCr (1 << 8)
-#define VIDCON2_YUVORDCrCb (1 << 7)
+#define VIDCON2 (0x08)
+#define VIDCON2_WB_SKIP_1_2 (1 << 0)
+#define VIDCON2_WB_SKIP_1_3 (1 << 1)
+#define VIDCON2_WB_SKIP_1_4 (3 << 0)
+#define VIDCON2_WB_SKIP_1_5 (1 << 2)
+#define VIDCON2_WB_SKIP_MASK (0x1f << 0)
+#define VIDCON2_EN601 (1 << 23)
+#define VIDCON2_WB_DISABLE (0 << 15)
+#define VIDCON2_WB_ENABLE (1 << 15)
+#define VIDCON2_WB_MASK (1 << 15)
+#define VIDCON2_TVFORMATSEL_HW (0 << 14)
+#define VIDCON2_TVFORMATSEL_SW (1 << 14)
+#define VIDCON2_TVFORMATSEL_HW_SW_MASK (1 << 14)
+#define VIDCON2_TVFORMATSEL_MASK (0x3 << 12)
+#define VIDCON2_TVFORMATSEL_SHIFT (12)
+#define VIDCON2_TVFORMATSEL_RGB (0x0 << 12)
+#define VIDCON2_TVFORMATSEL_YUV422 (0x1 << 12)
+#define VIDCON2_TVFORMATSEL_YUV444 (0x2 << 12)
+
+#define VIDCON2_ORGYCbCr (1 << 8)
+#define VIDCON2_YUVORDCrCb (1 << 7)
/* PRTCON (S3C6410, S5PC100)
* Might not be present in the S3C6410 documentation,
@@ -163,24 +201,29 @@
#define VIDTCON1_HSPW_LIMIT (0xff)
#define VIDTCON1_HSPW(_x) ((_x) << 0)
-#define VIDTCON2 (0x18)
+/* VIDTCON2 */
+
+#define VIDTCON2_LINEVAL_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
#define VIDTCON2_LINEVAL_SHIFT (11)
#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
-#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
+#define VIDTCON2_LINEVAL(_x) (((_x) & 0x7ff) << 11)
+#define VIDTCON2_HOZVAL_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
#define VIDTCON2_HOZVAL_SHIFT (0)
#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
-#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
+#define VIDTCON2_HOZVAL(_x) (((_x) & 0x7ff) << 0)
/* WINCONx */
-
#define WINCONx_BITSWP (1 << 18)
#define WINCONx_BYTSWP (1 << 17)
#define WINCONx_HAWSWP (1 << 16)
#define WINCONx_WSWP (1 << 15)
+#define WINCONx_ENLOCAL_MASK (0xf << 15)
+#define WINCONx_INRGB_RGB (0 << 13)
+#define WINCONx_INRGB_YCBCR (1 << 13)
#define WINCONx_BURSTLEN_MASK (0x3 << 9)
#define WINCONx_BURSTLEN_SHIFT (9)
#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
@@ -200,6 +243,7 @@
#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
#define WINCON1_BLD_PIX (1 << 6)
+#define WINCON1_BLD_PLANE (0 << 6)
#define WINCON1_ALPHA_SEL (1 << 1)
#define WINCON1_BPPMODE_MASK (0xf << 2)
@@ -228,25 +272,29 @@
/* Local input channels (windows 0-2) */
#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win)))
+#define VIDOSDxA_TOPLEFT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDOSDxA_TOPLEFT_X_MASK (0x7ff << 11)
#define VIDOSDxA_TOPLEFT_X_SHIFT (11)
#define VIDOSDxA_TOPLEFT_X_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_X(_x) ((_x) << 11)
+#define VIDOSDxA_TOPLEFT_X(_x) (((_x) & 0x7ff) << 11)
+#define VIDOSDxA_TOPLEFT_Y_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDOSDxA_TOPLEFT_Y_MASK (0x7ff << 0)
#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
-#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
+#define VIDOSDxA_TOPLEFT_Y(_x) (((_x) & 0x7ff) << 0)
+#define VIDOSDxB_BOTRIGHT_X_E(_x) ((((_x) & 0x800) >> 11) << 23)
#define VIDOSDxB_BOTRIGHT_X_MASK (0x7ff << 11)
#define VIDOSDxB_BOTRIGHT_X_SHIFT (11)
#define VIDOSDxB_BOTRIGHT_X_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_X(_x) ((_x) << 11)
+#define VIDOSDxB_BOTRIGHT_X(_x) (((_x) & 0x7ff) << 11)
+#define VIDOSDxB_BOTRIGHT_Y_E(_x) ((((_x) & 0x800) >> 11) << 22)
#define VIDOSDxB_BOTRIGHT_Y_MASK (0x7ff << 0)
#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
-#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
+#define VIDOSDxB_BOTRIGHT_Y(_x) (((_x) & 0x7ff) << 0)
/* For VIDOSD[1..4]C */
#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
@@ -278,15 +326,17 @@
#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
+#define VIDW_BUF_SIZE_OFFSET_E(_x) ((((_x) & 0x2000) >> 13) << 27)
#define VIDW_BUF_SIZE_OFFSET_MASK (0x1fff << 13)
#define VIDW_BUF_SIZE_OFFSET_SHIFT (13)
#define VIDW_BUF_SIZE_OFFSET_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_OFFSET(_x) ((_x) << 13)
+#define VIDW_BUF_SIZE_OFFSET(_x) (((_x) & 0x1fff) << 13)
+#define VIDW_BUF_SIZE_PAGEWIDTH_E(_x) ((((_x) & 0x2000) >> 13) << 26)
#define VIDW_BUF_SIZE_PAGEWIDTH_MASK (0x1fff << 0)
#define VIDW_BUF_SIZE_PAGEWIDTH_SHIFT (0)
#define VIDW_BUF_SIZE_PAGEWIDTH_LIMIT (0x1fff)
-#define VIDW_BUF_SIZE_PAGEWIDTH(_x) ((_x) << 0)
+#define VIDW_BUF_SIZE_PAGEWIDTH(_x) (((_x) & 0x1fff) << 0)
/* Interrupt controls and status */
@@ -384,3 +434,22 @@
#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
+/* Clock gate mode control */
+#define REG_CLKGATE_MODE (0x1b0)
+#define REG_CLKGATE_MODE_AUTO_CLOCK_GATE (0 << 0)
+#define REG_CLKGATE_MODE_NON_CLOCK_GATE (1 << 0)
+
+/* Blending equation control */
+#define BLENDCON (0x260)
+#define BLENDCON_NEW_MASK (1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
+
+/* DP clock control */
+#define DPCLKCON (0x27c)
+#define DPCLKCON_ENABLE (1 << 1)
+
+/* Window alpha control */
+#define VIDW0ALPHA0 (0x200)
+#define VIDW0ALPHA1 (0x204)
+#define DUALRGB (0x27c)
diff --git a/arch/arm/plat-samsung/include/plat/regs-otg.h b/arch/arm/plat-samsung/include/plat/regs-otg.h
new file mode 100644
index 0000000..baeda10
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-otg.h
@@ -0,0 +1,260 @@
+/* linux/arch/arm/plat-samsung/include/plat/regs-otg.h
+ *
+ * Copyright (C) 2004 Herbert Poetzl <herbert@13thfloor.at>
+ *
+ * This include file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+*/
+
+#ifndef __ASM_ARCH_REGS_USB_OTG_HS_H
+#define __ASM_ARCH_REGS_USB_OTG_HS_H
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTG_PHYREG(x) ((x) + S3C_VA_HSPHY)
+#define S3C_USBOTG_PHYPWR S3C_USBOTG_PHYREG(0x0)
+#define S3C_USBOTG_PHYCLK S3C_USBOTG_PHYREG(0x4)
+#define S3C_USBOTG_RSTCON S3C_USBOTG_PHYREG(0x8)
+#define S3C_USBOTG_PHYTUNE S3C_USBOTG_PHYREG(0x24)
+#define S3C_USBOTG_PHY1CON S3C_USBOTG_PHYREG(0x34)
+
+/* USB2.0 OTG Controller register */
+#define S3C_USBOTGREG(x) (x)
+/*============================================================================================== */
+ /* Core Global Registers */
+#define S3C_UDC_OTG_GOTGCTL S3C_USBOTGREG(0x000) /* OTG Control & Status */
+#define S3C_UDC_OTG_GOTGINT S3C_USBOTGREG(0x004) /* OTG Interrupt */
+#define S3C_UDC_OTG_GAHBCFG S3C_USBOTGREG(0x008) /* Core AHB Configuration */
+#define S3C_UDC_OTG_GUSBCFG S3C_USBOTGREG(0x00C) /* Core USB Configuration */
+#define S3C_UDC_OTG_GRSTCTL S3C_USBOTGREG(0x010) /* Core Reset */
+#define S3C_UDC_OTG_GINTSTS S3C_USBOTGREG(0x014) /* Core Interrupt */
+#define S3C_UDC_OTG_GINTMSK S3C_USBOTGREG(0x018) /* Core Interrupt Mask */
+#define S3C_UDC_OTG_GRXSTSR S3C_USBOTGREG(0x01C) /* Receive Status Debug Read/Status Read */
+#define S3C_UDC_OTG_GRXSTSP S3C_USBOTGREG(0x020) /* Receive Status Debug Pop/Status Pop */
+#define S3C_UDC_OTG_GRXFSIZ S3C_USBOTGREG(0x024) /* Receive FIFO Size */
+#define S3C_UDC_OTG_GNPTXFSIZ S3C_USBOTGREG(0x028) /* Non-Periodic Transmit FIFO Size */
+#define S3C_UDC_OTG_GNPTXSTS S3C_USBOTGREG(0x02C) /* Non-Periodic Transmit FIFO/Queue Status */
+
+#define S3C_UDC_OTG_HPTXFSIZ S3C_USBOTGREG(0x100) /* Host Periodic Transmit FIFO Size */
+#define S3C_UDC_OTG_DIEPTXF(n) S3C_USBOTGREG(0x104 + (n-1)*0x4)/* Device IN EP Transmit FIFO Size Register */
+
+/*============================================================================================== */
+/* Host Mode Registers */
+/*------------------------------------------------ */
+/* Host Global Registers */
+#define S3C_UDC_OTG_HCFG S3C_USBOTGREG(0x400) /* Host Configuration */
+#define S3C_UDC_OTG_HFIR S3C_USBOTGREG(0x404) /* Host Frame Interval */
+#define S3C_UDC_OTG_HFNUM S3C_USBOTGREG(0x408) /* Host Frame Number/Frame Time Remaining */
+#define S3C_UDC_OTG_HPTXSTS S3C_USBOTGREG(0x410) /* Host Periodic Transmit FIFO/Queue Status */
+#define S3C_UDC_OTG_HAINT S3C_USBOTGREG(0x414) /* Host All Channels Interrupt */
+#define S3C_UDC_OTG_HAINTMSK S3C_USBOTGREG(0x418) /* Host All Channels Interrupt Mask */
+
+/*------------------------------------------------ */
+/* Host Port Control & Status Registers */
+#define S3C_UDC_OTG_HPRT S3C_USBOTGREG(0x440) /* Host Port Control & Status */
+
+/*------------------------------------------------ */
+/* Host Channel-Specific Registers */
+#define S3C_UDC_OTG_HCCHAR0 S3C_USBOTGREG(0x500) /* Host Channel-0 Characteristics */
+#define S3C_UDC_OTG_HCSPLT0 S3C_USBOTGREG(0x504) /* Host Channel-0 Split Control */
+#define S3C_UDC_OTG_HCINT0 S3C_USBOTGREG(0x508) /* Host Channel-0 Interrupt */
+#define S3C_UDC_OTG_HCINTMSK0 S3C_USBOTGREG(0x50C) /* Host Channel-0 Interrupt Mask */
+#define S3C_UDC_OTG_HCTSIZ0 S3C_USBOTGREG(0x510) /* Host Channel-0 Transfer Size */
+#define S3C_UDC_OTG_HCDMA0 S3C_USBOTGREG(0x514) /* Host Channel-0 DMA Address */
+
+/*============================================================================================== */
+/* Device Mode Registers */
+/*------------------------------------------------ */
+/* Device Global Registers */
+#define S3C_UDC_OTG_DCFG S3C_USBOTGREG(0x800) /* Device Configuration */
+#define S3C_UDC_OTG_DCTL S3C_USBOTGREG(0x804) /* Device Control */
+#define S3C_UDC_OTG_DSTS S3C_USBOTGREG(0x808) /* Device Status */
+#define S3C_UDC_OTG_DIEPMSK S3C_USBOTGREG(0x810) /* Device IN Endpoint Common Interrupt Mask */
+#define S3C_UDC_OTG_DOEPMSK S3C_USBOTGREG(0x814) /* Device OUT Endpoint Common Interrupt Mask */
+#define S3C_UDC_OTG_DAINT S3C_USBOTGREG(0x818) /* Device All Endpoints Interrupt */
+#define S3C_UDC_OTG_DAINTMSK S3C_USBOTGREG(0x81C) /* Device All Endpoints Interrupt Mask */
+#define S3C_UDC_OTG_DTKNQR1 S3C_USBOTGREG(0x820) /* Device IN Token Sequence Learning Queue Read 1 */
+#define S3C_UDC_OTG_DTKNQR2 S3C_USBOTGREG(0x824) /* Device IN Token Sequence Learning Queue Read 2 */
+#define S3C_UDC_OTG_DVBUSDIS S3C_USBOTGREG(0x828) /* Device VBUS Discharge Time */
+#define S3C_UDC_OTG_DVBUSPULSE S3C_USBOTGREG(0x82C) /* Device VBUS Pulsing Time */
+#define S3C_UDC_OTG_DTKNQR3 S3C_USBOTGREG(0x830) /* Device IN Token Sequence Learning Queue Read 3 */
+#define S3C_UDC_OTG_DTKNQR4 S3C_USBOTGREG(0x834) /* Device IN Token Sequence Learning Queue Read 4 */
+
+/*------------------------------------------------ */
+/* Device Logical IN Endpoint-Specific Registers */
+#define S3C_UDC_OTG_DIEPCTL(n) S3C_USBOTGREG(0x900 + n*0x20) /* Device IN Endpoint n Control */
+#define S3C_UDC_OTG_DIEPINT(n) S3C_USBOTGREG(0x908 + n*0x20) /* Device IN Endpoint n Interrupt */
+#define S3C_UDC_OTG_DIEPTSIZ(n) S3C_USBOTGREG(0x910 + n*0x20) /* Device IN Endpoint n Transfer Size */
+#define S3C_UDC_OTG_DIEPDMA(n) S3C_USBOTGREG(0x914 + n*0x20) /* Device IN Endpoint n DMA Address */
+
+/*------------------------------------------------ */
+/* Device Logical OUT Endpoint-Specific Registers */
+#define S3C_UDC_OTG_DOEPCTL(n) S3C_USBOTGREG(0xB00 + n*0x20) /* Device OUT Endpoint n Control */
+#define S3C_UDC_OTG_DOEPINT(n) S3C_USBOTGREG(0xB08 + n*0x20) /* Device OUT Endpoint n Interrupt */
+#define S3C_UDC_OTG_DOEPTSIZ(n) S3C_USBOTGREG(0xB10 + n*0x20) /* Device OUT Endpoint n Transfer Size */
+#define S3C_UDC_OTG_DOEPDMA(n) S3C_USBOTGREG(0xB14 + n*0x20) /* Device OUT Endpoint n DMA Address */
+
+/*------------------------------------------------ */
+/* Endpoint FIFO address */
+#define S3C_UDC_OTG_EP0_FIFO S3C_USBOTGREG(0x1000)
+#define S3C_UDC_OTG_EP1_FIFO S3C_USBOTGREG(0x2000)
+#define S3C_UDC_OTG_EP2_FIFO S3C_USBOTGREG(0x3000)
+#define S3C_UDC_OTG_EP3_FIFO S3C_USBOTGREG(0x4000)
+#define S3C_UDC_OTG_EP4_FIFO S3C_USBOTGREG(0x5000)
+#define S3C_UDC_OTG_EP5_FIFO S3C_USBOTGREG(0x6000)
+#define S3C_UDC_OTG_EP6_FIFO S3C_USBOTGREG(0x7000)
+#define S3C_UDC_OTG_EP7_FIFO S3C_USBOTGREG(0x8000)
+#define S3C_UDC_OTG_EP8_FIFO S3C_USBOTGREG(0x9000)
+#define S3C_UDC_OTG_EP9_FIFO S3C_USBOTGREG(0xA000)
+#define S3C_UDC_OTG_EP10_FIFO S3C_USBOTGREG(0xB000)
+#define S3C_UDC_OTG_EP11_FIFO S3C_USBOTGREG(0xC000)
+#define S3C_UDC_OTG_EP12_FIFO S3C_USBOTGREG(0xD000)
+#define S3C_UDC_OTG_EP13_FIFO S3C_USBOTGREG(0xE000)
+#define S3C_UDC_OTG_EP14_FIFO S3C_USBOTGREG(0xF000)
+#define S3C_UDC_OTG_EP15_FIFO S3C_USBOTGREG(0x10000)
+
+/*===================================================================== */
+/*definitions related to CSR setting */
+
+/* S3C_UDC_OTG_GOTGCTL */
+#define B_SESSION_VALID (0x1<<19)
+#define A_SESSION_VALID (0x1<<18)
+
+/* S3C_UDC_OTG_GAHBCFG */
+#define PTXFE_HALF (0<<8)
+#define PTXFE_ZERO (1<<8)
+#define NPTXFE_HALF (0<<7)
+#define NPTXFE_ZERO (1<<7)
+#define MODE_SLAVE (0<<5)
+#define MODE_DMA (1<<5)
+#define BURST_SINGLE (0<<1)
+#define BURST_INCR (1<<1)
+#define BURST_INCR4 (3<<1)
+#define BURST_INCR8 (5<<1)
+#define BURST_INCR16 (7<<1)
+#define GBL_INT_UNMASK (1<<0)
+#define GBL_INT_MASK (0<<0)
+
+/* S3C_UDC_OTG_GRSTCTL */
+#define AHB_MASTER_IDLE (1u<<31)
+#define CORE_SOFT_RESET (0x1<<0)
+
+/* S3C_UDC_OTG_GINTSTS/S3C_UDC_OTG_GINTMSK core interrupt register */
+#define INT_RESUME (1u<<31)
+#define INT_DISCONN (0x1<<29)
+#define INT_CONN_ID_STS_CNG (0x1<<28)
+#define INT_OUT_EP (0x1<<19)
+#define INT_IN_EP (0x1<<18)
+#define INT_ENUMDONE (0x1<<13)
+#define INT_RESET (0x1<<12)
+#define INT_SUSPEND (0x1<<11)
+#define INT_EARLY_SUSPEND (0x1<<10)
+#define INT_NP_TX_FIFO_EMPTY (0x1<<5)
+#define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
+#define INT_SOF (0x1<<3)
+#define INT_DEV_MODE (0x0<<0)
+#define INT_HOST_MODE (0x1<<1)
+#define INT_GOUTNakEff (0x01<<7)
+#define INT_GINNakEff (0x01<<6)
+
+#define FULL_SPEED_CONTROL_PKT_SIZE 8
+#define FULL_SPEED_BULK_PKT_SIZE 64
+
+#define HIGH_SPEED_CONTROL_PKT_SIZE 64
+#define HIGH_SPEED_BULK_PKT_SIZE 512
+
+#ifdef CONFIG_CPU_S5P6450
+#define RX_FIFO_SIZE (4096>>2)
+#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE
+#define NPTX_FIFO_SIZE (4096>>2)
+#define PTX_FIFO_SIZE (1520>>2)
+#else
+#define RX_FIFO_SIZE (4096>>2)
+#define NPTX_FIFO_START_ADDR RX_FIFO_SIZE
+#define NPTX_FIFO_SIZE (4096>>2)
+#define PTX_FIFO_SIZE (1024>>2)
+#endif
+
+/* Enumeration speed */
+#define USB_HIGH_30_60MHZ (0x0<<1)
+#define USB_FULL_30_60MHZ (0x1<<1)
+#define USB_LOW_6MHZ (0x2<<1)
+#define USB_FULL_48MHZ (0x3<<1)
+
+/* S3C_UDC_OTG_GRXSTSP STATUS */
+#define OUT_PKT_RECEIVED (0x2<<17)
+#define OUT_TRANSFER_COMPLELTED (0x3<<17)
+#define SETUP_TRANSACTION_COMPLETED (0x4<<17)
+#define SETUP_PKT_RECEIVED (0x6<<17)
+#define GLOBAL_OUT_NAK (0x1<<17)
+
+/* S3C_UDC_OTG_DCTL device control register */
+#define NORMAL_OPERATION (0x1<<0)
+#define SOFT_DISCONNECT (0x1<<1)
+#define TEST_CONTROL_MASK (0x7<<4)
+#define TEST_J_MODE (0x1<<4)
+#define TEST_K_MODE (0x2<<4)
+#define TEST_SE0_NAK_MODE (0x3<<4)
+#define TEST_PACKET_MODE (0x4<<4)
+#define TEST_FORCE_ENABLE_MODE (0x5<<4)
+
+/* S3C_UDC_OTG_DAINT device all endpoint interrupt register */
+#define DAINT_OUT_BIT (16)
+#define DAINT_MASK (0xFFFF)
+
+/* S3C_UDC_OTG_DIEPCTL0/DOEPCTL0 device control IN/OUT endpoint 0 control register */
+#define DEPCTL_EPENA (0x1<<31)
+#define DEPCTL_EPDIS (0x1<<30)
+#define DEPCTL_SETD1PID (0x1<<29)
+#define DEPCTL_SETD0PID (0x1<<28)
+#define DEPCTL_SNAK (0x1<<27)
+#define DEPCTL_CNAK (0x1<<26)
+#define DEPCTL_STALL (0x1<<21)
+#define DEPCTL_TYPE_BIT (18)
+#define DEPCTL_TXFNUM_BIT (22)
+#define DEPCTL_TXFNUM_MASK (0xF<<22)
+#define DEPCTL_TYPE_MASK (0x3<<18)
+#define DEPCTL_CTRL_TYPE (0x0<<18)
+#define DEPCTL_ISO_TYPE (0x1<<18)
+#define DEPCTL_BULK_TYPE (0x2<<18)
+#define DEPCTL_INTR_TYPE (0x3<<18)
+#define DEPCTL_NAKSTS (0x1<<17)
+#define DEPCTL_USBACTEP (0x1<<15)
+#define DEPCTL_NEXT_EP_BIT (11)
+#define DEPCTL_MPS_BIT (0)
+#define DEPCTL_MPS_MASK (0x7FF)
+
+#define DEPCTL0_MPS_64 (0x0<<0)
+#define DEPCTL0_MPS_32 (0x1<<0)
+#define DEPCTL0_MPS_16 (0x2<<0)
+#define DEPCTL0_MPS_8 (0x3<<0)
+#define DEPCTL_MPS_BULK_512 (512<<0)
+#define DEPCTL_MPS_INT_MPS_16 (16<<0)
+
+#define DIEPCTL0_NEXT_EP_BIT (11)
+
+/* S3C_UDC_OTG_DIEPCTLn/DOEPCTLn device control IN/OUT endpoint n control register */
+
+/* S3C_UDC_OTG_DIEPMSK/DOEPMSK device IN/OUT endpoint common interrupt mask register */
+/* S3C_UDC_OTG_DIEPINTn/DOEPINTn device IN/OUT endpoint interrupt register */
+#define BACK2BACK_SETUP_RECEIVED (0x1<<6)
+#define INTKNEPMIS (0x1<<5)
+#define INTKN_TXFEMP (0x1<<4)
+#define NON_ISO_IN_EP_TIMEOUT (0x1<<3)
+#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3)
+#define AHB_ERROR (0x1<<2)
+#define EPDISBLD (0x1<<1)
+#define TRANSFER_DONE (0x1<<0)
+
+/*DIEPTSIZ0 / DOEPTSIZ0 */
+
+/* DEPTSIZ common bit */
+#define DEPTSIZ_PKT_CNT_BIT (19)
+#define DEPTSIZ_XFER_SIZE_BIT (0)
+
+#define DEPTSIZ_SETUP_PKCNT_1 (1<<29)
+#define DEPTSIZ_SETUP_PKCNT_2 (2<<29)
+#define DEPTSIZ_SETUP_PKCNT_3 (3<<29)
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 116edfe..5adf78f 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -255,6 +255,8 @@ struct s3c24xx_uart_clksrc {
* arch/arm/mach-s3c2410/ directory.
*/
+struct uart_port;
+
struct s3c2410_uartcfg {
unsigned char hwport; /* hardware port number */
unsigned char unused;
@@ -269,6 +271,9 @@ struct s3c2410_uartcfg {
struct s3c24xx_uart_clksrc *clocks;
unsigned int clocks_size;
+
+ void (*wake_peer)(struct uart_port *);
+ void (*set_runstate)(int onoff);
};
/* s3c24xx_uart_devs
@@ -282,4 +287,3 @@ extern struct platform_device *s3c24xx_uart_devs[4];
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARM_REGS_SERIAL_H */
-
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h
new file mode 100644
index 0000000..50d2954
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb3-exynos-drd-phy.h
@@ -0,0 +1,75 @@
+/* arch/arm/plat-samsung/include/plat/regs-usb3-exynos-udc-drd.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co. Ltd
+ * Author: Anton Tikhomirov <av.tikhomirov@samsung.com>
+ *
+ * Exynos SuperSpeed USB 3.0 DRD Controller PHY registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_SAMSUNG_REGS_USB3_EXYNOS_DRD_PHY_H
+#define __PLAT_SAMSUNG_REGS_USB3_EXYNOS_DRD_PHY_H __FILE__
+
+#define EXYNOS_USB3_PHYREG(x) ((x) + S5P_VA_SS_PHY)
+
+
+#define EXYNOS_USB3_LINKSYSTEM EXYNOS_USB3_PHYREG(0x04)
+#define EXYNOS_USB3_PHYUTMI EXYNOS_USB3_PHYREG(0x08)
+
+#define EXYNOS_USB3_PHYUTMI_OTGDISABLE (1 << 6)
+#define EXYNOS_USB3_PHYUTMI_FORCESUSPEND (1 << 1)
+#define EXYNOS_USB3_PHYUTMI_FORCESLEEP (1 << 0)
+
+#define EXYNOS_USB3_PHYPIPE EXYNOS_USB3_PHYREG(0x0C)
+
+
+#define EXYNOS_USB3_PHYCLKRST EXYNOS_USB3_PHYREG(0x10)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_MASK (0xff << 23)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_SHIFT (23)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_LIMIT (0xff)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(_x) ((_x) << 23)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_MASK (0x03 << 21)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_SHIFT (21)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_LIMIT (0x03)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE(_x) ((_x) << 21)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_EN (1 << 20)
+#define EXYNOS_USB3_PHYCLKRST_REF_SSP_EN (1 << 19)
+#define EXYNOS_USB3_PHYCLKRST_REF_CLKDIV2 (1 << 18)
+
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_SHIFT (11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_LIMIT (0x7f)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(_x) ((_x) << 11)
+
+#define EXYNOS_USB3_PHYCLKRST_FSEL_MASK (0x3f << 5)
+#define EXYNOS_USB3_PHYCLKRST_FSEL_SHIFT (5)
+#define EXYNOS_USB3_PHYCLKRST_FSEL_LIMIT (0x3f)
+#define EXYNOS_USB3_PHYCLKRST_FSEL(_x) ((_x) << 5)
+
+#define EXYNOS_USB3_PHYCLKRST_RETENABLEN (1 << 4)
+
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_MASK (0x03 << 2)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_SHIFT (2)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_LIMIT (0x03)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL(_x) ((_x) << 2)
+
+#define EXYNOS_USB3_PHYCLKRST_PORTRESET (1 << 1)
+#define EXYNOS_USB3_PHYCLKRST_COMMONONN (1 << 0)
+
+#define EXYNOS_USB3_PHYREG0 EXYNOS_USB3_PHYREG(0x14)
+#define EXYNOS_USB3_PHYREG1 EXYNOS_USB3_PHYREG(0x18)
+#define EXYNOS_USB3_PHYPARAM0 EXYNOS_USB3_PHYREG(0x1C)
+#define EXYNOS_USB3_PHYPARAM1 EXYNOS_USB3_PHYREG(0x20)
+#define EXYNOS_USB3_PHYTERM EXYNOS_USB3_PHYREG(0x24)
+#define EXYNOS_USB3_PHYTEST EXYNOS_USB3_PHYREG(0x28)
+#define EXYNOS_USB3_PHYADP EXYNOS_USB3_PHYREG(0x2C)
+#define EXYNOS_USB3_PHYBATCHG EXYNOS_USB3_PHYREG(0x30)
+#define EXYNOS_USB3_PHYRESUME EXYNOS_USB3_PHYREG(0x34)
+#define EXYNOS_USB3_LINKPORT EXYNOS_USB3_PHYREG(0x44)
+#endif /* __PLAT_SAMSUNG_REGS_USB3_EXYNOS_DRD_PHY_H */
diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h
new file mode 100644
index 0000000..65967ca
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/rtc-core.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung RTC Device core function
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the term of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_RTC_CORE_H
+#define __ASM_PLAT_RTC_CORE_H __FILE__
+
+/* These function are only for use with the core support code, such as
+ * the cpu specific initialization code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_RTC
+ s3c_device_rtc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_RTC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
index 8107442..ee155ad 100644
--- a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -84,6 +84,23 @@ enum dma_ch {
DMACH_SLIMBUS4_TX,
DMACH_SLIMBUS5_RX,
DMACH_SLIMBUS5_TX,
+ DMACH_MIPI_HSI0,
+ DMACH_MIPI_HSI1,
+ DMACH_MIPI_HSI2,
+ DMACH_MIPI_HSI3,
+ DMACH_MIPI_HSI4,
+ DMACH_MIPI_HSI5,
+ DMACH_MIPI_HSI6,
+ DMACH_MIPI_HSI7,
+ DMACH_DISP1,
+ DMACH_MTOM_0,
+ DMACH_MTOM_1,
+ DMACH_MTOM_2,
+ DMACH_MTOM_3,
+ DMACH_MTOM_4,
+ DMACH_MTOM_5,
+ DMACH_MTOM_6,
+ DMACH_MTOM_7,
/* END Marker, also used to denote a reserved channel */
DMACH_MAX,
};
@@ -93,6 +110,11 @@ static inline bool s3c_dma_has_circular(void)
return true;
}
+static inline bool s3c_dma_has_infiniteloop(void)
+{
+ return true;
+}
+
#include <plat/dma.h>
#endif /* __S3C_DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index 4c16fa3..353ceb6 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -71,5 +71,6 @@ extern void s3c64xx_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
+extern void exynos_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
#endif /* __S3C64XX_PLAT_SPI_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 058e096..c0e3799 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -18,6 +18,8 @@
#ifndef __PLAT_S3C_SDHCI_H
#define __PLAT_S3C_SDHCI_H __FILE__
+/* ignore mmc suspend/resume for BCM WIFI */
+#define S3C_SDHCI_PM_IGNORE_SUSPEND_RESUME (1 << 30)
struct platform_device;
struct mmc_host;
struct mmc_card;
@@ -72,8 +74,11 @@ struct s3c_sdhci_platdata {
char **clocks; /* set of clock sources */
+ char *vmmc_name; /* name for regulator */
int ext_cd_gpio;
bool ext_cd_gpio_invert;
+ unsigned int pm_flags;
+
int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
int state));
int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
@@ -84,6 +89,10 @@ struct s3c_sdhci_platdata {
void __iomem *regbase,
struct mmc_ios *ios,
struct mmc_card *card);
+#ifdef CONFIG_MACH_PX
+ int (*ext_pdev)(struct platform_device *dev_id);
+#endif
+
};
/**
@@ -126,6 +135,10 @@ extern void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void exynos5_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C2416 SDHCI setup */
@@ -390,4 +403,58 @@ static inline void exynos4_default_sdhci3(void) { }
#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
+extern void mmc_force_presence_change(struct platform_device *pdev);
+
+/* EXYNOS5 SDHCI setup */
+#ifdef CONFIG_EXYNOS4_SETUP_SDHCI
+extern char *exynos4_hsmmc_clksrcs[4];
+
+extern void exynos4_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void exynos5_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = exynos5_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = exynos5_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = exynos5_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos5_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = exynos5_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void exynos5_default_sdhci0(void) { }
+static inline void exynos5_default_sdhci1(void) { }
+static inline void exynos5_default_sdhci2(void) { }
+static inline void exynos5_default_sdhci3(void) { }
+
+#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/sysmmu.h b/arch/arm/plat-samsung/include/plat/sysmmu.h
new file mode 100644
index 0000000..bbe2091
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/sysmmu.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung System MMU driver for Exynos platforms
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM__PLAT_SYSMMU_H
+#define __ASM__PLAT_SYSMMU_H __FILE__
+
+#include <linux/list.h>
+#include <linux/atomic.h>
+#include <linux/spinlock.h>
+
+enum exynos_sysmmu_inttype {
+ SYSMMU_PAGEFAULT,
+ SYSMMU_AR_MULTIHIT,
+ SYSMMU_AW_MULTIHIT,
+ SYSMMU_BUSERROR,
+ SYSMMU_AR_SECURITY,
+ SYSMMU_AR_ACCESS,
+ SYSMMU_AW_SECURITY,
+ SYSMMU_AW_PROTECTION, /* 7 */
+ SYSMMU_FAULT_UNKNOWN,
+ SYSMMU_FAULTS_NUM
+};
+
+/*
+ * @itype: type of fault.
+ * @pgtable_base: the physical address of page table base. This is 0 if @itype
+ * is SYSMMU_BUSERROR.
+ * @fault_addr: the device (virtual) address that the System MMU tried to
+ * translated. This is 0 if @itype is SYSMMU_BUSERROR.
+ */
+typedef int (*sysmmu_fault_handler_t)(enum exynos_sysmmu_inttype itype,
+ unsigned long pgtable_base, unsigned long fault_addr);
+
+#ifdef CONFIG_EXYNOS_IOMMU
+/**
+ * exynos_sysmmu_enable() - enable system mmu
+ * @owner: The device whose System MMU is about to be enabled.
+ * @pgd: Base physical address of the 1st level page table
+ *
+ * This function enable system mmu to transfer address
+ * from virtual address to physical address.
+ * Return non-zero if it fails to enable System MMU.
+ */
+int exynos_sysmmu_enable(struct device *owner, unsigned long pgd);
+
+/**
+ * exynos_sysmmu_disable() - disable sysmmu mmu of ip
+ * @owner: The device whose System MMU is about to be disabled.
+ *
+ * This function disable system mmu to transfer address
+ * from virtual address to physical address
+ */
+bool exynos_sysmmu_disable(struct device *owner);
+
+/**
+ * exynos_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
+ * @owner: The device whose System MMU.
+ *
+ * This function flush all TLB entry in system mmu
+ */
+void exynos_sysmmu_tlb_invalidate(struct device *owner);
+
+/** exynos_sysmmu_set_fault_handler() - Fault handler for System MMUs
+ * Called when interrupt occurred by the System MMUs
+ * The device drivers of peripheral devices that has a System MMU can implement
+ * a fault handler to resolve address translation fault by System MMU.
+ * The meanings of return value and parameters are described below.
+ *
+ * return value: non-zero if the fault is correctly resolved.
+ * zero if the fault is not handled.
+ */
+void exynos_sysmmu_set_fault_handler(struct device *sysmmu,
+ sysmmu_fault_handler_t handler);
+
+/** exynos_sysmmu_set_prefbuf() - Initialize prefetch buffers of System MMU v3
+ * @owner: The device which need to set the prefetch buffers
+ * @base0: The start virtual address of the area of the @owner device that the
+ * first prefetch buffer loads translation descriptors
+ * @size0: The last virtual address of the area of the @owner device that the
+ * first prefetch buffer loads translation descriptors.
+ * @base1: The start virtual address of the area of the @owner device that the
+ * second prefetch buffer loads translation descriptors. This will be
+ * ignored if @size1 is 0 and this function assigns the 2 prefetch
+ * buffers with each half of the area specified by @base0 and @size0
+ * @size1: The last virtual address of the area of the @owner device that the
+ * prefetch buffer loads translation descriptors. This can be 0. See
+ * the description of @base1 for more information with @size1 = 0
+ */
+void exynos_sysmmu_set_prefbuf(struct device *owner,
+ unsigned long base0, unsigned long size0,
+ unsigned long base1, unsigned long size1);
+#else /* CONFIG_EXYNOS_IOMMU */
+#define exynos_sysmmu_enable(owner, pgd) do { } while (0)
+#define exynos_sysmmu_disable(owner) do { } while (0)
+#define exynos_sysmmu_tlb_invalidate(owner) do { } while (0)
+#define exynos_sysmmu_set_fault_handler(sysmmu, handler) do { } while (0)
+#define exynos_sysmmu_set_prefbuf(owner, b0, s0, b1, s1) do { } while (0)
+#endif
+#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h
index 26fdb22..3fb52b9 100644
--- a/arch/arm/plat-samsung/include/plat/ts.h
+++ b/arch/arm/plat-samsung/include/plat/ts.h
@@ -14,10 +14,16 @@ struct s3c2410_ts_mach_info {
int delay;
int presc;
int oversampling_shift;
+
+ int cal_x_max;
+ int cal_y_max;
+ int cal_param[7];
+
void (*cfg_gpio)(struct platform_device *dev);
};
extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+extern void s3c24xx_ts1_set_platdata(struct s3c2410_ts_mach_info *);
/* defined by architecture to configure gpio */
extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/plat-samsung/include/plat/tv-core.h b/arch/arm/plat-samsung/include/plat/tv-core.h
new file mode 100644
index 0000000..d647eec
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/tv-core.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/plat-samsung/include/plat/tv.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * Tomasz Stanislawski <t.stanislaws@samsung.com>
+ *
+ * Samsung TV driver core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __SAMSUNG_PLAT_TV_H
+#define __SAMSUNG_PLAT_TV_H __FILE__
+
+/*
+ * These functions are only for use with the core support code, such as
+ * the CPU-specific initialization code.
+ */
+
+/* Re-define device name to differentiate the subsystem in various SoCs. */
+static inline void s5p_hdmi_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+ s5p_device_hdmi.name = name;
+#endif
+}
+
+static inline void s5p_mixer_setname(char *name)
+{
+#ifdef CONFIG_S5P_DEV_TV
+ s5p_device_mixer.name = name;
+#endif
+}
+
+#endif /* __SAMSUNG_PLAT_TV_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
index a22a4f2..9b90b08 100644
--- a/arch/arm/plat-samsung/include/plat/udc-hs.h
+++ b/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -27,3 +27,14 @@ struct s3c_hsotg_plat {
enum s3c_hsotg_dmamode dma;
unsigned int is_osc : 1;
};
+
+typedef enum usb_cable_status {
+ USB_CABLE_DETACHED = 0,
+ USB_CABLE_ATTACHED,
+ USB_OTGHOST_DETACHED,
+ USB_OTGHOST_ATTACHED,
+ USB_POWERED_HOST_DETACHED,
+ USB_POWERED_HOST_ATTACHED,
+ USB_CABLE_DETACHED_WITHOUT_NOTI,
+} usb_cable_status;
+
diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
index 54b762a..4dc5adf 100644
--- a/arch/arm/plat-samsung/include/plat/watchdog-reset.h
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -10,26 +10,24 @@
* published by the Free Software Foundation.
*/
+#include <plat/clock.h>
#include <plat/regs-watchdog.h>
#include <mach/map.h>
+#include <linux/kernel.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
static inline void arch_wdt_reset(void)
{
- struct clk *wdtclk;
-
printk("arch_reset: attempting watchdog reset\n");
__raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */
- wdtclk = clk_get(NULL, "watchdog");
- if (!IS_ERR(wdtclk)) {
- clk_enable(wdtclk);
- } else
- printk(KERN_WARNING "%s: warning: cannot get watchdog clock\n", __func__);
+ if (s3c2410_wdtclk)
+ clk_enable(s3c2410_wdtclk);
/* put initial values into count and data */
__raw_writel(0x80, S3C2410_WTCNT);
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
index 657405c..384f131 100644
--- a/arch/arm/plat-samsung/irq-uart.c
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -23,6 +23,7 @@
#include <plat/irq-uart.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
+#include <asm/mach/irq.h>
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
* are consecutive when looking up the interrupt in the demux routines.
@@ -32,6 +33,12 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
int base = uirq->base_irq;
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
+
+ if (!(pend & 0xf))
+ do_bad_IRQ(irq, desc);
if (pend & (1 << 0))
generic_handle_irq(base);
@@ -41,6 +48,8 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(base + 2);
if (pend & (1 << 3))
generic_handle_irq(base + 3);
+
+ chained_irq_exit(chip, desc);
}
static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
@@ -65,6 +74,8 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_mask_ack = irq_gc_mask_and_ack_set;
+ ct->chip.irq_disable = irq_gc_mask_and_ack_set;
ct->regs.ack = S3C64XX_UINTP;
ct->regs.mask = S3C64XX_UINTM;
irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
index f714d06..7837f48 100644
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -21,10 +21,15 @@
#include <mach/map.h>
#include <plat/irq-vic-timer.h>
#include <plat/regs-timer.h>
+#include <asm/mach/irq.h>
static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
{
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
generic_handle_irq((int)desc->irq_data.handler_data);
+ chained_irq_exit(chip, desc);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
index efe1d56..2d40889 100644
--- a/arch/arm/plat-samsung/pd.c
+++ b/arch/arm/plat-samsung/pd.c
@@ -22,12 +22,22 @@ static int samsung_pd_probe(struct platform_device *pdev)
{
struct samsung_pd_info *pdata = pdev->dev.platform_data;
struct device *dev = &pdev->dev;
+ int ret = 0;
if (!pdata) {
dev_err(dev, "no device data specified\n");
return -ENOENT;
}
+ pdata->id = pdev->id;
+ if (pdata->init) {
+ ret = pdata->init(dev);
+ if (ret) {
+ dev_err(dev, "init fails");
+ return ret;
+ }
+ }
+
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -43,6 +53,32 @@ static int __devexit samsung_pd_remove(struct platform_device *pdev)
return 0;
}
+static int samsung_pd_suspend(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->save)
+ ret = pdata->save(dev);
+
+ dev_dbg(dev, "suspended\n");
+
+ return ret;
+}
+
+static int samsung_pd_resume(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->restore)
+ ret = pdata->restore(dev);
+
+ dev_dbg(dev, "resumed\n");
+
+ return ret;
+}
+
static int samsung_pd_runtime_suspend(struct device *dev)
{
struct samsung_pd_info *pdata = dev->platform_data;
@@ -51,7 +87,7 @@ static int samsung_pd_runtime_suspend(struct device *dev)
if (pdata->disable)
ret = pdata->disable(dev);
- dev_dbg(dev, "suspended\n");
+ dev_dbg(dev, "runtime suspended\n");
return ret;
}
@@ -63,11 +99,13 @@ static int samsung_pd_runtime_resume(struct device *dev)
if (pdata->enable)
ret = pdata->enable(dev);
- dev_dbg(dev, "resumed\n");
+ dev_dbg(dev, "runtime resumed\n");
return ret;
}
static const struct dev_pm_ops samsung_pd_pm_ops = {
+ .suspend = samsung_pd_suspend,
+ .resume = samsung_pd_resume,
.runtime_suspend = samsung_pd_runtime_suspend,
.runtime_resume = samsung_pd_runtime_resume,
};
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
index 9652820..c365b40 100644
--- a/arch/arm/plat-samsung/pm-gpio.c
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -21,6 +21,7 @@
#include <plat/gpio-core.h>
#include <plat/pm.h>
+#include <plat/cpu.h>
/* PM GPIO helpers */
@@ -318,6 +319,26 @@ static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
pm->save(ourchip);
}
+static int s3c_get_gpio_max_nr (void)
+{
+ static int gpio_max_nr = 0;
+
+ if (unlikely(!gpio_max_nr)) {
+ if (soc_is_exynos4210())
+ gpio_max_nr = EXYNOS4210_GPIO_END;
+ else if (soc_is_exynos4212() || soc_is_exynos4412())
+ gpio_max_nr = EXYNOS4212_GPIO_END;
+ else if (soc_is_exynos5210())
+ gpio_max_nr = EXYNOS5210_GPIO_END;
+ else if (soc_is_exynos5250())
+ gpio_max_nr = EXYNOS5250_GPIO_END;
+ else
+ gpio_max_nr = S3C_GPIO_END;
+ }
+
+ return gpio_max_nr;
+}
+
/**
* s3c_pm_save_gpios() - Save the state of the GPIO banks.
*
@@ -328,9 +349,12 @@ void s3c_pm_save_gpios(void)
{
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
+ unsigned int gpio_max_nr;
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
- ourchip = s3c_gpiolib_getchip(gpio_nr);
+ gpio_max_nr = s3c_get_gpio_max_nr();
+
+ for (gpio_nr = 0; gpio_nr < gpio_max_nr;) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip) {
gpio_nr++;
continue;
@@ -368,8 +392,11 @@ void s3c_pm_restore_gpios(void)
{
struct s3c_gpio_chip *ourchip;
unsigned int gpio_nr;
+ unsigned int gpio_max_nr;
+
+ gpio_max_nr = s3c_get_gpio_max_nr();
- for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ for (gpio_nr = 0; gpio_nr < gpio_max_nr;) {
ourchip = s3c_gpiolib_getchip(gpio_nr);
if (!ourchip) {
gpio_nr++;
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 5c0a440..e46ecce 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -18,6 +18,7 @@
#include <linux/delay.h>
#include <linux/serial_core.h>
#include <linux/io.h>
+#include <linux/power/charger-manager.h>
#include <asm/cacheflush.h>
#include <mach/hardware.h>
@@ -32,6 +33,7 @@
#include <mach/pm-core.h>
/* for external use */
+unsigned long s3c_suspend_wakeup_stat;
unsigned long s3c_pm_flags;
@@ -53,7 +55,9 @@ void s3c_pm_dbg(const char *fmt, ...)
vsprintf(buff, fmt, va);
va_end(va);
+#ifdef CONFIG_DEBUG_LL
printascii(buff);
+#endif
}
static inline void s3c_pm_debug_init(void)
@@ -63,7 +67,7 @@ static inline void s3c_pm_debug_init(void)
}
#else
-#define s3c_pm_debug_init() do { } while(0)
+#define s3c_pm_debug_init() do { } while (0)
#endif /* CONFIG_SAMSUNG_PM_DEBUG */
@@ -186,8 +190,13 @@ void s3c_pm_do_save(struct sleep_save *ptr, int count)
void s3c_pm_do_restore(struct sleep_save *ptr, int count)
{
for (; count > 0; count--, ptr++) {
- printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+#if defined(CONFIG_CPU_EXYNOS4210)
+ S3C_PMDBG("restore %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#else
+ S3C_PMDBG("restore %p (restore %08lx, was %08x)\n",
ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#endif
__raw_writel(ptr->val, ptr->reg);
}
@@ -206,8 +215,13 @@ void s3c_pm_do_restore(struct sleep_save *ptr, int count)
void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
{
- for (; count > 0; count--, ptr++)
+ for (; count > 0; count--, ptr++) {
+#if !defined(CONFIG_CPU_EXYNOS4210)
+ pr_debug("restore_core %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+#endif
__raw_writel(ptr->val, ptr->reg);
+ }
}
/* s3c2410_pm_show_resume_irqs
@@ -223,15 +237,16 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start,
which &= ~mask;
for (i = 0; i <= 31; i++) {
- if (which & (1L<<i)) {
+ if (which & (1L<<i))
S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
- }
}
}
-
void (*pm_cpu_prep)(void);
void (*pm_cpu_sleep)(void);
+void (*pm_cpu_restore)(void);
+int (*pm_prepare)(void);
+void (*pm_finish)(void);
#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
@@ -268,6 +283,7 @@ static int s3c_pm_enter(suspend_state_t state)
/* save all necessary core registers not covered by the drivers */
s3c_pm_save_gpios();
+ s3c_pm_saved_gpios();
s3c_pm_save_uarts();
s3c_pm_save_core();
@@ -294,24 +310,35 @@ static int s3c_pm_enter(suspend_state_t state)
s3c_pm_arch_stop_clocks();
+ printk(KERN_ALERT "PM: SLEEP\n");
+
/* s3c_cpu_save will also act as our return point from when
* we resume as it saves its own register state and restores it
* during the resume. */
+ printk(KERN_ALERT "ARM_COREx_STATUS CORE1[0x%08x], CORE2[0x%08x], CORE3[0x%08x]\n",
+ __raw_readl(S5P_VA_PMU + 0x2084),
+ __raw_readl(S5P_VA_PMU + 0x2104),
+ __raw_readl(S5P_VA_PMU + 0x2184));
+
s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
/* restore the cpu state using the kernel's cpu init code. */
cpu_init();
- /* restore the system state */
-
s3c_pm_restore_core();
s3c_pm_restore_uarts();
s3c_pm_restore_gpios();
+ s3c_pm_restored_gpios();
s3c_pm_debug_init();
+ /* restore the system state */
+
+ if (pm_cpu_restore)
+ pm_cpu_restore();
+
/* check what irq (if any) restored the system */
s3c_pm_arch_show_resume_irqs();
@@ -334,19 +361,43 @@ static int s3c_pm_prepare(void)
/* prepare check area if configured */
s3c_pm_check_prepare();
+
+ if (pm_prepare)
+ pm_prepare();
+
return 0;
}
static void s3c_pm_finish(void)
{
+ if (pm_finish)
+ pm_finish();
+
s3c_pm_check_cleanup();
}
+#if defined(CONFIG_CHARGER_MANAGER)
+static bool s3c_cm_suspend_again(void)
+{
+ bool ret;
+
+ if (!is_charger_manager_active())
+ return false;
+
+ ret = cm_suspend_again();
+
+ return ret;
+}
+#endif
+
static const struct platform_suspend_ops s3c_pm_ops = {
.enter = s3c_pm_enter,
.prepare = s3c_pm_prepare,
.finish = s3c_pm_finish,
.valid = suspend_valid_only_mem,
+#if defined(CONFIG_CHARGER_MANAGER)
+ .suspend_again = s3c_cm_suspend_again,
+#endif
};
/* s3c_pm_init
@@ -358,7 +409,7 @@ static const struct platform_suspend_ops s3c_pm_ops = {
int __init s3c_pm_init(void)
{
- printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+ printk(KERN_INFO "S3C Power Management, Copyright 2004 Simtec Electronics\n");
suspend_set_ops(&s3c_pm_ops);
return 0;
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
index f37457c..bdc892a 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -19,10 +19,12 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pwm.h>
+#include <linux/gpio.h>
#include <mach/map.h>
#include <plat/regs-timer.h>
+#include <plat/gpio-cfg.h>
struct pwm_device {
struct list_head list;
@@ -39,11 +41,28 @@ struct pwm_device {
unsigned char running;
unsigned char use_count;
unsigned char pwm_id;
+
+ unsigned long tcfg0;
+};
+
+struct s3c_pwm_pdata {
+ /* PWM output port */
+ unsigned int gpio_no;
+ const char *gpio_name;
+ unsigned int gpio_set_value;
};
+struct s3c_pwm_pdata *to_pwm_pdata(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return (struct s3c_pwm_pdata *)pdev->dev.platform_data;
+}
+
#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
static struct clk *clk_scaler[2];
+static DEFINE_SPINLOCK(pwm_spin_lock);
static inline int pwm_is_tdiv(struct pwm_device *pwm)
{
@@ -108,15 +127,21 @@ int pwm_enable(struct pwm_device *pwm)
unsigned long flags;
unsigned long tcon;
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ if (!pwm->running) {
+ clk_enable(pwm->clk);
+ clk_enable(pwm->clk_div);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ pwm->running = 1;
+ }
+
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
- pwm->running = 1;
return 0;
}
@@ -127,15 +152,19 @@ void pwm_disable(struct pwm_device *pwm)
unsigned long flags;
unsigned long tcon;
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
- tcon = __raw_readl(S3C2410_TCON);
- tcon &= ~pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ if (pwm->running) {
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon &= ~pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ clk_disable(pwm->clk);
+ clk_disable(pwm->clk_div);
+ pwm->running = 0;
+ }
- pwm->running = 0;
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
}
EXPORT_SYMBOL(pwm_disable);
@@ -185,6 +214,9 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
/* The TCMP and TCNT can be read without a lock, they're not
* shared between the timers. */
+ clk_enable(pwm->clk);
+ clk_enable(pwm->clk_div);
+
tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
@@ -227,12 +259,13 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
/* Update the PWM register block. */
- local_irq_save(flags);
+ spin_lock_irqsave(&pwm_spin_lock, flags);
__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_invert(pwm);
tcon |= pwm_tcon_manulupdate(pwm);
tcon |= pwm_tcon_autoreload(pwm);
__raw_writel(tcon, S3C2410_TCON);
@@ -240,7 +273,10 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
tcon &= ~pwm_tcon_manulupdate(pwm);
__raw_writel(tcon, S3C2410_TCON);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&pwm_spin_lock, flags);
+
+ clk_disable(pwm->clk);
+ clk_disable(pwm->clk_div);
return 0;
}
@@ -263,11 +299,21 @@ static int s3c_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pwm_device *pwm;
- unsigned long flags;
- unsigned long tcon;
+ struct s3c_pwm_pdata *pdata = to_pwm_pdata(dev);
unsigned int id = pdev->id;
int ret;
+ if (gpio_is_valid(pdata->gpio_no)) {
+ ret = gpio_request(pdata->gpio_no, pdata->gpio_name);
+ if (ret)
+ printk(KERN_ERR "failed to get GPIO for PWM0\n");
+ s3c_gpio_cfgpin(pdata->gpio_no, pdata->gpio_set_value);
+
+ /* Inserting the following for commit 2010.02.26: [BACKLIGHT] Fix PWM
+ driver handling GPIO routine (request but not free)*/
+ gpio_free(pdata->gpio_no);
+ }
+
if (id == 4) {
dev_err(dev, "TIMER4 is currently not supported\n");
return -ENXIO;
@@ -299,15 +345,6 @@ static int s3c_pwm_probe(struct platform_device *pdev)
goto err_clk_tin;
}
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
-
ret = pwm_register(pwm);
if (ret) {
dev_err(dev, "failed to register pwm\n");
@@ -359,18 +396,24 @@ static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
pwm->period_ns = 0;
pwm->duty_ns = 0;
+ clk_enable(pwm->clk);
+
+ pwm->tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ clk_disable(pwm->clk);
+
return 0;
}
static int s3c_pwm_resume(struct platform_device *pdev)
{
struct pwm_device *pwm = platform_get_drvdata(pdev);
- unsigned long tcon;
- /* Restore invertion */
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
+ clk_enable(pwm->clk);
+
+ __raw_writel(pwm->tcfg0, S3C2410_TCFG0);
+
+ clk_disable(pwm->clk);
return 0;
}
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
index f85638c..92f30f7 100644
--- a/arch/arm/plat-samsung/s3c-pl330.c
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -17,6 +17,9 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+#include <linux/pm_runtime.h>
+#endif
#include <asm/hardware/pl330.h>
@@ -498,9 +501,11 @@ static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
spin_lock_irqsave(&res_lock, flags);
- r->x = NULL;
+ if (!r->infiniteloop) {
+ r->x = NULL;
- s3c_pl330_submit(ch, r);
+ s3c_pl330_submit(ch, r);
+ }
spin_unlock_irqrestore(&res_lock, flags);
@@ -513,12 +518,20 @@ static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
res = S3C2410_RES_ERR;
/* If last request had some xfer */
- if (xl) {
- xfer = container_of(xl, struct s3c_pl330_xfer, px);
- _finish_off(xfer, res, 0);
+ if (!r->infiniteloop) {
+ if (xl) {
+ xfer = container_of(xl, struct s3c_pl330_xfer, px);
+ _finish_off(xfer, res, 0);
+ } else {
+ dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
+ __func__, __LINE__);
+ }
} else {
- dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
- __func__, __LINE__);
+ /* Do callback */
+
+ xfer = container_of(xl, struct s3c_pl330_xfer, px);
+ if (ch->callback_fn)
+ ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
}
}
@@ -660,8 +673,8 @@ ctrl_exit:
}
EXPORT_SYMBOL(s3c2410_dma_ctrl);
-int s3c2410_dma_enqueue(enum dma_ch id, void *token,
- dma_addr_t addr, int size)
+int s3c2410_dma_enqueue_ring(enum dma_ch id, void *token,
+ dma_addr_t addr, int size, int numofblock)
{
struct s3c_pl330_chan *ch;
struct s3c_pl330_xfer *xfer;
@@ -669,7 +682,6 @@ int s3c2410_dma_enqueue(enum dma_ch id, void *token,
int idx, ret = 0;
spin_lock_irqsave(&res_lock, flags);
-
ch = id_to_chan(id);
/* Error if invalid or free channel */
@@ -709,11 +721,13 @@ int s3c2410_dma_enqueue(enum dma_ch id, void *token,
/* Try submitting on either request */
idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
- if (!ch->req[idx].x)
+ if (!ch->req[idx].x) {
+ ch->req[idx].infiniteloop = numofblock;
s3c_pl330_submit(ch, &ch->req[idx]);
- else
+ } else {
+ ch->req[1 - idx].infiniteloop = numofblock;
s3c_pl330_submit(ch, &ch->req[1 - idx]);
-
+ }
spin_unlock_irqrestore(&res_lock, flags);
if (ch->options & S3C2410_DMAF_AUTOSTART)
@@ -726,7 +740,7 @@ enq_exit:
return ret;
}
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
+EXPORT_SYMBOL(s3c2410_dma_enqueue_ring);
int s3c2410_dma_request(enum dma_ch id,
struct s3c2410_dma_client *client,
@@ -747,9 +761,24 @@ int s3c2410_dma_request(enum dma_ch id,
dmac = ch->dmac;
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* enable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_get_sync(dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
+ clk_enable(dmac->clk);
+
ch->pl330_chan_id = pl330_request_channel(dmac->pi);
if (!ch->pl330_chan_id) {
chan_release(ch);
+ clk_disable(dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_put(dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
ret = -EBUSY;
goto req_exit;
}
@@ -860,7 +889,14 @@ int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
pl330_release_channel(ch->pl330_chan_id);
ch->pl330_chan_id = NULL;
+ clk_disable(ch->dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ spin_unlock_irqrestore(&res_lock, flags);
+ pm_runtime_put(ch->dmac->pi->dev);
+ spin_lock_irqsave(&res_lock, flags);
+#endif
chan_release(ch);
free_exit:
@@ -986,6 +1022,18 @@ int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
ch->rqcfg.src_inc = 1;
ch->rqcfg.dst_inc = 0;
break;
+ case S3C_DMA_MEM2MEM:
+ ch->req[0].rqtype = MEMTOMEM;
+ ch->req[1].rqtype = MEMTOMEM;
+ ch->rqcfg.src_inc = 1;
+ ch->rqcfg.dst_inc = 1;
+ break;
+ case S3C_DMA_MEM2MEM_SET:
+ ch->req[0].rqtype = MEMTOMEM;
+ ch->req[1].rqtype = MEMTOMEM;
+ ch->rqcfg.src_inc = 0;
+ ch->rqcfg.dst_inc = 1;
+ break;
default:
ret = -EINVAL;
goto devcfg_exit;
@@ -1057,6 +1105,16 @@ static int pl330_probe(struct platform_device *pdev)
goto probe_err1;
}
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* to use the runtime PM helper functions */
+ pm_runtime_enable(&pdev->dev);
+ /* enable the power domain */
+ if (pm_runtime_get_sync(&pdev->dev)) {
+ dev_err(&pdev->dev, "failed to get runtime pm\n");
+ ret = -ENODEV;
+ goto probe_err1;
+ }
+#endif
request_mem_region(res->start, resource_size(res), pdev->name);
pl330_info->base = ioremap(res->start, resource_size(res));
@@ -1131,6 +1189,11 @@ static int pl330_probe(struct platform_device *pdev)
pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
+ clk_disable(s3c_pl330_dmac->clk);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ pm_runtime_put(&pdev->dev);
+#endif
return 0;
probe_err8:
@@ -1147,6 +1210,11 @@ probe_err3:
iounmap(pl330_info->base);
probe_err2:
release_mem_region(res->start, resource_size(res));
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+#endif
probe_err1:
kfree(pl330_info);
@@ -1156,7 +1224,7 @@ probe_err1:
static int pl330_remove(struct platform_device *pdev)
{
struct s3c_pl330_dmac *dmac, *d;
- struct s3c_pl330_chan *ch;
+ struct s3c_pl330_chan *ch, *ch_tmp;
unsigned long flags;
int del, found;
@@ -1180,7 +1248,7 @@ static int pl330_remove(struct platform_device *pdev)
dmac = d;
/* Remove all Channels that are managed only by this DMAC */
- list_for_each_entry(ch, &chan_list, node) {
+ list_for_each_entry_safe(ch, ch_tmp, &chan_list, node) {
/* Only channels that are handled by this DMAC */
if (iface_of_dmac(dmac, ch->id))
@@ -1205,15 +1273,20 @@ static int pl330_remove(struct platform_device *pdev)
}
/* Disable operation clock */
- clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */
list_del(&dmac->node);
kfree(dmac);
+#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
+ /* disable the power domain */
spin_unlock_irqrestore(&res_lock, flags);
-
+ pm_runtime_put(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+#else
+ spin_unlock_irqrestore(&res_lock, flags);
+#endif
return 0;
}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 3b3776d..f91b98d 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1113,3 +1113,9 @@ blissc MACH_BLISSC BLISSC 3491
thales_adc MACH_THALES_ADC THALES_ADC 3492
ubisys_p9d_evp MACH_UBISYS_P9D_EVP UBISYS_P9D_EVP 3493
atdgp318 MACH_ATDGP318 ATDGP318 3494
+smdk4212 MACH_SMDK4212 SMDK4212 3698
+smdk4412 MACH_SMDK4412 SMDK4412 3765
+slp_pq MACH_SLP_PQ SLP_PQ 3766
+slp_pq_lte MACH_SLP_PQ_LTE SLP_PQ_LTE 3767
+smdk5210 MACH_SMDK5210 SMDK5210 3774
+smdk5250 MACH_SMDK5250 SMDK5250 3825
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index 4fa9903..c1a9784 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -10,7 +10,7 @@
*
* Basic entry code, called from the kernel's undefined instruction trap.
* r0 = faulted instruction
- * r5 = faulted PC+4
+ * r2 = faulted PC+4
* r9 = successful return
* r10 = thread_info structure
* lr = failure return
@@ -26,6 +26,7 @@ ENTRY(do_vfp)
str r11, [r10, #TI_PREEMPT]
#endif
enable_irq
+ str r2, [sp, #S_PC] @ update regs->ARM_pc for Thumb 2 case
ldr r4, .LCvfp
ldr r11, [r10, #TI_CPU] @ CPU number
add r10, r10, #TI_VFPSTATE @ r10 = workspace
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 9897dcf..404538a 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -77,15 +77,12 @@ ENTRY(vfp_support_entry)
bne look_for_VFP_exceptions @ VFP is already enabled
DBGSTR1 "enable %x", r10
- ldr r3, last_VFP_context_address
+ ldr r3, vfp_current_hw_state_address
orr r1, r1, #FPEXC_EN @ user FPEXC has the enable bit set
- ldr r4, [r3, r11, lsl #2] @ last_VFP_context pointer
+ ldr r4, [r3, r11, lsl #2] @ vfp_current_hw_state pointer
bic r5, r1, #FPEXC_EX @ make sure exceptions are disabled
- cmp r4, r10
- beq check_for_exception @ we are returning to the same
- @ process, so the registers are
- @ still there. In this case, we do
- @ not want to drop a pending exception.
+ cmp r4, r10 @ this thread owns the hw context?
+ beq vfp_hw_state_valid
VFPFMXR FPEXC, r5 @ enable VFP, disable any pending
@ exceptions, so we can get at the
@@ -116,7 +113,7 @@ ENTRY(vfp_support_entry)
no_old_VFP_process:
DBGSTR1 "load state %p", r10
- str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer
+ str r10, [r3, r11, lsl #2] @ update the vfp_current_hw_state pointer
@ Load the saved state back into the VFP
VFPFLDMIA r10, r5 @ reload the working registers while
@ FPEXC is in a safe state
@@ -132,7 +129,8 @@ no_old_VFP_process:
#endif
VFPFMXR FPSCR, r5 @ restore status
-check_for_exception:
+@ The context stored in the VFP hardware is up to date with this thread
+vfp_hw_state_valid:
tst r1, #FPEXC_EX
bne process_exception @ might as well handle the pending
@ exception before retrying branch
@@ -207,8 +205,8 @@ ENTRY(vfp_save_state)
ENDPROC(vfp_save_state)
.align
-last_VFP_context_address:
- .word last_VFP_context
+vfp_current_hw_state_address:
+ .word vfp_current_hw_state
.macro tbl_branch, base, tmp, shift
#ifdef CONFIG_THUMB2_KERNEL
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index f25e7ec..871f03c 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -33,7 +33,13 @@ void vfp_support_entry(void);
void vfp_null_entry(void);
void (*vfp_vector)(void) = vfp_null_entry;
-union vfp_state *last_VFP_context[NR_CPUS];
+
+/*
+ * The pointer to the vfpstate structure of the thread which currently
+ * owns the context held in the VFP hardware, or NULL if the hardware
+ * context is invalid.
+ */
+union vfp_state *vfp_current_hw_state[NR_CPUS];
/*
* Dual-use variable.
@@ -57,12 +63,12 @@ static void vfp_thread_flush(struct thread_info *thread)
/*
* Disable VFP to ensure we initialize it first. We must ensure
- * that the modification of last_VFP_context[] and hardware disable
+ * that the modification of vfp_current_hw_state[] and hardware disable
* are done for the same CPU and without preemption.
*/
cpu = get_cpu();
- if (last_VFP_context[cpu] == vfp)
- last_VFP_context[cpu] = NULL;
+ if (vfp_current_hw_state[cpu] == vfp)
+ vfp_current_hw_state[cpu] = NULL;
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
put_cpu();
}
@@ -73,8 +79,8 @@ static void vfp_thread_exit(struct thread_info *thread)
union vfp_state *vfp = &thread->vfpstate;
unsigned int cpu = get_cpu();
- if (last_VFP_context[cpu] == vfp)
- last_VFP_context[cpu] = NULL;
+ if (vfp_current_hw_state[cpu] == vfp)
+ vfp_current_hw_state[cpu] = NULL;
put_cpu();
}
@@ -129,9 +135,9 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
* case the thread migrates to a different CPU. The
* restoring is done lazily.
*/
- if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) {
- vfp_save_state(last_VFP_context[cpu], fpexc);
- last_VFP_context[cpu]->hard.cpu = cpu;
+ if ((fpexc & FPEXC_EN) && vfp_current_hw_state[cpu]) {
+ vfp_save_state(vfp_current_hw_state[cpu], fpexc);
+ vfp_current_hw_state[cpu]->hard.cpu = cpu;
}
/*
* Thread migration, just force the reloading of the
@@ -139,7 +145,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
* contain stale data.
*/
if (thread->vfpstate.hard.cpu != cpu)
- last_VFP_context[cpu] = NULL;
+ vfp_current_hw_state[cpu] = NULL;
#endif
/*
@@ -412,10 +418,14 @@ static int vfp_pm_suspend(void)
/* disable, just in case */
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ } else if (vfp_current_hw_state[ti->cpu]) {
+ fmxr(FPEXC, fpexc | FPEXC_EN);
+ vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc);
+ fmxr(FPEXC, fpexc);
}
/* clear any information we had about last context state */
- memset(last_VFP_context, 0, sizeof(last_VFP_context));
+ memset(vfp_current_hw_state, 0, sizeof(vfp_current_hw_state));
return 0;
}
@@ -451,7 +461,7 @@ void vfp_sync_hwstate(struct thread_info *thread)
* If the thread we're interested in is the current owner of the
* hardware VFP state, then we need to save its state.
*/
- if (last_VFP_context[cpu] == &thread->vfpstate) {
+ if (vfp_current_hw_state[cpu] == &thread->vfpstate) {
u32 fpexc = fmrx(FPEXC);
/*
@@ -473,7 +483,7 @@ void vfp_flush_hwstate(struct thread_info *thread)
* If the thread we're interested in is the current owner of the
* hardware VFP state, then we need to save its state.
*/
- if (last_VFP_context[cpu] == &thread->vfpstate) {
+ if (vfp_current_hw_state[cpu] == &thread->vfpstate) {
u32 fpexc = fmrx(FPEXC);
fmxr(FPEXC, fpexc & ~FPEXC_EN);
@@ -482,7 +492,7 @@ void vfp_flush_hwstate(struct thread_info *thread)
* Set the context to NULL to force a reload the next time
* the thread uses the VFP.
*/
- last_VFP_context[cpu] = NULL;
+ vfp_current_hw_state[cpu] = NULL;
}
#ifdef CONFIG_SMP
@@ -514,7 +524,7 @@ static int vfp_hotplug(struct notifier_block *b, unsigned long action,
{
if (action == CPU_DYING || action == CPU_DYING_FROZEN) {
unsigned int cpu = (long)hcpu;
- last_VFP_context[cpu] = NULL;
+ vfp_current_hw_state[cpu] = NULL;
} else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
vfp_enable(NULL);
return NOTIFY_OK;
@@ -582,7 +592,6 @@ static int __init vfp_init(void)
elf_hwcap |= HWCAP_VFPv3D16;
}
#endif
-#ifdef CONFIG_NEON
/*
* Check for the presence of the Advanced SIMD
* load/store instructions, integer and single
@@ -590,10 +599,13 @@ static int __init vfp_init(void)
* for NEON if the hardware has the MVFR registers.
*/
if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+#ifdef CONFIG_NEON
if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
elf_hwcap |= HWCAP_NEON;
- }
#endif
+ if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+ elf_hwcap |= HWCAP_VFPv4;
+ }
}
return 0;
}
diff --git a/arch/avr32/boot/images/.gitignore b/arch/avr32/boot/images/.gitignore
deleted file mode 100644
index 64ea9d0..0000000
--- a/arch/avr32/boot/images/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-uImage
-uImage.srec
-vmlinux.cso
-sfdwarf.log
diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/avr32/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/blackfin/boot/.gitignore b/arch/blackfin/boot/.gitignore
deleted file mode 100644
index 229e508..0000000
--- a/arch/blackfin/boot/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-vmImage*
-vmlinux*
diff --git a/arch/blackfin/kernel/.gitignore b/arch/blackfin/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/blackfin/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/cris/boot/.gitignore b/arch/cris/boot/.gitignore
deleted file mode 100644
index 171a085..0000000
--- a/arch/cris/boot/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Image
-zImage
diff --git a/arch/ia64/kernel/.gitignore b/arch/ia64/kernel/.gitignore
deleted file mode 100644
index 21cb0da..0000000
--- a/arch/ia64/kernel/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-gate.lds
-vmlinux.lds
diff --git a/arch/m32r/kernel/.gitignore b/arch/m32r/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/m32r/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/m68k/kernel/.gitignore b/arch/m68k/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/m68k/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
deleted file mode 100644
index f210b09..0000000
--- a/arch/mips/boot/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-mkboot
-elf2ecoff
-vmlinux.*
-zImage
-zImage.tmp
-calc_vmlinuz_load_addr
diff --git a/arch/mips/kernel/.gitignore b/arch/mips/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/mips/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/mn10300/boot/.gitignore b/arch/mn10300/boot/.gitignore
deleted file mode 100644
index b6718de..0000000
--- a/arch/mn10300/boot/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-zImage
diff --git a/arch/parisc/kernel/.gitignore b/arch/parisc/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/parisc/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
deleted file mode 100644
index 12da77e..0000000
--- a/arch/powerpc/boot/.gitignore
+++ /dev/null
@@ -1,47 +0,0 @@
-addnote
-empty.c
-hack-coff
-infblock.c
-infblock.h
-infcodes.c
-infcodes.h
-inffast.c
-inffast.h
-inffixed.h
-inflate.c
-inflate.h
-inftrees.c
-inftrees.h
-infutil.c
-infutil.h
-kernel-vmlinux.strip.c
-kernel-vmlinux.strip.gz
-mktree
-uImage
-cuImage.*
-dtbImage.*
-treeImage.*
-zImage
-zImage.initrd
-zImage.bin.*
-zImage.chrp
-zImage.coff
-zImage.holly
-zImage.iseries
-zImage.*lds
-zImage.miboot
-zImage.pmac
-zImage.pseries
-zconf.h
-zlib.h
-zutil.h
-fdt.c
-fdt.h
-fdt_ro.c
-fdt_rw.c
-fdt_strerror.c
-fdt_sw.c
-fdt_wip.c
-libfdt.h
-libfdt_internal.h
-
diff --git a/arch/powerpc/kernel/.gitignore b/arch/powerpc/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/powerpc/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/powerpc/kernel/vdso32/.gitignore b/arch/powerpc/kernel/vdso32/.gitignore
deleted file mode 100644
index fea58098..0000000
--- a/arch/powerpc/kernel/vdso32/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-vdso32.lds
-vdso32.so.dbg
diff --git a/arch/powerpc/kernel/vdso64/.gitignore b/arch/powerpc/kernel/vdso64/.gitignore
deleted file mode 100644
index 77a0b42..0000000
--- a/arch/powerpc/kernel/vdso64/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-vdso64.lds
-vdso64.so.dbg
diff --git a/arch/powerpc/platforms/cell/spufs/.gitignore b/arch/powerpc/platforms/cell/spufs/.gitignore
deleted file mode 100644
index a09ee8d..0000000
--- a/arch/powerpc/platforms/cell/spufs/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-spu_save_dump.h
-spu_restore_dump.h
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
deleted file mode 100644
index 541087d..0000000
--- a/arch/sh/boot/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-zImage
-vmlinux*
-uImage*
diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore
deleted file mode 100644
index 2374a83..0000000
--- a/arch/sh/boot/compressed/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.bin.*
diff --git a/arch/sh/kernel/.gitignore b/arch/sh/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/sh/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/sh/kernel/vsyscall/.gitignore b/arch/sh/kernel/vsyscall/.gitignore
deleted file mode 100644
index 40836ad..0000000
--- a/arch/sh/kernel/vsyscall/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vsyscall.lds
diff --git a/arch/sparc/boot/.gitignore b/arch/sparc/boot/.gitignore
deleted file mode 100644
index fc6f398..0000000
--- a/arch/sparc/boot/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-btfix.S
-btfixupprep
-image
-zImage
-tftpboot.img
-vmlinux.aout
-piggyback
-
diff --git a/arch/sparc/kernel/.gitignore b/arch/sparc/kernel/.gitignore
deleted file mode 100644
index c5f676c..0000000
--- a/arch/sparc/kernel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vmlinux.lds
diff --git a/arch/um/.gitignore b/arch/um/.gitignore
deleted file mode 100644
index a73d3a1..0000000
--- a/arch/um/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-kernel/config.c
-kernel/config.tmp
-kernel/vmlinux.lds
diff --git a/arch/unicore32/.gitignore b/arch/unicore32/.gitignore
deleted file mode 100644
index 947e99c..0000000
--- a/arch/unicore32/.gitignore
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Generated include files
-#
-include/generated
-#
-# Generated ld script file
-#
-kernel/vmlinux.lds
-#
-# Generated images in boot
-#
-boot/Image
-boot/zImage
-boot/uImage
-#
-# Generated files in boot/compressed
-#
-boot/compressed/piggy.S
-boot/compressed/piggy.gzip
-boot/compressed/vmlinux
-boot/compressed/vmlinux.lds
diff --git a/arch/x86/.gitignore b/arch/x86/.gitignore
deleted file mode 100644
index 0280790..0000000
--- a/arch/x86/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-boot/compressed/vmlinux
-tools/test_get_len
-
diff --git a/arch/x86/boot/.gitignore b/arch/x86/boot/.gitignore
deleted file mode 100644
index 851fe93..0000000
--- a/arch/x86/boot/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-bootsect
-bzImage
-cpustr.h
-mkcpustr
-offsets.h
-voffset.h
-zoffset.h
-setup
-setup.bin
-setup.elf
diff --git a/arch/x86/boot/compressed/.gitignore b/arch/x86/boot/compressed/.gitignore
deleted file mode 100644
index 4a46fab..0000000
--- a/arch/x86/boot/compressed/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-relocs
-vmlinux.bin.all
-vmlinux.relocs
-vmlinux.lds
-mkpiggy
-piggy.S
diff --git a/arch/x86/boot/tools/.gitignore b/arch/x86/boot/tools/.gitignore
deleted file mode 100644
index 378eac2..0000000
--- a/arch/x86/boot/tools/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h
index f49253d7..f1e4268 100644
--- a/arch/x86/include/asm/idle.h
+++ b/arch/x86/include/asm/idle.h
@@ -1,13 +1,6 @@
#ifndef _ASM_X86_IDLE_H
#define _ASM_X86_IDLE_H
-#define IDLE_START 1
-#define IDLE_END 2
-
-struct notifier_block;
-void idle_notifier_register(struct notifier_block *n);
-void idle_notifier_unregister(struct notifier_block *n);
-
#ifdef CONFIG_X86_64
void enter_idle(void);
void exit_idle(void);
diff --git a/arch/x86/kernel/.gitignore b/arch/x86/kernel/.gitignore
deleted file mode 100644
index 08f4fd7..0000000
--- a/arch/x86/kernel/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-vsyscall.lds
-vsyscall_32.lds
-vmlinux.lds
diff --git a/arch/x86/kernel/acpi/realmode/.gitignore b/arch/x86/kernel/acpi/realmode/.gitignore
deleted file mode 100644
index 58f1f48..0000000
--- a/arch/x86/kernel/acpi/realmode/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-wakeup.bin
-wakeup.elf
-wakeup.lds
diff --git a/arch/x86/kernel/cpu/.gitignore b/arch/x86/kernel/cpu/.gitignore
deleted file mode 100644
index 667df55..0000000
--- a/arch/x86/kernel/cpu/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-capflags.c
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ca6f7ab..63c8aed 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -56,31 +56,17 @@ asmlinkage extern void ret_from_fork(void);
DEFINE_PER_CPU(unsigned long, old_rsp);
static DEFINE_PER_CPU(unsigned char, is_idle);
-static ATOMIC_NOTIFIER_HEAD(idle_notifier);
-
-void idle_notifier_register(struct notifier_block *n)
-{
- atomic_notifier_chain_register(&idle_notifier, n);
-}
-EXPORT_SYMBOL_GPL(idle_notifier_register);
-
-void idle_notifier_unregister(struct notifier_block *n)
-{
- atomic_notifier_chain_unregister(&idle_notifier, n);
-}
-EXPORT_SYMBOL_GPL(idle_notifier_unregister);
-
void enter_idle(void)
{
percpu_write(is_idle, 1);
- atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
+ idle_notifier_call_chain(IDLE_START);
}
static void __exit_idle(void)
{
if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
return;
- atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
+ idle_notifier_call_chain(IDLE_END);
}
/* Called from interrupts to signify idle end */
diff --git a/arch/x86/lib/.gitignore b/arch/x86/lib/.gitignore
deleted file mode 100644
index 8df89f0..0000000
--- a/arch/x86/lib/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-inat-tables.c
diff --git a/arch/x86/vdso/.gitignore b/arch/x86/vdso/.gitignore
deleted file mode 100644
index 60274d5..0000000
--- a/arch/x86/vdso/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-vdso.lds
-vdso-syms.lds
-vdso32-syms.lds
-vdso32-syscall-syms.lds
-vdso32-sysenter-syms.lds
-vdso32-int80-syms.lds
diff --git a/arch/x86/vdso/vdso32/.gitignore b/arch/x86/vdso/vdso32/.gitignore
deleted file mode 100644
index e45fba9..0000000
--- a/arch/x86/vdso/vdso32/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-vdso32.lds